intel: emit is_indexed_draw in the same VE than gl_DrawID

The Vertex Elements are now:
* VE 1: <BaseVertex/firstvertex, BaseInstance, VertexID, InstanceID>
* VE 2: <DrawID, is-indexed-draw, 0, 0>

VE1 is it kept as it was before, VE2 additionally contains the new
system value.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Antia Puentes 2018-04-28 14:09:20 +02:00
parent 6ba9088d9c
commit 0cbf29fa55
7 changed files with 78 additions and 48 deletions

View file

@ -116,6 +116,7 @@ emit_system_values_block(nir_block *block, fs_visitor *v)
case nir_intrinsic_load_vertex_id_zero_base:
case nir_intrinsic_load_base_vertex:
case nir_intrinsic_load_is_indexed_draw:
case nir_intrinsic_load_first_vertex:
case nir_intrinsic_load_instance_id:
case nir_intrinsic_load_base_instance:
@ -2460,6 +2461,7 @@ fs_visitor::nir_emit_vs_intrinsic(const fs_builder &bld,
}
case nir_intrinsic_load_first_vertex:
case nir_intrinsic_load_is_indexed_draw:
unreachable("lowered by brw_nir_lower_vs_inputs");
default:

View file

@ -266,6 +266,7 @@ brw_nir_lower_vs_inputs(nir_shader *nir,
case nir_intrinsic_load_base_instance:
case nir_intrinsic_load_vertex_id_zero_base:
case nir_intrinsic_load_instance_id:
case nir_intrinsic_load_is_indexed_draw:
case nir_intrinsic_load_draw_id: {
b.cursor = nir_after_instr(&intrin->instr);
@ -293,11 +294,15 @@ brw_nir_lower_vs_inputs(nir_shader *nir,
nir_intrinsic_set_component(load, 3);
break;
case nir_intrinsic_load_draw_id:
/* gl_DrawID is stored right after gl_VertexID and friends
* if any of them exist.
case nir_intrinsic_load_is_indexed_draw:
/* gl_DrawID and IsIndexedDraw are 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");

View file

@ -2833,6 +2833,13 @@ brw_compile_vs(const struct brw_compiler *compiler, void *log_data,
nr_attribute_slots++;
}
/* gl_DrawID and IsIndexedDraw share its very own vec4 */
if (shader->info.system_values_read &
(BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID) |
BITFIELD64_BIT(SYSTEM_VALUE_IS_INDEXED_DRAW))) {
nr_attribute_slots++;
}
if (shader->info.system_values_read &
BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX))
prog_data->uses_basevertex = true;
@ -2857,12 +2864,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)) {
prog_data->uses_drawid = true;
nr_attribute_slots++;
}
BITFIELD64_BIT(SYSTEM_VALUE_DRAW_ID))
prog_data->uses_drawid = true;
/* 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

View file

@ -900,20 +900,35 @@ struct brw_context
} 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 which will
* point to the indirect buffer for indirect draw calls.
*/
struct brw_bo *draw_params_bo;
uint32_t draw_params_offset;
struct {
/**
* 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.
*/
int gl_drawid;
/**
* Stores if the current _mesa_prim is an indexed or non-indexed draw
* (~0/0). Useful to calculate gl_BaseVertex as an AND of firstvertex
* and is_indexed_draw.
*/
int is_indexed_draw;
} 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 used for GL_ARB_shader_draw_parameters which contains
* parameters that are not present in the indirect buffer. They will go in
* their own vertex element.
*/
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

View file

@ -861,17 +861,21 @@ brw_draw_single_prim(struct gl_context *ctx,
}
/* gl_DrawID always needs its own vertex buffer since it's not part of
* the indirect parameter buffer. If the program uses gl_DrawID we need
* to flag BRW_NEW_VERTICES. For the first iteration, we don't have
* valid vs_prog_data, but we always flag BRW_NEW_VERTICES before
* the loop.
* the indirect parameter buffer. Same for is_indexed_draw, which shares
* the buffer with gl_DrawID. If the program uses gl_DrawID, we need to
* flag BRW_NEW_VERTICES. For the first iteration, we don't have 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)
brw->ctx.NewDriverState |= BRW_NEW_VERTICES;
brw->draw.derived_params.gl_drawid = prim->draw_id;
brw->draw.derived_params.is_indexed_draw = prim->indexed ? ~0 : 0;
brw_bo_unreference(brw->draw.derived_draw_params_bo);
brw->draw.derived_draw_params_bo = NULL;
brw->draw.derived_draw_params_offset = 0;
if (devinfo->gen < 6)
brw_set_prim(brw, prim);
else

View file

@ -716,11 +716,11 @@ brw_prepare_shader_draw_parameters(struct brw_context *brw)
&brw->draw.draw_params_offset);
}
if (vs_prog_data->uses_drawid) {
if (vs_prog_data->uses_drawid || vs_prog_data->uses_is_indexed_draw) {
brw_upload_data(&brw->upload,
&brw->draw.gl_drawid, sizeof(brw->draw.gl_drawid), 4,
&brw->draw.draw_id_bo,
&brw->draw.draw_id_offset);
&brw->draw.derived_params, sizeof(brw->draw.derived_params), 4,
&brw->draw.derived_draw_params_bo,
&brw->draw.derived_draw_params_offset);
}
}

View file

@ -539,16 +539,21 @@ genX(emit_vertices)(struct brw_context *brw)
}
#endif
const bool uses_firstvertex =
vs_prog_data->uses_basevertex || vs_prog_data->uses_firstvertex;
const bool uses_draw_params =
vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_basevertex ||
vs_prog_data->uses_baseinstance;
const bool needs_sgvs_element = (uses_firstvertex ||
vs_prog_data->uses_baseinstance ||
const bool uses_derived_draw_params =
vs_prog_data->uses_drawid ||
vs_prog_data->uses_is_indexed_draw;
const bool needs_sgvs_element = (uses_draw_params ||
vs_prog_data->uses_instanceid ||
vs_prog_data->uses_vertexid);
unsigned nr_elements =
brw->vb.nr_enabled + needs_sgvs_element + vs_prog_data->uses_drawid;
brw->vb.nr_enabled + needs_sgvs_element + uses_derived_draw_params;
#if GEN_GEN < 8
/* If any of the formats of vb.enabled needs more that one upload, we need
@ -588,11 +593,8 @@ genX(emit_vertices)(struct brw_context *brw)
}
/* Now emit 3DSTATE_VERTEX_BUFFERS and 3DSTATE_VERTEX_ELEMENTS packets. */
const bool uses_draw_params =
uses_firstvertex ||
vs_prog_data->uses_baseinstance;
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));
@ -626,11 +628,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 */);
}
@ -772,8 +774,7 @@ genX(emit_vertices)(struct brw_context *brw)
};
#if GEN_GEN >= 8
if (uses_firstvertex ||
vs_prog_data->uses_baseinstance) {
if (uses_draw_params) {
elem_state.VertexBufferIndex = brw->vb.nr_buffers;
elem_state.SourceElementFormat = ISL_FORMAT_R32G32_UINT;
elem_state.Component0Control = VFCOMP_STORE_SRC;
@ -782,11 +783,10 @@ genX(emit_vertices)(struct brw_context *brw)
#else
elem_state.VertexBufferIndex = brw->vb.nr_buffers;
elem_state.SourceElementFormat = ISL_FORMAT_R32G32_UINT;
if (uses_firstvertex)
if (uses_draw_params) {
elem_state.Component0Control = VFCOMP_STORE_SRC;
if (vs_prog_data->uses_baseinstance)
elem_state.Component1Control = VFCOMP_STORE_SRC;
}
if (vs_prog_data->uses_vertexid)
elem_state.Component2Control = VFCOMP_STORE_VID;
@ -799,13 +799,13 @@ genX(emit_vertices)(struct brw_context *brw)
dw += GENX(VERTEX_ELEMENT_STATE_length);
}
if (vs_prog_data->uses_drawid) {
if (uses_derived_draw_params) {
struct GENX(VERTEX_ELEMENT_STATE) elem_state = {
.Valid = true,
.VertexBufferIndex = brw->vb.nr_buffers + 1,
.SourceElementFormat = ISL_FORMAT_R32_UINT,
.SourceElementFormat = 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