radeonsi/nir: implement default tess level system values
authorMarek Olšák <marek.olsak@amd.com>
Thu, 1 Aug 2019 18:47:03 +0000 (14:47 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 12 Aug 2019 18:52:17 +0000 (14:52 -0400)
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
src/amd/common/ac_nir_to_llvm.c
src/amd/common/ac_shader_abi.h
src/gallium/drivers/radeonsi/si_shader.c

index 219aa5f95f00180e879357fa149e5adad33946bd..9b59c82f385fa80d70d34e817e9e542e733417b6 100644 (file)
@@ -3537,10 +3537,16 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
                result = ctx->abi->load_tess_coord(ctx->abi);
                break;
        case nir_intrinsic_load_tess_level_outer:
-               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER);
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER, false);
                break;
        case nir_intrinsic_load_tess_level_inner:
-               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER);
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER, false);
+               break;
+       case nir_intrinsic_load_tess_level_outer_default:
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_OUTER, true);
+               break;
+       case nir_intrinsic_load_tess_level_inner_default:
+               result = ctx->abi->load_tess_level(ctx->abi, VARYING_SLOT_TESS_LEVEL_INNER, true);
                break;
        case nir_intrinsic_load_patch_vertices_in:
                result = ctx->abi->load_patch_vertices_in(ctx->abi);
index 3a2b53223850ab0baea5c8d0d099453add8182c6..7dd580bb195deb87d57fa8cfe50a67d9dab0efc6 100644 (file)
@@ -139,7 +139,8 @@ struct ac_shader_abi {
        LLVMValueRef (*load_patch_vertices_in)(struct ac_shader_abi *abi);
 
        LLVMValueRef (*load_tess_level)(struct ac_shader_abi *abi,
-                                       unsigned varying_id);
+                                       unsigned varying_id,
+                                       bool load_default_state);
 
 
        LLVMValueRef (*load_ubo)(struct ac_shader_abi *abi, LLVMValueRef index);
index 69466361d41629c5aacd0fabad675c2e41f332d4..a16a4a5557e4596221505f421f721b494e0f858c 100644 (file)
@@ -1977,12 +1977,44 @@ static LLVMValueRef load_tess_level(struct si_shader_context *ctx,
 
 }
 
+static LLVMValueRef load_tess_level_default(struct si_shader_context *ctx,
+                                           unsigned semantic_name)
+{
+       LLVMValueRef buf, slot, val[4];
+       int i, offset;
+
+       slot = LLVMConstInt(ctx->i32, SI_HS_CONST_DEFAULT_TESS_LEVELS, 0);
+       buf = LLVMGetParam(ctx->main_fn, ctx->param_rw_buffers);
+       buf = ac_build_load_to_sgpr(&ctx->ac, buf, slot);
+       offset = semantic_name == TGSI_SEMANTIC_TESS_DEFAULT_INNER_LEVEL ? 4 : 0;
+
+       for (i = 0; i < 4; i++)
+               val[i] = buffer_load_const(ctx, buf,
+                                          LLVMConstInt(ctx->i32, (offset + i) * 4, 0));
+       return ac_build_gather_values(&ctx->ac, val, 4);
+}
+
 static LLVMValueRef si_load_tess_level(struct ac_shader_abi *abi,
-                                      unsigned varying_id)
+                                      unsigned varying_id,
+                                      bool load_default_state)
 {
        struct si_shader_context *ctx = si_shader_context_from_abi(abi);
        unsigned semantic_name;
 
+       if (load_default_state) {
+               switch (varying_id) {
+               case VARYING_SLOT_TESS_LEVEL_INNER:
+                       semantic_name = TGSI_SEMANTIC_TESS_DEFAULT_INNER_LEVEL;
+                       break;
+               case VARYING_SLOT_TESS_LEVEL_OUTER:
+                       semantic_name = TGSI_SEMANTIC_TESS_DEFAULT_OUTER_LEVEL;
+                       break;
+               default:
+                       unreachable("unknown tess level");
+               }
+               return load_tess_level_default(ctx, semantic_name);
+       }
+
        switch (varying_id) {
        case VARYING_SLOT_TESS_LEVEL_INNER:
                semantic_name = TGSI_SEMANTIC_TESSINNER;
@@ -2118,21 +2150,8 @@ void si_load_system_value(struct si_shader_context *ctx,
 
        case TGSI_SEMANTIC_TESS_DEFAULT_OUTER_LEVEL:
        case TGSI_SEMANTIC_TESS_DEFAULT_INNER_LEVEL:
-       {
-               LLVMValueRef buf, slot, val[4];
-               int i, offset;
-
-               slot = LLVMConstInt(ctx->i32, SI_HS_CONST_DEFAULT_TESS_LEVELS, 0);
-               buf = LLVMGetParam(ctx->main_fn, ctx->param_rw_buffers);
-               buf = ac_build_load_to_sgpr(&ctx->ac, buf, slot);
-               offset = decl->Semantic.Name == TGSI_SEMANTIC_TESS_DEFAULT_INNER_LEVEL ? 4 : 0;
-
-               for (i = 0; i < 4; i++)
-                       val[i] = buffer_load_const(ctx, buf,
-                                                  LLVMConstInt(ctx->i32, (offset + i) * 4, 0));
-               value = ac_build_gather_values(&ctx->ac, val, 4);
+               value = load_tess_level_default(ctx, decl->Semantic.Name);
                break;
-       }
 
        case TGSI_SEMANTIC_PRIMID:
                value = si_get_primitive_id(ctx, 0);
@@ -6086,6 +6105,7 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx)
        case PIPE_SHADER_TESS_CTRL:
                bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
                ctx->abi.load_tess_varyings = si_nir_load_tcs_varyings;
+               ctx->abi.load_tess_level = si_load_tess_level;
                bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs;
                bld_base->emit_store = store_output_tcs;
                ctx->abi.store_tcs_outputs = si_nir_store_output_tcs;