radeonsi: only use new versions of LLVM image and sample intrinsics
authorMarek Olšák <marek.olsak@amd.com>
Thu, 3 Jul 2014 18:17:36 +0000 (20:17 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 10 Sep 2015 15:14:15 +0000 (17:14 +0200)
Just a cleanup I had made a long time ago and forgot about.

v2: use tgsi_is_shadow_target

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/drivers/radeonsi/si_shader.c

index 9a216c7..b108664 100644 (file)
@@ -2245,15 +2245,62 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
                                struct lp_build_tgsi_context * bld_base,
                                struct lp_build_emit_data * emit_data);
 
-static bool tgsi_is_shadow_sampler(unsigned target)
+static bool tgsi_is_array_sampler(unsigned target)
 {
-       return target == TGSI_TEXTURE_SHADOW1D ||
+       return target == TGSI_TEXTURE_1D_ARRAY ||
               target == TGSI_TEXTURE_SHADOW1D_ARRAY ||
-              target == TGSI_TEXTURE_SHADOW2D ||
+              target == TGSI_TEXTURE_2D_ARRAY ||
               target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
-              target == TGSI_TEXTURE_SHADOWCUBE ||
+              target == TGSI_TEXTURE_CUBE_ARRAY ||
               target == TGSI_TEXTURE_SHADOWCUBE_ARRAY ||
-              target == TGSI_TEXTURE_SHADOWRECT;
+              target == TGSI_TEXTURE_2D_ARRAY_MSAA;
+}
+
+static void set_tex_fetch_args(struct gallivm_state *gallivm,
+                              struct lp_build_emit_data *emit_data,
+                              unsigned opcode, unsigned target,
+                              LLVMValueRef res_ptr, LLVMValueRef samp_ptr,
+                              LLVMValueRef *param, unsigned count,
+                              unsigned dmask)
+{
+       unsigned num_args;
+       unsigned is_rect = target == TGSI_TEXTURE_RECT;
+       LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
+
+       /* Pad to power of two vector */
+       while (count < util_next_power_of_two(count))
+               param[count++] = LLVMGetUndef(i32);
+
+       /* Texture coordinates. */
+       if (count > 1)
+               emit_data->args[0] = lp_build_gather_values(gallivm, param, count);
+       else
+               emit_data->args[0] = param[0];
+
+       /* Resource. */
+       emit_data->args[1] = res_ptr;
+       num_args = 2;
+
+       if (opcode == TGSI_OPCODE_TXF || opcode == TGSI_OPCODE_TXQ)
+               emit_data->dst_type = LLVMVectorType(i32, 4);
+       else {
+               emit_data->dst_type = LLVMVectorType(
+                       LLVMFloatTypeInContext(gallivm->context), 4);
+
+               emit_data->args[num_args++] = samp_ptr;
+       }
+
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, dmask);
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, is_rect); /* unorm */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, 0); /* r128 */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm,
+                                       tgsi_is_array_sampler(target)); /* da */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, 0); /* glc */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, 0); /* slc */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, 0); /* tfe */
+       emit_data->args[num_args++] = lp_build_const_int32(gallivm, 0); /* lwe */
+
+       emit_data->arg_count = num_args;
 }
 
 static const struct lp_build_tgsi_action tex_action;
@@ -2264,6 +2311,7 @@ static void tex_fetch_args(
 {
        struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
+       LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        unsigned opcode = inst->Instruction.Opcode;
        unsigned target = inst->Texture.Texture;
@@ -2278,6 +2326,8 @@ static void tex_fetch_args(
        unsigned num_deriv_channels = 0;
        bool has_offset = inst->Texture.NumOffsets > 0;
        LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL;
+       LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
+       unsigned dmask = 0xf;
 
        sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1;
        sampler_index = emit_data->inst->Src[sampler_src].Register.Index;
@@ -2308,6 +2358,43 @@ static void tex_fetch_args(
                fmask_ptr = si_shader_ctx->resources[SI_FMASK_TEX_OFFSET + sampler_index];
        }
 
+       if (opcode == TGSI_OPCODE_TXQ) {
+               if (target == TGSI_TEXTURE_BUFFER) {
+                       LLVMTypeRef v8i32 = LLVMVectorType(i32, 8);
+
+                       /* Read the size from the buffer descriptor directly. */
+                       LLVMValueRef res = LLVMBuildBitCast(builder, res_ptr, v8i32, "");
+                       LLVMValueRef size = LLVMBuildExtractElement(builder, res,
+                                                       lp_build_const_int32(gallivm, 6), "");
+
+                       if (si_shader_ctx->screen->b.chip_class >= VI) {
+                               /* On VI, the descriptor contains the size in bytes,
+                                * but TXQ must return the size in elements.
+                                * The stride is always non-zero for resources using TXQ.
+                                */
+                               LLVMValueRef stride =
+                                       LLVMBuildExtractElement(builder, res,
+                                                               lp_build_const_int32(gallivm, 5), "");
+                               stride = LLVMBuildLShr(builder, stride,
+                                                      lp_build_const_int32(gallivm, 16), "");
+                               stride = LLVMBuildAnd(builder, stride,
+                                                     lp_build_const_int32(gallivm, 0x3FFF), "");
+
+                               size = LLVMBuildUDiv(builder, size, stride, "");
+                       }
+
+                       emit_data->args[0] = size;
+                       return;
+               }
+
+               /* Textures - set the mip level. */
+               address[count++] = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X);
+
+               set_tex_fetch_args(gallivm, emit_data, opcode, target, res_ptr,
+                                  NULL, address, count, 0xf);
+               return;
+       }
+
        if (target == TGSI_TEXTURE_BUFFER) {
                LLVMTypeRef i128 = LLVMIntTypeInContext(gallivm->context, 128);
                LLVMTypeRef v2i128 = LLVMVectorType(i128, 2);
@@ -2375,7 +2462,7 @@ static void tex_fetch_args(
                address[count++] = lp_build_emit_fetch(bld_base, inst, 1, 0);
 
        /* Pack depth comparison value */
-       if (tgsi_is_shadow_sampler(target) && opcode != TGSI_OPCODE_LODQ) {
+       if (tgsi_is_shadow_target(target) && opcode != TGSI_OPCODE_LODQ) {
                if (target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
                        address[count++] = lp_build_emit_fetch(bld_base, inst, 1, 0);
                } else {
@@ -2457,9 +2544,7 @@ static void tex_fetch_args(
 
        for (chan = 0; chan < count; chan++ ) {
                address[chan] = LLVMBuildBitCast(gallivm->builder,
-                                                address[chan],
-                                                LLVMInt32TypeInContext(gallivm->context),
-                                                "");
+                                                address[chan], i32, "");
        }
 
        /* Adjust the sample index according to FMASK.
@@ -2491,22 +2576,14 @@ static void tex_fetch_args(
                }
                txf_address[3] = bld_base->uint_bld.zero;
 
-               /* Pad to a power-of-two size. */
-               while (txf_count < util_next_power_of_two(txf_count))
-                       txf_address[txf_count++] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
-
                /* Read FMASK using TXF. */
                inst.Instruction.Opcode = TGSI_OPCODE_TXF;
-               inst.Texture.Texture = target == TGSI_TEXTURE_2D_MSAA ? TGSI_TEXTURE_2D : TGSI_TEXTURE_2D_ARRAY;
+               inst.Texture.Texture = target;
                txf_emit_data.inst = &inst;
                txf_emit_data.chan = 0;
-               txf_emit_data.dst_type = LLVMVectorType(
-                       LLVMInt32TypeInContext(gallivm->context), 4);
-               txf_emit_data.args[0] = lp_build_gather_values(gallivm, txf_address, txf_count);
-               txf_emit_data.args[1] = fmask_ptr;
-               txf_emit_data.args[2] = lp_build_const_int32(gallivm, inst.Texture.Texture);
-               txf_emit_data.arg_count = 3;
-
+               set_tex_fetch_args(gallivm, &txf_emit_data, TGSI_OPCODE_TXF,
+                                  target, fmask_ptr, NULL,
+                                  txf_address, txf_count, 0xf);
                build_tex_intrinsic(&tex_action, bld_base, &txf_emit_data);
 
                /* Initialize some constants. */
@@ -2551,9 +2628,6 @@ static void tex_fetch_args(
                                        final_sample, address[sample_chan], "");
        }
 
-       /* Resource */
-       emit_data->args[1] = res_ptr;
-
        if (opcode == TGSI_OPCODE_TXF) {
                /* add tex offsets */
                if (inst->Texture.NumOffsets) {
@@ -2589,89 +2663,37 @@ static void tex_fetch_args(
                                /* texture offsets do not apply to other texture targets */
                        }
                }
+       }
 
-               emit_data->args[2] = lp_build_const_int32(gallivm, target);
-               emit_data->arg_count = 3;
-
-               emit_data->dst_type = LLVMVectorType(
-                       LLVMInt32TypeInContext(gallivm->context),
-                       4);
-       } else if (opcode == TGSI_OPCODE_TG4 ||
-                  opcode == TGSI_OPCODE_LODQ ||
-                  has_offset) {
-               unsigned is_array = target == TGSI_TEXTURE_1D_ARRAY ||
-                                   target == TGSI_TEXTURE_SHADOW1D_ARRAY ||
-                                   target == TGSI_TEXTURE_2D_ARRAY ||
-                                   target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
-                                   target == TGSI_TEXTURE_CUBE_ARRAY ||
-                                   target == TGSI_TEXTURE_SHADOWCUBE_ARRAY;
-               unsigned is_rect = target == TGSI_TEXTURE_RECT;
-               unsigned dmask = 0xf;
-
-               if (opcode == TGSI_OPCODE_TG4) {
-                       unsigned gather_comp = 0;
-
-                       /* DMASK was repurposed for GATHER4. 4 components are always
-                        * returned and DMASK works like a swizzle - it selects
-                        * the component to fetch. The only valid DMASK values are
-                        * 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
-                        * (red,red,red,red) etc.) The ISA document doesn't mention
-                        * this.
-                        */
+       if (opcode == TGSI_OPCODE_TG4) {
+               unsigned gather_comp = 0;
 
-                       /* Get the component index from src1.x for Gather4. */
-                       if (!tgsi_is_shadow_sampler(target)) {
-                               LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
-                               LLVMValueRef comp_imm;
-                               struct tgsi_src_register src1 = inst->Src[1].Register;
+               /* DMASK was repurposed for GATHER4. 4 components are always
+                * returned and DMASK works like a swizzle - it selects
+                * the component to fetch. The only valid DMASK values are
+                * 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
+                * (red,red,red,red) etc.) The ISA document doesn't mention
+                * this.
+                */
 
-                               assert(src1.File == TGSI_FILE_IMMEDIATE);
+               /* Get the component index from src1.x for Gather4. */
+               if (!tgsi_is_shadow_target(target)) {
+                       LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
+                       LLVMValueRef comp_imm;
+                       struct tgsi_src_register src1 = inst->Src[1].Register;
 
-                               comp_imm = imms[src1.Index][src1.SwizzleX];
-                               gather_comp = LLVMConstIntGetZExtValue(comp_imm);
-                               gather_comp = CLAMP(gather_comp, 0, 3);
-                       }
+                       assert(src1.File == TGSI_FILE_IMMEDIATE);
 
-                       dmask = 1 << gather_comp;
+                       comp_imm = imms[src1.Index][src1.SwizzleX];
+                       gather_comp = LLVMConstIntGetZExtValue(comp_imm);
+                       gather_comp = CLAMP(gather_comp, 0, 3);
                }
 
-               emit_data->args[2] = samp_ptr;
-               emit_data->args[3] = lp_build_const_int32(gallivm, dmask);
-               emit_data->args[4] = lp_build_const_int32(gallivm, is_rect); /* unorm */
-               emit_data->args[5] = lp_build_const_int32(gallivm, 0); /* r128 */
-               emit_data->args[6] = lp_build_const_int32(gallivm, is_array); /* da */
-               emit_data->args[7] = lp_build_const_int32(gallivm, 0); /* glc */
-               emit_data->args[8] = lp_build_const_int32(gallivm, 0); /* slc */
-               emit_data->args[9] = lp_build_const_int32(gallivm, 0); /* tfe */
-               emit_data->args[10] = lp_build_const_int32(gallivm, 0); /* lwe */
-
-               emit_data->arg_count = 11;
-
-               emit_data->dst_type = LLVMVectorType(
-                       LLVMFloatTypeInContext(gallivm->context),
-                       4);
-       } else {
-               emit_data->args[2] = samp_ptr;
-               emit_data->args[3] = lp_build_const_int32(gallivm, target);
-               emit_data->arg_count = 4;
-
-               emit_data->dst_type = LLVMVectorType(
-                       LLVMFloatTypeInContext(gallivm->context),
-                       4);
+               dmask = 1 << gather_comp;
        }
 
-       /* The fetch opcode has been converted to a 2D array fetch.
-        * This simplifies the LLVM backend. */
-       if (target == TGSI_TEXTURE_CUBE_ARRAY)
-               target = TGSI_TEXTURE_2D_ARRAY;
-       else if (target == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
-               target = TGSI_TEXTURE_SHADOW2D_ARRAY;
-
-       /* Pad to power of two vector */
-       while (count < util_next_power_of_two(count))
-               address[count++] = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
-
-       emit_data->args[0] = lp_build_gather_values(gallivm, address, count);
+       set_tex_fetch_args(gallivm, emit_data, opcode, target, res_ptr,
+                          samp_ptr, address, count, dmask);
 }
 
 static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
@@ -2683,6 +2705,16 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
        unsigned target = emit_data->inst->Texture.Texture;
        char intr_name[127];
        bool has_offset = emit_data->inst->Texture.NumOffsets > 0;
+       bool is_shadow = tgsi_is_shadow_target(target);
+       char type[64];
+       const char *name = "llvm.SI.image.sample";
+       const char *infix = "";
+
+       if (opcode == TGSI_OPCODE_TXQ && target == TGSI_TEXTURE_BUFFER) {
+               /* Just return the buffer size. */
+               emit_data->output[emit_data->chan] = emit_data->args[0];
+               return;
+       }
 
        if (target == TGSI_TEXTURE_BUFFER) {
                emit_data->output[emit_data->chan] = lp_build_intrinsic(
@@ -2693,191 +2725,68 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
                return;
        }
 
-       if (opcode == TGSI_OPCODE_TG4 ||
-           opcode == TGSI_OPCODE_LODQ ||
-           (opcode != TGSI_OPCODE_TXF && has_offset)) {
-               bool is_shadow = tgsi_is_shadow_sampler(target);
-               const char *name = "llvm.SI.image.sample";
-               const char *infix = "";
-
-               switch (opcode) {
-               case TGSI_OPCODE_TEX:
-               case TGSI_OPCODE_TEX2:
-               case TGSI_OPCODE_TXP:
-                       break;
-               case TGSI_OPCODE_TXB:
-               case TGSI_OPCODE_TXB2:
-                       infix = ".b";
-                       break;
-               case TGSI_OPCODE_TXL:
-               case TGSI_OPCODE_TXL2:
-                       infix = ".l";
-                       break;
-               case TGSI_OPCODE_TXD:
-                       infix = ".d";
-                       break;
-               case TGSI_OPCODE_TG4:
-                       name = "llvm.SI.gather4";
-                       break;
-               case TGSI_OPCODE_LODQ:
-                       name = "llvm.SI.getlod";
-                       is_shadow = false;
-                       has_offset = false;
-                       break;
-               default:
-                       assert(0);
-                       return;
-               }
-
-               /* Add the type and suffixes .c, .o if needed. */
-               sprintf(intr_name, "%s%s%s%s.v%ui32", name,
-                       is_shadow ? ".c" : "", infix, has_offset ? ".o" : "",
-                       LLVMGetVectorSize(LLVMTypeOf(emit_data->args[0])));
-
-               emit_data->output[emit_data->chan] = lp_build_intrinsic(
-                       base->gallivm->builder, intr_name, emit_data->dst_type,
-                       emit_data->args, emit_data->arg_count,
-                       LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
-       } else {
-               LLVMTypeRef i8, v16i8, v32i8;
-               const char *name;
-
-               switch (opcode) {
-               case TGSI_OPCODE_TEX:
-               case TGSI_OPCODE_TEX2:
-               case TGSI_OPCODE_TXP:
-                       name = "llvm.SI.sample";
-                       break;
-               case TGSI_OPCODE_TXB:
-               case TGSI_OPCODE_TXB2:
-                       name = "llvm.SI.sampleb";
-                       break;
-               case TGSI_OPCODE_TXD:
-                       name = "llvm.SI.sampled";
-                       break;
-               case TGSI_OPCODE_TXF:
-                       name = "llvm.SI.imageload";
-                       break;
-               case TGSI_OPCODE_TXL:
-               case TGSI_OPCODE_TXL2:
-                       name = "llvm.SI.samplel";
-                       break;
-               default:
-                       assert(0);
-                       return;
-               }
-
-               i8 = LLVMInt8TypeInContext(base->gallivm->context);
-               v16i8 = LLVMVectorType(i8, 16);
-               v32i8 = LLVMVectorType(i8, 32);
-
-               emit_data->args[1] = LLVMBuildBitCast(base->gallivm->builder,
-                                               emit_data->args[1], v32i8, "");
-               if (opcode != TGSI_OPCODE_TXF) {
-                       emit_data->args[2] = LLVMBuildBitCast(base->gallivm->builder,
-                                               emit_data->args[2], v16i8, "");
-               }
-
-               sprintf(intr_name, "%s.v%ui32", name,
-                       LLVMGetVectorSize(LLVMTypeOf(emit_data->args[0])));
-
-               emit_data->output[emit_data->chan] = lp_build_intrinsic(
-                       base->gallivm->builder, intr_name, emit_data->dst_type,
-                       emit_data->args, emit_data->arg_count,
-                       LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
-       }
-}
-
-static void txq_fetch_args(
-       struct lp_build_tgsi_context * bld_base,
-       struct lp_build_emit_data * emit_data)
-{
-       struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
-       const struct tgsi_full_instruction *inst = emit_data->inst;
-       struct gallivm_state *gallivm = bld_base->base.gallivm;
-       LLVMBuilderRef builder = gallivm->builder;
-       unsigned target = inst->Texture.Texture;
-       LLVMValueRef res_ptr;
-
-       if (inst->Src[1].Register.Indirect) {
-               const struct tgsi_full_src_register *reg = &inst->Src[1];
-               LLVMValueRef ind_index;
-
-               ind_index = get_indirect_index(si_shader_ctx, &reg->Indirect, reg->Register.Index);
-
-               res_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE);
-               res_ptr = build_indexed_load_const(si_shader_ctx, res_ptr,
-                                                  ind_index);
-       } else
-               res_ptr = si_shader_ctx->resources[inst->Src[1].Register.Index];
-
-       if (target == TGSI_TEXTURE_BUFFER) {
-               LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
-               LLVMTypeRef v8i32 = LLVMVectorType(i32, 8);
-
-               /* Read the size from the buffer descriptor directly. */
-               LLVMValueRef res = LLVMBuildBitCast(builder, res_ptr, v8i32, "");
-               LLVMValueRef size = LLVMBuildExtractElement(builder, res,
-                                               lp_build_const_int32(gallivm, 6), "");
-
-               if (si_shader_ctx->screen->b.chip_class >= VI) {
-                       /* On VI, the descriptor contains the size in bytes,
-                        * but TXQ must return the size in elements.
-                        * The stride is always non-zero for resources using TXQ.
-                        */
-                       LLVMValueRef stride =
-                               LLVMBuildExtractElement(builder, res,
-                                                       lp_build_const_int32(gallivm, 5), "");
-                       stride = LLVMBuildLShr(builder, stride,
-                                              lp_build_const_int32(gallivm, 16), "");
-                       stride = LLVMBuildAnd(builder, stride,
-                                             lp_build_const_int32(gallivm, 0x3FFF), "");
-
-                       size = LLVMBuildUDiv(builder, size, stride, "");
-               }
-
-               emit_data->args[0] = size;
+       switch (opcode) {
+       case TGSI_OPCODE_TXF:
+               name = target == TGSI_TEXTURE_2D_MSAA ||
+                      target == TGSI_TEXTURE_2D_ARRAY_MSAA ?
+                              "llvm.SI.image.load" :
+                              "llvm.SI.image.load.mip";
+               is_shadow = false;
+               has_offset = false;
+               break;
+       case TGSI_OPCODE_TXQ:
+               name = "llvm.SI.getresinfo";
+               is_shadow = false;
+               has_offset = false;
+               break;
+       case TGSI_OPCODE_LODQ:
+               name = "llvm.SI.getlod";
+               is_shadow = false;
+               has_offset = false;
+               break;
+       case TGSI_OPCODE_TEX:
+       case TGSI_OPCODE_TEX2:
+       case TGSI_OPCODE_TXP:
+               break;
+       case TGSI_OPCODE_TXB:
+       case TGSI_OPCODE_TXB2:
+               infix = ".b";
+               break;
+       case TGSI_OPCODE_TXL:
+       case TGSI_OPCODE_TXL2:
+               infix = ".l";
+               break;
+       case TGSI_OPCODE_TXD:
+               infix = ".d";
+               break;
+       case TGSI_OPCODE_TG4:
+               name = "llvm.SI.gather4";
+               break;
+       default:
+               assert(0);
                return;
        }
 
-       /* Mip level */
-       emit_data->args[0] = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X);
-
-       /* Resource */
-       emit_data->args[1] = res_ptr;
-
-       /* Texture target */
-       if (target == TGSI_TEXTURE_CUBE_ARRAY ||
-           target == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
-               target = TGSI_TEXTURE_2D_ARRAY;
-
-       emit_data->args[2] = lp_build_const_int32(bld_base->base.gallivm,
-                                                 target);
-
-       emit_data->arg_count = 3;
-
-       emit_data->dst_type = LLVMVectorType(
-               LLVMInt32TypeInContext(bld_base->base.gallivm->context),
-               4);
-}
-
-static void build_txq_intrinsic(const struct lp_build_tgsi_action * action,
-                               struct lp_build_tgsi_context * bld_base,
-                               struct lp_build_emit_data * emit_data)
-{
-       unsigned target = emit_data->inst->Texture.Texture;
+       if (LLVMGetTypeKind(LLVMTypeOf(emit_data->args[0])) == LLVMVectorTypeKind)
+               sprintf(type, ".v%ui32",
+                       LLVMGetVectorSize(LLVMTypeOf(emit_data->args[0])));
+       else
+               strcpy(type, ".i32");
 
-       if (target == TGSI_TEXTURE_BUFFER) {
-               /* Just return the buffer size. */
-               emit_data->output[emit_data->chan] = emit_data->args[0];
-               return;
-       }
+       /* Add the type and suffixes .c, .o if needed. */
+       sprintf(intr_name, "%s%s%s%s%s",
+               name, is_shadow ? ".c" : "", infix,
+               has_offset ? ".o" : "", type);
 
-       build_tgsi_intrinsic_nomem(action, bld_base, emit_data);
+       emit_data->output[emit_data->chan] = lp_build_intrinsic(
+               base->gallivm->builder, intr_name, emit_data->dst_type,
+               emit_data->args, emit_data->arg_count,
+               LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
 
        /* Divide the number of layers by 6 to get the number of cubes. */
-       if (target == TGSI_TEXTURE_CUBE_ARRAY ||
-           target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
+       if (opcode == TGSI_OPCODE_TXQ &&
+           (target == TGSI_TEXTURE_CUBE_ARRAY ||
+            target == TGSI_TEXTURE_SHADOWCUBE_ARRAY)) {
                LLVMBuilderRef builder = bld_base->base.gallivm->builder;
                LLVMValueRef two = lp_build_const_int32(bld_base->base.gallivm, 2);
                LLVMValueRef six = lp_build_const_int32(bld_base->base.gallivm, 6);
@@ -3354,12 +3263,6 @@ static const struct lp_build_tgsi_action tex_action = {
        .emit = build_tex_intrinsic,
 };
 
-static const struct lp_build_tgsi_action txq_action = {
-       .fetch_args = txq_fetch_args,
-       .emit = build_txq_intrinsic,
-       .intr_name = "llvm.SI.resinfo"
-};
-
 static const struct lp_build_tgsi_action interp_action = {
        .fetch_args = interp_fetch_args,
        .emit = build_interp_intrinsic,
@@ -4069,7 +3972,7 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
        bld_base->op_actions[TGSI_OPCODE_TXL] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXL2] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXP] = tex_action;
-       bld_base->op_actions[TGSI_OPCODE_TXQ] = txq_action;
+       bld_base->op_actions[TGSI_OPCODE_TXQ] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TG4] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_LODQ] = tex_action;