radeonsi: Adapt to sample intrinsics changes.
[mesa.git] / src / gallium / drivers / radeonsi / radeonsi_shader.c
index 0994fac6f219336a01e2b34599b20b08e42f53a9..575cc67383a79e5eda4a301553dca91e67837f4e 100644 (file)
@@ -31,6 +31,7 @@
 #include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_gather.h"
 #include "gallivm/lp_bld_intr.h"
+#include "gallivm/lp_bld_logic.h"
 #include "gallivm/lp_bld_tgsi.h"
 #include "radeon_llvm.h"
 #include "radeon_llvm_emit.h"
 #include <errno.h>
 #include <stdio.h>
 
-/*
-static ps_remap_inputs(
-       struct tgsi_llvm_context * tl_ctx,
-       unsigned tgsi_index,
-       unsigned tgsi_chan)
-{
-       :
-}
-
-struct si_input
-{
-       struct list_head head;
-       unsigned tgsi_index;
-       unsigned tgsi_chan;
-       unsigned order;
-};
-*/
-
-
 struct si_shader_context
 {
        struct radeon_llvm_context radeon_bld;
@@ -74,6 +56,7 @@ struct si_shader_context
        struct tgsi_parse_context parse;
        struct tgsi_token * tokens;
        struct si_pipe_shader *shader;
+       struct si_shader_key key;
        unsigned type; /* TGSI_PROCESSOR_* specifies the type of shader. */
        unsigned ninput_emitted;
 /*     struct list_head inputs; */
@@ -210,15 +193,11 @@ static void declare_input_vs(
        LLVMValueRef input;
        struct lp_build_context * uint = &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
        struct lp_build_context * base = &si_shader_ctx->radeon_bld.soa.bld_base.base;
-       struct r600_context *rctx = si_shader_ctx->rctx;
        //struct pipe_vertex_element *velem = &rctx->vertex_elements->elements[input_index];
        unsigned chan;
 
        /* Load the T list */
-       /* XXX: Communicate with the rest of the driver about which SGPR the T#
-        * list pointer is going to be stored in.  Hard code to SGPR[6:7] for
-        * now */
-       t_list_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_V4I32, 6);
+       t_list_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_V4I32, SI_SGPR_VERTEX_BUFFER);
 
        t_offset = lp_build_const_int32(base->gallivm, input_index);
 
@@ -258,9 +237,11 @@ static void declare_input_fs(
 {
        const char * intr_name;
        unsigned chan;
+       struct si_shader *shader = &si_shader_ctx->shader->shader;
        struct lp_build_context * base =
                                &si_shader_ctx->radeon_bld.soa.bld_base.base;
        struct gallivm_state * gallivm = base->gallivm;
+       LLVMTypeRef input_type = LLVMFloatTypeInContext(gallivm->context);
 
        /* This value is:
         * [15:0] NewPrimMask (Bit mask for each quad.  It is set it the
@@ -269,14 +250,53 @@ static void declare_input_fs(
         * [32:16] ParamOffset
         *
         */
-       /* XXX: This register number must be identical to the S_00B02C_USER_SGPR
-        * register field value
-        */
-       LLVMValueRef params = use_sgpr(base->gallivm, SGPR_I32, 6);
+       LLVMValueRef params = use_sgpr(base->gallivm, SGPR_I32, SI_PS_NUM_USER_SGPR);
+       LLVMValueRef attr_number;
+
+       if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       LLVMValueRef args[1];
+                       unsigned soa_index =
+                               radeon_llvm_reg_index_soa(input_index, chan);
+                       args[0] = lp_build_const_int32(gallivm, chan);
+                       si_shader_ctx->radeon_bld.inputs[soa_index] =
+                               build_intrinsic(base->gallivm->builder,
+                                       "llvm.SI.fs.read.pos", input_type,
+                                       args, 1, LLVMReadNoneAttribute);
+               }
+               return;
+       }
 
+       if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
+               LLVMValueRef face, is_face_positive;
+
+               face = build_intrinsic(gallivm->builder,
+                                      "llvm.SI.fs.read.face",
+                                      input_type,
+                                      NULL, 0, LLVMReadNoneAttribute);
+               is_face_positive = LLVMBuildFCmp(gallivm->builder,
+                                                LLVMRealUGT, face,
+                                                lp_build_const_float(gallivm, 0.0f),
+                                                "");
+
+               si_shader_ctx->radeon_bld.inputs[radeon_llvm_reg_index_soa(input_index, 0)] =
+                       LLVMBuildSelect(gallivm->builder,
+                                       is_face_positive,
+                                       lp_build_const_float(gallivm, 1.0f),
+                                       lp_build_const_float(gallivm, 0.0f),
+                                       "");
+               si_shader_ctx->radeon_bld.inputs[radeon_llvm_reg_index_soa(input_index, 1)] =
+               si_shader_ctx->radeon_bld.inputs[radeon_llvm_reg_index_soa(input_index, 2)] =
+                       lp_build_const_float(gallivm, 0.0f);
+               si_shader_ctx->radeon_bld.inputs[radeon_llvm_reg_index_soa(input_index, 3)] =
+                       lp_build_const_float(gallivm, 1.0f);
+
+               return;
+       }
 
-       /* XXX: Is this the input_index? */
-       LLVMValueRef attr_number = lp_build_const_int32(gallivm, input_index);
+       shader->input[input_index].param_offset = shader->ninterp++;
+       attr_number = lp_build_const_int32(gallivm,
+                                          shader->input[input_index].param_offset);
 
        /* XXX: Handle all possible interpolation modes */
        switch (decl->Interp.Interpolate) {
@@ -328,17 +348,59 @@ static void declare_input_fs(
        }
 
        /* XXX: Could there be more than TGSI_NUM_CHANNELS (4) ? */
-       for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+       if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+           si_shader_ctx->key.color_two_side) {
                LLVMValueRef args[3];
-               LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
-               unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
-               LLVMTypeRef input_type = LLVMFloatTypeInContext(gallivm->context);
-               args[0] = llvm_chan;
-               args[1] = attr_number;
+               LLVMValueRef face, is_face_positive;
+               LLVMValueRef back_attr_number =
+                       lp_build_const_int32(gallivm,
+                                            shader->input[input_index].param_offset + 1);
+
+               face = build_intrinsic(gallivm->builder,
+                                      "llvm.SI.fs.read.face",
+                                      input_type,
+                                      NULL, 0, LLVMReadNoneAttribute);
+               is_face_positive = LLVMBuildFCmp(gallivm->builder,
+                                                LLVMRealUGT, face,
+                                                lp_build_const_float(gallivm, 0.0f),
+                                                "");
+
                args[2] = params;
-               si_shader_ctx->radeon_bld.inputs[soa_index] =
-                       build_intrinsic(base->gallivm->builder, intr_name,
-                               input_type, args, 3, LLVMReadOnlyAttribute);
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+                       unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+                       LLVMValueRef front, back;
+
+                       args[0] = llvm_chan;
+                       args[1] = attr_number;
+                       front = build_intrinsic(base->gallivm->builder, intr_name,
+                                               input_type, args, 3, LLVMReadOnlyAttribute);
+
+                       args[1] = back_attr_number;
+                       back = build_intrinsic(base->gallivm->builder, intr_name,
+                                              input_type, args, 3, LLVMReadOnlyAttribute);
+
+                       si_shader_ctx->radeon_bld.inputs[soa_index] =
+                               LLVMBuildSelect(gallivm->builder,
+                                               is_face_positive,
+                                               front,
+                                               back,
+                                               "");
+               }
+
+               shader->ninterp++;
+       } else {
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       LLVMValueRef args[3];
+                       LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+                       unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+                       args[0] = llvm_chan;
+                       args[1] = attr_number;
+                       args[2] = params;
+                       si_shader_ctx->radeon_bld.inputs[soa_index] =
+                               build_intrinsic(base->gallivm->builder, intr_name,
+                                               input_type, args, 3, LLVMReadOnlyAttribute);
+               }
        }
 }
 
@@ -378,9 +440,7 @@ static LLVMValueRef fetch_constant(
                return bitcast(bld_base, type, load);
        }
 
-       /* XXX: Assume the pointer to the constant buffer is being stored in
-        * SGPR[0:1] */
-       const_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_F32, 0);
+       const_ptr = use_sgpr(base->gallivm, SGPR_CONST_PTR_F32, SI_SGPR_CONST);
 
        /* XXX: This assumes that the constant buffer is not packed, so
         * CONST[0].x will have an offset of 0 and CONST[1].x will have an
@@ -417,7 +477,14 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
 
                if (cbuf >= 0 && cbuf < 8) {
                        struct r600_context *rctx = si_shader_ctx->rctx;
-                       compressed = (rctx->export_16bpc >> cbuf) & 0x1;
+                       compressed = (si_shader_ctx->key.export_16bpc >> cbuf) & 0x1;
+
+                       if (compressed)
+                               si_shader_ctx->shader->spi_shader_col_format |=
+                                       V_028714_SPI_SHADER_FP16_ABGR << (4 * cbuf);
+                       else
+                               si_shader_ctx->shader->spi_shader_col_format |=
+                                       V_028714_SPI_SHADER_32_ABGR << (4 * cbuf);
                }
        }
 
@@ -436,7 +503,11 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
                                                LLVMInt32TypeInContext(base->gallivm->context),
                                                args, 2,
                                                LLVMReadNoneAttribute);
-                       args[chan + 7] = args[chan + 5];
+                       args[chan + 7] = args[chan + 5] =
+                               LLVMBuildBitCast(base->gallivm->builder,
+                                                args[chan + 5],
+                                                LLVMFloatTypeInContext(base->gallivm->context),
+                                                "");
                }
 
                /* Set COMPR flag */
@@ -487,6 +558,37 @@ static void si_llvm_emit_prologue(struct lp_build_tgsi_context *bld_base)
 }
 
 
+static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
+                         unsigned index)
+{
+       struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
+       struct gallivm_state *gallivm = bld_base->base.gallivm;
+
+       if (si_shader_ctx->key.alpha_func != PIPE_FUNC_NEVER) {
+               LLVMValueRef out_ptr = si_shader_ctx->radeon_bld.soa.outputs[index][3];
+               LLVMValueRef alpha_pass =
+                       lp_build_cmp(&bld_base->base,
+                                    si_shader_ctx->key.alpha_func,
+                                    LLVMBuildLoad(gallivm->builder, out_ptr, ""),
+                                    lp_build_const_float(gallivm, si_shader_ctx->key.alpha_ref));
+               LLVMValueRef arg =
+                       lp_build_select(&bld_base->base,
+                                       alpha_pass,
+                                       lp_build_const_float(gallivm, 1.0f),
+                                       lp_build_const_float(gallivm, -1.0f));
+
+               build_intrinsic(gallivm->builder,
+                               "llvm.AMDGPU.kill",
+                               LLVMVoidTypeInContext(gallivm->context),
+                               &arg, 1, 0);
+       } else {
+               build_intrinsic(gallivm->builder,
+                               "llvm.AMDGPU.kilp",
+                               LLVMVoidTypeInContext(gallivm->context),
+                               NULL, 0, 0);
+       }
+}
+
 /* XXX: This is partially implemented for VS only at this point.  It is not complete */
 static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 {
@@ -496,14 +598,15 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
        struct lp_build_context * uint =
                                &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
        struct tgsi_parse_context *parse = &si_shader_ctx->parse;
+       LLVMValueRef args[9];
        LLVMValueRef last_args[9] = { 0 };
        unsigned color_count = 0;
        unsigned param_count = 0;
+       int depth_index = -1, stencil_index = -1;
 
        while (!tgsi_parse_end_of_tokens(parse)) {
                struct tgsi_full_declaration *d =
                                        &parse->FullToken.FullDeclaration;
-               LLVMValueRef args[9];
                unsigned target;
                unsigned index;
                int i;
@@ -536,16 +639,31 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
                        /* Select the correct target */
                        switch(d->Semantic.Name) {
                        case TGSI_SEMANTIC_PSIZE:
-                       case TGSI_SEMANTIC_POSITION:
                                target = V_008DFC_SQ_EXP_POS;
                                break;
+                       case TGSI_SEMANTIC_POSITION:
+                               if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+                                       target = V_008DFC_SQ_EXP_POS;
+                                       break;
+                               } else {
+                                       depth_index = index;
+                                       continue;
+                               }
+                       case TGSI_SEMANTIC_STENCIL:
+                               stencil_index = index;
+                               continue;
                        case TGSI_SEMANTIC_COLOR:
                                if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+                       case TGSI_SEMANTIC_BCOLOR:
                                        target = V_008DFC_SQ_EXP_PARAM + param_count;
                                        shader->output[i].param_offset = param_count;
                                        param_count++;
                                } else {
                                        target = V_008DFC_SQ_EXP_MRT + color_count;
+                                       if (color_count == 0 &&
+                                           si_shader_ctx->key.alpha_func != PIPE_FUNC_ALWAYS)
+                                               si_alpha_test(bld_base, index);
+
                                        color_count++;
                                }
                                break;
@@ -585,6 +703,52 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
                }
        }
 
+       if (depth_index >= 0 || stencil_index >= 0) {
+               LLVMValueRef out_ptr;
+               unsigned mask = 0;
+
+               /* Specify the target we are exporting */
+               args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRTZ);
+
+               if (depth_index >= 0) {
+                       out_ptr = si_shader_ctx->radeon_bld.soa.outputs[depth_index][2];
+                       args[5] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+                       mask |= 0x1;
+
+                       if (stencil_index < 0) {
+                               args[6] =
+                               args[7] =
+                               args[8] = args[5];
+                       }
+               }
+
+               if (stencil_index >= 0) {
+                       out_ptr = si_shader_ctx->radeon_bld.soa.outputs[stencil_index][1];
+                       args[7] =
+                       args[8] =
+                       args[6] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+                       mask |= 0x2;
+
+                       if (depth_index < 0)
+                               args[5] = args[6];
+               }
+
+               /* Specify which components to enable */
+               args[0] = lp_build_const_int32(base->gallivm, mask);
+
+               args[1] =
+               args[2] =
+               args[4] = uint->zero;
+
+               if (last_args[0])
+                       lp_build_intrinsic(base->gallivm->builder,
+                                          "llvm.SI.export",
+                                          LLVMVoidTypeInContext(base->gallivm->context),
+                                          args, 9);
+               else
+                       memcpy(last_args, args, sizeof(args));
+       }
+
        if (!last_args[0]) {
                assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);
 
@@ -602,6 +766,9 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
                last_args[6]= uint->zero;
                last_args[7]= uint->zero;
                last_args[8]= uint->zero;
+
+               si_shader_ctx->shader->spi_shader_col_format |=
+                       V_028714_SPI_SHADER_32_ABGR;
        }
 
        /* Specify whether the EXEC mask represents the valid mask */
@@ -624,9 +791,12 @@ static void tex_fetch_args(
        struct lp_build_tgsi_context * bld_base,
        struct lp_build_emit_data * emit_data)
 {
+       struct gallivm_state *gallivm = bld_base->base.gallivm;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        LLVMValueRef ptr;
        LLVMValueRef offset;
+       LLVMValueRef coords[5];
+       unsigned chan;
 
        /* WriteMask */
        /* XXX: should be optimized using emit_data->inst->Dst[0].Register.WriteMask*/
@@ -634,49 +804,68 @@ static void tex_fetch_args(
 
        /* Coordinates */
        /* XXX: Not all sample instructions need 4 address arguments. */
-       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP) {
-               LLVMValueRef src_w;
-               unsigned chan;
-               LLVMValueRef coords[4];
-
-               emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
-               src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W);
-
-               for (chan = 0; chan < 3; chan++ ) {
-                       LLVMValueRef arg = lp_build_emit_fetch(bld_base,
-                                                              emit_data->inst, 0, chan);
+       if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
+               coords[3] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W)
+;
+
+       for (chan = 0; chan < 3; chan++ ) {
+               coords[chan] = lp_build_emit_fetch(bld_base,
+                                                  emit_data->inst, 0,
+                                                  chan);
+               if (inst->Instruction.Opcode == TGSI_OPCODE_TXP)
                        coords[chan] = lp_build_emit_llvm_binary(bld_base,
                                                                 TGSI_OPCODE_DIV,
-                                                                arg, src_w);
-               }
-               coords[3] = bld_base->base.one;
-               emit_data->args[1] = lp_build_gather_values(bld_base->base.gallivm,
-                                                           coords, 4);
-       } else
-               emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst,
-                                                        0, LP_CHAN_ALL);
+                                                                coords[chan],
+                                                                coords[3]);
+       }
+
+       coords[3] = bld_base->base.one;
+
+       if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 ||
+               inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
+               inst->Instruction.Opcode == TGSI_OPCODE_TXL2) {
+               /* These instructions have additional operand that should be packed
+                * into the cube coord vector by radeon_llvm_emit_prepare_cube_coords.
+                * That operand should be passed as a float value in the args array
+                * right after the coord vector. After packing it's not used anymore,
+                * that's why arg_count is not increased */
+               coords[4] = lp_build_emit_fetch(bld_base, inst, 1, 0);
+       }
+
+       if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
+            inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
+           inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
+               radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords);
+       }
+
+       for (chan = 0; chan < 4; chan++ ) {
+               coords[chan] = LLVMBuildBitCast(gallivm->builder,
+                                               coords[chan],
+                                               LLVMInt32TypeInContext(gallivm->context),
+                                               "");
+       }
+
+       emit_data->args[1] = lp_build_gather_values(gallivm, coords, 4);
 
        /* Resource */
-       ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V8I32, 4);
+       ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V8I32, SI_SGPR_RESOURCE);
        offset = lp_build_const_int32(bld_base->base.gallivm,
                                  emit_data->inst->Src[1].Register.Index);
        emit_data->args[2] = build_indexed_load(bld_base->base.gallivm,
                                                ptr, offset);
 
        /* Sampler */
-       ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V4I32, 2);
+       ptr = use_sgpr(bld_base->base.gallivm, SGPR_CONST_PTR_V4I32, SI_SGPR_SAMPLER);
        offset = lp_build_const_int32(bld_base->base.gallivm,
                                  emit_data->inst->Src[1].Register.Index);
        emit_data->args[3] = build_indexed_load(bld_base->base.gallivm,
                                                ptr, offset);
 
        /* Dimensions */
-       /* XXX: We might want to pass this information to the shader at some. */
-/*     emit_data->args[4] = lp_build_const_int32(bld_base->base.gallivm,
+       emit_data->args[4] = lp_build_const_int32(bld_base->base.gallivm,
                                        emit_data->inst->Texture.Texture);
-*/
 
-       emit_data->arg_count = 4;
+       emit_data->arg_count = 5;
        /* XXX: To optimize, we could use a float or v2f32, if the last bits of
         * the writemask are clear */
        emit_data->dst_type = LLVMVectorType(
@@ -687,13 +876,26 @@ static void tex_fetch_args(
 static const struct lp_build_tgsi_action tex_action = {
        .fetch_args = tex_fetch_args,
        .emit = lp_build_tgsi_intrinsic,
-       .intr_name = "llvm.SI.sample"
+       .intr_name = "llvm.SI.sample."
+};
+
+static const struct lp_build_tgsi_action txb_action = {
+       .fetch_args = tex_fetch_args,
+       .emit = lp_build_tgsi_intrinsic,
+       .intr_name = "llvm.SI.sampleb."
+};
+
+static const struct lp_build_tgsi_action txl_action = {
+       .fetch_args = tex_fetch_args,
+       .emit = lp_build_tgsi_intrinsic,
+       .intr_name = "llvm.SI.samplel."
 };
 
 
 int si_pipe_shader_create(
        struct pipe_context *ctx,
-       struct si_pipe_shader *shader)
+       struct si_pipe_shader *shader,
+       struct si_shader_key key)
 {
        struct r600_context *rctx = (struct r600_context*)ctx;
        struct si_pipe_shader_selector *sel = shader->selector;
@@ -709,23 +911,36 @@ int si_pipe_shader_create(
 
        dump = debug_get_bool_option("RADEON_DUMP_SHADERS", FALSE);
 
+       assert(shader->shader.noutput == 0);
+       assert(shader->shader.ninterp == 0);
+       assert(shader->shader.ninput == 0);
+
        memset(&si_shader_ctx, 0, sizeof(si_shader_ctx));
        radeon_llvm_context_init(&si_shader_ctx.radeon_bld);
        bld_base = &si_shader_ctx.radeon_bld.soa.bld_base;
 
        tgsi_scan_shader(sel->tokens, &shader_info);
+       if (shader_info.indirect_files != 0) {
+               fprintf(stderr, "Indirect addressing not fully handled yet\n");
+               return -ENOSYS;
+       }
+
+       shader->shader.uses_kill = shader_info.uses_kill;
        bld_base->info = &shader_info;
        bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
        bld_base->emit_prologue = si_llvm_emit_prologue;
        bld_base->emit_epilogue = si_llvm_emit_epilogue;
 
        bld_base->op_actions[TGSI_OPCODE_TEX] = tex_action;
+       bld_base->op_actions[TGSI_OPCODE_TXB] = txb_action;
+       bld_base->op_actions[TGSI_OPCODE_TXL] = txl_action;
        bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
 
        si_shader_ctx.radeon_bld.load_input = declare_input;
        si_shader_ctx.tokens = sel->tokens;
        tgsi_parse_init(&si_shader_ctx.parse, si_shader_ctx.tokens);
        si_shader_ctx.shader = shader;
+       si_shader_ctx.key = key;
        si_shader_ctx.type = si_shader_ctx.parse.FullHeader.Processor.Processor;
        si_shader_ctx.rctx = rctx;