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_tc(ctx->bc, &vtx)))
+ 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;
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) {
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 {
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);
}
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;
}
/* 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;
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,
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) {
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;
}
}
}