diff options
author | Marek Olšák <[email protected]> | 2015-05-25 19:30:44 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-06-05 19:44:32 +0200 |
commit | b6ebe7eabf54936a02acc0968e718e0c264a73f5 (patch) | |
tree | 4b9866eed8885275a2f062dbf84e441f6fa8b241 /src/gallium/auxiliary | |
parent | a015b3952f568ad3da1ddfe42ff7ce6568f52780 (diff) |
tgsi/ureg: don't emit in/out arrays if drivers don't support ranged declarations
Softpipe, llvmpipe, r300g, and radeonsi pass tests. Other drivers need testing.
Freedreno and nv30 are definitely broken. Other drivers seem to be alright.
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_limits.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 170 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.h | 6 |
4 files changed, 142 insertions, 36 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_limits.h b/src/gallium/auxiliary/gallivm/lp_bld_limits.h index c5c51c18a0a..49064feddef 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_limits.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_limits.h @@ -125,6 +125,7 @@ gallivm_get_shader_param(enum pipe_shader_cap param) case PIPE_SHADER_CAP_PREFERRED_IR: return PIPE_SHADER_IR_TGSI; case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: return 1; case PIPE_SHADER_CAP_DOUBLES: case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 0f4c966cc11..208640cfd46 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -458,6 +458,7 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param) return 1; case PIPE_SHADER_CAP_DOUBLES: case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: + case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: return 1; case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 76ffe9f79a2..1cea0919ce4 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -26,6 +26,7 @@ **************************************************************************/ +#include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_state.h" #include "tgsi/tgsi_ureg.h" @@ -96,7 +97,7 @@ struct const_decl { struct ureg_program { unsigned processor; - struct pipe_context *pipe; + bool supports_any_inout_decl_range; struct { unsigned semantic_name; @@ -906,7 +907,11 @@ ureg_emit_src( struct ureg_program *ureg, out[n].ind.File = src.IndirectFile; out[n].ind.Swizzle = src.IndirectSwizzle; out[n].ind.Index = src.IndirectIndex; - out[n].ind.ArrayID = src.ArrayID; + if (!ureg->supports_any_inout_decl_range && + (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) + out[n].ind.ArrayID = 0; + else + out[n].ind.ArrayID = src.ArrayID; n++; } @@ -922,7 +927,11 @@ ureg_emit_src( struct ureg_program *ureg, out[n].ind.File = src.DimIndFile; out[n].ind.Swizzle = src.DimIndSwizzle; out[n].ind.Index = src.DimIndIndex; - out[n].ind.ArrayID = src.ArrayID; + if (!ureg->supports_any_inout_decl_range && + (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) + out[n].ind.ArrayID = 0; + else + out[n].ind.ArrayID = src.ArrayID; } else { out[n].dim.Indirect = 0; out[n].dim.Index = src.DimensionIndex; @@ -964,7 +973,11 @@ ureg_emit_dst( struct ureg_program *ureg, out[n].ind.File = dst.IndirectFile; out[n].ind.Swizzle = dst.IndirectSwizzle; out[n].ind.Index = dst.IndirectIndex; - out[n].ind.ArrayID = dst.ArrayID; + if (!ureg->supports_any_inout_decl_range && + (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) + out[n].ind.ArrayID = 0; + else + out[n].ind.ArrayID = dst.ArrayID; n++; } @@ -980,7 +993,11 @@ ureg_emit_dst( struct ureg_program *ureg, out[n].ind.File = dst.DimIndFile; out[n].ind.Swizzle = dst.DimIndSwizzle; out[n].ind.Index = dst.DimIndIndex; - out[n].ind.ArrayID = dst.ArrayID; + if (!ureg->supports_any_inout_decl_range && + (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) + out[n].ind.ArrayID = 0; + else + out[n].ind.ArrayID = dst.ArrayID; } else { out[n].dim.Indirect = 0; out[n].dim.Index = dst.DimensionIndex; @@ -1489,7 +1506,7 @@ emit_property(struct ureg_program *ureg, static void emit_decls( struct ureg_program *ureg ) { - unsigned i; + unsigned i,j; for (i = 0; i < Elements(ureg->properties); i++) if (ureg->properties[i] != ~0) @@ -1502,28 +1519,60 @@ static void emit_decls( struct ureg_program *ureg ) } } } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) { - for (i = 0; i < ureg->nr_inputs; i++) { - emit_decl_fs(ureg, - TGSI_FILE_INPUT, - ureg->input[i].first, - ureg->input[i].last, - ureg->input[i].semantic_name, - ureg->input[i].semantic_index, - ureg->input[i].interp, - ureg->input[i].cylindrical_wrap, - ureg->input[i].interp_location, - ureg->input[i].array_id); + if (ureg->supports_any_inout_decl_range) { + for (i = 0; i < ureg->nr_inputs; i++) { + emit_decl_fs(ureg, + TGSI_FILE_INPUT, + ureg->input[i].first, + ureg->input[i].last, + ureg->input[i].semantic_name, + ureg->input[i].semantic_index, + ureg->input[i].interp, + ureg->input[i].cylindrical_wrap, + ureg->input[i].interp_location, + ureg->input[i].array_id); + } } - } else { - for (i = 0; i < ureg->nr_inputs; i++) { - emit_decl_semantic(ureg, + else { + for (i = 0; i < ureg->nr_inputs; i++) { + for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { + emit_decl_fs(ureg, TGSI_FILE_INPUT, - ureg->input[i].first, - ureg->input[i].last, + j, j, ureg->input[i].semantic_name, - ureg->input[i].semantic_index, - TGSI_WRITEMASK_XYZW, - ureg->input[i].array_id); + ureg->input[i].semantic_index + + (j - ureg->input[i].first), + ureg->input[i].interp, + ureg->input[i].cylindrical_wrap, + ureg->input[i].interp_location, 0); + } + } + } + } else { + if (ureg->supports_any_inout_decl_range) { + for (i = 0; i < ureg->nr_inputs; i++) { + emit_decl_semantic(ureg, + TGSI_FILE_INPUT, + ureg->input[i].first, + ureg->input[i].last, + ureg->input[i].semantic_name, + ureg->input[i].semantic_index, + TGSI_WRITEMASK_XYZW, + ureg->input[i].array_id); + } + } + else { + for (i = 0; i < ureg->nr_inputs; i++) { + for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { + emit_decl_semantic(ureg, + TGSI_FILE_INPUT, + j, j, + ureg->input[i].semantic_name, + ureg->input[i].semantic_index + + (j - ureg->input[i].first), + TGSI_WRITEMASK_XYZW, 0); + } + } } } @@ -1537,15 +1586,30 @@ static void emit_decls( struct ureg_program *ureg ) TGSI_WRITEMASK_XYZW, 0); } - for (i = 0; i < ureg->nr_outputs; i++) { - emit_decl_semantic(ureg, - TGSI_FILE_OUTPUT, - ureg->output[i].first, - ureg->output[i].last, - ureg->output[i].semantic_name, - ureg->output[i].semantic_index, - ureg->output[i].usage_mask, - ureg->output[i].array_id); + if (ureg->supports_any_inout_decl_range) { + for (i = 0; i < ureg->nr_outputs; i++) { + emit_decl_semantic(ureg, + TGSI_FILE_OUTPUT, + ureg->output[i].first, + ureg->output[i].last, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index, + ureg->output[i].usage_mask, + ureg->output[i].array_id); + } + } + else { + for (i = 0; i < ureg->nr_outputs; i++) { + for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) { + emit_decl_semantic(ureg, + TGSI_FILE_OUTPUT, + j, j, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index + + (j - ureg->output[i].first), + ureg->output[i].usage_mask, 0); + } + } } for (i = 0; i < ureg->nr_samplers; i++) { @@ -1759,7 +1823,38 @@ void ureg_free_tokens( const struct tgsi_token *tokens ) } -struct ureg_program *ureg_create( unsigned processor ) +static INLINE unsigned +pipe_shader_from_tgsi_processor(unsigned processor) +{ + switch (processor) { + case TGSI_PROCESSOR_VERTEX: + return PIPE_SHADER_VERTEX; + case TGSI_PROCESSOR_TESS_CTRL: + return PIPE_SHADER_TESS_CTRL; + case TGSI_PROCESSOR_TESS_EVAL: + return PIPE_SHADER_TESS_EVAL; + case TGSI_PROCESSOR_GEOMETRY: + return PIPE_SHADER_GEOMETRY; + case TGSI_PROCESSOR_FRAGMENT: + return PIPE_SHADER_FRAGMENT; + case TGSI_PROCESSOR_COMPUTE: + return PIPE_SHADER_COMPUTE; + default: + assert(0); + return PIPE_SHADER_VERTEX; + } +} + + +struct ureg_program * +ureg_create(unsigned processor) +{ + return ureg_create_with_screen(processor, NULL); +} + + +struct ureg_program * +ureg_create_with_screen(unsigned processor, struct pipe_screen *screen) { int i; struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); @@ -1767,6 +1862,11 @@ struct ureg_program *ureg_create( unsigned processor ) goto no_ureg; ureg->processor = processor; + ureg->supports_any_inout_decl_range = + screen && + screen->get_shader_param(screen, + pipe_shader_from_tgsi_processor(processor), + PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0; for (i = 0; i < Elements(ureg->properties); i++) ureg->properties[i] = ~0; diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index e20f96d5674..1891b068774 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -36,6 +36,7 @@ extern "C" { #endif +struct pipe_screen; struct ureg_program; struct pipe_stream_output_info; @@ -98,7 +99,10 @@ struct ureg_dst struct pipe_context; struct ureg_program * -ureg_create( unsigned processor ); +ureg_create(unsigned processor); + +struct ureg_program * +ureg_create_with_screen(unsigned processor, struct pipe_screen *screen); const struct tgsi_token * ureg_finalize( struct ureg_program * ); |