shader->two_side = key.ps.color_two_side;
shader->atomic_base = key.ps.first_atomic_counter;
shader->rat_base = key.ps.nr_cbufs;
+ shader->image_size_const_offset = key.ps.image_size_const_offset;
break;
default:
break;
return 0;
}
-static int r600_do_buffer_txq(struct r600_shader_ctx *ctx)
+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, 1);
+ int id = tgsi_tex_get_src_gpr(ctx, reg_idx) + offset;
memset(&alu, 0, sizeof(struct r600_bytecode_alu));
alu.op = ALU_OP1_MOV;
if (inst->Texture.Texture == TGSI_TEXTURE_BUFFER) {
if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
ctx->shader->uses_tex_buffers = true;
- return r600_do_buffer_txq(ctx);
+ return r600_do_buffer_txq(ctx, 1, 0);
}
else if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
if (ctx->bc->chip_class < EVERGREEN)
return 0;
}
+static int tgsi_resq(struct r600_shader_ctx *ctx)
+{
+ struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ unsigned sampler_index_mode;
+ struct r600_bytecode_tex tex;
+ int r;
+ boolean has_txq_cube_array_z = false;
+
+ if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
+ ctx->shader->uses_tex_buffers = true;
+ return r600_do_buffer_txq(ctx, 0, ctx->shader->image_size_const_offset);
+ }
+
+ if (inst->Memory.Texture == TGSI_TEXTURE_CUBE_ARRAY &&
+ inst->Dst[0].Register.WriteMask & 4) {
+ ctx->shader->has_txq_cube_array_z_comp = true;
+ has_txq_cube_array_z = true;
+ }
+
+ sampler_index_mode = inst->Src[0].Indirect.Index == 2 ? 2 : 0; // CF_INDEX_1 : CF_INDEX_NONE
+ if (sampler_index_mode)
+ egcm_load_index_reg(ctx->bc, 1, false);
+
+
+ /* does this shader want a num layers from TXQ for a cube array? */
+ if (has_txq_cube_array_z) {
+ int id = tgsi_tex_get_src_gpr(ctx, 0) + ctx->shader->image_size_const_offset;
+ 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;
+ /* channel 1 or 3 of each word */
+ alu.src[0].sel += (id / 2);
+ alu.src[0].chan = ((id % 2) * 2) + 1;
+ alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
+ tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+ alu.last = 1;
+ r = r600_bytecode_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+ /* disable writemask from texture instruction */
+ inst->Dst[0].Register.WriteMask &= ~4;
+ }
+ memset(&tex, 0, sizeof(struct r600_bytecode_tex));
+ tex.op = ctx->inst_info->op;
+ tex.sampler_id = R600_IMAGE_REAL_RESOURCE_OFFSET + inst->Src[0].Register.Index;
+ tex.sampler_index_mode = sampler_index_mode;
+ tex.resource_id = tex.sampler_id;
+ tex.resource_index_mode = sampler_index_mode;
+ tex.src_sel_x = 4;
+ tex.src_sel_y = 4;
+ tex.src_sel_z = 4;
+ tex.src_sel_w = 4;
+ tex.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7;
+ tex.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7;
+ tex.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7;
+ tex.dst_sel_w = (inst->Dst[0].Register.WriteMask & 8) ? 3 : 7;
+ tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
+ r = r600_bytecode_add_tex(ctx->bc, &tex);
+ if (r)
+ return r;
+
+ return 0;
+}
+
static int tgsi_lrp(struct r600_shader_ctx *ctx)
{
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
[TGSI_OPCODE_ENDSUB] = { ALU_OP0_NOP, tgsi_unsupported},
[103] = { FETCH_OP_GET_TEXTURE_RESINFO, tgsi_tex},
[TGSI_OPCODE_TXQS] = { FETCH_OP_GET_NUMBER_OF_SAMPLES, tgsi_tex},
- [TGSI_OPCODE_RESQ] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_RESQ] = { FETCH_OP_GET_TEXTURE_RESINFO, tgsi_resq},
[106] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_NOP] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_FSEQ] = { ALU_OP2_SETE_DX10, tgsi_op2},
[TGSI_OPCODE_ENDSUB] = { ALU_OP0_NOP, tgsi_unsupported},
[103] = { FETCH_OP_GET_TEXTURE_RESINFO, tgsi_tex},
[TGSI_OPCODE_TXQS] = { FETCH_OP_GET_NUMBER_OF_SAMPLES, tgsi_tex},
- [TGSI_OPCODE_RESQ] = { ALU_OP0_NOP, tgsi_unsupported},
+ [TGSI_OPCODE_RESQ] = { FETCH_OP_GET_TEXTURE_RESINFO, tgsi_resq},
[106] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_NOP] = { ALU_OP0_NOP, tgsi_unsupported},
[TGSI_OPCODE_FSEQ] = { ALU_OP2_SETE_DX10, tgsi_op2},
key->gs.tri_strip_adj_fix = rctx->gs_tri_strip_adj_fix;
break;
case PIPE_SHADER_FRAGMENT: {
+ if (rctx->ps_shader->info.images_declared)
+ key->ps.image_size_const_offset = util_last_bit(rctx->samplers[PIPE_SHADER_FRAGMENT].views.enabled_mask);
key->ps.first_atomic_counter = r600_get_hw_atomic_count(ctx, PIPE_SHADER_FRAGMENT);
key->ps.color_two_side = rctx->rasterizer && rctx->rasterizer->two_side;
key->ps.alpha_to_one = rctx->alpha_to_one &&
static void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
{
struct r600_textures_info *samplers = &rctx->samplers[shader_type];
- int bits;
+ struct r600_image_state *images = NULL;
+ int bits, sview_bits;
uint32_t array_size;
int i;
uint32_t *constants;
uint32_t base_offset;
- if (!samplers->views.dirty_buffer_constants)
+
+ if (shader_type == PIPE_SHADER_FRAGMENT)
+ images = &rctx->fragment_images;
+
+ if (!samplers->views.dirty_buffer_constants &&
+ (images && !images->dirty_buffer_constants))
return;
+ if (images)
+ images->dirty_buffer_constants = FALSE;
samplers->views.dirty_buffer_constants = FALSE;
- bits = util_last_bit(samplers->views.enabled_mask);
+ bits = sview_bits = util_last_bit(samplers->views.enabled_mask);
+ if (images)
+ bits += util_last_bit(images->enabled_mask);
array_size = bits * 2 * sizeof(uint32_t) * 4;
constants = r600_alloc_buf_consts(rctx, shader_type, array_size,
&base_offset);
- for (i = 0; i < bits; i++) {
+ for (i = 0; i < sview_bits; i++) {
if (samplers->views.enabled_mask & (1 << i)) {
uint32_t offset = (base_offset / 4) + i * 2;
constants[offset] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
constants[offset + 1] = samplers->views.views[i]->base.texture->array_size / 6;
}
}
+ if (images) {
+ for (i = sview_bits; i < bits; i++) {
+ int idx = i - sview_bits;
+ if (images->enabled_mask & (1 << idx)) {
+ uint32_t offset = (base_offset / 4) + i * 2;
+ constants[offset] = images->views[i].base.resource->width0 / util_format_get_blocksize(images->views[i].base.format);
+ constants[offset + 1] = images->views[i].base.resource->array_size / 6;
+ }
+ }
+ }
}
/* set sample xy locations as array of fragment shader constants */