radeon/llvm: add support for VertexID, InstanceID
authorVadim Girlin <vadimgirlin@gmail.com>
Mon, 7 May 2012 16:26:32 +0000 (20:26 +0400)
committerVadim Girlin <vadimgirlin@gmail.com>
Mon, 7 May 2012 21:18:22 +0000 (01:18 +0400)
Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
src/gallium/drivers/r600/r600_llvm.c
src/gallium/drivers/radeon/radeon_llvm.h
src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c

index a36760cb56fb9e8ac0f9d8abb6c80b851beca03c..007980063521de162629d0c3e381b040051cbe30 100644 (file)
@@ -29,6 +29,38 @@ static LLVMValueRef llvm_fetch_const(
        return bitcast(bld_base, type, cval);
 }
 
+static void llvm_load_system_value(
+               struct radeon_llvm_context * ctx,
+               unsigned index,
+               const struct tgsi_full_declaration *decl)
+{
+       unsigned chan;
+
+       switch (decl->Semantic.Name) {
+       case TGSI_SEMANTIC_INSTANCEID: chan = 3; break;
+       case TGSI_SEMANTIC_VERTEXID: chan = 0; break;
+       default: assert(!"unknown system value");
+       }
+
+       LLVMValueRef reg = lp_build_const_int32(
+                       ctx->soa.bld_base.base.gallivm, chan);
+       ctx->system_values[index] = lp_build_intrinsic_unary(
+                       ctx->soa.bld_base.base.gallivm->builder,
+                       "llvm.R600.load.input",
+                       ctx->soa.bld_base.base.elem_type, reg);
+}
+
+static LLVMValueRef llvm_fetch_system_value(
+               struct lp_build_tgsi_context * bld_base,
+               const struct tgsi_full_src_register *reg,
+               enum tgsi_opcode_type type,
+               unsigned swizzle)
+{
+       struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
+       LLVMValueRef cval = ctx->system_values[reg->Register.Index];
+       return bitcast(bld_base, type, cval);
+}
+
 static void llvm_load_input(
        struct radeon_llvm_context * ctx,
        unsigned input_index,
@@ -206,10 +238,12 @@ LLVMModuleRef r600_tgsi_llvm(
        bld_base->info = &shader_info;
        bld_base->userdata = ctx;
        bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = llvm_fetch_const;
+       bld_base->emit_fetch_funcs[TGSI_FILE_SYSTEM_VALUE] = llvm_fetch_system_value;
        bld_base->emit_prologue = llvm_emit_prologue;
        bld_base->emit_epilogue = llvm_emit_epilogue;
        ctx->userdata = ctx;
        ctx->load_input = llvm_load_input;
+       ctx->load_system_value = llvm_load_system_value;
 
        bld_base->op_actions[TGSI_OPCODE_DP2] = dot_action;
        bld_base->op_actions[TGSI_OPCODE_DP3] = dot_action;
index 39b1214e836334058f808ed0b3f12e9ba9848f97..4a706397fddb6c79fe41f6d5c75e30073279cc39 100644 (file)
@@ -36,6 +36,8 @@
 #define RADEON_LLVM_MAX_BRANCH_DEPTH 16
 #define RADEON_LLVM_MAX_LOOP_DEPTH 16
 
+#define RADEON_LLVM_MAX_SYSTEM_VALUES 4
+
 struct radeon_llvm_branch {
        LLVMBasicBlockRef endif_block;
        LLVMBasicBlockRef if_block;
@@ -78,6 +80,9 @@ struct radeon_llvm_context {
                        unsigned input_index,
                        const struct tgsi_full_declaration *decl);
 
+       void (*load_system_value)(struct radeon_llvm_context *,
+                       unsigned index,
+                       const struct tgsi_full_declaration *decl);
 
        /** User data to use with the callbacks */
        void * userdata;
@@ -90,6 +95,8 @@ struct radeon_llvm_context {
        LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS];
        unsigned output_reg_count;
 
+       LLVMValueRef system_values[RADEON_LLVM_MAX_SYSTEM_VALUES];
+
        unsigned reserved_reg_count;
        /*=== Private Members ===*/
 
index c9b43651a91bae05000ff88618e314678604d431..4c437d52464f398ec109f3b0e2d2deffbaab108c 100644 (file)
@@ -231,6 +231,15 @@ static void emit_declaration(
        }
        break;
 
+       case TGSI_FILE_SYSTEM_VALUE:
+       {
+               unsigned idx;
+               for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
+                       ctx->load_system_value(ctx, idx, decl);
+               }
+       }
+       break;
+
        case TGSI_FILE_OUTPUT:
        {
                unsigned idx;