From: Roland Scheidegger <srol...@vmware.com>

Contrary to what the comment said, this appears to work just fine on my rv770
(tested with piglit textureSize 140 fs/vs samplerBuffer).
I have no clue though if it's actually preferrable to use it (unfortunately
we cannot get rid of the tex constants completely, as we still require them
for cube map txq).
Albeit filling in the format (1 channels or 4?) and the stuff related to mega-
or mini-fetch (what the hell is this...) is just a guess based on other usage
of vtx fetch instructions...
The docs (for eg, not cayman) suggests this has to be done through tc cache
but it seems to work either way (since it actually just fetches the value from
the buffer descriptor I'm not sure why caches would be involved).
---
 src/gallium/drivers/r600/evergreen_state.c   |  7 ++--
 src/gallium/drivers/r600/r600_asm.c          |  3 +-
 src/gallium/drivers/r600/r600_shader.c       | 59 ++++++++++++++++++----------
 src/gallium/drivers/r600/r600_state_common.c | 39 +++---------------
 4 files changed, 50 insertions(+), 58 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index f5b8e7115d..f645791a2c 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -653,11 +653,12 @@ static void evergreen_fill_buffer_resource_words(struct 
r600_context *rctx,
                S_030008_ENDIAN_SWAP(endian);
        tex_resource_words[3] = swizzle_res | 
S_03000C_UNCACHED(params->uncached);
        /*
-        * in theory dword 4 is for number of elements, for use with resinfo,
-        * but it seems to utterly fail to work, the amd gpu shader analyser
+        * dword 4 is for number of elements, for use with resinfo,
+        * albeit the amd gpu shader analyser
         * uses a const buffer to store the element sizes for buffer txq
         */
-       tex_resource_words[4] = 0;
+       tex_resource_words[4] = params->size / stride;
+
        tex_resource_words[5] = tex_resource_words[6] = 0;
        tex_resource_words[7] = S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_BUFFER);
 }
diff --git a/src/gallium/drivers/r600/r600_asm.c 
b/src/gallium/drivers/r600/r600_asm.c
index d6bd561f01..92c2bdf27c 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1510,7 +1510,8 @@ int cm_bytecode_add_cf_end(struct r600_bytecode *bc)
 /* common to all 3 families */
 static int r600_bytecode_vtx_build(struct r600_bytecode *bc, struct 
r600_bytecode_vtx *vtx, unsigned id)
 {
-       bc->bytecode[id] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
+       bc->bytecode[id] = S_SQ_VTX_WORD0_VTX_INST(vtx->op) |
+                       S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
                        S_SQ_VTX_WORD0_FETCH_TYPE(vtx->fetch_type) |
                        S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
                        S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x);
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 8a36bcf1b4..51c38a6e00 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -6949,31 +6949,48 @@ static int do_vtx_fetch_inst(struct r600_shader_ctx 
*ctx, boolean src_requires_l
 static int r600_do_buffer_txq(struct r600_shader_ctx *ctx, int reg_idx, int 
offset)
 {
        struct tgsi_full_instruction *inst = 
&ctx->parse.FullToken.FullInstruction;
-       struct r600_bytecode_alu alu;
        int r;
        int id = tgsi_tex_get_src_gpr(ctx, reg_idx) + offset;
+       int sampler_index_mode = inst->Src[reg_idx].Indirect.Index == 2 ? 2 : 
0; // CF_INDEX_1 : CF_INDEX_NONE
 
-       memset(&alu, 0, sizeof(struct r600_bytecode_alu));
-       alu.op = ALU_OP1_MOV;
-       alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
-       if (ctx->bc->chip_class >= EVERGREEN) {
-               /* with eg each dword is either buf size or number of cubes */
-               alu.src[0].sel += id / 4;
-               alu.src[0].chan = id % 4;
-       } else {
+       if (ctx->bc->chip_class < EVERGREEN) {
+               struct r600_bytecode_alu alu;
+               memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+               alu.op = ALU_OP1_MOV;
+               alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
                /* r600 we have them at channel 2 of the second dword */
                alu.src[0].sel += (id * 2) + 1;
                alu.src[0].chan = 1;
+               alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
+               tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
+               alu.last = 1;
+               r = r600_bytecode_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+               return 0;
+       } else {
+               struct r600_bytecode_vtx vtx;
+               memset(&vtx, 0, sizeof(vtx));
+               vtx.op = FETCH_OP_GDS_MIN_UINT; /* aka GET_BUFFER_RESINFO */
+               vtx.buffer_id = id + R600_MAX_CONST_BUFFERS;
+               vtx.fetch_type = SQ_VTX_FETCH_NO_INDEX_OFFSET;
+               vtx.src_gpr = 0;
+               vtx.mega_fetch_count = 16; /* no idea here really... */
+               vtx.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + 
inst->Dst[0].Register.Index;
+               vtx.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7;  
        /* SEL_X */
+               vtx.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 4 : 7;  
        /* SEL_Y */
+               vtx.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 4 : 7;  
        /* SEL_Z */
+               vtx.dst_sel_w = (inst->Dst[0].Register.WriteMask & 8) ? 4 : 7;  
        /* SEL_W */
+               vtx.data_format = FMT_32_32_32_32;
+               vtx.buffer_index_mode = sampler_index_mode;
+
+               if ((r = r600_bytecode_add_vtx(ctx->bc, &vtx))) /* add_vtx_tc 
works as well */
+                       return r;
+               return 0;
        }
-       alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
-       tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
-       alu.last = 1;
-       r = r600_bytecode_add_alu(ctx->bc, &alu);
-       if (r)
-               return r;
-       return 0;
 }
 
+
 static int tgsi_tex(struct r600_shader_ctx *ctx)
 {
        struct tgsi_full_instruction *inst = 
&ctx->parse.FullToken.FullInstruction;
@@ -7027,7 +7044,8 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
        if (inst->Texture.Texture == TGSI_TEXTURE_BUFFER) {
                if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
-                       ctx->shader->uses_tex_buffers = true;
+                       if (ctx->bc->chip_class < EVERGREEN)
+                               ctx->shader->uses_tex_buffers = true;
                        return r600_do_buffer_txq(ctx, 1, 0);
                }
                else if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
@@ -7617,7 +7635,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
                alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
                if (ctx->bc->chip_class >= EVERGREEN) {
-                       /* with eg each dword is either buf size or number of 
cubes */
+                       /* with eg each dword is number of cubes */
                        alu.src[0].sel += id / 4;
                        alu.src[0].chan = id % 4;
                } else {
@@ -8760,7 +8778,8 @@ static int tgsi_resq(struct r600_shader_ctx *ctx)
 
        if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
            (inst->Src[0].Register.File == TGSI_FILE_IMAGE && 
inst->Memory.Texture == TGSI_TEXTURE_BUFFER)) {
-               ctx->shader->uses_tex_buffers = true;
+               if (ctx->bc->chip_class < EVERGREEN)
+                       ctx->shader->uses_tex_buffers = true;
                return r600_do_buffer_txq(ctx, 0, 
ctx->shader->image_size_const_offset);
        }
 
@@ -8784,7 +8803,7 @@ static int tgsi_resq(struct r600_shader_ctx *ctx)
                alu.op = ALU_OP1_MOV;
 
                alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
-               /* with eg each dword is either buf size or number of cubes */
+               /* with eg each dword is either number of cubes */
                alu.src[0].sel += id / 4;
                alu.src[0].chan = id % 4;
                alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index 4429246d31..b3b2fd09ef 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1357,14 +1357,12 @@ static void r600_setup_buffer_constants(struct 
r600_context *rctx, int shader_ty
 }
 
 /* On evergreen we store one value
- * 1. buffer size for TXQ or
- * 2. number of cube layers in a cube map array.
+ * 1. number of cube layers in a cube map array.
  */
 void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
 {
        struct r600_textures_info *samplers = &rctx->samplers[shader_type];
        struct r600_image_state *images = NULL;
-       struct r600_image_state *buffers = NULL;
        int bits, sview_bits, img_bits;
        uint32_t array_size;
        int i;
@@ -1373,29 +1371,23 @@ void eg_setup_buffer_constants(struct r600_context 
*rctx, int shader_type)
 
        if (shader_type == PIPE_SHADER_FRAGMENT) {
                images = &rctx->fragment_images;
-               buffers = &rctx->fragment_buffers;
        } else if (shader_type == PIPE_SHADER_COMPUTE) {
                images = &rctx->compute_images;
-               buffers = &rctx->compute_buffers;
        }
 
        if (!samplers->views.dirty_buffer_constants &&
-           !(images && images->dirty_buffer_constants) &&
-           !(buffers && buffers->dirty_buffer_constants))
+           !(images && images->dirty_buffer_constants))
                return;
 
        if (images)
                images->dirty_buffer_constants = FALSE;
-       if (buffers)
-               buffers->dirty_buffer_constants = FALSE;
        samplers->views.dirty_buffer_constants = FALSE;
 
        bits = sview_bits = util_last_bit(samplers->views.enabled_mask);
        if (images)
                bits += util_last_bit(images->enabled_mask);
        img_bits = bits;
-       if (buffers)
-               bits += util_last_bit(buffers->enabled_mask);
+
        array_size = bits * sizeof(uint32_t);
 
        constants = r600_alloc_buf_consts(rctx, shader_type, array_size,
@@ -1404,12 +1396,7 @@ void eg_setup_buffer_constants(struct r600_context 
*rctx, int shader_type)
        for (i = 0; i < sview_bits; i++) {
                if (samplers->views.enabled_mask & (1 << i)) {
                        uint32_t offset = (base_offset / 4) + i;
-                       if (samplers->views.views[i]->base.target == 
PIPE_BUFFER) {
-                               constants[offset] = 
samplers->views.views[i]->base.u.buf.size /
-                                               
util_format_get_blocksize(samplers->views.views[i]->base.format);
-                       } else {
-                               constants[offset] = 
samplers->views.views[i]->base.texture->array_size / 6;
-                       }
+                       constants[offset] = 
samplers->views.views[i]->base.texture->array_size / 6;
                }
        }
        if (images) {
@@ -1417,23 +1404,7 @@ void eg_setup_buffer_constants(struct r600_context 
*rctx, int shader_type)
                        int idx = i - sview_bits;
                        if (images->enabled_mask & (1 << idx)) {
                                uint32_t offset = (base_offset / 4) + i;
-                               if (images->views[i].base.resource->target == 
PIPE_BUFFER) {
-                                       constants[offset] = 
images->views[i].base.u.buf.size /
-                                                       
util_format_get_blocksize(images->views[i].base.format);
-                               } else {
-                                       constants[offset] = 
images->views[i].base.resource->array_size / 6;
-                               }
-                       }
-               }
-       }
-       if (buffers) {
-               for (i = img_bits; i < bits; i++) {
-                       int idx = i - img_bits;
-                       if (buffers->enabled_mask & (1 << idx)) {
-                               uint32_t offset = (base_offset / 4) + i;
-                               assert(buffers->views[i].base.resource->target 
== PIPE_BUFFER);
-                               constants[offset] = 
buffers->views[i].base.u.buf.size /
-                                               
util_format_get_blocksize(buffers->views[i].base.format);
+                               constants[offset] = 
images->views[i].base.resource->array_size / 6;
                        }
                }
        }
-- 
2.12.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to