diff options
author | Chia-I Wu <[email protected]> | 2013-05-27 12:09:33 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2013-05-27 12:30:51 +0800 |
commit | 3a5dd39b1d8247791f7ba7eedb78654d1ecabe82 (patch) | |
tree | df3bdcf4581f1b12822a1f06a89beca4a3c25283 /src/gallium | |
parent | 8e7987cc4940909fde3fdde44c31c0ddfa276bb0 (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.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/shader/ilo_shader_fs.c | 98 |
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); } /** |