1 
2 #include "i915_sw_winsys.h"
3 #include "i915/i915_batchbuffer.h"
4 #include "i915/i915_debug.h"
5 #include "util/u_memory.h"
6 
7 #define BATCH_RESERVED 16
8 
9 #define INTEL_DEFAULT_RELOCS 100
10 #define INTEL_MAX_RELOCS 400
11 
12 #define INTEL_BATCH_NO_CLIPRECTS 0x1
13 #define INTEL_BATCH_CLIPRECTS    0x2
14 
15 #define INTEL_ALWAYS_FLUSH
16 
17 struct i915_sw_batchbuffer
18 {
19    struct i915_winsys_batchbuffer base;
20 
21    size_t actual_size;
22 };
23 
24 static INLINE struct i915_sw_batchbuffer *
i915_sw_batchbuffer(struct i915_winsys_batchbuffer * batch)25 i915_sw_batchbuffer(struct i915_winsys_batchbuffer *batch)
26 {
27    return (struct i915_sw_batchbuffer *)batch;
28 }
29 
30 static void
i915_sw_batchbuffer_reset(struct i915_sw_batchbuffer * batch)31 i915_sw_batchbuffer_reset(struct i915_sw_batchbuffer *batch)
32 {
33    memset(batch->base.map, 0, batch->actual_size);
34    batch->base.ptr = batch->base.map;
35    batch->base.size = batch->actual_size - BATCH_RESERVED;
36    batch->base.relocs = 0;
37 }
38 
39 static struct i915_winsys_batchbuffer *
i915_sw_batchbuffer_create(struct i915_winsys * iws)40 i915_sw_batchbuffer_create(struct i915_winsys *iws)
41 {
42    struct i915_sw_winsys *isws = i915_sw_winsys(iws);
43    struct i915_sw_batchbuffer *batch = CALLOC_STRUCT(i915_sw_batchbuffer);
44 
45    batch->actual_size = isws->max_batch_size;
46 
47    batch->base.map = MALLOC(batch->actual_size);
48    batch->base.ptr = NULL;
49    batch->base.size = 0;
50 
51    batch->base.relocs = 0;
52 
53    batch->base.iws = iws;
54 
55    i915_sw_batchbuffer_reset(batch);
56 
57    return &batch->base;
58 }
59 
60 static boolean
i915_sw_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer * batch,struct i915_winsys_buffer ** buffer,int num_of_buffers)61 i915_sw_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch,
62 				     struct i915_winsys_buffer **buffer,
63 				     int num_of_buffers)
64 {
65    return TRUE;
66 }
67 
68 static int
i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer * ibatch,struct i915_winsys_buffer * buffer,enum i915_winsys_buffer_usage usage,unsigned pre_add,boolean fenced)69 i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
70                           struct i915_winsys_buffer *buffer,
71                           enum i915_winsys_buffer_usage usage,
72                           unsigned pre_add, boolean fenced)
73 {
74    struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
75    int ret = 0;
76 
77    if (usage == I915_USAGE_SAMPLER) {
78 
79    } else if (usage == I915_USAGE_RENDER) {
80 
81    } else if (usage == I915_USAGE_2D_TARGET) {
82 
83    } else if (usage == I915_USAGE_2D_SOURCE) {
84 
85    } else if (usage == I915_USAGE_VERTEX) {
86 
87    } else {
88       assert(0);
89       return -1;
90    }
91 
92    ((uint32_t*)batch->base.ptr)[0] = 0;
93    batch->base.ptr += 4;
94 
95    if (!ret)
96       batch->base.relocs++;
97 
98    return ret;
99 }
100 
101 static void
i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer * ibatch,struct pipe_fence_handle ** fence)102 i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
103                           struct pipe_fence_handle **fence)
104 {
105    struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
106    unsigned used = 0;
107 
108    assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
109 
110    used = batch->base.ptr - batch->base.map;
111    assert((used & 3) == 0);
112 
113 #ifdef INTEL_ALWAYS_FLUSH
114    /* MI_FLUSH | FLUSH_MAP_CACHE */
115    i915_winsys_batchbuffer_dword_unchecked(ibatch, (0x4<<23)|(1<<0));
116    used += 4;
117 #endif
118 
119    if ((used & 4) == 0) {
120       /* MI_NOOP */
121       i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
122    }
123    /* MI_BATCH_BUFFER_END */
124    i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
125 
126    used = batch->base.ptr - batch->base.map;
127    assert((used & 4) == 0);
128 
129    if (i915_sw_winsys(ibatch->iws)->dump_cmd) {
130       i915_dump_batchbuffer(ibatch);
131    }
132 
133    if (fence) {
134       ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
135 
136       (*fence) = i915_sw_fence_create();
137    }
138 
139    i915_sw_batchbuffer_reset(batch);
140 }
141 
142 static void
i915_sw_batchbuffer_destroy(struct i915_winsys_batchbuffer * ibatch)143 i915_sw_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
144 {
145    struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
146 
147    FREE(batch->base.map);
148    FREE(batch);
149 }
150 
i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys * isws)151 void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *isws)
152 {
153    isws->base.batchbuffer_create = i915_sw_batchbuffer_create;
154    isws->base.validate_buffers = i915_sw_batchbuffer_validate_buffers;
155    isws->base.batchbuffer_reloc = i915_sw_batchbuffer_reloc;
156    isws->base.batchbuffer_flush = i915_sw_batchbuffer_flush;
157    isws->base.batchbuffer_destroy = i915_sw_batchbuffer_destroy;
158 }
159