anv: Use extended parameters on Gen11+

Gen11 added a nifty feature where we have three custom system-generated
values called extended parameters that we can set to any 32-bit values
we want.  These work just like vertex and instance ID and are controlled
in the pipeline by the 3DSTATE_SGVS_2 packet.  They are provided to the
draw call either by extra DWORDs on the end of 3DSTATE_PRIMITIVE or by
storing values to more state registers.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20295>
This commit is contained in:
Jason Ekstrand 2019-12-14 18:00:56 -06:00 committed by Marge Bot
parent 2680e32f71
commit c70ef757e6
3 changed files with 241 additions and 33 deletions

View file

@ -3826,6 +3826,7 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
genX(cmd_buffer_flush_dynamic_state)(cmd_buffer); genX(cmd_buffer_flush_dynamic_state)(cmd_buffer);
} }
#if GFX_VER < 11
static void static void
emit_vertex_bo(struct anv_cmd_buffer *cmd_buffer, emit_vertex_bo(struct anv_cmd_buffer *cmd_buffer,
struct anv_address addr, struct anv_address addr,
@ -3897,6 +3898,7 @@ emit_draw_index(struct anv_cmd_buffer *cmd_buffer, uint32_t draw_index)
emit_vertex_bo(cmd_buffer, addr, 4, ANV_DRAWID_VB_INDEX); emit_vertex_bo(cmd_buffer, addr, 4, ANV_DRAWID_VB_INDEX);
} }
#endif /* GFX_VER <= 11 */
static void static void
update_dirty_vbs_for_gfx8_vb_flush(struct anv_cmd_buffer *cmd_buffer, update_dirty_vbs_for_gfx8_vb_flush(struct anv_cmd_buffer *cmd_buffer,
@ -3919,6 +3921,7 @@ update_dirty_vbs_for_gfx8_vb_flush(struct anv_cmd_buffer *cmd_buffer,
#endif #endif
} }
#if GFX_VER < 11
ALWAYS_INLINE static void ALWAYS_INLINE static void
cmd_buffer_emit_vertex_constants_and_flush(struct anv_cmd_buffer *cmd_buffer, cmd_buffer_emit_vertex_constants_and_flush(struct anv_cmd_buffer *cmd_buffer,
const struct brw_vs_prog_data *vs_prog_data, const struct brw_vs_prog_data *vs_prog_data,
@ -3943,6 +3946,13 @@ cmd_buffer_emit_vertex_constants_and_flush(struct anv_cmd_buffer *cmd_buffer,
if (emitted || force_flush) if (emitted || force_flush)
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
} }
#endif
#if GFX_VER >= 11
#define _3DPRIMITIVE_DIRECT GENX(3DPRIMITIVE_EXTENDED)
#else
#define _3DPRIMITIVE_DIRECT GENX(3DPRIMITIVE)
#endif
void genX(CmdDraw)( void genX(CmdDraw)(
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,
@ -3953,7 +3963,6 @@ void genX(CmdDraw)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -3974,13 +3983,22 @@ void genX(CmdDraw)(
if (cmd_buffer->state.conditional_render_enabled) if (cmd_buffer->state.conditional_render_enabled)
genX(cmd_emit_conditional_render_predicate)(cmd_buffer); genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer, vs_prog_data, #if GFX_VER < 11
cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer,
get_vs_prog_data(pipeline),
firstVertex, firstInstance, 0, firstVertex, firstInstance, 0,
false /* force_flush */); false /* force_flush */);
#endif
genX(cmd_buffer_flush_gfx_state)(cmd_buffer); genX(cmd_buffer_flush_gfx_state)(cmd_buffer);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled; prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL; prim.VertexAccessType = SEQUENTIAL;
prim.VertexCountPerInstance = vertexCount; prim.VertexCountPerInstance = vertexCount;
@ -3989,6 +4007,12 @@ void genX(CmdDraw)(
pipeline->instance_multiplier; pipeline->instance_multiplier;
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = 0; prim.BaseVertexLocation = 0;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
prim.ExtendedParameter0 = firstVertex;
prim.ExtendedParameter1 = firstInstance;
prim.ExtendedParameter2 = 0;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4010,7 +4034,6 @@ void genX(CmdDrawMultiEXT)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4028,8 +4051,10 @@ void genX(CmdDrawMultiEXT)(
genX(cmd_emit_conditional_render_predicate)(cmd_buffer); genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
uint32_t i = 0; uint32_t i = 0;
#if GFX_VER < 11
vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride) { vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride) {
cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer, vs_prog_data, cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer,
get_vs_prog_data(pipeline),
draw->firstVertex, draw->firstVertex,
firstInstance, i, !i); firstInstance, i, !i);
@ -4043,12 +4068,27 @@ void genX(CmdDrawMultiEXT)(
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = 0; prim.BaseVertexLocation = 0;
} }
}
#else
vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE_EXTENDED), prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL;
prim.VertexCountPerInstance = draw->vertexCount;
prim.StartVertexLocation = draw->firstVertex;
prim.InstanceCount = instanceCount;
prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = 0;
prim.ExtendedParametersPresent = true;
prim.ExtendedParameter0 = draw->firstVertex;
prim.ExtendedParameter1 = firstInstance;
prim.ExtendedParameter2 = i;
}
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
genX(emit_dummy_post_sync_op)(cmd_buffer, draw->vertexCount); genX(emit_dummy_post_sync_op)(cmd_buffer, draw->vertexCount);
#endif #endif
} }
#endif
update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, SEQUENTIAL); update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, SEQUENTIAL);
@ -4065,7 +4105,6 @@ void genX(CmdDrawIndexed)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4087,13 +4126,22 @@ void genX(CmdDrawIndexed)(
if (cmd_buffer->state.conditional_render_enabled) if (cmd_buffer->state.conditional_render_enabled)
genX(cmd_emit_conditional_render_predicate)(cmd_buffer); genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
#if GFX_VER < 11
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer, vs_prog_data, cmd_buffer_emit_vertex_constants_and_flush(cmd_buffer, vs_prog_data,
vertexOffset, firstInstance, vertexOffset, firstInstance,
0, false /* force_flush */); 0, false /* force_flush */);
#endif
genX(cmd_buffer_flush_gfx_state)(cmd_buffer); genX(cmd_buffer_flush_gfx_state)(cmd_buffer);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled; prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = RANDOM; prim.VertexAccessType = RANDOM;
prim.VertexCountPerInstance = indexCount; prim.VertexCountPerInstance = indexCount;
@ -4102,6 +4150,12 @@ void genX(CmdDrawIndexed)(
pipeline->instance_multiplier; pipeline->instance_multiplier;
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = vertexOffset; prim.BaseVertexLocation = vertexOffset;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
prim.ExtendedParameter0 = vertexOffset;
prim.ExtendedParameter1 = firstInstance;
prim.ExtendedParameter2 = 0;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4124,7 +4178,6 @@ void genX(CmdDrawMultiIndexedEXT)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4143,6 +4196,8 @@ void genX(CmdDrawMultiIndexedEXT)(
genX(cmd_emit_conditional_render_predicate)(cmd_buffer); genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
uint32_t i = 0; uint32_t i = 0;
#if GFX_VER < 11
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (pVertexOffset) { if (pVertexOffset) {
if (vs_prog_data->uses_drawid) { if (vs_prog_data->uses_drawid) {
bool emitted = true; bool emitted = true;
@ -4172,9 +4227,6 @@ void genX(CmdDrawMultiIndexedEXT)(
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = *pVertexOffset; prim.BaseVertexLocation = *pVertexOffset;
} }
#if GFX_VERx10 == 125
genX(emit_dummy_post_sync_op)(cmd_buffer, draw->indexCount);
#endif
emitted = false; emitted = false;
} }
} else { } else {
@ -4197,9 +4249,6 @@ void genX(CmdDrawMultiIndexedEXT)(
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = *pVertexOffset; prim.BaseVertexLocation = *pVertexOffset;
} }
#if GFX_VERx10 == 125
genX(emit_dummy_post_sync_op)(cmd_buffer, draw->indexCount);
#endif
} }
} }
} else { } else {
@ -4218,11 +4267,29 @@ void genX(CmdDrawMultiIndexedEXT)(
prim.StartInstanceLocation = firstInstance; prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = draw->vertexOffset; prim.BaseVertexLocation = draw->vertexOffset;
} }
#if GFX_VERx10 == 125
genX(emit_dummy_post_sync_op)(cmd_buffer, draw->indexCount);
#endif
} }
} }
#else
vk_foreach_multi_draw_indexed(draw, i, pIndexInfo, drawCount, stride) {
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE_EXTENDED), prim) {
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = RANDOM;
prim.VertexCountPerInstance = draw->indexCount;
prim.StartVertexLocation = draw->firstIndex;
prim.InstanceCount = instanceCount *
pipeline->instance_multiplier;
prim.StartInstanceLocation = firstInstance;
prim.BaseVertexLocation = pVertexOffset ? *pVertexOffset : draw->vertexOffset;
prim.ExtendedParametersPresent = true;
prim.ExtendedParameter0 = draw->vertexOffset;
prim.ExtendedParameter1 = firstInstance;
prim.ExtendedParameter2 = i;
}
#if GFX_VERx10 == 125
genX(emit_dummy_post_sync_op)(cmd_buffer, draw->indexCount);
#endif
}
#endif
update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, RANDOM); update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, RANDOM);
@ -4237,6 +4304,25 @@ void genX(CmdDrawMultiIndexedEXT)(
#define GFX7_3DPRIM_START_INSTANCE 0x243C #define GFX7_3DPRIM_START_INSTANCE 0x243C
#define GFX7_3DPRIM_BASE_VERTEX 0x2440 #define GFX7_3DPRIM_BASE_VERTEX 0x2440
/* On Gen11+, we have three custom "extended parameters" which we can use to
* provide extra system-generated values to shaders. Our assignment of these
* is arbitrary; we choose to assign them as follows:
*
* gl_BaseVertex = XP0
* gl_BaseInstance = XP1
* gl_DrawID = XP2
*
* For gl_BaseInstance, we never actually have to set up the value because we
* can just program 3DSTATE_VF_SGVS_2 to load it implicitly. We can also do
* that for gl_BaseVertex but it does the wrong thing for indexed draws.
*/
#define GEN11_3DPRIM_XP0 0x2690
#define GEN11_3DPRIM_XP1 0x2694
#define GEN11_3DPRIM_XP2 0x2698
#define GEN11_3DPRIM_XP_BASE_VERTEX GEN11_3DPRIM_XP0
#define GEN11_3DPRIM_XP_BASE_INSTANCE GEN11_3DPRIM_XP1
#define GEN11_3DPRIM_XP_DRAW_ID GEN11_3DPRIM_XP2
void genX(CmdDrawIndirectByteCountEXT)( void genX(CmdDrawIndirectByteCountEXT)(
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,
uint32_t instanceCount, uint32_t instanceCount,
@ -4249,7 +4335,6 @@ void genX(CmdDrawIndirectByteCountEXT)(
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, counter_buffer, counterBuffer); ANV_FROM_HANDLE(anv_buffer, counter_buffer, counterBuffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
/* firstVertex is always zero for this draw function */ /* firstVertex is always zero for this draw function */
const uint32_t firstVertex = 0; const uint32_t firstVertex = 0;
@ -4272,11 +4357,14 @@ void genX(CmdDrawIndirectByteCountEXT)(
if (cmd_buffer->state.conditional_render_enabled) if (cmd_buffer->state.conditional_render_enabled)
genX(cmd_emit_conditional_render_predicate)(cmd_buffer); genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
#if GFX_VER < 11
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) vs_prog_data->uses_baseinstance)
emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance); emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance);
if (vs_prog_data->uses_drawid) if (vs_prog_data->uses_drawid)
emit_draw_index(cmd_buffer, 0); emit_draw_index(cmd_buffer, 0);
#endif
genX(cmd_buffer_flush_gfx_state)(cmd_buffer); genX(cmd_buffer_flush_gfx_state)(cmd_buffer);
@ -4296,10 +4384,26 @@ void genX(CmdDrawIndirectByteCountEXT)(
mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE), mi_imm(firstInstance)); mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE), mi_imm(firstInstance));
mi_store(&b, mi_reg32(GFX7_3DPRIM_BASE_VERTEX), mi_imm(0)); mi_store(&b, mi_reg32(GFX7_3DPRIM_BASE_VERTEX), mi_imm(0));
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { #if GFX_VER >= 11
mi_store(&b, mi_reg32(GEN11_3DPRIM_XP_BASE_VERTEX),
mi_imm(firstVertex));
/* GEN11_3DPRIM_XP_BASE_INSTANCE is implicit */
mi_store(&b, mi_reg32(GEN11_3DPRIM_XP_DRAW_ID), mi_imm(0));
#endif
anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.IndirectParameterEnable = true; prim.IndirectParameterEnable = true;
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled; prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL; prim.VertexAccessType = SEQUENTIAL;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4315,7 +4419,8 @@ void genX(CmdDrawIndirectByteCountEXT)(
static void static void
load_indirect_parameters(struct anv_cmd_buffer *cmd_buffer, load_indirect_parameters(struct anv_cmd_buffer *cmd_buffer,
struct anv_address addr, struct anv_address addr,
bool indexed) bool indexed,
uint32_t draw_id)
{ {
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
@ -4340,11 +4445,26 @@ load_indirect_parameters(struct anv_cmd_buffer *cmd_buffer,
mi_mem32(anv_address_add(addr, 12))); mi_mem32(anv_address_add(addr, 12)));
mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE), mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE),
mi_mem32(anv_address_add(addr, 16))); mi_mem32(anv_address_add(addr, 16)));
#if GFX_VER >= 11
mi_store(&b, mi_reg32(GEN11_3DPRIM_XP_BASE_VERTEX),
mi_mem32(anv_address_add(addr, 12)));
/* GEN11_3DPRIM_XP_BASE_INSTANCE is implicit */
#endif
} else { } else {
mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE), mi_store(&b, mi_reg32(GFX7_3DPRIM_START_INSTANCE),
mi_mem32(anv_address_add(addr, 12))); mi_mem32(anv_address_add(addr, 12)));
mi_store(&b, mi_reg32(GFX7_3DPRIM_BASE_VERTEX), mi_imm(0)); mi_store(&b, mi_reg32(GFX7_3DPRIM_BASE_VERTEX), mi_imm(0));
#if GFX_VER >= 11
mi_store(&b, mi_reg32(GEN11_3DPRIM_XP_BASE_VERTEX),
mi_mem32(anv_address_add(addr, 8)));
/* GEN11_3DPRIM_XP_BASE_INSTANCE is implicit */
#endif
} }
#if GFX_VER >= 11
mi_store(&b, mi_reg32(GEN11_3DPRIM_XP_DRAW_ID),
mi_imm(draw_id));
#endif
} }
void genX(CmdDrawIndirect)( void genX(CmdDrawIndirect)(
@ -4356,8 +4476,10 @@ void genX(CmdDrawIndirect)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
#if GFX_VER < 11
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
#endif
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4376,23 +4498,34 @@ void genX(CmdDrawIndirect)(
for (uint32_t i = 0; i < drawCount; i++) { for (uint32_t i = 0; i < drawCount; i++) {
struct anv_address draw = anv_address_add(buffer->address, offset); struct anv_address draw = anv_address_add(buffer->address, offset);
#if GFX_VER < 11
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) vs_prog_data->uses_baseinstance)
emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 8)); emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 8));
if (vs_prog_data->uses_drawid) if (vs_prog_data->uses_drawid)
emit_draw_index(cmd_buffer, i); emit_draw_index(cmd_buffer, i);
# endif
/* Emitting draw index or vertex index BOs may result in needing /* Emitting draw index or vertex index BOs may result in needing
* additional VF cache flushes. * additional VF cache flushes.
*/ */
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
load_indirect_parameters(cmd_buffer, draw, false); load_indirect_parameters(cmd_buffer, draw, false, i);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.IndirectParameterEnable = true; prim.IndirectParameterEnable = true;
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled; prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = SEQUENTIAL; prim.VertexAccessType = SEQUENTIAL;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4416,8 +4549,8 @@ void genX(CmdDrawIndexedIndirect)(
{ {
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; UNUSED struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); UNUSED const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4436,24 +4569,35 @@ void genX(CmdDrawIndexedIndirect)(
for (uint32_t i = 0; i < drawCount; i++) { for (uint32_t i = 0; i < drawCount; i++) {
struct anv_address draw = anv_address_add(buffer->address, offset); struct anv_address draw = anv_address_add(buffer->address, offset);
#if GFX_VER < 11
/* TODO: We need to stomp base vertex to 0 somehow */ /* TODO: We need to stomp base vertex to 0 somehow */
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) vs_prog_data->uses_baseinstance)
emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 12)); emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 12));
if (vs_prog_data->uses_drawid) if (vs_prog_data->uses_drawid)
emit_draw_index(cmd_buffer, i); emit_draw_index(cmd_buffer, i);
#endif
/* Emitting draw index or vertex index BOs may result in needing /* Emitting draw index or vertex index BOs may result in needing
* additional VF cache flushes. * additional VF cache flushes.
*/ */
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
load_indirect_parameters(cmd_buffer, draw, true); load_indirect_parameters(cmd_buffer, draw, true, i);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.IndirectParameterEnable = true; prim.IndirectParameterEnable = true;
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled; prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
prim.VertexAccessType = RANDOM; prim.VertexAccessType = RANDOM;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4562,9 +4706,11 @@ void genX(CmdDrawIndirectCount)(
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer); ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
#if GFX_VER < 11
struct anv_cmd_state *cmd_state = &cmd_buffer->state; struct anv_cmd_state *cmd_state = &cmd_buffer->state;
struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
#endif
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4588,23 +4734,34 @@ void genX(CmdDrawIndirectCount)(
emit_draw_count_predicate_cond(cmd_buffer, &b, i, max); emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
#if GFX_VER < 11
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) vs_prog_data->uses_baseinstance)
emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 8)); emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 8));
if (vs_prog_data->uses_drawid) if (vs_prog_data->uses_drawid)
emit_draw_index(cmd_buffer, i); emit_draw_index(cmd_buffer, i);
#endif
/* Emitting draw index or vertex index BOs may result in needing /* Emitting draw index or vertex index BOs may result in needing
* additional VF cache flushes. * additional VF cache flushes.
*/ */
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
load_indirect_parameters(cmd_buffer, draw, false); load_indirect_parameters(cmd_buffer, draw, false, i);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.IndirectParameterEnable = true; prim.IndirectParameterEnable = true;
prim.PredicateEnable = true; prim.PredicateEnable = true;
prim.VertexAccessType = SEQUENTIAL; prim.VertexAccessType = SEQUENTIAL;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -4633,9 +4790,11 @@ void genX(CmdDrawIndexedIndirectCount)(
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer); ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
#if GFX_VER < 11
struct anv_cmd_state *cmd_state = &cmd_buffer->state; struct anv_cmd_state *cmd_state = &cmd_buffer->state;
struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline; struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline;
const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
#endif
if (anv_batch_has_error(&cmd_buffer->batch)) if (anv_batch_has_error(&cmd_buffer->batch))
return; return;
@ -4659,24 +4818,35 @@ void genX(CmdDrawIndexedIndirectCount)(
emit_draw_count_predicate_cond(cmd_buffer, &b, i, max); emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
#if GFX_VER < 11
/* TODO: We need to stomp base vertex to 0 somehow */ /* TODO: We need to stomp base vertex to 0 somehow */
if (vs_prog_data->uses_firstvertex || if (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) vs_prog_data->uses_baseinstance)
emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 12)); emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 12));
if (vs_prog_data->uses_drawid) if (vs_prog_data->uses_drawid)
emit_draw_index(cmd_buffer, i); emit_draw_index(cmd_buffer, i);
#endif
/* Emitting draw index or vertex index BOs may result in needing /* Emitting draw index or vertex index BOs may result in needing
* additional VF cache flushes. * additional VF cache flushes.
*/ */
genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
load_indirect_parameters(cmd_buffer, draw, true); load_indirect_parameters(cmd_buffer, draw, true, i);
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) { anv_batch_emit(&cmd_buffer->batch,
#if GFX_VER < 11
GENX(3DPRIMITIVE),
#else
GENX(3DPRIMITIVE_EXTENDED),
#endif
prim) {
prim.IndirectParameterEnable = true; prim.IndirectParameterEnable = true;
prim.PredicateEnable = true; prim.PredicateEnable = true;
prim.VertexAccessType = RANDOM; prim.VertexAccessType = RANDOM;
#if GFX_VER >= 11
prim.ExtendedParametersPresent = true;
#endif
} }
#if GFX_VERx10 == 125 #if GFX_VERx10 == 125
@ -7637,6 +7807,7 @@ genX(batch_emit_dummy_post_sync_op)(struct anv_batch *batch,
#if GFX_VERx10 != 125 #if GFX_VERx10 != 125
return; return;
#endif #endif
/* Wa_14016118574 */
if ((primitive_topology == _3DPRIM_POINTLIST || if ((primitive_topology == _3DPRIM_POINTLIST ||
primitive_topology == _3DPRIM_LINELIST || primitive_topology == _3DPRIM_LINELIST ||
primitive_topology == _3DPRIM_LINESTRIP || primitive_topology == _3DPRIM_LINESTRIP ||

View file

@ -60,6 +60,9 @@ emit_common_so_memcpy(struct anv_batch *batch, struct anv_device *device,
vfi.VertexElementIndex = 0; vfi.VertexElementIndex = 0;
} }
anv_batch_emit(batch, GENX(3DSTATE_VF_SGVS), sgvs); anv_batch_emit(batch, GENX(3DSTATE_VF_SGVS), sgvs);
#if GFX_VER >= 11
anv_batch_emit(batch, GENX(3DSTATE_VF_SGVS_2), sgvs);
#endif
/* Disable all shader stages */ /* Disable all shader stages */
anv_batch_emit(batch, GENX(3DSTATE_VS), vs); anv_batch_emit(batch, GENX(3DSTATE_VS), vs);

View file

@ -193,7 +193,9 @@ emit_vertex_input(struct anv_graphics_pipeline *pipeline,
} }
const uint32_t id_slot = elem_count; const uint32_t id_slot = elem_count;
const uint32_t drawid_slot = elem_count + needs_svgs_elem;
if (needs_svgs_elem) { if (needs_svgs_elem) {
#if GFX_VER < 11
/* From the Broadwell PRM for the 3D_Vertex_Component_Control enum: /* From the Broadwell PRM for the 3D_Vertex_Component_Control enum:
* "Within a VERTEX_ELEMENT_STATE structure, if a Component * "Within a VERTEX_ELEMENT_STATE structure, if a Component
* Control field is set to something other than VFCOMP_STORE_SRC, * Control field is set to something other than VFCOMP_STORE_SRC,
@ -206,13 +208,20 @@ emit_vertex_input(struct anv_graphics_pipeline *pipeline,
uint32_t base_ctrl = (vs_prog_data->uses_firstvertex || uint32_t base_ctrl = (vs_prog_data->uses_firstvertex ||
vs_prog_data->uses_baseinstance) ? vs_prog_data->uses_baseinstance) ?
VFCOMP_STORE_SRC : VFCOMP_STORE_0; VFCOMP_STORE_SRC : VFCOMP_STORE_0;
#endif
struct GENX(VERTEX_ELEMENT_STATE) element = { struct GENX(VERTEX_ELEMENT_STATE) element = {
.VertexBufferIndex = ANV_SVGS_VB_INDEX, .VertexBufferIndex = ANV_SVGS_VB_INDEX,
.Valid = true, .Valid = true,
.SourceElementFormat = ISL_FORMAT_R32G32_UINT, .SourceElementFormat = ISL_FORMAT_R32G32_UINT,
#if GFX_VER >= 11
/* On gen11, these are taken care of by extra parameter slots */
.Component0Control = VFCOMP_STORE_0,
.Component1Control = VFCOMP_STORE_0,
#else
.Component0Control = base_ctrl, .Component0Control = base_ctrl,
.Component1Control = base_ctrl, .Component1Control = base_ctrl,
#endif
.Component2Control = VFCOMP_STORE_0, .Component2Control = VFCOMP_STORE_0,
.Component3Control = VFCOMP_STORE_0, .Component3Control = VFCOMP_STORE_0,
}; };
@ -232,13 +241,38 @@ emit_vertex_input(struct anv_graphics_pipeline *pipeline,
sgvs.InstanceIDElementOffset = id_slot; sgvs.InstanceIDElementOffset = id_slot;
} }
const uint32_t drawid_slot = elem_count + needs_svgs_elem; #if GFX_VER >= 11
anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_VF_SGVS_2), sgvs) {
/* gl_BaseVertex */
sgvs.XP0Enable = vs_prog_data->uses_firstvertex;
sgvs.XP0SourceSelect = XP0_PARAMETER;
sgvs.XP0ComponentNumber = 0;
sgvs.XP0ElementOffset = id_slot;
/* gl_BaseInstance */
sgvs.XP1Enable = vs_prog_data->uses_baseinstance;
sgvs.XP1SourceSelect = StartingInstanceLocation;
sgvs.XP1ComponentNumber = 1;
sgvs.XP1ElementOffset = id_slot;
/* gl_DrawID */
sgvs.XP2Enable = vs_prog_data->uses_drawid;
sgvs.XP2ComponentNumber = 0;
sgvs.XP2ElementOffset = drawid_slot;
}
#endif
if (vs_prog_data->uses_drawid) { if (vs_prog_data->uses_drawid) {
struct GENX(VERTEX_ELEMENT_STATE) element = { struct GENX(VERTEX_ELEMENT_STATE) element = {
.VertexBufferIndex = ANV_DRAWID_VB_INDEX, .VertexBufferIndex = ANV_DRAWID_VB_INDEX,
.Valid = true, .Valid = true,
.SourceElementFormat = ISL_FORMAT_R32_UINT, .SourceElementFormat = ISL_FORMAT_R32_UINT,
#if GFX_VER >= 11
/* On gen11, this is taken care of by extra parameter slots */
.Component0Control = VFCOMP_STORE_0,
#else
.Component0Control = VFCOMP_STORE_SRC, .Component0Control = VFCOMP_STORE_SRC,
#endif
.Component1Control = VFCOMP_STORE_0, .Component1Control = VFCOMP_STORE_0,
.Component2Control = VFCOMP_STORE_0, .Component2Control = VFCOMP_STORE_0,
.Component3Control = VFCOMP_STORE_0, .Component3Control = VFCOMP_STORE_0,