ilo: add support for indirect access of CONST in FS

Unlike other register files, CONST is read with a message and indirect access
is easier to implement.
This commit is contained in:
Chia-I Wu 2013-05-27 12:09:33 +08:00
parent 8e7987cc49
commit 3a5dd39b1d
2 changed files with 99 additions and 2 deletions

View file

@ -132,7 +132,7 @@ ilo_get_shader_param(struct pipe_screen *screen, unsigned shader,
case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
return (shader == PIPE_SHADER_FRAGMENT) ? 0 : 1;
case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
return (shader == PIPE_SHADER_FRAGMENT) ? 0 : 1;
return 1;
case PIPE_SHADER_CAP_SUBROUTINES:
return 0;
case PIPE_SHADER_CAP_INTEGERS:
@ -395,6 +395,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return false; /* TODO push constants */
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
/* imposed by OWord (Dual) Block Read */
return 16;
case PIPE_CAP_START_INSTANCE:
case PIPE_CAP_QUERY_TIMESTAMP:

View file

@ -250,6 +250,62 @@ fs_lower_opcode_tgsi_in(struct fs_compile_context *fcc,
}
}
static void
fs_lower_opcode_tgsi_indirect_const(struct fs_compile_context *fcc,
struct toy_dst dst, int dim,
struct toy_src idx)
{
const struct toy_dst offset =
tdst_ud(tdst(TOY_FILE_MRF, fcc->first_free_mrf, 0));
struct toy_compiler *tc = &fcc->tc;
unsigned simd_mode, param_size;
struct toy_inst *inst;
struct toy_src desc, real_src[4];
struct toy_dst tmp, real_dst[4];
int i;
tsrc_transpose(idx, real_src);
/* set offset */
inst = tc_MOV(tc, offset, real_src[0]);
inst->mask_ctrl = BRW_MASK_DISABLE;
switch (inst->exec_size) {
case BRW_EXECUTE_8:
simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
param_size = 1;
break;
case BRW_EXECUTE_16:
simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
param_size = 2;
break;
default:
assert(!"unsupported execution size");
tc_MOV(tc, dst, tsrc_imm_f(0.0f));
return;
break;
}
desc = tsrc_imm_mdesc_sampler(tc, param_size, param_size * 4, false,
simd_mode,
GEN5_SAMPLER_MESSAGE_SAMPLE_LD,
0,
ILO_WM_CONST_SURFACE(dim));
tmp = tdst(TOY_FILE_VRF, tc_alloc_vrf(tc, param_size * 4), 0);
inst = tc_SEND(tc, tmp, tsrc_from(offset), desc, BRW_SFID_SAMPLER);
inst->mask_ctrl = BRW_MASK_DISABLE;
tdst_transpose(dst, real_dst);
for (i = 0; i < 4; i++) {
const struct toy_src src =
tsrc_offset(tsrc_from(tmp), param_size * i, 0);
/* cast to type D to make sure these are raw moves */
tc_MOV(tc, tdst_d(real_dst[i]), tsrc_d(src));
}
}
static void
fs_lower_opcode_tgsi_const_gen6(struct fs_compile_context *fcc,
struct toy_dst dst, int dim, struct toy_src idx)
@ -425,7 +481,47 @@ static void
fs_lower_opcode_tgsi_indirect(struct fs_compile_context *fcc,
struct toy_inst *inst)
{
tc_fail(&fcc->tc, "no TGSI indirection support");
struct toy_compiler *tc = &fcc->tc;
enum tgsi_file_type file;
int dim, idx;
struct toy_src indirect_dim, indirect_idx;
assert(inst->src[0].file == TOY_FILE_IMM);
file = inst->src[0].val32;
assert(inst->src[1].file == TOY_FILE_IMM);
dim = inst->src[1].val32;
indirect_dim = inst->src[2];
assert(inst->src[3].file == TOY_FILE_IMM);
idx = inst->src[3].val32;
indirect_idx = inst->src[4];
/* no dimension indirection */
assert(indirect_dim.file == TOY_FILE_IMM);
dim += indirect_dim.val32;
switch (inst->opcode) {
case TOY_OPCODE_TGSI_INDIRECT_FETCH:
if (file == TGSI_FILE_CONSTANT) {
if (idx) {
struct toy_dst tmp = tc_alloc_tmp(tc);
tc_ADD(tc, tmp, indirect_idx, tsrc_imm_d(idx));
indirect_idx = tsrc_from(tmp);
}
fs_lower_opcode_tgsi_indirect_const(fcc, inst->dst, dim, indirect_idx);
break;
}
/* fall through */
case TOY_OPCODE_TGSI_INDIRECT_STORE:
default:
tc_fail(tc, "unhandled TGSI indirection");
break;
}
tc_discard_inst(tc, inst);
}
/**