mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
anv: add support for dynamic primitive topology change
This is done using 3DSTATE_VF_TOPOLOGY packet that overrides topology used in subsequent 3DPRIMITIVE commands. For gen7[5] we override the pipeline topology when emitting draw commands. v2: fix the way gen7[5] is handled (Lionel) Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5604>
This commit is contained in:
parent
f426663f9c
commit
f6fa4a8000
6 changed files with 95 additions and 7 deletions
|
|
@ -78,6 +78,7 @@ const struct anv_dynamic_state default_dynamic_state = {
|
||||||
},
|
},
|
||||||
.cull_mode = 0,
|
.cull_mode = 0,
|
||||||
.front_face = 0,
|
.front_face = 0,
|
||||||
|
.primitive_topology = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -145,6 +146,7 @@ anv_dynamic_state_copy(struct anv_dynamic_state *dest,
|
||||||
|
|
||||||
ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
|
ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
|
||||||
ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
|
ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
|
||||||
|
ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
|
||||||
|
|
||||||
#undef ANV_CMP_COPY
|
#undef ANV_CMP_COPY
|
||||||
|
|
||||||
|
|
@ -537,6 +539,17 @@ void anv_CmdSetScissorWithCountEXT(
|
||||||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
|
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void anv_CmdSetPrimitiveTopologyEXT(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkPrimitiveTopology primitiveTopology)
|
||||||
|
{
|
||||||
|
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
|
|
||||||
|
cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;
|
||||||
|
|
||||||
|
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
|
||||||
|
}
|
||||||
|
|
||||||
void anv_CmdSetLineWidth(
|
void anv_CmdSetLineWidth(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
float lineWidth)
|
float lineWidth)
|
||||||
|
|
|
||||||
|
|
@ -1883,6 +1883,24 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
|
||||||
pCreateInfo->pRasterizationState->frontFace;
|
pCreateInfo->pRasterizationState->frontFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
|
||||||
|
assert(pCreateInfo->pInputAssemblyState);
|
||||||
|
bool has_tess = false;
|
||||||
|
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
||||||
|
const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
|
||||||
|
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||||
|
if (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL)
|
||||||
|
has_tess = true;
|
||||||
|
}
|
||||||
|
if (has_tess) {
|
||||||
|
const VkPipelineTessellationStateCreateInfo *tess_info =
|
||||||
|
pCreateInfo->pTessellationState;
|
||||||
|
dynamic->primitive_topology = _3DPRIM_PATCHLIST(tess_info->patchControlPoints);
|
||||||
|
} else {
|
||||||
|
dynamic->primitive_topology = pCreateInfo->pInputAssemblyState->topology;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Section 9.2 of the Vulkan 1.0.15 spec says:
|
/* Section 9.2 of the Vulkan 1.0.15 spec says:
|
||||||
*
|
*
|
||||||
* pColorBlendState is [...] NULL if the pipeline has rasterization
|
* pColorBlendState is [...] NULL if the pipeline has rasterization
|
||||||
|
|
|
||||||
|
|
@ -2691,6 +2691,7 @@ struct anv_dynamic_state {
|
||||||
|
|
||||||
VkCullModeFlags cull_mode;
|
VkCullModeFlags cull_mode;
|
||||||
VkFrontFace front_face;
|
VkFrontFace front_face;
|
||||||
|
VkPrimitiveTopology primitive_topology;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct anv_dynamic_state default_dynamic_state;
|
extern const struct anv_dynamic_state default_dynamic_state;
|
||||||
|
|
@ -2804,6 +2805,8 @@ struct anv_cmd_graphics_state {
|
||||||
|
|
||||||
struct anv_dynamic_state dynamic;
|
struct anv_dynamic_state dynamic;
|
||||||
|
|
||||||
|
uint32_t primitive_topology;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct anv_buffer *index_buffer;
|
struct anv_buffer *index_buffer;
|
||||||
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
|
uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,30 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint32_t vk_to_gen_primitive_type[] = {
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = _3DPRIM_POINTLIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = _3DPRIM_LINELIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = _3DPRIM_LINESTRIP,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = _3DPRIM_TRILIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = _3DPRIM_LINELIST_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = _3DPRIM_LINESTRIP_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = _3DPRIM_TRILIST_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||||
|
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
|
||||||
|
uint32_t topology;
|
||||||
|
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
|
||||||
|
topology = d->primitive_topology;
|
||||||
|
else
|
||||||
|
topology = vk_to_gen_primitive_type[d->primitive_topology];
|
||||||
|
|
||||||
|
cmd_buffer->state.gfx.primitive_topology = topology;
|
||||||
|
}
|
||||||
|
|
||||||
cmd_buffer->state.gfx.dirty = 0;
|
cmd_buffer->state.gfx.dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,18 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||||
[VK_FRONT_FACE_COUNTER_CLOCKWISE] = 1,
|
[VK_FRONT_FACE_COUNTER_CLOCKWISE] = 1,
|
||||||
[VK_FRONT_FACE_CLOCKWISE] = 0
|
[VK_FRONT_FACE_CLOCKWISE] = 0
|
||||||
};
|
};
|
||||||
|
static const uint32_t vk_to_gen_primitive_type[] = {
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = _3DPRIM_POINTLIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = _3DPRIM_LINELIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = _3DPRIM_LINESTRIP,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = _3DPRIM_TRILIST,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = _3DPRIM_LINELIST_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = _3DPRIM_LINESTRIP_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = _3DPRIM_TRILIST_ADJ,
|
||||||
|
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ,
|
||||||
|
};
|
||||||
|
|
||||||
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||||
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
|
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
|
||||||
|
|
@ -606,6 +618,21 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
|
||||||
|
ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
|
||||||
|
uint32_t topology;
|
||||||
|
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
|
||||||
|
topology = d->primitive_topology;
|
||||||
|
else
|
||||||
|
topology = vk_to_gen_primitive_type[d->primitive_topology];
|
||||||
|
|
||||||
|
cmd_buffer->state.gfx.primitive_topology = topology;
|
||||||
|
|
||||||
|
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_TOPOLOGY), vft) {
|
||||||
|
vft.PrimitiveTopologyType = topology;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd_buffer->state.gfx.dirty = 0;
|
cmd_buffer->state.gfx.dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3404,6 +3404,9 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||||
cmd_buffer_alloc_push_constants(cmd_buffer);
|
cmd_buffer_alloc_push_constants(cmd_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE)
|
||||||
|
cmd_buffer->state.gfx.primitive_topology = pipeline->topology;
|
||||||
|
|
||||||
#if GEN_GEN <= 7
|
#if GEN_GEN <= 7
|
||||||
if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
|
if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
|
||||||
cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
|
cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
|
||||||
|
|
@ -3605,7 +3608,7 @@ void genX(CmdDraw)(
|
||||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
||||||
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
|
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
|
||||||
prim.VertexAccessType = SEQUENTIAL;
|
prim.VertexAccessType = SEQUENTIAL;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
prim.VertexCountPerInstance = vertexCount;
|
prim.VertexCountPerInstance = vertexCount;
|
||||||
prim.StartVertexLocation = firstVertex;
|
prim.StartVertexLocation = firstVertex;
|
||||||
prim.InstanceCount = instanceCount;
|
prim.InstanceCount = instanceCount;
|
||||||
|
|
@ -3656,7 +3659,7 @@ void genX(CmdDrawIndexed)(
|
||||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
||||||
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
|
prim.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
|
||||||
prim.VertexAccessType = RANDOM;
|
prim.VertexAccessType = RANDOM;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
prim.VertexCountPerInstance = indexCount;
|
prim.VertexCountPerInstance = indexCount;
|
||||||
prim.StartVertexLocation = firstIndex;
|
prim.StartVertexLocation = firstIndex;
|
||||||
prim.InstanceCount = instanceCount;
|
prim.InstanceCount = instanceCount;
|
||||||
|
|
@ -3736,7 +3739,7 @@ void genX(CmdDrawIndirectByteCountEXT)(
|
||||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE), prim) {
|
||||||
prim.IndirectParameterEnable = true;
|
prim.IndirectParameterEnable = true;
|
||||||
prim.VertexAccessType = SEQUENTIAL;
|
prim.VertexAccessType = SEQUENTIAL;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
||||||
|
|
@ -3821,7 +3824,7 @@ void genX(CmdDrawIndirect)(
|
||||||
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;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
||||||
|
|
@ -3871,7 +3874,7 @@ void genX(CmdDrawIndexedIndirect)(
|
||||||
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;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
|
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
|
||||||
|
|
@ -4026,7 +4029,7 @@ void genX(CmdDrawIndirectCount)(
|
||||||
prim.IndirectParameterEnable = true;
|
prim.IndirectParameterEnable = true;
|
||||||
prim.PredicateEnable = true;
|
prim.PredicateEnable = true;
|
||||||
prim.VertexAccessType = SEQUENTIAL;
|
prim.VertexAccessType = SEQUENTIAL;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, SEQUENTIAL);
|
||||||
|
|
@ -4098,7 +4101,7 @@ void genX(CmdDrawIndexedIndirectCount)(
|
||||||
prim.IndirectParameterEnable = true;
|
prim.IndirectParameterEnable = true;
|
||||||
prim.PredicateEnable = true;
|
prim.PredicateEnable = true;
|
||||||
prim.VertexAccessType = RANDOM;
|
prim.VertexAccessType = RANDOM;
|
||||||
prim.PrimitiveTopologyType = pipeline->topology;
|
prim.PrimitiveTopologyType = cmd_buffer->state.gfx.primitive_topology;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
|
update_dirty_vbs_for_gen8_vb_flush(cmd_buffer, RANDOM);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue