i915g: Use unchecked writes in sw winsys batchbuffer
[mesa.git] / src / gallium / winsys / i915 / sw / i915_sw_batchbuffer.c
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 *
25 i915_sw_batchbuffer(struct i915_winsys_batchbuffer *batch)
26 {
27 return (struct i915_sw_batchbuffer *)batch;
28 }
29
30 static void
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 *
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 batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
53
54 batch->base.iws = iws;
55
56 i915_sw_batchbuffer_reset(batch);
57
58 return &batch->base;
59 }
60
61 static int
62 i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
63 struct i915_winsys_buffer *buffer,
64 enum i915_winsys_buffer_usage usage,
65 unsigned pre_add, boolean fenced)
66 {
67 struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
68 int ret = 0;
69
70 assert(batch->base.relocs < batch->base.max_relocs);
71
72 if (usage == I915_USAGE_SAMPLER) {
73
74 } else if (usage == I915_USAGE_RENDER) {
75
76 } else if (usage == I915_USAGE_2D_TARGET) {
77
78 } else if (usage == I915_USAGE_2D_SOURCE) {
79
80 } else if (usage == I915_USAGE_VERTEX) {
81
82 } else {
83 assert(0);
84 return -1;
85 }
86
87 ((uint32_t*)batch->base.ptr)[0] = 0;
88 batch->base.ptr += 4;
89
90 if (!ret)
91 batch->base.relocs++;
92
93 return ret;
94 }
95
96 static void
97 i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
98 struct pipe_fence_handle **fence)
99 {
100 struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
101 unsigned used = 0;
102
103 assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
104
105 used = batch->base.ptr - batch->base.map;
106 assert((used & 3) == 0);
107
108 #ifdef INTEL_ALWAYS_FLUSH
109 /* MI_FLUSH | FLUSH_MAP_CACHE */
110 i915_winsys_batchbuffer_dword_unchecked(ibatch, (0x4<<23)|(1<<0));
111 used += 4;
112 #endif
113
114 if ((used & 4) == 0) {
115 /* MI_NOOP */
116 i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
117 }
118 /* MI_BATCH_BUFFER_END */
119 i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
120
121 used = batch->base.ptr - batch->base.map;
122 assert((used & 4) == 0);
123
124 if (i915_sw_winsys(ibatch->iws)->dump_cmd) {
125 i915_dump_batchbuffer(ibatch);
126 }
127
128 if (fence) {
129 ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
130
131 (*fence) = i915_sw_fence_create();
132 }
133
134 i915_sw_batchbuffer_reset(batch);
135 }
136
137 static void
138 i915_sw_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
139 {
140 struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
141
142 FREE(batch->base.map);
143 FREE(batch);
144 }
145
146 void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *isws)
147 {
148 isws->base.batchbuffer_create = i915_sw_batchbuffer_create;
149 isws->base.batchbuffer_reloc = i915_sw_batchbuffer_reloc;
150 isws->base.batchbuffer_flush = i915_sw_batchbuffer_flush;
151 isws->base.batchbuffer_destroy = i915_sw_batchbuffer_destroy;
152 }