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;