From: Marek Olšák <[email protected]>

This massively decreases VGPR spilling for DiRT Showdown, because we
no longer have to use v4i32 for 2D fetches when level == 0.
We now use v2i32 for those cases.

DiRT Showdown - Spilled VGPRs: -26 (-81%)

This surprisingly doesn't have any useful effect on performance (+ 0.05%).
---
 src/gallium/drivers/radeonsi/si_pipe.c   |  2 +-
 src/gallium/drivers/radeonsi/si_shader.c | 20 +++++++++++++++-----
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.c 
b/src/gallium/drivers/radeonsi/si_pipe.c
index 099ef4c..c0b61f1 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -409,20 +409,21 @@ static int si_get_param(struct pipe_screen* pscreen, enum 
pipe_cap param)
        case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
        case PIPE_CAP_STRING_MARKER:
        case PIPE_CAP_CLEAR_TEXTURE:
        case PIPE_CAP_CULL_DISTANCE:
        case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
        case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
        case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
        case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
        case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
        case PIPE_CAP_DOUBLES:
+       case PIPE_CAP_TGSI_TEX_TXF_LZ:
                return 1;
 
        case PIPE_CAP_INT64:
        case PIPE_CAP_INT64_DIVMOD:
                return HAVE_LLVM >= 0x0309;
 
        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
                return !SI_BIG_ENDIAN && sscreen->b.info.has_userptr;
 
        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
@@ -475,21 +476,20 @@ static int si_get_param(struct pipe_screen* pscreen, enum 
pipe_cap param)
        case PIPE_CAP_FAKE_SW_MSAA:
        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
        case PIPE_CAP_VERTEXID_NOBASE:
        case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
        case PIPE_CAP_TGSI_VOTE:
        case PIPE_CAP_MAX_WINDOW_RECTANGLES:
        case PIPE_CAP_NATIVE_FENCE_FD:
        case PIPE_CAP_TGSI_FS_FBFETCH:
        case PIPE_CAP_TGSI_MUL_ZERO_WINS:
        case PIPE_CAP_UMA:
-       case PIPE_CAP_TGSI_TEX_TXF_LZ:
                return 0;
 
        case PIPE_CAP_QUERY_BUFFER_OBJECT:
                return si_have_tgsi_compute(sscreen);
 
        case PIPE_CAP_DRAW_PARAMETERS:
        case PIPE_CAP_MULTI_DRAW_INDIRECT:
        case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
                return sscreen->has_draw_indirect_multi;
 
diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 2c98715..1b7854e 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -4404,21 +4404,23 @@ static void tex_fetch_args(
                        coords[chan] = lp_build_emit_llvm_binary(bld_base,
                                                                 
TGSI_OPCODE_DIV,
                                                                 coords[chan],
                                                                 coords[3]);
        }
 
        if (opcode == TGSI_OPCODE_TXP)
                coords[3] = bld_base->base.one;
 
        /* Pack offsets. */
-       if (has_offset && opcode != TGSI_OPCODE_TXF) {
+       if (has_offset &&
+           opcode != TGSI_OPCODE_TXF &&
+           opcode != TGSI_OPCODE_TXF_LZ) {
                /* The offsets are six-bit signed integers packed like this:
                 *   X=[5:0], Y=[13:8], and Z=[21:16].
                 */
                LLVMValueRef offset[3], pack;
 
                assert(inst->Texture.NumOffsets == 1);
 
                for (chan = 0; chan < 3; chan++) {
                        offset[chan] = lp_build_emit_fetch_texoffset(bld_base,
                                                                     
emit_data->inst, 0, chan);
@@ -4562,22 +4564,22 @@ static void tex_fetch_args(
            target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
                struct lp_build_context *uint_bld = &bld_base->uint_bld;
                struct lp_build_emit_data txf_emit_data = *emit_data;
                LLVMValueRef txf_address[4];
                /* We only need .xy for non-arrays, and .xyz for arrays. */
                unsigned txf_count = target == TGSI_TEXTURE_2D_MSAA ? 2 : 3;
                struct tgsi_full_instruction inst = {};
 
                memcpy(txf_address, address, sizeof(txf_address));
 
-               /* Read FMASK using TXF. */
-               inst.Instruction.Opcode = TGSI_OPCODE_TXF;
+               /* Read FMASK using TXF_LZ. */
+               inst.Instruction.Opcode = TGSI_OPCODE_TXF_LZ;
                inst.Texture.Texture = target;
                txf_emit_data.inst = &inst;
                txf_emit_data.chan = 0;
                set_tex_fetch_args(ctx, &txf_emit_data,
                                   target, fmask_ptr, NULL,
                                   txf_address, txf_count, 0xf);
                build_tex_intrinsic(&tex_action, bld_base, &txf_emit_data);
 
                /* Initialize some constants. */
                LLVMValueRef four = LLVMConstInt(ctx->i32, 4, 0);
@@ -4614,21 +4616,22 @@ static void tex_fetch_args(
                LLVMValueRef word1_is_nonzero =
                        LLVMBuildICmp(gallivm->builder, LLVMIntNE,
                                      fmask_word1, uint_bld->zero, "");
 
                /* Replace the MSAA sample index. */
                address[sample_chan] =
                        LLVMBuildSelect(gallivm->builder, word1_is_nonzero,
                                        final_sample, address[sample_chan], "");
        }
 
-       if (opcode == TGSI_OPCODE_TXF) {
+       if (opcode == TGSI_OPCODE_TXF ||
+           opcode == TGSI_OPCODE_TXF_LZ) {
                /* add tex offsets */
                if (inst->Texture.NumOffsets) {
                        struct lp_build_context *uint_bld = &bld_base->uint_bld;
                        const struct tgsi_texture_offset *off = 
inst->TexOffsets;
 
                        assert(inst->Texture.NumOffsets == 1);
 
                        switch (target) {
                        case TGSI_TEXTURE_3D:
                                address[2] = lp_build_add(uint_bld, address[2],
@@ -4776,37 +4779,42 @@ static void build_tex_intrinsic(const struct 
lp_build_tgsi_action *action,
        }
 
        memcpy(&args, emit_data->args, sizeof(args)); /* ugly */
 
        args.opcode = ac_image_sample;
        args.compare = tgsi_is_shadow_target(target);
        args.offset = inst->Texture.NumOffsets > 0;
 
        switch (opcode) {
        case TGSI_OPCODE_TXF:
-               args.opcode = target == TGSI_TEXTURE_2D_MSAA ||
+       case TGSI_OPCODE_TXF_LZ:
+               args.opcode = opcode == TGSI_OPCODE_TXF_LZ ||
+                             target == TGSI_TEXTURE_2D_MSAA ||
                              target == TGSI_TEXTURE_2D_ARRAY_MSAA ?
                                      ac_image_load : ac_image_load_mip;
                args.compare = false;
                args.offset = false;
                break;
        case TGSI_OPCODE_LODQ:
                args.opcode = ac_image_get_lod;
                args.compare = false;
                args.offset = false;
                break;
        case TGSI_OPCODE_TEX:
        case TGSI_OPCODE_TEX2:
        case TGSI_OPCODE_TXP:
                if (ctx->type != PIPE_SHADER_FRAGMENT)
                        args.level_zero = true;
                break;
+       case TGSI_OPCODE_TEX_LZ:
+               args.level_zero = true;
+               break;
        case TGSI_OPCODE_TXB:
        case TGSI_OPCODE_TXB2:
                assert(ctx->type == PIPE_SHADER_FRAGMENT);
                args.bias = true;
                break;
        case TGSI_OPCODE_TXL:
        case TGSI_OPCODE_TXL2:
                args.lod = true;
                break;
        case TGSI_OPCODE_TXD:
@@ -6447,25 +6455,27 @@ static void si_init_shader_ctx(struct si_shader_context 
*ctx,
                (shader && shader->selector) ? shader->selector->tokens : NULL);
 
        bld_base = &ctx->bld_base;
        bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
 
        bld_base->op_actions[TGSI_OPCODE_INTERP_CENTROID] = interp_action;
        bld_base->op_actions[TGSI_OPCODE_INTERP_SAMPLE] = interp_action;
        bld_base->op_actions[TGSI_OPCODE_INTERP_OFFSET] = interp_action;
 
        bld_base->op_actions[TGSI_OPCODE_TEX] = tex_action;
+       bld_base->op_actions[TGSI_OPCODE_TEX_LZ] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TEX2] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXB] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXB2] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXD] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXF] = tex_action;
+       bld_base->op_actions[TGSI_OPCODE_TXF_LZ] = tex_action;
        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].fetch_args = txq_fetch_args;
        bld_base->op_actions[TGSI_OPCODE_TXQ].emit = txq_emit;
        bld_base->op_actions[TGSI_OPCODE_TG4] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_LODQ] = tex_action;
        bld_base->op_actions[TGSI_OPCODE_TXQS].emit = si_llvm_emit_txqs;
 
        bld_base->op_actions[TGSI_OPCODE_LOAD].fetch_args = load_fetch_args;
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to