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;
67 batch
->base
.iws
= iws
;
69 i915_drm_batchbuffer_reset(batch
);
75 i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer
*batch
,
76 struct i915_winsys_buffer
**buffer
,
79 struct i915_drm_batchbuffer
*drm_batch
= i915_drm_batchbuffer(batch
);
80 drm_intel_bo
*bos
[num_of_buffers
+ 1];
83 bos
[0] = drm_batch
->bo
;
84 for (i
= 0; i
< num_of_buffers
; i
++)
85 bos
[i
+1] = intel_bo(buffer
[i
]);
87 ret
= drm_intel_bufmgr_check_aperture_space(bos
, num_of_buffers
);
95 i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer
*ibatch
,
96 struct i915_winsys_buffer
*buffer
,
97 enum i915_winsys_buffer_usage usage
,
98 unsigned pre_add
, boolean fenced
)
100 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
101 unsigned write_domain
= 0;
102 unsigned read_domain
= 0;
107 case I915_USAGE_SAMPLER
:
109 read_domain
= I915_GEM_DOMAIN_SAMPLER
;
111 case I915_USAGE_RENDER
:
112 write_domain
= I915_GEM_DOMAIN_RENDER
;
113 read_domain
= I915_GEM_DOMAIN_RENDER
;
115 case I915_USAGE_2D_TARGET
:
116 write_domain
= I915_GEM_DOMAIN_RENDER
;
117 read_domain
= I915_GEM_DOMAIN_RENDER
;
119 case I915_USAGE_2D_SOURCE
:
121 read_domain
= I915_GEM_DOMAIN_RENDER
;
123 case I915_USAGE_VERTEX
:
125 read_domain
= I915_GEM_DOMAIN_VERTEX
;
132 offset
= (unsigned)(batch
->base
.ptr
- batch
->base
.map
);
135 ret
= drm_intel_bo_emit_reloc_fence(batch
->bo
, offset
,
136 intel_bo(buffer
), pre_add
,
140 ret
= drm_intel_bo_emit_reloc(batch
->bo
, offset
,
141 intel_bo(buffer
), pre_add
,
145 ((uint32_t*)batch
->base
.ptr
)[0] = intel_bo(buffer
)->offset
+ pre_add
;
146 batch
->base
.ptr
+= 4;
149 batch
->base
.relocs
++;
155 i915_drm_throttle(struct i915_drm_winsys
*idws
)
157 drmIoctl(idws
->fd
, DRM_IOCTL_I915_GEM_THROTTLE
, NULL
);
161 i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer
*ibatch
,
162 struct pipe_fence_handle
**fence
,
163 enum i915_winsys_flush_flags flags
)
165 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
169 /* MI_BATCH_BUFFER_END */
170 i915_winsys_batchbuffer_dword_unchecked(ibatch
, (0xA<<23));
172 used
= batch
->base
.ptr
- batch
->base
.map
;
175 i915_winsys_batchbuffer_dword_unchecked(ibatch
, 0);
179 /* Do the sending to HW */
180 ret
= drm_intel_bo_subdata(batch
->bo
, 0, used
, batch
->base
.map
);
181 if (ret
== 0 && i915_drm_winsys(ibatch
->iws
)->send_cmd
)
182 ret
= drm_intel_bo_exec(batch
->bo
, used
, NULL
, 0, 0);
184 if (flags
& I915_FLUSH_END_OF_FRAME
)
185 i915_drm_throttle(i915_drm_winsys(ibatch
->iws
));
187 if (ret
!= 0 || i915_drm_winsys(ibatch
->iws
)->dump_cmd
) {
188 i915_dump_batchbuffer(ibatch
);
192 if (i915_drm_winsys(ibatch
->iws
)->dump_raw_file
) {
193 FILE *file
= fopen(i915_drm_winsys(ibatch
->iws
)->dump_raw_file
, "a");
195 fwrite(batch
->base
.map
, used
, 1, file
);
200 #ifdef INTEL_RUN_SYNC
201 drm_intel_bo_wait_rendering(batch
->bo
);
205 ibatch
->iws
->fence_reference(ibatch
->iws
, fence
, NULL
);
207 #ifdef INTEL_RUN_SYNC
208 /* we run synced to GPU so just pass null */
209 (*fence
) = i915_drm_fence_create(NULL
);
211 (*fence
) = i915_drm_fence_create(batch
->bo
);
215 i915_drm_batchbuffer_reset(batch
);
219 i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer
*ibatch
)
221 struct i915_drm_batchbuffer
*batch
= i915_drm_batchbuffer(ibatch
);
224 drm_intel_bo_unreference(batch
->bo
);
226 FREE(batch
->base
.map
);
230 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys
*idws
)
232 idws
->base
.batchbuffer_create
= i915_drm_batchbuffer_create
;
233 idws
->base
.validate_buffers
= i915_drm_batchbuffer_validate_buffers
;
234 idws
->base
.batchbuffer_reloc
= i915_drm_batchbuffer_reloc
;
235 idws
->base
.batchbuffer_flush
= i915_drm_batchbuffer_flush
;
236 idws
->base
.batchbuffer_destroy
= i915_drm_batchbuffer_destroy
;