struct intel_batchbuffer * intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int buffer_size) { struct intel_batchbuffer *batch = calloc(1, sizeof(*batch)); assert(flag == I915_EXEC_RENDER || flag == I915_EXEC_BSD || flag == I915_EXEC_BLT || flag == I915_EXEC_VEBOX); if (!buffer_size || buffer_size < BATCH_SIZE) { buffer_size = BATCH_SIZE; } /* the buffer size can't exceed 4M */ if (buffer_size > MAX_BATCH_SIZE) { buffer_size = MAX_BATCH_SIZE; } batch->intel = intel; batch->flag = flag; batch->run = drm_intel_bo_mrb_exec; if (IS_GEN6(intel->device_info) && flag == I915_EXEC_RENDER) batch->wa_render_bo = dri_bo_alloc(intel->bufmgr, "wa scratch", 4096, 4096); else batch->wa_render_bo = NULL; intel_batchbuffer_reset(batch, buffer_size); return batch; }
struct intel_batchbuffer * intel_batchbuffer_alloc(drm_intel_bufmgr *bufmgr, uint32_t devid) { struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); batch->bufmgr = bufmgr; batch->devid = devid; intel_batchbuffer_reset(batch); return batch; }
void gen9_media_fillfunc(struct intel_batchbuffer *batch, struct igt_buf *dst, unsigned x, unsigned y, unsigned width, unsigned height, uint8_t color) { uint32_t curbe_buffer, interface_descriptor; uint32_t batch_end; intel_batchbuffer_flush(batch); /* setup states */ batch->ptr = &batch->buffer[BATCH_STATE_SPLIT]; curbe_buffer = gen8_fill_curbe_buffer_data(batch, color); interface_descriptor = gen8_fill_interface_descriptor(batch, dst); assert(batch->ptr < &batch->buffer[4095]); /* media pipeline */ batch->ptr = batch->buffer; OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA | GEN9_FORCE_MEDIA_AWAKE_ENABLE | GEN9_SAMPLER_DOP_GATE_DISABLE | GEN9_PIPELINE_SELECTION_MASK | GEN9_SAMPLER_DOP_GATE_MASK | GEN9_FORCE_MEDIA_AWAKE_MASK); gen9_emit_state_base_address(batch); gen8_emit_vfe_state(batch); gen8_emit_curbe_load(batch, curbe_buffer); gen8_emit_interface_descriptor_load(batch, interface_descriptor); gen8_emit_media_objects(batch, x, y, width, height); OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA | GEN9_FORCE_MEDIA_AWAKE_DISABLE | GEN9_SAMPLER_DOP_GATE_ENABLE | GEN9_PIPELINE_SELECTION_MASK | GEN9_SAMPLER_DOP_GATE_MASK | GEN9_FORCE_MEDIA_AWAKE_MASK); OUT_BATCH(MI_BATCH_BUFFER_END); batch_end = batch_align(batch, 8); assert(batch_end < BATCH_STATE_SPLIT); gen8_render_flush(batch, batch_end); intel_batchbuffer_reset(batch); }
void intel_batchbuffer_init(struct intel_context *intel) { intel_batchbuffer_reset(intel); if (intel->gen >= 6) { /* We can't just use brw_state_batch to get a chunk of space for * the gen6 workaround because it involves actually writing to * the buffer, and the kernel doesn't let us write to the batch. */ intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr, "pipe_control workaround", 4096, 4096); } }
/*====================================================================== * Public functions */ struct intel_batchbuffer * intel_batchbuffer_alloc(struct intel_context *intel) { struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); batch->intel = intel; driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, &batch->buffer, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); batch->last_fence = NULL; driBOCreateList(20, &batch->list); intel_batchbuffer_reset(batch); return batch; }
void intel_batchbuffer_flush_on_ring(struct intel_batchbuffer *batch, int ring) { unsigned int used = flush_on_ring_common(batch, ring); if (used == 0) return; do_or_die(drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer)); batch->ptr = NULL; do_or_die(drm_intel_bo_mrb_exec(batch->bo, used, NULL, 0, 0, ring)); intel_batchbuffer_reset(batch); }
struct _DriFenceObject * intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; GLboolean was_locked = intel->locked; if (used == 0) return batch->last_fence; /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. */ if (used & 4) { ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = 0; ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; used += 12; } else { ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; used += 8; } driBOUnmap(batch->buffer); batch->ptr = NULL; batch->map = NULL; /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ if (!was_locked) LOCK_HARDWARE(intel); do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), GL_FALSE); if (!was_locked) UNLOCK_HARDWARE(intel); /* Reset the buffer: */ intel_batchbuffer_reset(batch); return batch->last_fence; }
void intel_batchbuffer_init(struct brw_context *brw) { intel_batchbuffer_reset(brw); if (brw->gen >= 6) { /* We can't just use brw_state_batch to get a chunk of space for * the gen6 workaround because it involves actually writing to * the buffer, and the kernel doesn't let us write to the batch. */ brw->batch.workaround_bo = drm_intel_bo_alloc(brw->bufmgr, "pipe_control workaround", 4096, 4096); } if (!brw->has_llc) { brw->batch.cpu_map = malloc(BATCH_SZ); brw->batch.map = brw->batch.cpu_map; } }
void intel_batchbuffer_flush(struct intel_batchbuffer *batch) { unsigned int used = batch->ptr - batch->map; if (used == 0) { return; } if ((used & 4) == 0) { *(unsigned int*)batch->ptr = 0; batch->ptr += 4; } *(unsigned int*)batch->ptr = MI_BATCH_BUFFER_END; batch->ptr += 4; dri_bo_unmap(batch->buffer); used = batch->ptr - batch->map; batch->run(batch->buffer, used, 0, 0, 0, batch->flag); intel_batchbuffer_reset(batch, batch->size); }
void intel_batchbuffer_flush_with_context(struct intel_batchbuffer *batch, drm_intel_context *context) { int ret; unsigned int used = flush_on_ring_common(batch, I915_EXEC_RENDER); if (used == 0) return; ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->buffer); assert(ret == 0); batch->ptr = NULL; ret = drm_intel_gem_bo_context_exec(batch->bo, context, used, I915_EXEC_RENDER); assert(ret == 0); intel_batchbuffer_reset(batch); }
void gen9_render_copyfunc(struct intel_batchbuffer *batch, drm_intel_context *context, struct igt_buf *src, unsigned src_x, unsigned src_y, unsigned width, unsigned height, struct igt_buf *dst, unsigned dst_x, unsigned dst_y) { uint32_t ps_sampler_state, ps_kernel_off, ps_binding_table; uint32_t scissor_state; uint32_t vertex_buffer; uint32_t batch_end; intel_batchbuffer_flush_with_context(batch, context); batch_align(batch, 8); batch->ptr = &batch->buffer[BATCH_STATE_SPLIT]; annotation_init(&aub_annotations); ps_binding_table = gen8_bind_surfaces(batch, src, dst); ps_sampler_state = gen8_create_sampler(batch); ps_kernel_off = gen8_fill_ps(batch, ps_kernel, sizeof(ps_kernel)); vertex_buffer = gen7_fill_vertex_buffer_data(batch, src, src_x, src_y, dst_x, dst_y, width, height); cc.cc_state = gen6_create_cc_state(batch); cc.blend_state = gen8_create_blend_state(batch); viewport.cc_state = gen6_create_cc_viewport(batch); viewport.sf_clip_state = gen7_create_sf_clip_viewport(batch); scissor_state = gen6_create_scissor_rect(batch); /* TODO: theree is other state which isn't setup */ assert(batch->ptr < &batch->buffer[4095]); batch->ptr = batch->buffer; /* Start emitting the commands. The order roughly follows the mesa blorp * order */ OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D | GEN9_PIPELINE_SELECTION_MASK); gen8_emit_sip(batch); gen7_emit_push_constants(batch); gen9_emit_state_base_address(batch); OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC); OUT_BATCH(viewport.cc_state); OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP); OUT_BATCH(viewport.sf_clip_state); gen7_emit_urb(batch); gen8_emit_cc(batch); gen8_emit_multisample(batch); gen8_emit_null_state(batch); OUT_BATCH(GEN7_3DSTATE_STREAMOUT | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); gen7_emit_clip(batch); gen8_emit_sf(batch); gen8_emit_ps(batch, ps_kernel_off); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS); OUT_BATCH(ps_binding_table); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS); OUT_BATCH(ps_sampler_state); OUT_BATCH(GEN6_3DSTATE_SCISSOR_STATE_POINTERS); OUT_BATCH(scissor_state); gen9_emit_depth(batch); gen7_emit_clear(batch); gen6_emit_drawing_rectangle(batch, dst); gen7_emit_vertex_buffer(batch, vertex_buffer); gen6_emit_vertex_elements(batch); gen8_emit_vf_topology(batch); gen8_emit_primitive(batch, vertex_buffer); OUT_BATCH(MI_BATCH_BUFFER_END); batch_end = batch_align(batch, 8); assert(batch_end < BATCH_STATE_SPLIT); annotation_add_batch(&aub_annotations, batch_end); dump_batch(batch); annotation_flush(&aub_annotations, batch); gen6_render_flush(batch, context, batch_end); intel_batchbuffer_reset(batch); }
void gen6_render_copyfunc(struct intel_batchbuffer *batch, struct scratch_buf *src, unsigned src_x, unsigned src_y, unsigned width, unsigned height, struct scratch_buf *dst, unsigned dst_x, unsigned dst_y) { uint32_t wm_state, wm_kernel, wm_table; uint32_t cc_vp, cc_blend, offset; uint32_t batch_end; intel_batchbuffer_flush(batch); batch->ptr = batch->buffer + 1024; batch_alloc(batch, 64, 64); wm_table = gen6_bind_surfaces(batch, src, dst); wm_kernel = gen6_create_kernel(batch); wm_state = gen6_create_sampler(batch, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); cc_vp = gen6_create_cc_viewport(batch); cc_blend = gen6_create_cc_blend(batch); batch->ptr = batch->buffer; gen6_emit_invariant(batch); gen6_emit_state_base_address(batch); gen6_emit_sip(batch); gen6_emit_urb(batch); gen6_emit_viewports(batch, cc_vp); gen6_emit_vs(batch); gen6_emit_gs(batch); gen6_emit_clip(batch); gen6_emit_wm_constants(batch); gen6_emit_null_depth_buffer(batch); gen6_emit_drawing_rectangle(batch, dst); gen6_emit_cc(batch, cc_blend); gen6_emit_sampler(batch, wm_state); gen6_emit_sf(batch); gen6_emit_wm(batch, wm_kernel); gen6_emit_vertex_elements(batch); gen6_emit_binding_table(batch, wm_table); gen6_emit_vertex_buffer(batch); offset = gen6_emit_primitive(batch); OUT_BATCH(MI_BATCH_BUFFER_END); batch_end = batch_align(batch, 8); *(uint32_t*)(batch->buffer + offset) = batch_round_upto(batch, VERTEX_SIZE)/VERTEX_SIZE; emit_vertex_2s(batch, dst_x + width, dst_y + height); emit_vertex_normalized(batch, src_x + width, buf_width(src)); emit_vertex_normalized(batch, src_y + height, buf_height(src)); emit_vertex_2s(batch, dst_x, dst_y + height); emit_vertex_normalized(batch, src_x, buf_width(src)); emit_vertex_normalized(batch, src_y + height, buf_height(src)); emit_vertex_2s(batch, dst_x, dst_y); emit_vertex_normalized(batch, src_x, buf_width(src)); emit_vertex_normalized(batch, src_y, buf_height(src)); gen6_render_flush(batch, batch_end); intel_batchbuffer_reset(batch); }