+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));
+}
+