boolean brw_upload_vertex_buffers( struct brw_context *brw ) { struct brw_array_state vbp; unsigned nr_enabled = 0; unsigned i; memset(&vbp, 0, sizeof(vbp)); /* This is a hardware limit: */ for (i = 0; i < BRW_VEP_MAX; i++) { if (brw->vb.vbo_array[i] == NULL) { nr_enabled = i; break; } vbp.vb[i].vb0.bits.pitch = brw->vb.vbo_array[i]->stride; vbp.vb[i].vb0.bits.pad = 0; vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA; vbp.vb[i].vb0.bits.vb_index = i; vbp.vb[i].offset = brw->vb.vbo_array[i]->buffer_offset; vbp.vb[i].buffer = brw->vb.vbo_array[i]->buffer; vbp.vb[i].max_index = brw->vb.vbo_array[i]->max_index; } vbp.header.bits.length = (1 + nr_enabled * 4) - 2; vbp.header.bits.opcode = CMD_VERTEX_BUFFER; BEGIN_BATCH(vbp.header.bits.length+2, 0); OUT_BATCH( vbp.header.dword ); for (i = 0; i < nr_enabled; i++) { OUT_BATCH( vbp.vb[i].vb0.dword ); OUT_RELOC( vbp.vb[i].buffer, PIPE_BUFFER_USAGE_GPU_READ, vbp.vb[i].offset); OUT_BATCH( vbp.vb[i].max_index ); OUT_BATCH( vbp.vb[i].instance_data_step_rate ); } ADVANCE_BATCH(); return TRUE; }
static void upload_3dstate_streamout(struct brw_context *brw, bool active, const struct brw_vue_map *vue_map) { struct gl_context *ctx = &brw->ctx; /* BRW_NEW_TRANSFORM_FEEDBACK */ struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; uint32_t dw1 = 0, dw2 = 0; int i; if (active) { int urb_entry_read_offset = 0; int urb_entry_read_length = (vue_map->num_slots + 1) / 2 - urb_entry_read_offset; dw1 |= SO_FUNCTION_ENABLE; dw1 |= SO_STATISTICS_ENABLE; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) dw1 |= SO_REORDER_TRAILING; for (i = 0; i < 4; i++) { if (xfb_obj->Buffers[i]) { dw1 |= SO_BUFFER_ENABLE(i); } } /* We always read the whole vertex. This could be reduced at some * point by reading less and offsetting the register index in the * SO_DECLs. */ dw2 |= urb_entry_read_offset << SO_STREAM_0_VERTEX_READ_OFFSET_SHIFT; dw2 |= (urb_entry_read_length - 1) << SO_STREAM_0_VERTEX_READ_LENGTH_SHIFT; } BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_STREAMOUT << 16 | (3 - 2)); OUT_BATCH(dw1); OUT_BATCH(dw2); ADVANCE_BATCH(); }
/** * Upload the binding table pointers, which point each stage's array of surface * state pointers. * * The binding table pointers are relative to the surface state base address, * which is 0. */ static int upload_binding_table_pointers(struct brw_context *brw) { BEGIN_BATCH(6, IGNORE_CLIPRECTS); OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2)); if (brw->vs.bind_bo != NULL) OUT_RELOC(brw->vs.bind_bo, BRW_USAGE_SAMPLER, 0); /* vs */ else OUT_BATCH(0); OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ OUT_RELOC(brw->wm.bind_bo, BRW_USAGE_SAMPLER, 0); /* wm/ps */ ADVANCE_BATCH(); return 0; }
/** * AA Line parameters */ static void upload_aa_line_parameters(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; if (!ctx->Line.SmoothFlag) return; /* Original Gen4 doesn't have 3DSTATE_AA_LINE_PARAMETERS. */ if (brw->gen == 4 && !brw->is_g4x) return; BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_AA_LINE_PARAMETERS << 16 | (3 - 2)); /* use legacy aa line coverage computation */ OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); }
static void blt_color_fill(struct intel_batchbuffer *batch, drm_intel_bo *buf, const unsigned int pages) { const unsigned short height = pages/4; const unsigned short width = 4096; COLOR_BLIT_COPY_BATCH_START(COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); OUT_BATCH((3 << 24) | /* 32 Bit Color */ (0xF0 << 16) | /* Raster OP copy background register */ 0); /* Dest pitch is 0 */ OUT_BATCH(0); OUT_BATCH(width << 16 | height); OUT_RELOC_FENCED(buf, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(rand()); /* random pattern */ ADVANCE_BATCH(); }
/** * Edit a single entry in a hardware-generated binding table */ void gen7_edit_hw_binding_table_entry(struct brw_context *brw, gl_shader_stage stage, uint32_t index, uint32_t surf_offset) { assert(stage < ARRAY_SIZE(stage_to_bt_edit)); assert(stage_to_bt_edit[stage]); uint32_t dw2 = SET_FIELD(index, BRW_BINDING_TABLE_INDEX) | (brw->gen >= 8 ? GEN8_SURFACE_STATE_EDIT(surf_offset) : HSW_SURFACE_STATE_EDIT(surf_offset)); BEGIN_BATCH(3); OUT_BATCH(stage_to_bt_edit[stage] << 16 | (3 - 2)); OUT_BATCH(BRW_BINDING_TABLE_EDIT_TARGET_ALL); OUT_BATCH(dw2); ADVANCE_BATCH(); }
/* Define the number of curbes within CS's urb allocation. Multiple * urb entries -> multiple curbes. These will be used by * fixed-function hardware in a double-buffering scheme to avoid a * pipeline stall each time the contents of the curbe is changed. */ void brw_upload_cs_urb_state(struct brw_context *brw) { BEGIN_BATCH(2); /* It appears that this is the state packet for the CS unit, ie. the * urb entries detailed here are housed in the CS range from the * URB_FENCE command. */ OUT_BATCH(CMD_CS_URB_STATE << 16 | (2-2)); /* BRW_NEW_URB_FENCE */ if (brw->urb.csize == 0) { OUT_BATCH(0); } else { /* BRW_NEW_URB_FENCE */ assert(brw->urb.nr_cs_entries); OUT_BATCH((brw->urb.csize - 1) << 4 | brw->urb.nr_cs_entries); } ADVANCE_BATCH(); }
static void gen7_blorp_emit_cc_viewport(struct brw_context *brw, const brw_blorp_params *params) { struct intel_context *intel = &brw->intel; struct brw_cc_viewport *ccv; uint32_t cc_vp_offset; ccv = (struct brw_cc_viewport *)brw_state_batch(brw, AUB_TRACE_CC_VP_STATE, sizeof(*ccv), 32, &cc_vp_offset); ccv->min_depth = 0.0; ccv->max_depth = 1.0; BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_VIEWPORT_STATE_POINTERS_CC << 16 | (2 - 2)); OUT_BATCH(cc_vp_offset); ADVANCE_BATCH(); }
/* Emit a pipelined flush to either flush render and texture cache for * reading from a FBO-drawn texture, or flush so that frontbuffer * render appears on the screen in DRI1. * * This is also used for the always_flush_cache driconf debug option. */ void brw_emit_mi_flush(struct brw_context *brw) { if (brw->batch.ring == BLT_RING && brw->gen >= 6) { BEGIN_BATCH_BLT(4); OUT_BATCH(MI_FLUSH_DW); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } else { int flags = PIPE_CONTROL_NO_WRITE | PIPE_CONTROL_RENDER_TARGET_FLUSH; if (brw->gen >= 6) { if (brw->gen == 9) { /* Hardware workaround: SKL * * Emit Pipe Control with all bits set to zero before emitting * a Pipe Control with VF Cache Invalidate set. */ brw_emit_pipe_control_flush(brw, 0); } flags |= PIPE_CONTROL_INSTRUCTION_INVALIDATE | PIPE_CONTROL_DEPTH_CACHE_FLUSH | PIPE_CONTROL_VF_CACHE_INVALIDATE | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | PIPE_CONTROL_CS_STALL; if (brw->gen == 6) { /* Hardware workaround: SNB B-Spec says: * * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache * Flush Enable =1, a PIPE_CONTROL with any non-zero * post-sync-op is required. */ brw_emit_post_sync_nonzero_flush(brw); } } brw_emit_pipe_control_flush(brw, flags); } brw_render_cache_set_clear(brw); }
static void upload_clip_state(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; uint32_t depth_clamp = 0; uint32_t provoking, userclip; if (!ctx->Transform.DepthClamp) depth_clamp = GEN6_CLIP_Z_TEST; /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION) { provoking = (0 << GEN6_CLIP_TRI_PROVOKE_SHIFT) | (1 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) | (0 << GEN6_CLIP_LINE_PROVOKE_SHIFT); } else { provoking = (2 << GEN6_CLIP_TRI_PROVOKE_SHIFT) | (2 << GEN6_CLIP_TRIFAN_PROVOKE_SHIFT) | (1 << GEN6_CLIP_LINE_PROVOKE_SHIFT); } /* _NEW_TRANSFORM */ userclip = (1 << brw_count_bits(ctx->Transform.ClipPlanesEnabled)) - 1; BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2)); OUT_BATCH(GEN6_CLIP_STATISTICS_ENABLE); OUT_BATCH(GEN6_CLIP_ENABLE | GEN6_CLIP_API_OGL | GEN6_CLIP_MODE_NORMAL | GEN6_CLIP_XY_TEST | userclip << GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT | depth_clamp | provoking); OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT | U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT | GEN6_CLIP_FORCE_ZERO_RTAINDEX); ADVANCE_BATCH(); }
static void mi_lri_loop(void) { int i; srandom(0xdeadbeef); for (i = 0; i < 0x100; i++) { int ring = random() % num_rings + 1; BEGIN_BATCH(4); OUT_BATCH(MI_LOAD_REGISTER_IMM | 1); OUT_BATCH(0x203c); /* RENDER RING CTL */ OUT_BATCH(0); /* try to stop the ring */ OUT_BATCH(MI_NOOP); ADVANCE_BATCH(); intel_batchbuffer_flush_on_ring(batch, ring); } }
/** * Upload a shader stage's binding table as indirect state. * * This copies brw_stage_state::surf_offset[] into the indirect state section * of the batchbuffer (allocated by brw_state_batch()). */ static void brw_upload_binding_table(struct brw_context *brw, uint32_t packet_name, GLbitfield brw_new_binding_table, struct brw_stage_state *stage_state) { /* CACHE_NEW_*_PROG */ struct brw_stage_prog_data *prog_data = stage_state->prog_data; if (prog_data->binding_table.size_bytes == 0) { /* There are no surfaces; skip making the binding table altogether. */ if (stage_state->bind_bo_offset == 0) return; stage_state->bind_bo_offset = 0; } else { /* Upload a new binding table. */ if (INTEL_DEBUG & DEBUG_SHADER_TIME) { brw->vtbl.create_raw_surface( brw, brw->shader_time.bo, 0, brw->shader_time.bo->size, &stage_state->surf_offset[prog_data->binding_table.shader_time_start], true); } uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, prog_data->binding_table.size_bytes, 32, &stage_state->bind_bo_offset); /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */ memcpy(bind, stage_state->surf_offset, prog_data->binding_table.size_bytes); } brw->state.dirty.brw |= brw_new_binding_table; if (brw->gen >= 7) { BEGIN_BATCH(2); OUT_BATCH(packet_name << 16 | (2 - 2)); OUT_BATCH(stage_state->bind_bo_offset); ADVANCE_BATCH(); } }
static void dummy_reloc_loop_random_ring_multi_fd(int num_rings) { int i; struct intel_batchbuffer *saved_batch; saved_batch = batch; srandom(0xdeadbeef); for (i = 0; i < 0x100000; i++) { int mindex; int ring = random() % num_rings + 1; mindex = random() % NUM_FD; batch = mbatch[mindex]; BEGIN_BATCH(4, 1); if (ring == I915_EXEC_RENDER) { OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE); OUT_BATCH(0xffffffff); /* compare dword */ OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(MI_NOOP); } else { OUT_BATCH(MI_FLUSH_DW | 1); OUT_BATCH(0); /* reserved */ OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(MI_NOOP | (1<<22) | (0xf)); } ADVANCE_BATCH(); intel_batchbuffer_flush_on_ring(batch, ring); drm_intel_bo_map(target_buffer, 0); // map to force waiting on rendering drm_intel_bo_unmap(target_buffer); } batch = saved_batch; }
/** * 3DSTATE_PS * * Pixel shader dispatch is disabled above in 3DSTATE_WM, dw1.29. Despite * that, thread dispatch info must still be specified. * - Maximum Number of Threads (dw4.24:31) must be nonzero, as the BSpec * states that the valid range for this field is [0x3, 0x2f]. * - A dispatch mode must be given; that is, at least one of the * "N Pixel Dispatch Enable" (N=8,16,32) fields must be set. This was * discovered through simulator error messages. */ static void gen7_blorp_emit_ps_config(struct brw_context *brw, const brw_blorp_params *params, uint32_t prog_offset, brw_blorp_prog_data *prog_data) { struct intel_context *intel = &brw->intel; uint32_t dw2, dw4, dw5; const int max_threads_shift = brw->intel.is_haswell ? HSW_PS_MAX_THREADS_SHIFT : IVB_PS_MAX_THREADS_SHIFT; dw2 = dw4 = dw5 = 0; dw4 |= (brw->max_wm_threads - 1) << max_threads_shift; /* If there's a WM program, we need to do 16-pixel dispatch since that's * what the program is compiled for. If there isn't, then it shouldn't * matter because no program is actually being run. However, the hardware * gets angry if we don't enable at least one dispatch mode, so just enable * 16-pixel dispatch unconditionally. */ dw4 |= GEN7_PS_16_DISPATCH_ENABLE; if (intel->is_haswell) dw4 |= SET_FIELD(1, HSW_PS_SAMPLE_MASK); /* 1 sample for now */ if (params->use_wm_prog) { dw2 |= 1 << GEN7_PS_SAMPLER_COUNT_SHIFT; /* Up to 4 samplers */ dw4 |= GEN7_PS_PUSH_CONSTANT_ENABLE; dw5 |= prog_data->first_curbe_grf << GEN7_PS_DISPATCH_START_GRF_SHIFT_0; } BEGIN_BATCH(8); OUT_BATCH(_3DSTATE_PS << 16 | (8 - 2)); OUT_BATCH(params->use_wm_prog ? prog_offset : 0); OUT_BATCH(dw2); OUT_BATCH(0); OUT_BATCH(dw4); OUT_BATCH(dw5); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); }
static void upload_gs_state_for_tf(struct brw_context *brw) { BEGIN_BATCH(7); OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2)); OUT_BATCH(brw->ff_gs.prog_offset); OUT_BATCH(GEN6_GS_SPF_MODE | GEN6_GS_VECTOR_MASK_ENABLE); OUT_BATCH(0); /* no scratch space */ OUT_BATCH((2 << GEN6_GS_DISPATCH_START_GRF_SHIFT) | (brw->ff_gs.prog_data->urb_read_length << GEN6_GS_URB_READ_LENGTH_SHIFT)); OUT_BATCH(((brw->max_gs_threads - 1) << GEN6_GS_MAX_THREADS_SHIFT) | GEN6_GS_STATISTICS_ENABLE | GEN6_GS_SO_STATISTICS_ENABLE | GEN6_GS_RENDERING_ENABLE); OUT_BATCH(GEN6_GS_SVBI_PAYLOAD_ENABLE | GEN6_GS_SVBI_POSTINCREMENT_ENABLE | (brw->ff_gs.prog_data->svbi_postincrement_value << GEN6_GS_SVBI_POSTINCREMENT_VALUE_SHIFT) | GEN6_GS_ENABLE); ADVANCE_BATCH(); }
static void brw_emit_index_buffer(struct brw_context *brw) { struct intel_context *intel = &brw->intel; const struct _mesa_index_buffer *index_buffer = brw->ib.ib; if (index_buffer == NULL) return; BEGIN_BATCH(3); OUT_BATCH(CMD_INDEX_BUFFER << 16 | /* cut index enable << 10 */ get_index_type(index_buffer->type) << 8 | 1); OUT_RELOC(brw->ib.bo, I915_GEM_DOMAIN_VERTEX, 0, 0); OUT_RELOC(brw->ib.bo, I915_GEM_DOMAIN_VERTEX, 0, brw->ib.bo->size - 1); ADVANCE_BATCH(); }
void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, GLuint dst_buffer, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color ) { GLuint BR13, CMD; BATCH_LOCALS; dst_pitch *= cpp; switch(cpp) { case 1: case 2: case 3: BR13 = dst_pitch | (0xF0 << 16) | (1<<24); CMD = XY_COLOR_BLT_CMD; break; case 4: BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25); CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); break; default: return; } BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (y << 16) | x ); OUT_BATCH( ((y+h) << 16) | (x+w) ); OUT_RELOC( dst_buffer, DRM_MM_TT|DRM_MM_WRITE, dst_offset ); OUT_BATCH( color ); ADVANCE_BATCH(); }
/** * Upload a whole hardware binding table for the given stage. * * Takes an array of surface offsets and the number of binding table * entries. */ void gen7_update_binding_table_from_array(struct brw_context *brw, gl_shader_stage stage, const uint32_t* binding_table, int num_surfaces) { uint32_t dw2 = 0; assert(stage < ARRAY_SIZE(stage_to_bt_edit)); assert(stage_to_bt_edit[stage]); BEGIN_BATCH(num_surfaces + 2); OUT_BATCH(stage_to_bt_edit[stage] << 16 | num_surfaces); OUT_BATCH(BRW_BINDING_TABLE_EDIT_TARGET_ALL); for (int i = 0; i < num_surfaces; i++) { dw2 = SET_FIELD(i, BRW_BINDING_TABLE_INDEX) | (brw->gen >= 8 ? GEN8_SURFACE_STATE_EDIT(binding_table[i]) : HSW_SURFACE_STATE_EDIT(binding_table[i])); OUT_BATCH(dw2); } ADVANCE_BATCH(); }
/* Emit a pipelined flush to either flush render and texture cache for * reading from a FBO-drawn texture, or flush so that frontbuffer * render appears on the screen in DRI1. * * This is also used for the always_flush_cache driconf debug option. */ void brw_emit_mi_flush(struct brw_context *brw) { if (brw->batch.ring == BLT_RING && brw->gen >= 6) { BEGIN_BATCH_BLT(4); OUT_BATCH(MI_FLUSH_DW); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } else { int flags = PIPE_CONTROL_NO_WRITE | PIPE_CONTROL_RENDER_TARGET_FLUSH; if (brw->gen >= 6) { flags |= PIPE_CONTROL_INSTRUCTION_INVALIDATE | PIPE_CONTROL_DEPTH_CACHE_FLUSH | PIPE_CONTROL_VF_CACHE_INVALIDATE | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | PIPE_CONTROL_CS_STALL; } brw_emit_pipe_control_flush(brw, flags); } }
void gen8_upload_ps_extra(struct brw_context *brw, const struct gl_fragment_program *fp, const struct brw_wm_prog_data *prog_data, bool multisampled_fbo) { struct gl_context *ctx = &brw->ctx; uint32_t dw1 = 0; dw1 |= GEN8_PSX_PIXEL_SHADER_VALID; dw1 |= prog_data->computed_depth_mode << GEN8_PSX_COMPUTED_DEPTH_MODE_SHIFT; if (prog_data->uses_kill) dw1 |= GEN8_PSX_KILL_ENABLE; if (prog_data->num_varying_inputs != 0) dw1 |= GEN8_PSX_ATTRIBUTE_ENABLE; if (fp->Base.InputsRead & VARYING_BIT_POS) dw1 |= GEN8_PSX_USES_SOURCE_DEPTH | GEN8_PSX_USES_SOURCE_W; if (multisampled_fbo && _mesa_get_min_invocations_per_fragment(ctx, fp, false) > 1) dw1 |= GEN8_PSX_SHADER_IS_PER_SAMPLE; if (fp->Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_MASK_IN) dw1 |= GEN8_PSX_SHADER_USES_INPUT_COVERAGE_MASK; if (prog_data->uses_omask) dw1 |= GEN8_PSX_OMASK_TO_RENDER_TARGET; if (brw->gen >= 9 && prog_data->pulls_bary) dw1 |= GEN9_PSX_SHADER_PULLS_BARY; BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_PS_EXTRA << 16 | (2 - 2)); OUT_BATCH(dw1); ADVANCE_BATCH(); }
/** * Upload pointers to the per-stage state. * * The state pointers in this packet are all relative to the general state * base address set by CMD_STATE_BASE_ADDRESS, which is 0. */ static void upload_pipelined_state_pointers(struct brw_context *brw ) { struct intel_context *intel = &brw->intel; BEGIN_BATCH(7, IGNORE_CLIPRECTS); OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2)); OUT_RELOC(brw->vs.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0); if (brw->gs.prog_active) OUT_RELOC(brw->gs.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 1); else OUT_BATCH(0); if (!brw->metaops.active) OUT_RELOC(brw->clip.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 1); else OUT_BATCH(0); OUT_RELOC(brw->sf.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0); OUT_RELOC(brw->wm.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0); OUT_RELOC(brw->cc.state_bo, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, 0); ADVANCE_BATCH(); brw->state.dirty.brw |= BRW_NEW_PSP; }
/* 3DSTATE_VIEWPORT_STATE_POINTERS */ static void gen6_blorp_emit_viewport_state(struct brw_context *brw, const struct brw_blorp_params *params) { struct brw_cc_viewport *ccv; uint32_t cc_vp_offset; ccv = (struct brw_cc_viewport *)brw_state_batch(brw, AUB_TRACE_CC_VP_STATE, sizeof(*ccv), 32, &cc_vp_offset); ccv->min_depth = 0.0; ccv->max_depth = 1.0; BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_VIEWPORT_STATE_POINTERS << 16 | (4 - 2) | GEN6_CC_VIEWPORT_MODIFY); OUT_BATCH(0); /* clip VP */ OUT_BATCH(0); /* SF VP */ OUT_BATCH(cc_vp_offset); ADVANCE_BATCH(); }
/* 3DSTATE_SF * * Disable ViewportTransformEnable (dw2.1) * * From the SandyBridge PRM, Volume 2, Part 1, Section 1.3, "3D * Primitives Overview": * RECTLIST: Viewport Mapping must be DISABLED (as is typical with the * use of screen- space coordinates). * * A solid rectangle must be rendered, so set FrontFaceFillMode (dw2.4:3) * and BackFaceFillMode (dw2.5:6) to SOLID(0). * * From the Sandy Bridge PRM, Volume 2, Part 1, Section * 6.4.1.1 3DSTATE_SF, Field FrontFaceFillMode: * SOLID: Any triangle or rectangle object found to be front-facing * is rendered as a solid object. This setting is required when * (rendering rectangle (RECTLIST) objects. */ static void gen6_blorp_emit_sf_config(struct brw_context *brw, const struct brw_blorp_params *params) { const unsigned num_varyings = params->wm_prog_data ? params->wm_prog_data->num_varying_inputs : 0; BEGIN_BATCH(20); OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2)); OUT_BATCH(num_varyings << GEN6_SF_NUM_OUTPUTS_SHIFT | 1 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT | BRW_SF_URB_ENTRY_READ_OFFSET << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT); OUT_BATCH(0); /* dw2 */ OUT_BATCH(params->dst.num_samples > 1 ? GEN6_SF_MSRAST_ON_PATTERN : 0); for (int i = 0; i < 13; ++i) OUT_BATCH(0); OUT_BATCH(params->wm_prog_data ? params->wm_prog_data->flat_inputs : 0); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); }
void gen8_upload_constant_state(struct brw_context *brw, const struct brw_stage_state *stage_state, bool active, unsigned opcode) { /* Disable if the shader stage is inactive or there are no push constants. */ active = active && stage_state->push_const_size != 0; BEGIN_BATCH(11); OUT_BATCH(opcode << 16 | (11 - 2)); OUT_BATCH(active ? stage_state->push_const_size : 0); OUT_BATCH(0); OUT_BATCH(active ? stage_state->push_const_offset : 0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); }
void intelEmitFillBlitLocked( intelContextPtr intel, GLuint cpp, GLshort dst_pitch, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color ) { GLuint BR13, CMD; BATCH_LOCALS; dst_pitch *= cpp; switch(cpp) { case 1: case 2: case 3: BR13 = dst_pitch | (0xF0 << 16) | (1<<24); CMD = XY_COLOR_BLT_CMD; break; case 4: BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25); CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); break; default: return; } BEGIN_BATCH( 6); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (y << 16) | x ); OUT_BATCH( ((y+h) << 16) | (x+w) ); OUT_BATCH( dst_offset ); OUT_BATCH( color ); ADVANCE_BATCH(); }
/** * 3DSTATE_SAMPLE_PATTERN */ void gen8_emit_3dstate_sample_pattern(struct brw_context *brw) { BEGIN_BATCH(9); OUT_BATCH(_3DSTATE_SAMPLE_PATTERN << 16 | (9 - 2)); /* 16x MSAA */ OUT_BATCH(brw_multisample_positions_16x[0]); /* positions 3, 2, 1, 0 */ OUT_BATCH(brw_multisample_positions_16x[1]); /* positions 7, 6, 5, 4 */ OUT_BATCH(brw_multisample_positions_16x[2]); /* positions 11, 10, 9, 8 */ OUT_BATCH(brw_multisample_positions_16x[3]); /* positions 15, 14, 13, 12 */ /* 8x MSAA */ OUT_BATCH(brw_multisample_positions_8x[1]); /* sample positions 7654 */ OUT_BATCH(brw_multisample_positions_8x[0]); /* sample positions 3210 */ /* 4x MSAA */ OUT_BATCH(brw_multisample_positions_4x); /* 1x and 2x MSAA */ OUT_BATCH(brw_multisample_positions_1x_2x); ADVANCE_BATCH(); }
static void upload_wm_state(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; uint32_t dw1 = 0; /* BRW_NEW_FS_PROG_DATA */ const struct brw_wm_prog_data *wm_prog_data = brw_wm_prog_data(brw->wm.base.prog_data); dw1 |= GEN7_WM_STATISTICS_ENABLE; dw1 |= GEN7_WM_LINE_AA_WIDTH_1_0; dw1 |= GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5; dw1 |= GEN7_WM_POINT_RASTRULE_UPPER_RIGHT; /* _NEW_LINE */ if (ctx->Line.StippleFlag) dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE; /* _NEW_POLYGON */ if (ctx->Polygon.StippleFlag) dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE; dw1 |= wm_prog_data->barycentric_interp_modes << GEN7_WM_BARYCENTRIC_INTERPOLATION_MODE_SHIFT; /* BRW_NEW_FS_PROG_DATA */ if (wm_prog_data->early_fragment_tests) dw1 |= GEN7_WM_EARLY_DS_CONTROL_PREPS; else if (wm_prog_data->has_side_effects) dw1 |= GEN7_WM_EARLY_DS_CONTROL_PSEXEC; BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_WM << 16 | (2 - 2)); OUT_BATCH(dw1); ADVANCE_BATCH(); }
/* Emit a primitive referencing vertices in a vertex buffer. */ void intelStartInlinePrimitive(struct intel_context *intel, GLuint prim, GLuint batch_flags) { BATCH_LOCALS; intel->vtbl.emit_state(intel); /* Need to make sure at the very least that we don't wrap * batchbuffers in BEGIN_BATCH below, otherwise the primitive will * be emitted to a batchbuffer missing the required full-state * preamble. */ if (intel_batchbuffer_space(intel->batch) < 100) { intel_batchbuffer_flush(intel->batch); intel->vtbl.emit_state(intel); } /* _mesa_printf("%s *", __progname); */ intel_wait_flips(intel, batch_flags); /* Emit a slot which will be filled with the inline primitive * command later. */ BEGIN_BATCH(2, batch_flags); OUT_BATCH(0); intel->prim.start_ptr = intel->batch->ptr; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; OUT_BATCH(0); ADVANCE_BATCH(); /* _mesa_printf(">"); */ }
static void do_render(drm_intel_bufmgr *bufmgr, struct intel_batchbuffer *batch, drm_intel_bo *dst_bo, int width, int height) { uint32_t data[width * height]; drm_intel_bo *src_bo; int i; static uint32_t seed = 1; /* Generate some junk. Real workloads would be doing a lot more * work to generate the junk. */ for (i = 0; i < width * height; i++) { data[i] = seed++; } /* Upload the junk. */ src_bo = drm_intel_bo_alloc(bufmgr, "src", sizeof(data), 4096); drm_intel_bo_subdata(src_bo, 0, sizeof(data), data); /* Render the junk to the dst. */ BLIT_COPY_BATCH_START(0); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ (width * 4) /* dst pitch */); OUT_BATCH(0); /* dst x1,y1 */ OUT_BATCH((height << 16) | width); /* dst x2,y2 */ OUT_RELOC(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(0); /* src x1,y1 */ OUT_BATCH(width * 4); /* src pitch */ OUT_RELOC(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); intel_batchbuffer_flush(batch); drm_intel_bo_unreference(src_bo); }
/** * ResumeTransformFeedback() driver hook. */ void hsw_resume_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj) { struct brw_context *brw = brw_context(ctx); struct brw_transform_feedback_object *brw_obj = (struct brw_transform_feedback_object *) obj; if (brw->is_haswell) { /* Reload the SOL buffer offset registers. */ for (int i = 0; i < BRW_MAX_XFB_STREAMS; i++) { BEGIN_BATCH(3); OUT_BATCH(GEN7_MI_LOAD_REGISTER_MEM | (3 - 2)); OUT_BATCH(GEN7_SO_WRITE_OFFSET(i)); OUT_RELOC(brw_obj->offset_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, i * sizeof(uint32_t)); ADVANCE_BATCH(); } } /* Store the new starting value of the SO_NUM_PRIMS_WRITTEN counters. */ save_prim_start_values(brw, brw_obj); }