radv/gfx10: Add pipeline state support for tess.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 8 Jul 2019 21:44:32 +0000 (23:44 +0200)
committerDave Airlie <airlied@redhat.com>
Tue, 9 Jul 2019 02:04:26 +0000 (12:04 +1000)
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_shader.c

index 5751440f3010353949eb46d850098494965723c0..91ce108ef92c34828e59adf8beff37498f70e4a3 100644 (file)
@@ -2254,7 +2254,11 @@ radv_fill_shader_keys(struct radv_device *device,
        }
 
        if (device->physical_device->rad_info.chip_class >= GFX10) {
-               keys[MESA_SHADER_VERTEX].vs.out.as_ngg = true;
+               if (nir[MESA_SHADER_TESS_CTRL]) {
+                       keys[MESA_SHADER_TESS_EVAL].tes.out.as_ngg = true;
+               } else {
+                       keys[MESA_SHADER_VERTEX].vs.out.as_ngg = true;
+               }
        }
 
        for(int i = 0; i < MESA_SHADER_STAGES; ++i)
@@ -2623,6 +2627,8 @@ radv_pipeline_stage_to_user_data_0(struct radv_pipeline *pipeline,
                if (has_gs) {
                        return chip_class >= GFX10 ? R_00B230_SPI_SHADER_USER_DATA_GS_0 :
                                                     R_00B330_SPI_SHADER_USER_DATA_ES_0;
+               } else if (has_ngg) {
+                       return R_00B230_SPI_SHADER_USER_DATA_GS_0;
                } else {
                        return R_00B130_SPI_SHADER_USER_DATA_VS_0;
                }
@@ -3210,6 +3216,8 @@ radv_pipeline_generate_vgt_gs_mode(struct radeon_cmdbuf *ctx_cs,
                                             pipeline->device->physical_device->rad_info.chip_class);
        } else if (radv_pipeline_has_ngg(pipeline)) {
                const struct radv_shader_variant *vs =
+                       pipeline->shaders[MESA_SHADER_TESS_EVAL] ?
+                       pipeline->shaders[MESA_SHADER_TESS_EVAL] :
                        pipeline->shaders[MESA_SHADER_VERTEX];
                bool enable_prim_id =
                        outinfo->export_prim_id || vs->info.info.uses_prim_id;
@@ -3489,7 +3497,8 @@ 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)
+                                   const struct radv_tessellation_state *tess,
+                                   const struct radv_ngg_state *ngg)
 {
        if (!radv_pipeline_has_tess(pipeline))
                return;
@@ -3500,7 +3509,9 @@ radv_pipeline_generate_tess_shaders(struct radeon_cmdbuf *ctx_cs,
        tes = pipeline->shaders[MESA_SHADER_TESS_EVAL];
 
        if (tes) {
-               if (tes->info.tes.as_es)
+               if (tes->info.is_ngg) {
+                       radv_pipeline_generate_hw_ngg(ctx_cs, cs, pipeline, tes, ngg);
+               } else if (tes->info.tes.as_es)
                        radv_pipeline_generate_hw_es(cs, pipeline, tes);
                else
                        radv_pipeline_generate_hw_vs(ctx_cs, cs, pipeline, tes);
@@ -3919,7 +3930,7 @@ radv_pipeline_generate_pm4(struct radv_pipeline *pipeline,
        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, ngg);
-       radv_pipeline_generate_tess_shaders(ctx_cs, cs, pipeline, tess);
+       radv_pipeline_generate_tess_shaders(ctx_cs, cs, pipeline, tess, ngg);
        radv_pipeline_generate_geometry_shader(ctx_cs, cs, pipeline, gs);
        radv_pipeline_generate_fragment_shader(ctx_cs, cs, pipeline);
        radv_pipeline_generate_ps_inputs(ctx_cs, pipeline);
index 8f42514feb99bf03336029976cfff380a411274b..b6270136643339d87f5eb238e1a354135d99247b 100644 (file)
@@ -710,16 +710,21 @@ static void radv_postprocess_config(const struct radv_physical_device *pdevice,
 
        switch (stage) {
        case MESA_SHADER_TESS_EVAL:
-               if (info->tes.as_es) {
+               if (info->is_ngg) {
+                       config_out->rsrc1 |= S_00B228_MEM_ORDERED(pdevice->rad_info.chip_class >= GFX10);
+                       config_out->rsrc2 |= S_00B22C_OC_LDS_EN(1);
+               } else if (info->tes.as_es) {
                        assert(pdevice->rad_info.chip_class <= GFX8);
                        vgpr_comp_cnt = info->info.uses_prim_id ? 3 : 2;
+
+                       config_out->rsrc2 |= S_00B12C_OC_LDS_EN(1);
                } else {
                        bool enable_prim_id = info->tes.export_prim_id || info->info.uses_prim_id;
                        vgpr_comp_cnt = enable_prim_id ? 3 : 2;
 
                        config_out->rsrc1 |= S_00B128_MEM_ORDERED(pdevice->rad_info.chip_class >= GFX10);
+                       config_out->rsrc2 |= S_00B12C_OC_LDS_EN(1);
                }
-               config_out->rsrc2 |= S_00B12C_OC_LDS_EN(1);
                break;
        case MESA_SHADER_TESS_CTRL:
                if (pdevice->rad_info.chip_class >= GFX9) {
@@ -727,7 +732,11 @@ static void radv_postprocess_config(const struct radv_physical_device *pdevice,
                         * VGPR0-3: (VertexID, RelAutoindex, InstanceID / StepRate0, InstanceID).
                         * StepRate0 is set to 1. so that VGPR3 doesn't have to be loaded.
                         */
-                       vgpr_comp_cnt = info->info.vs.needs_instance_id ? 2 : 1;
+                       if (pdevice->rad_info.chip_class >= GFX10) {
+                               vgpr_comp_cnt = info->info.vs.needs_instance_id ? 3 : 1;
+                       } else {
+                               vgpr_comp_cnt = info->info.vs.needs_instance_id ? 2 : 1;
+                       }
                } else {
                        config_out->rsrc2 |= S_00B12C_OC_LDS_EN(1);
                }
@@ -786,12 +795,27 @@ static void radv_postprocess_config(const struct radv_physical_device *pdevice,
        }
 
        if (pdevice->rad_info.chip_class >= GFX10 &&
-           stage == MESA_SHADER_VERTEX) {
+           (stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_TESS_EVAL)) {
                unsigned gs_vgpr_comp_cnt, es_vgpr_comp_cnt;
 
                /* VGPR5-8: (VertexID, UserVGPR0, UserVGPR1, UserVGPR2 / InstanceID) */
-               es_vgpr_comp_cnt = info->info.vs.needs_instance_id ? 3 : 0;
-               gs_vgpr_comp_cnt = 3;
+               if (stage == MESA_SHADER_VERTEX) {
+                       es_vgpr_comp_cnt = info->info.vs.needs_instance_id ? 3 : 0;
+               } else if (stage == MESA_SHADER_TESS_EVAL) {
+                       es_vgpr_comp_cnt = info->info.vs.needs_instance_id ? 3 : 2;
+               }
+
+               bool tes_triangles = stage == MESA_SHADER_TESS_EVAL &&
+                       info->tes.primitive_mode >= 4; /* GL_TRIANGLES */
+               if (info->info.uses_invocation_id || stage == MESA_SHADER_VERTEX) {
+                       gs_vgpr_comp_cnt = 3; /* VGPR3 contains InvocationID. */
+               } else if (info->info.uses_prim_id) {
+                       gs_vgpr_comp_cnt = 2; /* VGPR2 contains PrimitiveID. */
+               } else if (info->gs.vertices_in >= 3 || tes_triangles) {
+                       gs_vgpr_comp_cnt = 1; /* VGPR1 contains offsets 2, 3 */
+               } else {
+                       gs_vgpr_comp_cnt = 0; /* VGPR0 contains offsets 0, 1 */
+               }
 
                config_out->rsrc1 |= S_00B228_GS_VGPR_COMP_CNT(gs_vgpr_comp_cnt);
                config_out->rsrc2 |= S_00B22C_ES_VGPR_COMP_CNT(es_vgpr_comp_cnt) |