radv: add support for dynamic tessellation domain origin
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18882>
This commit is contained in:

committed by
Marge Bot

parent
6bf34e9f36
commit
f22290949d
@@ -123,6 +123,7 @@ const struct radv_dynamic_state default_dynamic_state = {
|
||||
.color_write_enable = 0u,
|
||||
.patch_control_points = 0,
|
||||
.polygon_mode = 0,
|
||||
.tess_domain_origin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT,
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -258,6 +259,8 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy
|
||||
|
||||
RADV_CMP_COPY(polygon_mode, RADV_DYNAMIC_POLYGON_MODE);
|
||||
|
||||
RADV_CMP_COPY(tess_domain_origin, RADV_DYNAMIC_TESS_DOMAIN_ORIGIN);
|
||||
|
||||
#undef RADV_CMP_COPY
|
||||
|
||||
cmd_buffer->state.dirty |= dest_mask;
|
||||
@@ -1481,6 +1484,10 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
|
||||
cmd_buffer->state.emitted_graphics_pipeline->cb_target_mask != pipeline->cb_target_mask)
|
||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE;
|
||||
|
||||
if (!cmd_buffer->state.emitted_graphics_pipeline ||
|
||||
cmd_buffer->state.emitted_graphics_pipeline->vgt_tf_param != pipeline->vgt_tf_param)
|
||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_TESS_DOMAIN_ORIGIN;
|
||||
|
||||
radeon_emit_array(cmd_buffer->cs, pipeline->base.cs.buf, pipeline->base.cs.cdw);
|
||||
|
||||
if (pipeline->has_ngg_culling &&
|
||||
@@ -3292,6 +3299,34 @@ radv_emit_vertex_input(struct radv_cmd_buffer *cmd_buffer, bool pipeline_is_dirt
|
||||
radv_save_vs_prolog(cmd_buffer, prolog);
|
||||
}
|
||||
|
||||
static void
|
||||
radv_emit_tess_domain_origin(struct radv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline;
|
||||
struct radv_shader *tes = radv_get_shader(&pipeline->base, MESA_SHADER_TESS_EVAL);
|
||||
struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
|
||||
unsigned vgt_tf_param = pipeline->vgt_tf_param;
|
||||
unsigned topology;
|
||||
|
||||
if (tes->info.tes.point_mode) {
|
||||
topology = V_028B6C_OUTPUT_POINT;
|
||||
} else if (tes->info.tes._primitive_mode == TESS_PRIMITIVE_ISOLINES) {
|
||||
topology = V_028B6C_OUTPUT_LINE;
|
||||
} else {
|
||||
bool ccw = tes->info.tes.ccw;
|
||||
|
||||
if (d->tess_domain_origin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT) {
|
||||
ccw = !ccw;
|
||||
}
|
||||
|
||||
topology = ccw ? V_028B6C_OUTPUT_TRIANGLE_CCW : V_028B6C_OUTPUT_TRIANGLE_CW;
|
||||
}
|
||||
|
||||
vgt_tf_param |= S_028B6C_TOPOLOGY(topology);
|
||||
|
||||
radeon_set_context_reg(cmd_buffer->cs, R_028B6C_VGT_TF_PARAM, vgt_tf_param);
|
||||
}
|
||||
|
||||
static void
|
||||
radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pipeline_is_dirty)
|
||||
{
|
||||
@@ -3368,6 +3403,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pip
|
||||
if (states & RADV_CMD_DIRTY_DYNAMIC_PATCH_CONTROL_POINTS)
|
||||
radv_emit_patch_control_points(cmd_buffer);
|
||||
|
||||
if (states & RADV_CMD_DIRTY_DYNAMIC_TESS_DOMAIN_ORIGIN)
|
||||
radv_emit_tess_domain_origin(cmd_buffer);
|
||||
|
||||
cmd_buffer->state.dirty &= ~states;
|
||||
}
|
||||
|
||||
@@ -5772,6 +5810,18 @@ radv_CmdSetPolygonModeEXT(VkCommandBuffer commandBuffer, VkPolygonMode polygonMo
|
||||
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_POLYGON_MODE;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
radv_CmdSetTessellationDomainOriginEXT(VkCommandBuffer commandBuffer,
|
||||
VkTessellationDomainOrigin domainOrigin)
|
||||
{
|
||||
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
struct radv_cmd_state *state = &cmd_buffer->state;
|
||||
|
||||
state->dynamic.tess_domain_origin = domainOrigin;
|
||||
|
||||
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_TESS_DOMAIN_ORIGIN;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
|
||||
const VkCommandBuffer *pCmdBuffers)
|
||||
|
@@ -1396,7 +1396,7 @@ radv_pipeline_needed_dynamic_state(const struct radv_graphics_pipeline *pipeline
|
||||
RADV_DYNAMIC_VERTEX_INPUT;
|
||||
|
||||
if (pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
|
||||
states |= RADV_DYNAMIC_PATCH_CONTROL_POINTS;
|
||||
states |= RADV_DYNAMIC_PATCH_CONTROL_POINTS | RADV_DYNAMIC_TESS_DOMAIN_ORIGIN;
|
||||
|
||||
return states;
|
||||
}
|
||||
@@ -1433,7 +1433,7 @@ radv_pipeline_needed_dynamic_state(const struct radv_graphics_pipeline *pipeline
|
||||
states &= ~RADV_DYNAMIC_COLOR_WRITE_ENABLE;
|
||||
|
||||
if (!(pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))
|
||||
states &= ~RADV_DYNAMIC_PATCH_CONTROL_POINTS;
|
||||
states &= ~(RADV_DYNAMIC_PATCH_CONTROL_POINTS | RADV_DYNAMIC_TESS_DOMAIN_ORIGIN);
|
||||
|
||||
return states;
|
||||
}
|
||||
@@ -1891,6 +1891,10 @@ radv_pipeline_init_dynamic_state(struct radv_graphics_pipeline *pipeline,
|
||||
dynamic->polygon_mode = si_translate_fill(state->rs->polygon_mode);
|
||||
}
|
||||
|
||||
if (states & RADV_DYNAMIC_TESS_DOMAIN_ORIGIN) {
|
||||
dynamic->tess_domain_origin = state->ts->domain_origin;
|
||||
}
|
||||
|
||||
pipeline->dynamic_state.mask = states;
|
||||
}
|
||||
|
||||
@@ -5234,70 +5238,6 @@ radv_pipeline_emit_tess_shaders(struct radeon_cmdbuf *ctx_cs, struct radeon_cmdb
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radv_pipeline_emit_tess_state(struct radeon_cmdbuf *ctx_cs,
|
||||
const struct radv_graphics_pipeline *pipeline,
|
||||
const struct vk_graphics_pipeline_state *state)
|
||||
{
|
||||
const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
|
||||
struct radv_shader *tes = radv_get_shader(&pipeline->base, MESA_SHADER_TESS_EVAL);
|
||||
unsigned type = 0, partitioning = 0, topology = 0, distribution_mode = 0;
|
||||
|
||||
switch (tes->info.tes._primitive_mode) {
|
||||
case TESS_PRIMITIVE_TRIANGLES:
|
||||
type = V_028B6C_TESS_TRIANGLE;
|
||||
break;
|
||||
case TESS_PRIMITIVE_QUADS:
|
||||
type = V_028B6C_TESS_QUAD;
|
||||
break;
|
||||
case TESS_PRIMITIVE_ISOLINES:
|
||||
type = V_028B6C_TESS_ISOLINE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tes->info.tes.spacing) {
|
||||
case TESS_SPACING_EQUAL:
|
||||
partitioning = V_028B6C_PART_INTEGER;
|
||||
break;
|
||||
case TESS_SPACING_FRACTIONAL_ODD:
|
||||
partitioning = V_028B6C_PART_FRAC_ODD;
|
||||
break;
|
||||
case TESS_SPACING_FRACTIONAL_EVEN:
|
||||
partitioning = V_028B6C_PART_FRAC_EVEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool ccw = tes->info.tes.ccw;
|
||||
if (state->ts->domain_origin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT)
|
||||
ccw = !ccw;
|
||||
|
||||
if (tes->info.tes.point_mode)
|
||||
topology = V_028B6C_OUTPUT_POINT;
|
||||
else if (tes->info.tes._primitive_mode == TESS_PRIMITIVE_ISOLINES)
|
||||
topology = V_028B6C_OUTPUT_LINE;
|
||||
else if (ccw)
|
||||
topology = V_028B6C_OUTPUT_TRIANGLE_CCW;
|
||||
else
|
||||
topology = V_028B6C_OUTPUT_TRIANGLE_CW;
|
||||
|
||||
if (pdevice->rad_info.has_distributed_tess) {
|
||||
if (pdevice->rad_info.family == CHIP_FIJI || pdevice->rad_info.family >= CHIP_POLARIS10)
|
||||
distribution_mode = V_028B6C_TRAPEZOIDS;
|
||||
else
|
||||
distribution_mode = V_028B6C_DONUTS;
|
||||
} else
|
||||
distribution_mode = V_028B6C_NO_DIST;
|
||||
|
||||
radeon_set_context_reg(ctx_cs, R_028B6C_VGT_TF_PARAM,
|
||||
S_028B6C_TYPE(type) | S_028B6C_PARTITIONING(partitioning) |
|
||||
S_028B6C_TOPOLOGY(topology) |
|
||||
S_028B6C_DISTRIBUTION_MODE(distribution_mode));
|
||||
}
|
||||
|
||||
static void
|
||||
radv_pipeline_emit_hw_gs(struct radeon_cmdbuf *ctx_cs, struct radeon_cmdbuf *cs,
|
||||
const struct radv_graphics_pipeline *pipeline, const struct radv_shader *gs)
|
||||
@@ -5890,7 +5830,6 @@ radv_pipeline_emit_pm4(struct radv_graphics_pipeline *pipeline,
|
||||
|
||||
if (radv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_CTRL)) {
|
||||
radv_pipeline_emit_tess_shaders(ctx_cs, cs, pipeline);
|
||||
radv_pipeline_emit_tess_state(ctx_cs, pipeline, state);
|
||||
}
|
||||
|
||||
radv_pipeline_emit_geometry_shader(ctx_cs, cs, pipeline);
|
||||
@@ -6093,6 +6032,54 @@ radv_pipeline_init_vgt_gs_out(struct radv_graphics_pipeline *pipeline,
|
||||
return gs_out;
|
||||
}
|
||||
|
||||
static void
|
||||
radv_pipeline_init_tess_state(struct radv_graphics_pipeline *pipeline,
|
||||
const struct vk_graphics_pipeline_state *state)
|
||||
{
|
||||
const struct radv_physical_device *pdevice = pipeline->base.device->physical_device;
|
||||
struct radv_shader *tes = radv_get_shader(&pipeline->base, MESA_SHADER_TESS_EVAL);
|
||||
unsigned type = 0, partitioning = 0, distribution_mode = 0;
|
||||
|
||||
switch (tes->info.tes._primitive_mode) {
|
||||
case TESS_PRIMITIVE_TRIANGLES:
|
||||
type = V_028B6C_TESS_TRIANGLE;
|
||||
break;
|
||||
case TESS_PRIMITIVE_QUADS:
|
||||
type = V_028B6C_TESS_QUAD;
|
||||
break;
|
||||
case TESS_PRIMITIVE_ISOLINES:
|
||||
type = V_028B6C_TESS_ISOLINE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tes->info.tes.spacing) {
|
||||
case TESS_SPACING_EQUAL:
|
||||
partitioning = V_028B6C_PART_INTEGER;
|
||||
break;
|
||||
case TESS_SPACING_FRACTIONAL_ODD:
|
||||
partitioning = V_028B6C_PART_FRAC_ODD;
|
||||
break;
|
||||
case TESS_SPACING_FRACTIONAL_EVEN:
|
||||
partitioning = V_028B6C_PART_FRAC_EVEN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (pdevice->rad_info.has_distributed_tess) {
|
||||
if (pdevice->rad_info.family == CHIP_FIJI || pdevice->rad_info.family >= CHIP_POLARIS10)
|
||||
distribution_mode = V_028B6C_TRAPEZOIDS;
|
||||
else
|
||||
distribution_mode = V_028B6C_DONUTS;
|
||||
} else
|
||||
distribution_mode = V_028B6C_NO_DIST;
|
||||
|
||||
pipeline->vgt_tf_param = S_028B6C_TYPE(type) | S_028B6C_PARTITIONING(partitioning) |
|
||||
S_028B6C_DISTRIBUTION_MODE(distribution_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
radv_pipeline_init_extra(struct radv_graphics_pipeline *pipeline,
|
||||
const struct radv_graphics_pipeline_create_info *extra,
|
||||
@@ -6285,6 +6272,10 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
||||
radv_pipeline_init_gs_ring_state(pipeline, &gs->info.gs_ring_info);
|
||||
}
|
||||
|
||||
if (radv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_CTRL)) {
|
||||
radv_pipeline_init_tess_state(pipeline, &state);
|
||||
}
|
||||
|
||||
if (!radv_pipeline_has_stage(pipeline, MESA_SHADER_MESH))
|
||||
radv_pipeline_init_vertex_input_state(pipeline, &state);
|
||||
|
||||
|
@@ -1353,6 +1353,8 @@ struct radv_dynamic_state {
|
||||
uint32_t patch_control_points;
|
||||
|
||||
uint32_t polygon_mode;
|
||||
|
||||
VkTessellationDomainOrigin tess_domain_origin;
|
||||
};
|
||||
|
||||
extern const struct radv_dynamic_state default_dynamic_state;
|
||||
@@ -2045,6 +2047,7 @@ struct radv_graphics_pipeline {
|
||||
uint8_t next_vertex_stage : 8;
|
||||
uint32_t vb_desc_usage_mask;
|
||||
uint32_t vb_desc_alloc_size;
|
||||
uint32_t vgt_tf_param;
|
||||
|
||||
/* Last pre-PS API stage */
|
||||
gl_shader_stage last_vgt_api_stage;
|
||||
@@ -3088,6 +3091,9 @@ si_translate_blend_logic_op(VkLogicOp op)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t radv_get_tess_output_topology(const struct radv_graphics_pipeline *pipeline,
|
||||
VkTessellationDomainOrigin domain_origin);
|
||||
|
||||
ALWAYS_INLINE static bool
|
||||
radv_is_streamout_enabled(struct radv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
|
Reference in New Issue
Block a user