2 #include "i915_drm_winsys.h"
3 #include "util/u_memory.h"
7 #define BATCH_RESERVED 16
9 #define INTEL_DEFAULT_RELOCS 100
10 #define INTEL_MAX_RELOCS 400
12 #define INTEL_BATCH_NO_CLIPRECTS 0x1
13 #define INTEL_BATCH_CLIPRECTS 0x2
16 #undef INTEL_MAP_BATCHBUFFER
18 #define INTEL_ALWAYS_FLUSH
20 struct i915_drm_batchbuffer
22 struct i915_winsys_batchbuffer base
;
29 static INLINE
struct i915_drm_batchbuffer
*
30 i915_drm_batchbuffer(struct i915_winsys_batchbuffer
*batch
)
32 return (struct i915_drm_batchbuffer
*)batch
;
36 i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer
*batch
)
38 struct i915_drm_winsys
*idws
= i915_drm_winsys(batch
->base
.iws
);
42 drm_intel_bo_unreference(batch
->bo
);
43 batch
->bo
= drm_intel_bo_alloc(idws
->pools
.gem
,
44 "gallium3d_batchbuffer",
48 #ifdef INTEL_MAP_BATCHBUFFER
50 ret
= drm_intel_gem_bo_map_gtt(batch
->bo
);
52 ret
= drm_intel_bo_map(batch
->bo
, TRUE
);
55 batch
->base
.map
= batch
->bo
->virtual;
60 memset(batch
->base
.map
, 0, batch
->actual_size
);
61 batch
->base
.ptr
= batch
->base
.map
;
62 batch
->base
.size
= batch
->actual_size
- BATCH_RESERVED
;
63 batch
->base
.relocs
= 0;
66 static struct i915_winsys_batchbuffer
*
67 i915_drm_batchbuffer_create(struct i915_winsys
*iws
)
69 struct i915_drm_winsys
*idws
= i915_drm_winsys(iws
);
70 struct i915_drm_batchbuffer
*batch
= CALLOC_STRUCT(i915_drm_batchbuffer
);
72 batch
->actual_size
= idws
->max_batch_size
;
74 #ifdef INTEL_MAP_BATCHBUFFER
75 batch
->base
.map
= NULL
;
77 batch
->base
.map
= MALLOC(batch
->actual_size
);
79 batch
->base
.ptr
= NULL
;
82 batch
->base
.relocs
= 0;
83 batch
->base
.max_relocs
= 300;/*INTEL_DEFAULT_RELOCS;*/
85 batch
->base
.iws
= iws
;
87 i915_drm_batchbuffer_reset(batch
);
93 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer
*ibatch
,
94 struct i915_winsys_buffer
*buffer
,
95 enum i915_winsys_buffer_usage usage
,
98 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
99 unsigned write_domain
= 0;
100 unsigned read_domain
= 0;
104 assert(batch
->base
.relocs
< batch
->base
.max_relocs
);
106 if (usage
== I915_USAGE_SAMPLER
) {
108 read_domain
= I915_GEM_DOMAIN_SAMPLER
;
110 } else if (usage
== I915_USAGE_RENDER
) {
111 write_domain
= I915_GEM_DOMAIN_RENDER
;
112 read_domain
= I915_GEM_DOMAIN_RENDER
;
114 } else if (usage
== I915_USAGE_2D_TARGET
) {
115 write_domain
= I915_GEM_DOMAIN_RENDER
;
116 read_domain
= I915_GEM_DOMAIN_RENDER
;
118 } else if (usage
== I915_USAGE_2D_SOURCE
) {
120 read_domain
= I915_GEM_DOMAIN_RENDER
;
122 } else if (usage
== I915_USAGE_VERTEX
) {
124 read_domain
= I915_GEM_DOMAIN_VERTEX
;
131 offset
= (unsigned)(batch
->base
.ptr
- batch
->base
.map
);
133 ret
= drm_intel_bo_emit_reloc(batch
->bo
, offset
,
134 intel_bo(buffer
), pre_add
,
138 ((uint32_t*)batch
->base
.ptr
)[0] = intel_bo(buffer
)->offset
+ pre_add
;
139 batch
->base
.ptr
+= 4;
142 batch
->base
.relocs
++;
148 i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer
*ibatch
,
149 struct pipe_fence_handle
**fence
)
151 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
156 assert(i915_winsys_batchbuffer_space(ibatch
) >= 0);
158 used
= batch
->base
.ptr
- batch
->base
.map
;
159 assert((used
& 3) == 0);
162 #ifdef INTEL_ALWAYS_FLUSH
163 /* MI_FLUSH | FLUSH_MAP_CACHE */
164 i915_winsys_batchbuffer_dword(ibatch
, (0x4<<23)|(1<<0));
168 if ((used
& 4) == 0) {
170 i915_winsys_batchbuffer_dword(ibatch
, 0);
172 /* MI_BATCH_BUFFER_END */
173 i915_winsys_batchbuffer_dword(ibatch
, (0xA<<23));
175 used
= batch
->base
.ptr
- batch
->base
.map
;
176 assert((used
& 4) == 0);
178 #ifdef INTEL_MAP_BATCHBUFFER
180 drm_intel_gem_bo_unmap_gtt(batch
->bo
);
182 drm_intel_bo_unmap(batch
->bo
);
185 drm_intel_bo_subdata(batch
->bo
, 0, used
, batch
->base
.map
);
188 /* Do the sending to HW */
189 ret
= drm_intel_bo_exec(batch
->bo
, used
, NULL
, 0, 0);
192 if (i915_drm_winsys(ibatch
->iws
)->dump_cmd
) {
194 drm_intel_bo_map(batch
->bo
, FALSE
);
195 ptr
= (unsigned*)batch
->bo
->virtual;
197 debug_printf("%s:\n", __func__
);
198 for (i
= 0; i
< used
/ 4; i
++, ptr
++) {
199 debug_printf("\t%08x: %08x\n", i
*4, *ptr
);
202 drm_intel_bo_unmap(batch
->bo
);
204 #ifdef INTEL_RUN_SYNC
205 drm_intel_bo_map(batch
->bo
, FALSE
);
206 drm_intel_bo_unmap(batch
->bo
);
211 ibatch
->iws
->fence_reference(ibatch
->iws
, fence
, NULL
);
213 #ifdef INTEL_RUN_SYNC
214 /* we run synced to GPU so just pass null */
215 (*fence
) = i915_drm_fence_create(NULL
);
217 (*fence
) = i915_drm_fence_create(batch
->bo
);
221 i915_drm_batchbuffer_reset(batch
);
225 i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer
*ibatch
)
227 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
230 drm_intel_bo_unreference(batch
->bo
);
232 #ifndef INTEL_MAP_BATCHBUFFER
233 FREE(batch
->base
.map
);
238 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys
*idws
)
240 idws
->base
.batchbuffer_create
= i915_drm_batchbuffer_create
;
241 idws
->base
.batchbuffer_reloc
= i915_drm_batchbuffer_reloc
;
242 idws
->base
.batchbuffer_flush
= i915_drm_batchbuffer_flush
;
243 idws
->base
.batchbuffer_destroy
= i915_drm_batchbuffer_destroy
;