summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-05-27 12:09:33 +0800
committerChia-I Wu <[email protected]>2013-05-27 12:30:51 +0800
commit3a5dd39b1d8247791f7ba7eedb78654d1ecabe82 (patch)
treedf3bdcf4581f1b12822a1f06a89beca4a3c25283 /src/gallium
parent8e7987cc4940909fde3fdde44c31c0ddfa276bb0 (diff)
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.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/ilo_screen.c3
-rw-r--r--src/gallium/drivers/ilo/shader/ilo_shader_fs.c98
2 files changed, 99 insertions, 2 deletions
diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
index 40558b3c0c0..264c338816a 100644
--- a/src/gallium/drivers/ilo/ilo_screen.c
+++ b/src/gallium/drivers/ilo/ilo_screen.c
@@ -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:
diff --git a/src/gallium/drivers/ilo/shader/ilo_shader_fs.c b/src/gallium/drivers/ilo/shader/ilo_shader_fs.c
index 0a7921b25ff..b414b50365c 100644
--- a/src/gallium/drivers/ilo/shader/ilo_shader_fs.c
+++ b/src/gallium/drivers/ilo/shader/ilo_shader_fs.c
@@ -251,6 +251,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);
}
/**