},
.cull_mode = 0u,
.front_face = 0u,
+ .primitive_topology = 0u,
};
static void
}
}
+ if (copy_mask & RADV_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ if (dest->primitive_topology != src->primitive_topology) {
+ dest->primitive_topology = src->primitive_topology;
+ dest_mask |= RADV_DYNAMIC_PRIMITIVE_TOPOLOGY;
+ }
+ }
+
cmd_buffer->state.dirty |= dest_mask;
}
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+ if (!cmd_buffer->state.emitted_pipeline)
+ cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
+
radeon_emit_array(cmd_buffer->cs, pipeline->cs.buf, pipeline->cs.cdw);
if (!cmd_buffer->state.emitted_pipeline ||
radv_emit_line_stipple(struct radv_cmd_buffer *cmd_buffer)
{
struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
- struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
uint32_t auto_reset_cntl = 1;
- if (pipeline->graphics.topology == V_008958_DI_PT_LINESTRIP)
+ if (d->primitive_topology == V_008958_DI_PT_LINESTRIP)
auto_reset_cntl = 2;
radeon_set_context_reg(cmd_buffer->cs, R_028A0C_PA_SC_LINE_STIPPLE,
pa_su_sc_mode_cntl);
}
+static void
+radv_emit_primitive_topology(struct radv_cmd_buffer *cmd_buffer)
+{
+ struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
+
+ if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX7) {
+ radeon_set_uconfig_reg_idx(cmd_buffer->device->physical_device,
+ cmd_buffer->cs,
+ R_030908_VGT_PRIMITIVE_TYPE, 1,
+ d->primitive_topology);
+ } else {
+ radeon_set_config_reg(cmd_buffer->cs,
+ R_008958_VGT_PRIMITIVE_TYPE,
+ d->primitive_topology);
+ }
+}
+
static void
radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
int index,
RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE))
radv_emit_culling(cmd_buffer, states);
+ if (states & RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)
+ radv_emit_primitive_topology(cmd_buffer);
+
cmd_buffer->state.dirty &= ~states;
}
{
struct radeon_info *info = &cmd_buffer->device->physical_device->rad_info;
struct radv_cmd_state *state = &cmd_buffer->state;
+ unsigned topology = state->dynamic.primitive_topology;
struct radeon_cmdbuf *cs = cmd_buffer->cs;
unsigned ia_multi_vgt_param;
si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw,
indirect_draw,
count_from_stream_output,
- draw_vertex_count);
+ draw_vertex_count,
+ topology);
if (state->last_ia_multi_vgt_param != ia_multi_vgt_param) {
if (info->chip_class == GFX9) {
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
}
+void radv_CmdSetPrimitiveTopologyEXT(
+ VkCommandBuffer commandBuffer,
+ VkPrimitiveTopology primitiveTopology)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ struct radv_cmd_state *state = &cmd_buffer->state;
+ unsigned primitive_topology = si_translate_prim(primitiveTopology);
+
+ if (state->dynamic.primitive_topology == primitive_topology)
+ return;
+
+ state->dynamic.primitive_topology = primitive_topology;
+
+ state->dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
+}
+
void radv_CmdExecuteCommands(
VkCommandBuffer commandBuffer,
uint32_t commandBufferCount,
state->cull_mode = cmd_buffer->state.dynamic.cull_mode;
state->front_face = cmd_buffer->state.dynamic.front_face;
+
+ state->primitive_topology = cmd_buffer->state.dynamic.primitive_topology;
}
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
cmd_buffer->state.dynamic.cull_mode = state->cull_mode;
cmd_buffer->state.dynamic.front_face = state->front_face;
+ cmd_buffer->state.dynamic.primitive_topology = state->primitive_topology;
+
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_VIEWPORT |
RADV_CMD_DIRTY_DYNAMIC_SCISSOR |
RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
- RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
+ RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
+ RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
}
if (state->flags & RADV_META_SAVE_SAMPLE_LOCATIONS) {
VkCullModeFlags cull_mode;
VkFrontFace front_face;
+
+ unsigned primitive_topology;
};
VkResult radv_device_init_meta_clear_state(struct radv_device *device, bool on_demand);
}
}
-static uint32_t
-si_translate_prim(enum VkPrimitiveTopology topology)
-{
- switch (topology) {
- case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
- return V_008958_DI_PT_POINTLIST;
- case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
- return V_008958_DI_PT_LINELIST;
- case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
- return V_008958_DI_PT_LINESTRIP;
- case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
- return V_008958_DI_PT_TRILIST;
- case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
- return V_008958_DI_PT_TRISTRIP;
- case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
- return V_008958_DI_PT_TRIFAN;
- case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
- return V_008958_DI_PT_LINELIST_ADJ;
- case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
- return V_008958_DI_PT_LINESTRIP_ADJ;
- case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
- return V_008958_DI_PT_TRILIST_ADJ;
- case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
- return V_008958_DI_PT_TRISTRIP_ADJ;
- case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
- return V_008958_DI_PT_PATCH;
- default:
- assert(0);
- return 0;
- }
-}
-
static uint32_t
si_conv_gl_prim_to_gs_out(unsigned gl_prim)
{
return RADV_DYNAMIC_CULL_MODE;
case VK_DYNAMIC_STATE_FRONT_FACE_EXT:
return RADV_DYNAMIC_FRONT_FACE;
+ case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
+ return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY;
default:
unreachable("Unhandled dynamic state");
}
{
uint32_t states = RADV_DYNAMIC_ALL;
- /* If rasterization is disabled we do not care about any of the dynamic states,
- * since they are all rasterization related only. */
+ /* If rasterization is disabled we do not care about any of the
+ * dynamic states, since they are all rasterization related only,
+ * except primitive topology.
+ */
if (pCreateInfo->pRasterizationState->rasterizerDiscardEnable)
- return 0;
+ return RADV_DYNAMIC_PRIMITIVE_TOPOLOGY;
if (!pCreateInfo->pRasterizationState->depthBiasEnable)
states &= ~RADV_DYNAMIC_DEPTH_BIAS;
static void
radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
- const VkGraphicsPipelineCreateInfo *pCreateInfo)
+ const VkGraphicsPipelineCreateInfo *pCreateInfo,
+ const struct radv_graphics_pipeline_create_info *extra)
{
uint32_t needed_states = radv_pipeline_needed_dynamic_state(pCreateInfo);
uint32_t states = needed_states;
pCreateInfo->pRasterizationState->frontFace;
}
+ if (states & RADV_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ dynamic->primitive_topology =
+ si_translate_prim(pCreateInfo->pInputAssemblyState->topology);
+ if (extra && extra->use_rectlist) {
+ dynamic->primitive_topology = V_008958_DI_PT_RECTLIST;
+ }
+ }
+
/* If there is no depthstencil attachment, then don't read
* pDepthStencilState. The Vulkan spec states that pDepthStencilState may
* be NULL in this case. Even if pDepthStencilState is non-NULL, there is
const struct radv_graphics_pipeline_create_info *extra,
const struct radv_blend_state *blend,
const struct radv_tessellation_state *tess,
- unsigned prim, unsigned gs_out)
+ unsigned gs_out)
{
struct radeon_cmdbuf *ctx_cs = &pipeline->ctx_cs;
struct radeon_cmdbuf *cs = &pipeline->cs;
gfx10_pipeline_generate_ge_cntl(ctx_cs, pipeline, tess);
radeon_set_context_reg(ctx_cs, R_028B54_VGT_SHADER_STAGES_EN, radv_compute_vgt_shader_stages_en(pipeline));
-
- if (pipeline->device->physical_device->rad_info.chip_class >= GFX7) {
- radeon_set_uconfig_reg_idx(pipeline->device->physical_device,
- cs, R_030908_VGT_PRIMITIVE_TYPE, 1, prim);
- } else {
- radeon_set_config_reg(cs, R_008958_VGT_PRIMITIVE_TYPE, prim);
- }
radeon_set_context_reg(ctx_cs, R_028A6C_VGT_GS_OUT_PRIM_TYPE, gs_out);
radeon_set_context_reg(ctx_cs, R_02820C_PA_SC_CLIPRECT_RULE, radv_compute_cliprect_rule(pCreateInfo));
pipeline->graphics.spi_baryc_cntl = S_0286E0_FRONT_FACE_ALL_BITS(1);
radv_pipeline_init_multisample_state(pipeline, &blend, pCreateInfo);
uint32_t gs_out;
- uint32_t prim = si_translate_prim(pCreateInfo->pInputAssemblyState->topology);
- pipeline->graphics.topology = si_translate_prim(pCreateInfo->pInputAssemblyState->topology);
pipeline->graphics.can_use_guardband = radv_prim_can_use_guardband(pCreateInfo->pInputAssemblyState->topology);
if (radv_pipeline_has_gs(pipeline)) {
gs_out = si_conv_prim_to_gs_out(pCreateInfo->pInputAssemblyState->topology);
}
if (extra && extra->use_rectlist) {
- prim = V_008958_DI_PT_RECTLIST;
gs_out = V_028A6C_OUTPRIM_TYPE_TRISTRIP;
pipeline->graphics.can_use_guardband = true;
if (radv_pipeline_has_ngg(pipeline))
}
pipeline->graphics.prim_restart_enable = !!pCreateInfo->pInputAssemblyState->primitiveRestartEnable;
- radv_pipeline_init_dynamic_state(pipeline, pCreateInfo);
+ radv_pipeline_init_dynamic_state(pipeline, pCreateInfo, extra);
/* Ensure that some export memory is always allocated, for two reasons:
*
pipeline->streamout_shader = radv_pipeline_get_streamout_shader(pipeline);
result = radv_pipeline_scratch_init(device, pipeline);
- radv_pipeline_generate_pm4(pipeline, pCreateInfo, extra, &blend, &tess, prim, gs_out);
+ radv_pipeline_generate_pm4(pipeline, pCreateInfo, extra, &blend, &tess, gs_out);
return result;
}
VkCullModeFlags cull_mode;
VkFrontFace front_face;
+ unsigned primitive_topology;
};
extern const struct radv_dynamic_state default_dynamic_state;
uint32_t si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer,
bool instanced_draw, bool indirect_draw,
bool count_from_stream_output,
- uint32_t draw_vertex_count);
+ uint32_t draw_vertex_count,
+ unsigned topology);
void si_cs_emit_write_event_eop(struct radeon_cmdbuf *cs,
enum chip_class chip_class,
bool is_mec,
bool can_use_guardband;
uint32_t needed_dynamic_state;
bool disable_out_of_order_rast_for_occlusion;
- uint8_t topology;
unsigned tess_patch_control_points;
unsigned pa_su_sc_mode_cntl;
const VkRenderPassBeginInfo *pRenderPassBegin);
void radv_cmd_buffer_end_render_pass(struct radv_cmd_buffer *cmd_buffer);
+static inline uint32_t si_translate_prim(unsigned topology)
+{
+ switch (topology) {
+ case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
+ return V_008958_DI_PT_POINTLIST;
+ case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
+ return V_008958_DI_PT_LINELIST;
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
+ return V_008958_DI_PT_LINESTRIP;
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
+ return V_008958_DI_PT_TRILIST;
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
+ return V_008958_DI_PT_TRISTRIP;
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
+ return V_008958_DI_PT_TRIFAN;
+ case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
+ return V_008958_DI_PT_LINELIST_ADJ;
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
+ return V_008958_DI_PT_LINESTRIP_ADJ;
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
+ return V_008958_DI_PT_TRILIST_ADJ;
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
+ return V_008958_DI_PT_TRISTRIP_ADJ;
+ case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
+ return V_008958_DI_PT_PATCH;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
#define RADV_DEFINE_HANDLE_CASTS(__radv_type, __VkType) \
\
static inline struct __radv_type * \
si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer,
bool instanced_draw, bool indirect_draw,
bool count_from_stream_output,
- uint32_t draw_vertex_count)
+ uint32_t draw_vertex_count,
+ unsigned topology)
{
enum chip_class chip_class = cmd_buffer->device->physical_device->rad_info.chip_class;
enum radeon_family family = cmd_buffer->device->physical_device->rad_info.family;
bool ia_switch_on_eoi = false;
bool partial_vs_wave = false;
bool partial_es_wave = cmd_buffer->state.pipeline->graphics.ia_multi_vgt_param.partial_es_wave;
- unsigned topology = cmd_buffer->state.pipeline->graphics.topology;
bool multi_instances_smaller_than_primgroup;
struct radv_prim_vertex_count prim_vertex_count = prim_size_table[topology];