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