bool pass_set;
};
-struct radv_tessellation_state {
- uint32_t ls_hs_config;
- unsigned lds_size;
- uint32_t tf_param;
-};
-
static const VkPipelineMultisampleStateCreateInfo *
radv_pipeline_get_multisample_state(const VkGraphicsPipelineCreateInfo *pCreateInfo)
{
return pipeline->shaders[stage];
}
-static struct radv_tessellation_state
-calculate_tess_state(struct radv_pipeline *pipeline,
- const VkGraphicsPipelineCreateInfo *pCreateInfo)
-{
- unsigned num_tcs_input_cp;
- unsigned num_tcs_output_cp;
- unsigned lds_size;
- unsigned num_patches;
- struct radv_tessellation_state tess = {0};
-
- num_tcs_input_cp = pCreateInfo->pTessellationState->patchControlPoints;
- num_tcs_output_cp = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.tcs_vertices_out; //TCS VERTICES OUT
- num_patches = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.num_patches;
-
- lds_size = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.lds_size;
-
- if (pipeline->device->physical_device->rad_info.chip_class >= GFX7) {
- assert(lds_size <= 65536);
- lds_size = align(lds_size, 512) / 512;
- } else {
- assert(lds_size <= 32768);
- lds_size = align(lds_size, 256) / 256;
- }
-
- tess.lds_size = lds_size;
-
- tess.ls_hs_config = S_028B58_NUM_PATCHES(num_patches) |
- S_028B58_HS_NUM_INPUT_CP(num_tcs_input_cp) |
- S_028B58_HS_NUM_OUTPUT_CP(num_tcs_output_cp);
-
- struct radv_shader_variant *tes = radv_get_shader(pipeline, MESA_SHADER_TESS_EVAL);
- unsigned type = 0, partitioning = 0, topology = 0, distribution_mode = 0;
-
- switch (tes->info.tes.primitive_mode) {
- case GL_TRIANGLES:
- type = V_028B6C_TESS_TRIANGLE;
- break;
- case GL_QUADS:
- type = V_028B6C_TESS_QUAD;
- break;
- case GL_ISOLINES:
- type = V_028B6C_TESS_ISOLINE;
- 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;
- const VkPipelineTessellationDomainOriginStateCreateInfo *domain_origin_state =
- vk_find_struct_const(pCreateInfo->pTessellationState,
- PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
-
- if (domain_origin_state && domain_origin_state->domainOrigin != 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 == GL_ISOLINES)
- topology = V_028B6C_OUTPUT_LINE;
- else if (ccw)
- topology = V_028B6C_OUTPUT_TRIANGLE_CCW;
- else
- topology = V_028B6C_OUTPUT_TRIANGLE_CW;
-
- if (pipeline->device->physical_device->rad_info.has_distributed_tess) {
- if (pipeline->device->physical_device->rad_info.family == CHIP_FIJI ||
- pipeline->device->physical_device->rad_info.family >= CHIP_POLARIS10)
- distribution_mode = V_028B6C_DISTRIBUTION_MODE_TRAPEZOIDS;
- else
- distribution_mode = V_028B6C_DISTRIBUTION_MODE_DONUTS;
- } else
- distribution_mode = V_028B6C_DISTRIBUTION_MODE_NO_DIST;
-
- tess.tf_param = S_028B6C_TYPE(type) |
- S_028B6C_PARTITIONING(partitioning) |
- S_028B6C_TOPOLOGY(topology) |
- S_028B6C_DISTRIBUTION_MODE(distribution_mode);
-
- return tess;
-}
-
static const struct radv_vs_output_info *get_vs_output_info(const struct radv_pipeline *pipeline)
{
if (radv_pipeline_has_gs(pipeline))
static struct radv_pipeline_key
radv_generate_graphics_pipeline_key(struct radv_pipeline *pipeline,
const VkGraphicsPipelineCreateInfo *pCreateInfo,
- const struct radv_blend_state *blend,
- bool has_view_index)
+ const struct radv_blend_state *blend)
{
+ RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
+ struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass;
const VkPipelineVertexInputStateCreateInfo *input_state =
pCreateInfo->pVertexInputState;
const VkPipelineVertexInputDivisorStateCreateInfoEXT *divisor_state =
if (pCreateInfo->flags & VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT)
key.optimisations_disabled = 1;
- key.has_multiview_view_index = has_view_index;
+ key.has_multiview_view_index = !!subpass->view_mask;
uint32_t binding_input_rate = 0;
uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
static void
radv_pipeline_generate_hw_ls(struct radeon_cmdbuf *cs,
struct radv_pipeline *pipeline,
- struct radv_shader_variant *shader,
- const struct radv_tessellation_state *tess)
+ struct radv_shader_variant *shader)
{
+ unsigned num_lds_blocks = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.num_lds_blocks;
uint64_t va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
uint32_t rsrc2 = shader->config.rsrc2;
radeon_emit(cs, va >> 8);
radeon_emit(cs, S_00B524_MEM_BASE(va >> 40));
- rsrc2 |= S_00B52C_LDS_SIZE(tess->lds_size);
+ rsrc2 |= S_00B52C_LDS_SIZE(num_lds_blocks);
if (pipeline->device->physical_device->rad_info.chip_class == GFX7 &&
pipeline->device->physical_device->rad_info.family != CHIP_HAWAII)
radeon_set_sh_reg(cs, R_00B52C_SPI_SHADER_PGM_RSRC2_LS, rsrc2);
static void
radv_pipeline_generate_hw_hs(struct radeon_cmdbuf *cs,
struct radv_pipeline *pipeline,
- struct radv_shader_variant *shader,
- const struct radv_tessellation_state *tess)
+ struct radv_shader_variant *shader)
{
uint64_t va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
if (pipeline->device->physical_device->rad_info.chip_class >= GFX9) {
- unsigned hs_rsrc2 = shader->config.rsrc2;
-
- if (pipeline->device->physical_device->rad_info.chip_class >= GFX10) {
- hs_rsrc2 |= S_00B42C_LDS_SIZE_GFX10(tess->lds_size);
- } else {
- hs_rsrc2 |= S_00B42C_LDS_SIZE_GFX9(tess->lds_size);
- }
-
if (pipeline->device->physical_device->rad_info.chip_class >= GFX10) {
radeon_set_sh_reg_seq(cs, R_00B520_SPI_SHADER_PGM_LO_LS, 2);
radeon_emit(cs, va >> 8);
radeon_set_sh_reg_seq(cs, R_00B428_SPI_SHADER_PGM_RSRC1_HS, 2);
radeon_emit(cs, shader->config.rsrc1);
- radeon_emit(cs, hs_rsrc2);
+ radeon_emit(cs, shader->config.rsrc2);
} else {
radeon_set_sh_reg_seq(cs, R_00B420_SPI_SHADER_PGM_LO_HS, 4);
radeon_emit(cs, va >> 8);
static void
radv_pipeline_generate_vertex_shader(struct radeon_cmdbuf *ctx_cs,
struct radeon_cmdbuf *cs,
- struct radv_pipeline *pipeline,
- const struct radv_tessellation_state *tess)
+ struct radv_pipeline *pipeline)
{
struct radv_shader_variant *vs;
return;
if (vs->info.vs.as_ls)
- radv_pipeline_generate_hw_ls(cs, pipeline, vs, tess);
+ radv_pipeline_generate_hw_ls(cs, pipeline, vs);
else if (vs->info.vs.as_es)
radv_pipeline_generate_hw_es(cs, pipeline, vs);
else if (vs->info.is_ngg)
static void
radv_pipeline_generate_tess_shaders(struct radeon_cmdbuf *ctx_cs,
struct radeon_cmdbuf *cs,
- struct radv_pipeline *pipeline,
- const struct radv_tessellation_state *tess)
+ struct radv_pipeline *pipeline)
{
- if (!radv_pipeline_has_tess(pipeline))
- return;
-
struct radv_shader_variant *tes, *tcs;
tcs = pipeline->shaders[MESA_SHADER_TESS_CTRL];
radv_pipeline_generate_hw_vs(ctx_cs, cs, pipeline, tes);
}
- radv_pipeline_generate_hw_hs(cs, pipeline, tcs, tess);
-
- radeon_set_context_reg(ctx_cs, R_028B6C_VGT_TF_PARAM,
- tess->tf_param);
-
- if (pipeline->device->physical_device->rad_info.chip_class >= GFX7)
- radeon_set_context_reg_idx(ctx_cs, R_028B58_VGT_LS_HS_CONFIG, 2,
- tess->ls_hs_config);
- else
- radeon_set_context_reg(ctx_cs, R_028B58_VGT_LS_HS_CONFIG,
- tess->ls_hs_config);
+ radv_pipeline_generate_hw_hs(cs, pipeline, tcs);
if (pipeline->device->physical_device->rad_info.chip_class >= GFX10 &&
!radv_pipeline_has_gs(pipeline) && !radv_pipeline_has_ngg(pipeline)) {
}
}
+static void
+radv_pipeline_generate_tess_state(struct radeon_cmdbuf *ctx_cs,
+ struct radv_pipeline *pipeline,
+ const VkGraphicsPipelineCreateInfo *pCreateInfo)
+{
+ struct radv_shader_variant *tes = radv_get_shader(pipeline, MESA_SHADER_TESS_EVAL);
+ unsigned type = 0, partitioning = 0, topology = 0, distribution_mode = 0;
+ unsigned num_tcs_input_cp, num_tcs_output_cp, num_patches;
+ unsigned ls_hs_config;
+
+ num_tcs_input_cp = pCreateInfo->pTessellationState->patchControlPoints;
+ num_tcs_output_cp = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.tcs_vertices_out; //TCS VERTICES OUT
+ num_patches = pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.num_patches;
+
+ ls_hs_config = S_028B58_NUM_PATCHES(num_patches) |
+ S_028B58_HS_NUM_INPUT_CP(num_tcs_input_cp) |
+ S_028B58_HS_NUM_OUTPUT_CP(num_tcs_output_cp);
+
+ if (pipeline->device->physical_device->rad_info.chip_class >= GFX7) {
+ radeon_set_context_reg_idx(ctx_cs, R_028B58_VGT_LS_HS_CONFIG,
+ 2, ls_hs_config);
+ } else {
+ radeon_set_context_reg(ctx_cs, R_028B58_VGT_LS_HS_CONFIG,
+ ls_hs_config);
+ }
+
+ switch (tes->info.tes.primitive_mode) {
+ case GL_TRIANGLES:
+ type = V_028B6C_TESS_TRIANGLE;
+ break;
+ case GL_QUADS:
+ type = V_028B6C_TESS_QUAD;
+ break;
+ case GL_ISOLINES:
+ type = V_028B6C_TESS_ISOLINE;
+ 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;
+ const VkPipelineTessellationDomainOriginStateCreateInfo *domain_origin_state =
+ vk_find_struct_const(pCreateInfo->pTessellationState,
+ PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
+
+ if (domain_origin_state && domain_origin_state->domainOrigin != 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 == GL_ISOLINES)
+ topology = V_028B6C_OUTPUT_LINE;
+ else if (ccw)
+ topology = V_028B6C_OUTPUT_TRIANGLE_CCW;
+ else
+ topology = V_028B6C_OUTPUT_TRIANGLE_CW;
+
+ if (pipeline->device->physical_device->rad_info.has_distributed_tess) {
+ if (pipeline->device->physical_device->rad_info.family == CHIP_FIJI ||
+ pipeline->device->physical_device->rad_info.family >= CHIP_POLARIS10)
+ distribution_mode = V_028B6C_DISTRIBUTION_MODE_TRAPEZOIDS;
+ else
+ distribution_mode = V_028B6C_DISTRIBUTION_MODE_DONUTS;
+ } else
+ distribution_mode = V_028B6C_DISTRIBUTION_MODE_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_generate_hw_gs(struct radeon_cmdbuf *ctx_cs,
struct radeon_cmdbuf *cs,
const VkGraphicsPipelineCreateInfo *pCreateInfo,
const struct radv_graphics_pipeline_create_info *extra,
const struct radv_blend_state *blend,
- const struct radv_tessellation_state *tess,
unsigned gs_out)
{
struct radeon_cmdbuf *ctx_cs = &pipeline->ctx_cs;
radv_pipeline_generate_raster_state(ctx_cs, pipeline, pCreateInfo);
radv_pipeline_generate_multisample_state(ctx_cs, pipeline);
radv_pipeline_generate_vgt_gs_mode(ctx_cs, pipeline);
- radv_pipeline_generate_vertex_shader(ctx_cs, cs, pipeline, tess);
- radv_pipeline_generate_tess_shaders(ctx_cs, cs, pipeline, tess);
+ radv_pipeline_generate_vertex_shader(ctx_cs, cs, pipeline);
+
+ if (radv_pipeline_has_tess(pipeline)) {
+ radv_pipeline_generate_tess_shaders(ctx_cs, cs, pipeline);
+ radv_pipeline_generate_tess_state(ctx_cs, pipeline, pCreateInfo);
+ }
+
radv_pipeline_generate_geometry_shader(ctx_cs, cs, pipeline);
radv_pipeline_generate_fragment_shader(ctx_cs, cs, pipeline);
radv_pipeline_generate_ps_inputs(ctx_cs, pipeline);
const struct radv_graphics_pipeline_create_info *extra)
{
VkResult result;
- bool has_view_index = false;
-
- RADV_FROM_HANDLE(radv_render_pass, pass, pCreateInfo->renderPass);
- struct radv_subpass *subpass = pass->subpasses + pCreateInfo->subpass;
- if (subpass->view_mask)
- has_view_index = true;
pipeline->device = device;
pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout);
stage_feedbacks[stage] = &creation_feedback->pPipelineStageCreationFeedbacks[i];
}
- struct radv_pipeline_key key = radv_generate_graphics_pipeline_key(pipeline, pCreateInfo, &blend, has_view_index);
+ struct radv_pipeline_key key = radv_generate_graphics_pipeline_key(pipeline, pCreateInfo, &blend);
result = radv_create_shaders(pipeline, device, cache, &key, pStages,
pCreateInfo->flags, pipeline_feedback,
calculate_gs_ring_sizes(pipeline, &gs->info.gs_ring_info);
}
- struct radv_tessellation_state tess = {0};
if (radv_pipeline_has_tess(pipeline)) {
pipeline->graphics.tess_patch_control_points =
pCreateInfo->pTessellationState->patchControlPoints;
- tess = calculate_tess_state(pipeline, pCreateInfo);
}
pipeline->graphics.ia_multi_vgt_param = radv_compute_ia_multi_vgt_param_helpers(pipeline);
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, gs_out);
+ radv_pipeline_generate_pm4(pipeline, pCreateInfo, extra, &blend, gs_out);
return result;
}