ac/nir, radv, radeonsi: Switch to using ac_shader_args
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_tgsi_mem.c
index 01df9962ee8bc3451866b53cddab58906a3c5ea3..67db98d6fed69162b182ea807a189aeecd3d8b48 100644 (file)
@@ -22,6 +22,8 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <llvm/Config/llvm-config.h>
+
 #include "si_shader_internal.h"
 #include "si_pipe.h"
 #include "sid.h"
@@ -93,7 +95,7 @@ ac_texture_dim_from_tgsi_target(struct si_screen *screen, enum tgsi_texture_type
        switch (target) {
        case TGSI_TEXTURE_1D:
        case TGSI_TEXTURE_SHADOW1D:
-               if (screen->info.chip_class >= GFX9)
+               if (screen->info.chip_class == GFX9)
                        return ac_image_2d;
                return ac_image_1d;
        case TGSI_TEXTURE_2D:
@@ -110,7 +112,7 @@ ac_texture_dim_from_tgsi_target(struct si_screen *screen, enum tgsi_texture_type
                return ac_image_cube;
        case TGSI_TEXTURE_1D_ARRAY:
        case TGSI_TEXTURE_SHADOW1D_ARRAY:
-               if (screen->info.chip_class >= GFX9)
+               if (screen->info.chip_class == GFX9)
                        return ac_image_2darray;
                return ac_image_1darray;
        case TGSI_TEXTURE_2D_ARRAY:
@@ -174,6 +176,8 @@ static LLVMValueRef force_dcc_off(struct si_shader_context *ctx,
        }
 }
 
+/* AC_DESC_FMASK is handled exactly like AC_DESC_IMAGE. The caller should
+ * adjust "index" to point to FMASK. */
 LLVMValueRef si_load_image_desc(struct si_shader_context *ctx,
                                LLVMValueRef list, LLVMValueRef index,
                                enum ac_descriptor_type desc_type,
@@ -188,7 +192,8 @@ LLVMValueRef si_load_image_desc(struct si_shader_context *ctx,
                list = LLVMBuildPointerCast(builder, list,
                                            ac_array_in_const32_addr_space(ctx->v4i32), "");
        } else {
-               assert(desc_type == AC_DESC_IMAGE);
+               assert(desc_type == AC_DESC_IMAGE ||
+                      desc_type == AC_DESC_FMASK);
        }
 
        if (bindless)
@@ -196,8 +201,7 @@ LLVMValueRef si_load_image_desc(struct si_shader_context *ctx,
        else
                rsrc = ac_build_load_to_sgpr(&ctx->ac, list, index);
 
-       if (ctx->ac.chip_class <= GFX9 &&
-           desc_type == AC_DESC_IMAGE && uses_store)
+       if (desc_type == AC_DESC_IMAGE && uses_store)
                rsrc = force_dcc_off(ctx, rsrc);
        return rsrc;
 }
@@ -209,55 +213,58 @@ static void
 image_fetch_rsrc(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *image,
-       bool is_store, unsigned target,
+       bool fmask, bool is_store, unsigned target,
        LLVMValueRef *rsrc)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->main_fn,
-                                            ctx->param_samplers_and_images);
-       LLVMValueRef index;
-
-       if (!image->Register.Indirect) {
-               index = LLVMConstInt(ctx->i32,
-                                    si_get_image_slot(image->Register.Index), 0);
-       } else {
-               /* From the GL_ARB_shader_image_load_store extension spec:
-                *
-                *    If a shader performs an image load, store, or atomic
-                *    operation using an image variable declared as an array,
-                *    and if the index used to select an individual element is
-                *    negative or greater than or equal to the size of the
-                *    array, the results of the operation are undefined but may
-                *    not lead to termination.
-                */
-               index = si_get_bounded_indirect_index(ctx, &image->Indirect,
-                                                     image->Register.Index,
-                                                     ctx->num_images);
-               index = LLVMBuildSub(ctx->ac.builder,
-                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGES - 1, 0),
-                                    index, "");
-       }
+       bool bindless = image->Register.File != TGSI_FILE_IMAGE;
+       LLVMValueRef rsrc_ptr, index;
 
-       bool bindless = false;
-
-       if (image->Register.File != TGSI_FILE_IMAGE) {
+       if (bindless) {
                /* Bindless descriptors are accessible from a different pair of
                 * user SGPR indices.
                 */
-               rsrc_ptr = LLVMGetParam(ctx->main_fn,
-                                       ctx->param_bindless_samplers_and_images);
-               index = lp_build_emit_fetch_src(bld_base, image,
-                                               TGSI_TYPE_UNSIGNED, 0);
+               rsrc_ptr = ac_get_arg(&ctx->ac,
+                                     ctx->bindless_samplers_and_images);
+               index = lp_build_emit_fetch_src(bld_base, image, TGSI_TYPE_UNSIGNED, 0);
 
-               /* For simplicity, bindless image descriptors use fixed
-                * 16-dword slots for now.
-                */
+               /* Bindless image descriptors use 16-dword slots. */
                index = LLVMBuildMul(ctx->ac.builder, index,
                                     LLVMConstInt(ctx->i32, 2, 0), "");
-               bindless = true;
+               /* FMASK is right after the image. */
+               if (fmask)
+                       index = LLVMBuildAdd(ctx->ac.builder, index, ctx->i32_1, "");
+       } else {
+               rsrc_ptr = ac_get_arg(&ctx->ac, ctx->samplers_and_images);
+
+               if (!image->Register.Indirect) {
+                       index = LLVMConstInt(ctx->i32, image->Register.Index, 0);
+               } else {
+                       /* From the GL_ARB_shader_image_load_store extension spec:
+                        *
+                        *    If a shader performs an image load, store, or atomic
+                        *    operation using an image variable declared as an array,
+                        *    and if the index used to select an individual element is
+                        *    negative or greater than or equal to the size of the
+                        *    array, the results of the operation are undefined but may
+                        *    not lead to termination.
+                        */
+                       index = si_get_bounded_indirect_index(ctx, &image->Indirect,
+                                                             image->Register.Index,
+                                                             ctx->num_images);
+               }
+               /* FMASKs are separate from images. */
+               if (fmask) {
+                       index = LLVMBuildAdd(ctx->ac.builder, index,
+                                            LLVMConstInt(ctx->i32, SI_NUM_IMAGES, 0), "");
+               }
+               index = LLVMBuildSub(ctx->ac.builder,
+                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGE_SLOTS - 1, 0),
+                                    index, "");
        }
 
        *rsrc = si_load_image_desc(ctx, rsrc_ptr, index,
+                                  fmask ? AC_DESC_FMASK :
                                   target == TGSI_TEXTURE_BUFFER ? AC_DESC_BUFFER : AC_DESC_IMAGE,
                                   is_store, bindless);
 }
@@ -275,27 +282,27 @@ static void image_fetch_coords(
        LLVMValueRef tmp;
        int chan;
 
-       if (target == TGSI_TEXTURE_2D_MSAA ||
-           target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
-               /* Need the sample index as well. */
-               num_coords++;
-       }
-
        for (chan = 0; chan < num_coords; ++chan) {
                tmp = lp_build_emit_fetch(bld_base, inst, src, chan);
                tmp = ac_to_integer(&ctx->ac, tmp);
                coords[chan] = tmp;
        }
 
-       if (ctx->screen->info.chip_class >= GFX9) {
+       if (target == TGSI_TEXTURE_2D_MSAA ||
+           target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
+               /* Need the sample index as well. */
+               tmp = lp_build_emit_fetch(bld_base, inst, src, TGSI_SWIZZLE_W);
+               coords[chan] = ac_to_integer(&ctx->ac, tmp);
+       }
+
+       if (ctx->screen->info.chip_class == GFX9) {
                /* 1D textures are allocated and used as 2D on GFX9. */
                if (target == TGSI_TEXTURE_1D) {
                        coords[1] = ctx->i32_0;
                } else if (target == TGSI_TEXTURE_1D_ARRAY) {
                        coords[2] = coords[1];
                        coords[1] = ctx->i32_0;
-               } else if (ctx->screen->info.chip_class == GFX9 &&
-                          target == TGSI_TEXTURE_2D) {
+               } else if (target == TGSI_TEXTURE_2D) {
                        /* The hw can't bind a slice of a 3D image as a 2D
                         * image, because it ignores BASE_ARRAY if the target
                         * is 3D. The workaround is to read BASE_ARRAY and set
@@ -505,8 +512,18 @@ static void load_emit(
        } else {
                unsigned target = inst->Memory.Texture;
 
-               image_fetch_rsrc(bld_base, &inst->Src[0], false, target, &args.resource);
+               image_fetch_rsrc(bld_base, &inst->Src[0], false, false, target, &args.resource);
                image_fetch_coords(bld_base, inst, 1, args.resource, args.coords);
+
+               if ((inst->Memory.Texture == TGSI_TEXTURE_2D_MSAA ||
+                    inst->Memory.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA) &&
+                   !(ctx->screen->debug_flags & DBG(NO_FMASK))) {
+                       LLVMValueRef fmask;
+
+                       image_fetch_rsrc(bld_base, &inst->Src[0], true, false, target, &fmask);
+                       ac_apply_fmask_to_sample(&ctx->ac, fmask, args.coords,
+                                                inst->Memory.Texture == TGSI_TEXTURE_2D_ARRAY_MSAA);
+               }
                vindex = args.coords[0]; /* for buffers only */
        }
 
@@ -698,7 +715,7 @@ static void store_emit(
                args.resource = shader_buffer_fetch_rsrc(ctx, &resource_reg, false);
                voffset = ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 0, 0));
        } else {
-               image_fetch_rsrc(bld_base, &resource_reg, true, target, &args.resource);
+               image_fetch_rsrc(bld_base, &resource_reg, false, true, target, &args.resource);
                image_fetch_coords(bld_base, inst, 0, args.resource, args.coords);
                vindex = args.coords[0]; /* for buffers only */
        }
@@ -744,7 +761,7 @@ static void atomic_emit_memory(struct si_shader_context *ctx,
        LLVMBuilderRef builder = ctx->ac.builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        LLVMValueRef ptr, result, arg;
-       const char *sync_scope = HAVE_LLVM >= 0x0900 ? "workgroup-one-as" : "workgroup";
+       const char *sync_scope = LLVM_VERSION_MAJOR >= 9 ? "workgroup-one-as" : "workgroup";
 
        ptr = get_memory_ptr(ctx, inst, ctx->i32, 1);
 
@@ -829,20 +846,20 @@ static void atomic_emit(
 
        args.data[num_data++] =
                ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 2, 0));
+
        args.cache_policy = get_cache_policy(ctx, inst, true, false, false);
 
        if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
                args.resource = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
                voffset = ac_to_integer(&ctx->ac, lp_build_emit_fetch(bld_base, inst, 1, 0));
        } else {
-               image_fetch_rsrc(bld_base, &inst->Src[0], true,
+               image_fetch_rsrc(bld_base, &inst->Src[0], false, true,
                                inst->Memory.Texture, &args.resource);
                image_fetch_coords(bld_base, inst, 1, args.resource, args.coords);
                vindex = args.coords[0]; /* for buffers only */
        }
 
-       if (HAVE_LLVM >= 0x0800 &&
-           inst->Src[0].Register.File != TGSI_FILE_BUFFER &&
+       if (inst->Src[0].Register.File != TGSI_FILE_BUFFER &&
            inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
                LLVMValueRef buf_args[7];
                unsigned num_args = 0;
@@ -867,9 +884,7 @@ static void atomic_emit(
                return;
        }
 
-       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
-           (HAVE_LLVM < 0x0800 &&
-            inst->Memory.Texture == TGSI_TEXTURE_BUFFER)) {
+       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
                LLVMValueRef buf_args[7];
                unsigned num_args = 0;
 
@@ -904,6 +919,12 @@ static void atomic_emit(
                        case TGSI_OPCODE_ATOMUMAX: args.atomic = ac_atomic_umax; break;
                        case TGSI_OPCODE_ATOMIMIN: args.atomic = ac_atomic_smin; break;
                        case TGSI_OPCODE_ATOMIMAX: args.atomic = ac_atomic_smax; break;
+                       case TGSI_OPCODE_ATOMINC_WRAP:
+                               args.atomic = ac_atomic_inc_wrap;
+                               break;
+                       case TGSI_OPCODE_ATOMDEC_WRAP:
+                               args.atomic = ac_atomic_dec_wrap;
+                               break;
                        default: unreachable("unhandled image atomic");
                        }
                }
@@ -920,7 +941,7 @@ static LLVMValueRef fix_resinfo(struct si_shader_context *ctx,
        LLVMBuilderRef builder = ctx->ac.builder;
 
        /* 1D textures are allocated and used as 2D on GFX9. */
-        if (ctx->screen->info.chip_class >= GFX9 &&
+        if (ctx->screen->info.chip_class == GFX9 &&
            (target == TGSI_TEXTURE_1D_ARRAY ||
             target == TGSI_TEXTURE_SHADOW1D_ARRAY)) {
                LLVMValueRef layers =
@@ -978,7 +999,7 @@ static void resq_emit(
            inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
                LLVMValueRef rsrc;
 
-               image_fetch_rsrc(bld_base, reg, false, inst->Memory.Texture, &rsrc);
+               image_fetch_rsrc(bld_base, reg, false, false, inst->Memory.Texture, &rsrc);
                emit_data->output[emit_data->chan] =
                        get_buffer_size(bld_base, rsrc);
                return;
@@ -1005,12 +1026,25 @@ static void resq_emit(
                tex_fetch_ptrs(bld_base, emit_data, &args.resource, NULL, NULL);
                args.lod = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X);
        } else {
-               image_fetch_rsrc(bld_base, reg, false, target, &args.resource);
+               image_fetch_rsrc(bld_base, reg, false, false, target, &args.resource);
                args.lod = ctx->i32_0;
        }
 
        emit_data->output[emit_data->chan] =
                fix_resinfo(ctx, target, ac_build_image_opcode(&ctx->ac, &args));
+
+       if (inst->Instruction.Opcode == TGSI_OPCODE_RESQ &&
+           (target == TGSI_TEXTURE_2D_MSAA ||
+            target == TGSI_TEXTURE_2D_ARRAY_MSAA)) {
+               LLVMValueRef samples =
+                       ac_build_image_get_sample_count(&ctx->ac, args.resource);
+
+               emit_data->output[emit_data->chan] =
+                       LLVMBuildInsertElement(ctx->ac.builder,
+                                              emit_data->output[emit_data->chan],
+                                              samples,
+                                              LLVMConstInt(ctx->i32, 3, 0), "");
+       }
 }
 
 /**
@@ -1092,7 +1126,7 @@ static void tex_fetch_ptrs(struct lp_build_tgsi_context *bld_base,
                           LLVMValueRef *fmask_ptr)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       LLVMValueRef list = LLVMGetParam(ctx->main_fn, ctx->param_samplers_and_images);
+       LLVMValueRef list = ac_get_arg(&ctx->ac, ctx->samplers_and_images);
        const struct tgsi_full_instruction *inst = emit_data->inst;
        const struct tgsi_full_src_register *reg;
        unsigned target = inst->Texture.Texture;
@@ -1108,7 +1142,7 @@ static void tex_fetch_ptrs(struct lp_build_tgsi_context *bld_base,
                                                      reg->Register.Index,
                                                      ctx->num_samplers);
                index = LLVMBuildAdd(ctx->ac.builder, index,
-                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), "");
+                                    LLVMConstInt(ctx->i32, SI_NUM_IMAGE_SLOTS / 2, 0), "");
        } else {
                index = LLVMConstInt(ctx->i32,
                                     si_get_sampler_slot(reg->Register.Index), 0);
@@ -1118,8 +1152,7 @@ static void tex_fetch_ptrs(struct lp_build_tgsi_context *bld_base,
                /* Bindless descriptors are accessible from a different pair of
                 * user SGPR indices.
                 */
-               list = LLVMGetParam(ctx->main_fn,
-                                   ctx->param_bindless_samplers_and_images);
+               list = ac_get_arg(&ctx->ac, ctx->bindless_samplers_and_images);
                index = lp_build_emit_fetch_src(bld_base, reg,
                                                TGSI_TYPE_UNSIGNED, 0);
 
@@ -1457,7 +1490,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
                        num_src_deriv_channels = 1;
 
                        /* 1D textures are allocated and used as 2D on GFX9. */
-                       if (ctx->screen->info.chip_class >= GFX9) {
+                       if (ctx->screen->info.chip_class == GFX9) {
                                num_dst_deriv_channels = 2;
                        } else {
                                num_dst_deriv_channels = 1;
@@ -1499,7 +1532,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
        }
 
        /* 1D textures are allocated and used as 2D on GFX9. */
-       if (ctx->screen->info.chip_class >= GFX9) {
+       if (ctx->screen->info.chip_class == GFX9) {
                LLVMValueRef filler;
 
                /* Use 0.5, so that we don't sample the border color. */
@@ -1681,30 +1714,17 @@ static void si_llvm_emit_txqs(
        struct lp_build_emit_data *emit_data)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       LLVMValueRef res, samples;
-       LLVMValueRef res_ptr, samp_ptr, fmask_ptr = NULL;
-
-       tex_fetch_ptrs(bld_base, emit_data, &res_ptr, &samp_ptr, &fmask_ptr);
-
-       /* Read the samples from the descriptor directly. */
-       res = LLVMBuildBitCast(ctx->ac.builder, res_ptr, ctx->v8i32, "");
-       samples = LLVMBuildExtractElement(ctx->ac.builder, res,
-                                         LLVMConstInt(ctx->i32, 3, 0), "");
-       samples = LLVMBuildLShr(ctx->ac.builder, samples,
-                               LLVMConstInt(ctx->i32, 16, 0), "");
-       samples = LLVMBuildAnd(ctx->ac.builder, samples,
-                              LLVMConstInt(ctx->i32, 0xf, 0), "");
-       samples = LLVMBuildShl(ctx->ac.builder, ctx->i32_1,
-                              samples, "");
-
-       emit_data->output[emit_data->chan] = samples;
+       LLVMValueRef rsrc;
+
+       tex_fetch_ptrs(bld_base, emit_data, &rsrc, NULL, NULL);
+
+       rsrc = LLVMBuildBitCast(ctx->ac.builder, rsrc, ctx->v8i32, "");
+       emit_data->output[emit_data->chan] =
+               ac_build_image_get_sample_count(&ctx->ac, rsrc);
 }
 
-static void si_llvm_emit_fbfetch(const struct lp_build_tgsi_action *action,
-                                struct lp_build_tgsi_context *bld_base,
-                                struct lp_build_emit_data *emit_data)
+static LLVMValueRef si_llvm_emit_fbfetch(struct si_shader_context *ctx)
 {
-       struct si_shader_context *ctx = si_shader_context(bld_base);
        struct ac_image_args args = {};
        LLVMValueRef ptr, image, fmask;
 
@@ -1714,7 +1734,7 @@ static void si_llvm_emit_fbfetch(const struct lp_build_tgsi_action *action,
 
        /* Load the image descriptor. */
        STATIC_ASSERT(SI_PS_IMAGE_COLORBUF0 % 2 == 0);
-       ptr = LLVMGetParam(ctx->main_fn, ctx->param_rw_buffers);
+       ptr = ac_get_arg(&ctx->ac, ctx->rw_buffers);
        ptr = LLVMBuildPointerCast(ctx->ac.builder, ptr,
                                   ac_array_in_const32_addr_space(ctx->v8i32), "");
        image = ac_build_load_to_sgpr(&ctx->ac, ptr,
@@ -1722,14 +1742,14 @@ static void si_llvm_emit_fbfetch(const struct lp_build_tgsi_action *action,
 
        unsigned chan = 0;
 
-       args.coords[chan++] = si_unpack_param(ctx, SI_PARAM_POS_FIXED_PT, 0, 16);
+       args.coords[chan++] = si_unpack_param(ctx, ctx->pos_fixed_pt, 0, 16);
 
        if (!ctx->shader->key.mono.u.ps.fbfetch_is_1D)
-               args.coords[chan++] = si_unpack_param(ctx, SI_PARAM_POS_FIXED_PT, 16, 16);
+               args.coords[chan++] = si_unpack_param(ctx, ctx->pos_fixed_pt, 16, 16);
 
        /* Get the current render target layer index. */
        if (ctx->shader->key.mono.u.ps.fbfetch_layered)
-               args.coords[chan++] = si_unpack_param(ctx, SI_PARAM_ANCILLARY, 16, 11);
+               args.coords[chan++] = si_unpack_param(ctx, ctx->args.ancillary, 16, 11);
 
        if (ctx->shader->key.mono.u.ps.fbfetch_msaa)
                args.coords[chan++] = si_get_sample_id(ctx);
@@ -1758,8 +1778,23 @@ static void si_llvm_emit_fbfetch(const struct lp_build_tgsi_action *action,
                args.dim = ctx->shader->key.mono.u.ps.fbfetch_layered ?
                        ac_image_2darray : ac_image_2d;
 
-       emit_data->output[emit_data->chan] =
-               ac_build_image_opcode(&ctx->ac, &args);
+       return ac_build_image_opcode(&ctx->ac, &args);
+}
+
+static void si_tgsi_emit_fbfetch(const struct lp_build_tgsi_action *action,
+                                struct lp_build_tgsi_context *bld_base,
+                                struct lp_build_emit_data *emit_data)
+{
+       struct si_shader_context *ctx = si_shader_context(bld_base);
+
+       emit_data->output[emit_data->chan] = si_llvm_emit_fbfetch(ctx);
+}
+
+LLVMValueRef si_nir_emit_fbfetch(struct ac_shader_abi *abi)
+{
+       struct si_shader_context *ctx = si_shader_context_from_abi(abi);
+
+       return si_llvm_emit_fbfetch(ctx);
 }
 
 /**
@@ -1785,7 +1820,7 @@ void si_shader_context_init_mem(struct si_shader_context *ctx)
        bld_base->op_actions[TGSI_OPCODE_LODQ].emit = build_tex_intrinsic;
        bld_base->op_actions[TGSI_OPCODE_TXQS].emit = si_llvm_emit_txqs;
 
-       bld_base->op_actions[TGSI_OPCODE_FBFETCH].emit = si_llvm_emit_fbfetch;
+       bld_base->op_actions[TGSI_OPCODE_FBFETCH].emit = si_tgsi_emit_fbfetch;
 
        bld_base->op_actions[TGSI_OPCODE_LOAD].emit = load_emit;
        bld_base->op_actions[TGSI_OPCODE_STORE].emit = store_emit;
@@ -1811,4 +1846,8 @@ void si_shader_context_init_mem(struct si_shader_context *ctx)
        bld_base->op_actions[TGSI_OPCODE_ATOMIMIN].intr_name = "smin";
        bld_base->op_actions[TGSI_OPCODE_ATOMIMAX].emit = atomic_emit;
        bld_base->op_actions[TGSI_OPCODE_ATOMIMAX].intr_name = "smax";
+       bld_base->op_actions[TGSI_OPCODE_ATOMINC_WRAP].emit = atomic_emit;
+       bld_base->op_actions[TGSI_OPCODE_ATOMINC_WRAP].intr_name = "inc";
+       bld_base->op_actions[TGSI_OPCODE_ATOMDEC_WRAP].emit = atomic_emit;
+       bld_base->op_actions[TGSI_OPCODE_ATOMDEC_WRAP].intr_name = "dec";
 }