The new order is: * VE 1: <firstvertex, BaseInstance, VertexID, InstanceID> * VE 2: <Draw ID, BaseVertex, 0, 0>
Previously it was: * VE 1: <BaseVertex, BaseInstance, VertexID, InstanceID> * VE 2: <Draw ID, 0, 0, 0> The gl_BaseVertex is in a new location now, and firstvertex occupies the old gl_BaseVertex place. This way we can keep pointing to the indirect buffer for indirect draw calls. Reviewed-by: Neil Roberts <nrobe...@igalia.com> --- src/intel/compiler/brw_nir.c | 11 +++++--- src/intel/compiler/brw_vec4.cpp | 13 +++++---- src/mesa/drivers/dri/i965/brw_context.h | 36 ++++++++++++++++++------- src/mesa/drivers/dri/i965/brw_draw.c | 26 +++++++++++------- src/mesa/drivers/dri/i965/brw_draw_upload.c | 13 ++++----- src/mesa/drivers/dri/i965/genX_state_upload.c | 39 +++++++++++++++------------ 6 files changed, 88 insertions(+), 50 deletions(-) diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c index 8f3f77f89ae..f702f5b8534 100644 --- a/src/intel/compiler/brw_nir.c +++ b/src/intel/compiler/brw_nir.c @@ -240,7 +240,7 @@ brw_nir_lower_vs_inputs(nir_shader *nir, */ const bool has_sgvs = nir->info.system_values_read & - (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) | + (BITFIELD64_BIT(SYSTEM_VALUE_FIRST_VERTEX) | BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) | BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) | BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID)); @@ -262,6 +262,7 @@ brw_nir_lower_vs_inputs(nir_shader *nir, nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); switch (intrin->intrinsic) { + case nir_intrinsic_load_first_vertex: case nir_intrinsic_load_base_vertex: case nir_intrinsic_load_base_instance: case nir_intrinsic_load_vertex_id_zero_base: @@ -279,7 +280,7 @@ brw_nir_lower_vs_inputs(nir_shader *nir, nir_intrinsic_set_base(load, num_inputs); switch (intrin->intrinsic) { - case nir_intrinsic_load_base_vertex: + case nir_intrinsic_load_first_vertex: nir_intrinsic_set_component(load, 0); break; case nir_intrinsic_load_base_instance: @@ -292,11 +293,15 @@ brw_nir_lower_vs_inputs(nir_shader *nir, nir_intrinsic_set_component(load, 3); break; case nir_intrinsic_load_draw_id: + case nir_intrinsic_load_base_vertex: /* gl_DrawID is stored right after gl_VertexID and friends * if any of them exist. */ nir_intrinsic_set_base(load, num_inputs + has_sgvs); - nir_intrinsic_set_component(load, 0); + if (intrin->intrinsic == nir_intrinsic_load_draw_id) + nir_intrinsic_set_component(load, 0); + else + nir_intrinsic_set_component(load, 1); break; default: unreachable("Invalid system value intrinsic"); diff --git a/src/intel/compiler/brw_vec4.cpp b/src/intel/compiler/brw_vec4.cpp index 14f930e0264..70a197a9fa0 100644 --- a/src/intel/compiler/brw_vec4.cpp +++ b/src/intel/compiler/brw_vec4.cpp @@ -2789,13 +2789,19 @@ brw_compile_vs(const struct brw_compiler *compiler, void *log_data, * incoming vertex attribute. So, add an extra slot. */ if (shader->info.system_values_read & - (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) | + (BITFIELD64_BIT(SYSTEM_VALUE_FIRST_VERTEX) | BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) | BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) | BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID))) { nr_attribute_slots++; } + if (shader->info.system_values_read & + (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) | + BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID))) { + nr_attribute_slots++; + } + if (shader->info.system_values_read & BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX)) prog_data->uses_basevertex = true; @@ -2816,12 +2822,9 @@ brw_compile_vs(const struct brw_compiler *compiler, void *log_data, BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID)) prog_data->uses_instanceid = true; - /* gl_DrawID has its very own vec4 */ if (shader->info.system_values_read & - BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID)) { + BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID)) prog_data->uses_drawid = true; - nr_attribute_slots++; - } /* The 3DSTATE_VS documentation lists the lower bound on "Vertex URB Entry * Read Length" as 1 in vec4 mode, and 0 in SIMD8 mode. Empirically, in diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 06704838061..c6d176bc243 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -843,28 +843,44 @@ struct brw_context struct { struct { - /** The value of gl_BaseVertex for the current _mesa_prim. */ - int gl_basevertex; + /** + * Either the value of gl_BaseVertex for indexed draw calls or the + * value of the argument <first> for non-indexed draw calls, for the + * current _mesa_prim. + */ + int firstvertex; /** The value of gl_BaseInstance for the current _mesa_prim. */ int gl_baseinstance; } params; /** - * Buffer and offset used for GL_ARB_shader_draw_parameters - * (for now, only gl_BaseVertex). + * Buffer and offset used for GL_ARB_shader_draw_parameters. For indirect + * draw calls it will point to the indirect buffer. */ struct brw_bo *draw_params_bo; uint32_t draw_params_offset; + struct { + /** The value of gl_DrawID for the current _mesa_prim. */ + int gl_drawid; + + /** + * The value of gl_BaseVertex for the current _mesa_prim. It must be + * zero for non-indexed calls. + */ + int gl_basevertex; + } derived_params; + /** - * The value of gl_DrawID for the current _mesa_prim. This always comes - * in from it's own vertex buffer since it's not part of the indirect - * draw parameters. + * Buffer and offset also used for GL_ARB_shader_draw_parameters. As they + * are not part of the indirect buffer they will go in their own vertex + * element. Note that although gl_BaseVertex is part of the indirect + * buffer for indexed draw calls, that is not longer the case for + * non-indexed. */ - int gl_drawid; - struct brw_bo *draw_id_bo; - uint32_t draw_id_offset; + struct brw_bo *derived_draw_params_bo; + uint32_t derived_draw_params_offset; /** * Pointer to the the buffer storing the indirect draw parameters. It diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 7e29dcfd4e8..18d26cfafca 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -760,25 +760,25 @@ brw_draw_single_prim(struct gl_context *ctx, * always flag if the shader uses one of the values. For direct draws, * we only flag if the values change. */ - const int new_basevertex = + const int new_firstvertex = prim->indexed ? prim->basevertex : prim->start; const int new_baseinstance = prim->base_instance; const struct brw_vs_prog_data *vs_prog_data = brw_vs_prog_data(brw->vs.base.prog_data); if (prim_id > 0) { const bool uses_draw_parameters = - vs_prog_data->uses_basevertex || + vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance; if ((uses_draw_parameters && prim->is_indirect) || - (vs_prog_data->uses_basevertex && - brw->draw.params.gl_basevertex != new_basevertex) || + (vs_prog_data->uses_firstvertex && + brw->draw.params.firstvertex != new_firstvertex) || (vs_prog_data->uses_baseinstance && brw->draw.params.gl_baseinstance != new_baseinstance)) brw->ctx.NewDriverState |= BRW_NEW_VERTICES; } - brw->draw.params.gl_basevertex = new_basevertex; + brw->draw.params.firstvertex = new_firstvertex; brw->draw.params.gl_baseinstance = new_baseinstance; brw_bo_unreference(brw->draw.draw_params_bo); @@ -803,12 +803,20 @@ brw_draw_single_prim(struct gl_context *ctx, * valid vs_prog_data, but we always flag BRW_NEW_VERTICES before * the loop. */ - brw->draw.gl_drawid = prim->draw_id; - brw_bo_unreference(brw->draw.draw_id_bo); - brw->draw.draw_id_bo = NULL; - if (prim_id > 0 && vs_prog_data->uses_drawid) + const int new_basevertex = prim->indexed ? prim->basevertex : prim->start; + + if (prim_id > 0 && + (vs_prog_data->uses_drawid || + (vs_prog_data->uses_basevertex && + brw->draw.derived_params.gl_basevertex != new_basevertex))) brw->ctx.NewDriverState |= BRW_NEW_VERTICES; + brw->draw.derived_params.gl_drawid = prim->draw_id; + brw->draw.derived_params.gl_basevertex = new_basevertex; + + brw_bo_unreference(brw->draw.derived_draw_params_bo); + brw->draw.derived_draw_params_bo = NULL; + if (devinfo->gen < 6) brw_set_prim(brw, prim); else diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 9b81999ea05..da3a0569ccb 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -696,18 +696,19 @@ brw_prepare_shader_draw_parameters(struct brw_context *brw) const struct brw_vs_prog_data *vs_prog_data = brw_vs_prog_data(brw->vs.base.prog_data); - /* For non-indirect draws, upload gl_BaseVertex. */ - if ((vs_prog_data->uses_basevertex || vs_prog_data->uses_baseinstance) && + /* For non-indirect draws, upload the parameters. */ + if ((vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance) && brw->draw.draw_params_bo == NULL) { intel_upload_data(brw, &brw->draw.params, sizeof(brw->draw.params), 4, &brw->draw.draw_params_bo, &brw->draw.draw_params_offset); } - if (vs_prog_data->uses_drawid) { - intel_upload_data(brw, &brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4, - &brw->draw.draw_id_bo, - &brw->draw.draw_id_offset); + if (vs_prog_data->uses_drawid || vs_prog_data->uses_basevertex) { + intel_upload_data(brw, &brw->draw.derived_params, + sizeof(brw->draw.derived_params), 4, + &brw->draw.derived_draw_params_bo, + &brw->draw.derived_draw_params_offset); } } diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index dcf497c9183..db68d89aa66 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -498,19 +498,20 @@ genX(emit_vertices)(struct brw_context *brw) * can't be inserted past that so we need a dummy element to ensure that * the edge flag is the last one. */ - const bool needs_sgvs_element = (vs_prog_data->uses_basevertex || + const bool needs_sgvs_element = (vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance || ((vs_prog_data->uses_instanceid || vs_prog_data->uses_vertexid) && uses_edge_flag)); #else - const bool needs_sgvs_element = (vs_prog_data->uses_basevertex || + const bool needs_sgvs_element = (vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance || vs_prog_data->uses_instanceid || vs_prog_data->uses_vertexid); #endif unsigned nr_elements = - brw->vb.nr_enabled + needs_sgvs_element + vs_prog_data->uses_drawid; + brw->vb.nr_enabled + needs_sgvs_element + + (vs_prog_data->uses_drawid || vs_prog_data->uses_basevertex); #if GEN_GEN < 8 /* If any of the formats of vb.enabled needs more that one upload, we need @@ -549,10 +550,15 @@ genX(emit_vertices)(struct brw_context *brw) /* Now emit 3DSTATE_VERTEX_BUFFERS and 3DSTATE_VERTEX_ELEMENTS packets. */ const bool uses_draw_params = - vs_prog_data->uses_basevertex || + vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance; + + const bool uses_derived_draw_params = + vs_prog_data->uses_basevertex || + vs_prog_data->uses_drawid; + const unsigned nr_buffers = brw->vb.nr_buffers + - uses_draw_params + vs_prog_data->uses_drawid; + uses_draw_params + uses_derived_draw_params; if (nr_buffers) { assert(nr_buffers <= (GEN_GEN >= 6 ? 33 : 17)); @@ -586,11 +592,11 @@ genX(emit_vertices)(struct brw_context *brw) 0 /* step rate */); } - if (vs_prog_data->uses_drawid) { + if (uses_derived_draw_params) { dw = genX(emit_vertex_buffer_state)(brw, dw, brw->vb.nr_buffers + 1, - brw->draw.draw_id_bo, - brw->draw.draw_id_offset, - brw->draw.draw_id_bo->size, + brw->draw.derived_draw_params_bo, + brw->draw.derived_draw_params_offset, + brw->draw.derived_draw_params_bo->size, 0 /* stride */, 0 /* step rate */); } @@ -727,7 +733,7 @@ genX(emit_vertices)(struct brw_context *brw) }; #if GEN_GEN >= 8 - if (vs_prog_data->uses_basevertex || + if (vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance) { elem_state.VertexBufferIndex = brw->vb.nr_buffers; elem_state.SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32_UINT; @@ -737,13 +743,12 @@ genX(emit_vertices)(struct brw_context *brw) #else elem_state.VertexBufferIndex = brw->vb.nr_buffers; elem_state.SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32_UINT; - if (vs_prog_data->uses_basevertex) + if (vs_prog_data->uses_firstvertex || vs_prog_data->uses_baseinstance) { elem_state.Component0Control = VFCOMP_STORE_SRC; - - if (vs_prog_data->uses_baseinstance) elem_state.Component1Control = VFCOMP_STORE_SRC; + } - if (vs_prog_data->uses_vertexid) + if (vs_prog_data->uses_firstvertex) elem_state.Component2Control = VFCOMP_STORE_VID; if (vs_prog_data->uses_instanceid) @@ -754,13 +759,13 @@ genX(emit_vertices)(struct brw_context *brw) dw += GENX(VERTEX_ELEMENT_STATE_length); } - if (vs_prog_data->uses_drawid) { + if (vs_prog_data->uses_drawid || vs_prog_data->uses_basevertex) { struct GENX(VERTEX_ELEMENT_STATE) elem_state = { .Valid = true, .VertexBufferIndex = brw->vb.nr_buffers + 1, - .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32_UINT, + .SourceElementFormat = (enum GENX(SURFACE_FORMAT)) ISL_FORMAT_R32G32_UINT, .Component0Control = VFCOMP_STORE_SRC, - .Component1Control = VFCOMP_STORE_0, + .Component1Control = VFCOMP_STORE_SRC, .Component2Control = VFCOMP_STORE_0, .Component3Control = VFCOMP_STORE_0, #if GEN_GEN < 5 -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev