radeonsi: add instanceid support
authorChristian König <christian.koenig@amd.com>
Thu, 21 Mar 2013 17:02:52 +0000 (18:02 +0100)
committerChristian König <christian.koenig@amd.com>
Tue, 2 Apr 2013 11:01:43 +0000 (13:01 +0200)
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/drivers/radeonsi/radeonsi_shader.c
src/gallium/drivers/radeonsi/radeonsi_shader.h
src/gallium/drivers/radeonsi/si_state_draw.c

index 0d24309783947e69c4f05bfe4ee8bb885e72f4ac..b660f9896b0b11ef68d6c4ed20879ab75044214c 100644 (file)
@@ -330,6 +330,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_START_INSTANCE:
        case PIPE_CAP_NPOT_TEXTURES:
         case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+       case PIPE_CAP_TGSI_INSTANCEID:
                return 1;
        case PIPE_CAP_TGSI_TEXCOORD:
                return 0;
@@ -344,7 +345,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
                return debug_get_bool_option("R600_GLSL130", FALSE) ? 130 : 120;
 
        /* Unsupported features. */
-       case PIPE_CAP_TGSI_INSTANCEID:
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
        case PIPE_CAP_SCALED_RESOLVE:
index 840537a69b2c61c461fc842f00751f5015ea4eb1..62f478e1300e0a95831da2bf30ec0f85f5d413e2 100644 (file)
@@ -141,7 +141,7 @@ static void declare_input_vs(
 
        /* Load the buffer index, which is always stored in VGPR0
         * for Vertex Shaders */
-       buffer_index_reg = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_VERTEX_INDEX);
+       buffer_index_reg = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_VERTEX_ID);
 
        vec4_type = LLVMVectorType(base->elem_type, 4);
        args[0] = t_list;
@@ -346,6 +346,30 @@ static void declare_input(
        }
 }
 
+static void declare_system_value(
+       struct radeon_llvm_context * radeon_bld,
+       unsigned index,
+       const struct tgsi_full_declaration *decl)
+{
+       LLVMValueRef value = 0;
+
+       switch (decl->Semantic.Name) {
+       case TGSI_SEMANTIC_INSTANCEID:
+               value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_INSTANCE_ID);
+               break;
+
+       case TGSI_SEMANTIC_VERTEXID:
+               value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_VERTEX_ID);
+               break;
+
+       default:
+               assert(!"unknown system value");
+               return;
+       }
+
+       radeon_bld->system_values[index] = value;
+}
+
 static LLVMValueRef fetch_constant(
        struct lp_build_tgsi_context * bld_base,
        const struct tgsi_full_src_register *reg,
@@ -939,8 +963,11 @@ static void create_function(struct si_shader_context *si_shader_ctx)
 
        if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
                params[SI_PARAM_VERTEX_BUFFER] = params[SI_PARAM_SAMPLER];
-               params[SI_PARAM_VERTEX_INDEX] = i32;
-               radeon_llvm_create_func(&si_shader_ctx->radeon_bld, params, 5);
+               params[SI_PARAM_VERTEX_ID] = i32;
+               params[SI_PARAM_DUMMY_0] = i32;
+               params[SI_PARAM_DUMMY_1] = i32;
+               params[SI_PARAM_INSTANCE_ID] = i32;
+               radeon_llvm_create_func(&si_shader_ctx->radeon_bld, params, 8);
 
        } else {
                params[SI_PARAM_PRIM_MASK] = i32;
@@ -1064,6 +1091,7 @@ int si_pipe_shader_create(
 
        tgsi_scan_shader(sel->tokens, &shader_info);
        shader->shader.uses_kill = shader_info.uses_kill;
+       shader->shader.uses_instanceid = shader_info.uses_instanceid;
        bld_base->info = &shader_info;
        bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
        bld_base->emit_epilogue = si_llvm_emit_epilogue;
@@ -1074,6 +1102,7 @@ int si_pipe_shader_create(
        bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
 
        si_shader_ctx.radeon_bld.load_input = declare_input;
+       si_shader_ctx.radeon_bld.load_system_value = declare_system_value;
        si_shader_ctx.tokens = sel->tokens;
        tgsi_parse_init(&si_shader_ctx.parse, si_shader_ctx.tokens);
        si_shader_ctx.shader = shader;
index fe771cee660a83cd57d3915ec7b8fb111d50d1f5..8f5efd0113588b6c1377e6d401baa7b5c21c17ba 100644 (file)
 
 /* VS only parameters */
 #define SI_PARAM_VERTEX_BUFFER 3
-#define SI_PARAM_VERTEX_INDEX  4
+#define SI_PARAM_VERTEX_ID     4
+#define SI_PARAM_DUMMY_0       5
+#define SI_PARAM_DUMMY_1       6
+#define SI_PARAM_INSTANCE_ID   7
 
 /* PS only parameters */
 #define SI_PARAM_PRIM_MASK             3
@@ -101,6 +104,7 @@ struct si_shader {
 
        unsigned                ninterp;
        bool                    uses_kill;
+       bool                    uses_instanceid;
        bool                    fs_write_all;
        unsigned                nr_cbufs;
 };
index 1e1d1cc6d6b03e36448d61ac94166873028e013e..d357d64939b25d8b25242e14bb9f775c9a6dbf86 100644 (file)
@@ -42,7 +42,7 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pm4_state *pm4;
        unsigned num_sgprs, num_user_sgprs;
-       unsigned nparams, i;
+       unsigned nparams, i, vgpr_comp_cnt;
        uint64_t va;
 
        si_pm4_delete_state(rctx, vs, shader->pm4);
@@ -83,9 +83,12 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
        num_sgprs += 2;
        assert(num_sgprs <= 104);
 
+       vgpr_comp_cnt = shader->shader.uses_instanceid ? 3 : 0;
+
        si_pm4_set_reg(pm4, R_00B128_SPI_SHADER_PGM_RSRC1_VS,
                       S_00B128_VGPRS((shader->num_vgprs - 1) / 4) |
-                      S_00B128_SGPRS((num_sgprs - 1) / 8));
+                      S_00B128_SGPRS((num_sgprs - 1) / 8) |
+                      S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt));
        si_pm4_set_reg(pm4, R_00B12C_SPI_SHADER_PGM_RSRC2_VS,
                       S_00B12C_USER_SGPR(num_user_sgprs));