2 #include "i915_drm_winsys.h"
3 #include "util/u_memory.h"
6 #include "i915/i915_debug.h"
10 #define BATCH_RESERVED 16
12 #define INTEL_DEFAULT_RELOCS 100
13 #define INTEL_MAX_RELOCS 400
15 #define INTEL_BATCH_NO_CLIPRECTS 0x1
16 #define INTEL_BATCH_CLIPRECTS 0x2
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
);
41 drm_intel_bo_unreference(batch
->bo
);
42 batch
->bo
= drm_intel_bo_alloc(idws
->gem_manager
,
43 "gallium3d_batchbuffer",
47 memset(batch
->base
.map
, 0, batch
->actual_size
);
48 batch
->base
.ptr
= batch
->base
.map
;
49 batch
->base
.size
= batch
->actual_size
- BATCH_RESERVED
;
50 batch
->base
.relocs
= 0;
53 static struct i915_winsys_batchbuffer
*
54 i915_drm_batchbuffer_create(struct i915_winsys
*iws
)
56 struct i915_drm_winsys
*idws
= i915_drm_winsys(iws
);
57 struct i915_drm_batchbuffer
*batch
= CALLOC_STRUCT(i915_drm_batchbuffer
);
59 batch
->actual_size
= idws
->max_batch_size
;
61 batch
->base
.map
= MALLOC(batch
->actual_size
);
62 batch
->base
.ptr
= NULL
;
65 batch
->base
.relocs
= 0;
66 batch
->base
.max_relocs
= 300;/*INTEL_DEFAULT_RELOCS;*/
68 batch
->base
.iws
= iws
;
70 i915_drm_batchbuffer_reset(batch
);
76 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer
*ibatch
,
77 struct i915_winsys_buffer
*buffer
,
78 enum i915_winsys_buffer_usage usage
,
79 unsigned pre_add
, boolean fenced
)
81 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
82 unsigned write_domain
= 0;
83 unsigned read_domain
= 0;
87 assert(batch
->base
.relocs
< batch
->base
.max_relocs
);
90 case I915_USAGE_SAMPLER
:
92 read_domain
= I915_GEM_DOMAIN_SAMPLER
;
94 case I915_USAGE_RENDER
:
95 write_domain
= I915_GEM_DOMAIN_RENDER
;
96 read_domain
= I915_GEM_DOMAIN_RENDER
;
98 case I915_USAGE_2D_TARGET
:
99 write_domain
= I915_GEM_DOMAIN_RENDER
;
100 read_domain
= I915_GEM_DOMAIN_RENDER
;
102 case I915_USAGE_2D_SOURCE
:
104 read_domain
= I915_GEM_DOMAIN_RENDER
;
106 case I915_USAGE_VERTEX
:
108 read_domain
= I915_GEM_DOMAIN_VERTEX
;
115 offset
= (unsigned)(batch
->base
.ptr
- batch
->base
.map
);
118 ret
= drm_intel_bo_emit_reloc_fence(batch
->bo
, offset
,
119 intel_bo(buffer
), pre_add
,
123 ret
= drm_intel_bo_emit_reloc(batch
->bo
, offset
,
124 intel_bo(buffer
), pre_add
,
128 ((uint32_t*)batch
->base
.ptr
)[0] = intel_bo(buffer
)->offset
+ pre_add
;
129 batch
->base
.ptr
+= 4;
132 batch
->base
.relocs
++;
138 i915_drm_throttle(struct i915_drm_winsys
*idws
)
140 drmIoctl(idws
->fd
, DRM_IOCTL_I915_GEM_THROTTLE
, NULL
);
144 i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer
*ibatch
,
145 struct pipe_fence_handle
**fence
)
147 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
151 /* MI_BATCH_BUFFER_END */
152 i915_winsys_batchbuffer_dword_unchecked(ibatch
, (0xA<<23));
154 used
= batch
->base
.ptr
- batch
->base
.map
;
157 i915_winsys_batchbuffer_dword_unchecked(ibatch
, 0);
161 /* Do the sending to HW */
162 ret
= drm_intel_bo_subdata(batch
->bo
, 0, used
, batch
->base
.map
);
163 if (ret
== 0 && i915_drm_winsys(ibatch
->iws
)->send_cmd
)
164 ret
= drm_intel_bo_exec(batch
->bo
, used
, NULL
, 0, 0);
166 i915_drm_throttle(i915_drm_winsys(ibatch
->iws
));
168 if (ret
!= 0 || i915_drm_winsys(ibatch
->iws
)->dump_cmd
) {
169 i915_dump_batchbuffer(ibatch
);
173 if (i915_drm_winsys(ibatch
->iws
)->dump_raw_file
) {
174 FILE *file
= fopen(i915_drm_winsys(ibatch
->iws
)->dump_raw_file
, "a");
176 fwrite(batch
->base
.map
, used
, 1, file
);
181 #ifdef INTEL_RUN_SYNC
182 drm_intel_bo_wait_rendering(batch
->bo
);
186 ibatch
->iws
->fence_reference(ibatch
->iws
, fence
, NULL
);
188 #ifdef INTEL_RUN_SYNC
189 /* we run synced to GPU so just pass null */
190 (*fence
) = i915_drm_fence_create(NULL
);
192 (*fence
) = i915_drm_fence_create(batch
->bo
);
196 i915_drm_batchbuffer_reset(batch
);
200 i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer
*ibatch
)
202 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
205 drm_intel_bo_unreference(batch
->bo
);
207 FREE(batch
->base
.map
);
211 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys
*idws
)
213 idws
->base
.batchbuffer_create
= i915_drm_batchbuffer_create
;
214 idws
->base
.batchbuffer_reloc
= i915_drm_batchbuffer_reloc
;
215 idws
->base
.batchbuffer_flush
= i915_drm_batchbuffer_flush
;
216 idws
->base
.batchbuffer_destroy
= i915_drm_batchbuffer_destroy
;