diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_ureg.c')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 148 |
1 files changed, 91 insertions, 57 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 463c35362e2..fdbc37220d0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -35,12 +35,13 @@ #include "tgsi/tgsi_info.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_sanity.h" +#include "util/glheader.h" #include "util/u_debug.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_prim.h" #include "util/u_bitmask.h" -#include "GL/gl.h" #include "compiler/shader_info.h" union tgsi_any_token { @@ -97,7 +98,7 @@ struct const_decl { }; struct hw_atomic_decl { - struct { + struct hw_atomic_decl_range { unsigned first; unsigned last; unsigned array_id; @@ -114,7 +115,7 @@ struct ureg_program bool supports_any_inout_decl_range; int next_shader_processor; - struct { + struct ureg_input_decl { enum tgsi_semantic semantic_name; unsigned semantic_index; enum tgsi_interpolate_mode interp; @@ -142,7 +143,7 @@ struct ureg_program unsigned first; unsigned last; unsigned array_id; - boolean invariant; + bool invariant; } output[UREG_MAX_OUTPUT]; unsigned nr_outputs, nr_output_regs; @@ -174,8 +175,8 @@ struct ureg_program unsigned index; enum tgsi_texture_type target; enum pipe_format format; - boolean wr; - boolean raw; + bool wr; + bool raw; } image[PIPE_MAX_SHADER_IMAGES]; unsigned nr_images; @@ -205,6 +206,8 @@ struct ureg_program struct ureg_tokens domain[2]; bool use_memory[TGSI_MEMORY_TYPE_COUNT]; + + bool precise; }; static union tgsi_any_token error_tokens[32]; @@ -305,6 +308,8 @@ ureg_DECL_fs_input_centroid_layout(struct ureg_program *ureg, assert(ureg->input[i].interp_location == interp_location); if (ureg->input[i].array_id == array_id) { ureg->input[i].usage_mask |= usage_mask; + ureg->input[i].last = MAX2(ureg->input[i].last, ureg->input[i].first + array_size - 1); + ureg->nr_input_regs = MAX2(ureg->nr_input_regs, ureg->input[i].last + 1); goto out; } assert((ureg->input[i].usage_mask & usage_mask) == 0); @@ -427,7 +432,7 @@ ureg_DECL_output_layout(struct ureg_program *ureg, unsigned usage_mask, unsigned array_id, unsigned array_size, - boolean invariant) + bool invariant) { unsigned i; @@ -442,6 +447,8 @@ ureg_DECL_output_layout(struct ureg_program *ureg, ureg->output[i].semantic_index == semantic_index) { if (ureg->output[i].array_id == array_id) { ureg->output[i].usage_mask |= usage_mask; + ureg->output[i].last = MAX2(ureg->output[i].last, ureg->output[i].first + array_size - 1); + ureg->nr_output_regs = MAX2(ureg->nr_output_regs, ureg->output[i].last + 1); goto out; } assert((ureg->output[i].usage_mask & usage_mask) == 0); @@ -474,7 +481,7 @@ out: struct ureg_dst ureg_DECL_output_masked(struct ureg_program *ureg, - unsigned name, + enum tgsi_semantic name, unsigned index, unsigned usage_mask, unsigned array_id, @@ -482,7 +489,7 @@ ureg_DECL_output_masked(struct ureg_program *ureg, { return ureg_DECL_output_layout(ureg, name, index, 0, ureg->nr_output_regs, usage_mask, array_id, - array_size, FALSE); + array_size, false); } @@ -529,7 +536,7 @@ ureg_DECL_constant2D(struct ureg_program *ureg, assert(index2D < PIPE_MAX_CONSTANT_BUFFERS); if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { - uint i = decl->nr_constant_ranges++; + unsigned i = decl->nr_constant_ranges++; decl->constant_range[i].first = first; decl->constant_range[i].last = last; @@ -615,7 +622,7 @@ ureg_DECL_hw_atomic(struct ureg_program *ureg, struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[buffer_id]; if (decl->nr_hw_atomic_ranges < UREG_MAX_HW_ATOMIC_RANGE) { - uint i = decl->nr_hw_atomic_ranges++; + unsigned i = decl->nr_hw_atomic_ranges++; decl->hw_atomic_range[i].first = first; decl->hw_atomic_range[i].last = last; @@ -626,7 +633,7 @@ ureg_DECL_hw_atomic(struct ureg_program *ureg, } static struct ureg_dst alloc_temporary( struct ureg_program *ureg, - boolean local ) + bool local ) { unsigned i; @@ -659,17 +666,17 @@ static struct ureg_dst alloc_temporary( struct ureg_program *ureg, struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) { - return alloc_temporary(ureg, FALSE); + return alloc_temporary(ureg, false); } struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg ) { - return alloc_temporary(ureg, TRUE); + return alloc_temporary(ureg, true); } struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg, unsigned size, - boolean local ) + bool local ) { unsigned i = ureg->nr_temps; struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i ); @@ -746,7 +753,7 @@ ureg_DECL_sampler_view(struct ureg_program *ureg, enum tgsi_return_type return_type_w) { struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index); - uint i; + unsigned i; for (i = 0; i < ureg->nr_sampler_views; i++) { if (ureg->sampler_view[i].index == index) { @@ -776,8 +783,8 @@ ureg_DECL_image(struct ureg_program *ureg, unsigned index, enum tgsi_texture_type target, enum pipe_format format, - boolean wr, - boolean raw) + bool wr, + bool raw) { struct ureg_src reg = ureg_src_register(TGSI_FILE_IMAGE, index); unsigned i; @@ -846,17 +853,17 @@ match_or_expand_immediate64( const unsigned *v, *swizzle = 0; for (i = 0; i < nr; i += 2) { - boolean found = FALSE; + bool found = false; for (j = 0; j < nr2 && !found; j += 2) { if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) { *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2)); - found = TRUE; + found = true; } } if (!found) { if ((nr2) >= 4) { - return FALSE; + return false; } v2[nr2] = v[i]; @@ -870,7 +877,7 @@ match_or_expand_immediate64( const unsigned *v, /* Actually expand immediate only when fully succeeded. */ *pnr2 = nr2; - return TRUE; + return true; } static int @@ -892,18 +899,18 @@ match_or_expand_immediate( const unsigned *v, *swizzle = 0; for (i = 0; i < nr; i++) { - boolean found = FALSE; + bool found = false; for (j = 0; j < nr2 && !found; j++) { if (v[i] == v2[j]) { *swizzle |= j << (i * 2); - found = TRUE; + found = true; } } if (!found) { if (nr2 >= 4) { - return FALSE; + return false; } v2[nr2] = v[i]; @@ -915,7 +922,7 @@ match_or_expand_immediate( const unsigned *v, /* Actually expand immediate only when fully succeeded. */ *pnr2 = nr2; - return TRUE; + return true; } @@ -1035,8 +1042,8 @@ ureg_DECL_immediate_block_uint( struct ureg_program *ureg, const unsigned *v, unsigned nr ) { - uint index; - uint i; + unsigned index; + unsigned i; if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) { set_bad(ureg); @@ -1051,7 +1058,7 @@ ureg_DECL_immediate_block_uint( struct ureg_program *ureg, ureg->immediate[i].nr = nr > 4 ? 4 : nr; memcpy(ureg->immediate[i].value.u, &v[(i - index) * 4], - ureg->immediate[i].nr * sizeof(uint)); + ureg->immediate[i].nr * sizeof(unsigned)); nr -= 4; } @@ -1252,13 +1259,13 @@ static void validate( enum tgsi_opcode opcode, struct ureg_emit_insn_result ureg_emit_insn(struct ureg_program *ureg, enum tgsi_opcode opcode, - boolean saturate, + bool saturate, unsigned precise, unsigned num_dst, unsigned num_src) { union tgsi_any_token *out; - uint count = 1; + unsigned count = 1; struct ureg_emit_insn_result result; validate( opcode, num_dst, num_src ); @@ -1267,7 +1274,7 @@ ureg_emit_insn(struct ureg_program *ureg, out[0].insn = tgsi_default_instruction(); out[0].insn.Opcode = opcode; out[0].insn.Saturate = saturate; - out[0].insn.Precise = precise; + out[0].insn.Precise = precise || ureg->precise; out[0].insn.NumDstRegs = num_dst; out[0].insn.NumSrcRegs = num_src; @@ -1401,13 +1408,13 @@ ureg_insn(struct ureg_program *ureg, { struct ureg_emit_insn_result insn; unsigned i; - boolean saturate; + bool saturate; if (nr_dst && ureg_dst_is_empty(dst[0])) { return; } - saturate = nr_dst ? dst[0].Saturate : FALSE; + saturate = nr_dst ? dst[0].Saturate : false; insn = ureg_emit_insn(ureg, opcode, @@ -1439,13 +1446,13 @@ ureg_tex_insn(struct ureg_program *ureg, { struct ureg_emit_insn_result insn; unsigned i; - boolean saturate; + bool saturate; if (nr_dst && ureg_dst_is_empty(dst[0])) { return; } - saturate = nr_dst ? dst[0].Saturate : FALSE; + saturate = nr_dst ? dst[0].Saturate : false; insn = ureg_emit_insn(ureg, opcode, @@ -1486,7 +1493,7 @@ ureg_memory_insn(struct ureg_program *ureg, insn = ureg_emit_insn(ureg, opcode, - FALSE, + false, 0, nr_dst, nr_src); @@ -1513,7 +1520,7 @@ emit_decl_semantic(struct ureg_program *ureg, unsigned streams, unsigned usage_mask, unsigned array_id, - boolean invariant) + bool invariant) { union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); @@ -1619,7 +1626,7 @@ emit_decl_fs(struct ureg_program *ureg, static void emit_decl_temps( struct ureg_program *ureg, unsigned first, unsigned last, - boolean local, + bool local, unsigned arrayid ) { union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, @@ -1720,8 +1727,8 @@ emit_decl_image(struct ureg_program *ureg, unsigned index, enum tgsi_texture_type target, enum pipe_format format, - boolean wr, - boolean raw) + bool wr, + bool raw) { union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); @@ -1813,6 +1820,14 @@ emit_property(struct ureg_program *ureg, } static int +input_sort(const void *in_a, const void *in_b) +{ + const struct ureg_input_decl *a = in_a, *b = in_b; + + return a->first - b->first; +} + +static int output_sort(const void *in_a, const void *in_b) { const struct ureg_output_decl *a = in_a, *b = in_b; @@ -1820,6 +1835,14 @@ output_sort(const void *in_a, const void *in_b) return a->first - b->first; } +static int +atomic_decl_range_sort(const void *in_a, const void *in_b) +{ + const struct hw_atomic_decl_range *a = in_a, *b = in_b; + + return a->first - b->first; +} + static void emit_decls( struct ureg_program *ureg ) { unsigned i,j; @@ -1828,6 +1851,11 @@ static void emit_decls( struct ureg_program *ureg ) if (ureg->properties[i] != ~0u) emit_property(ureg, i, ureg->properties[i]); + /* While not required by TGSI spec, virglrenderer has a dependency on the + * inputs being sorted. + */ + qsort(ureg->input, ureg->nr_inputs, sizeof(ureg->input[0]), input_sort); + if (ureg->processor == PIPE_SHADER_VERTEX) { for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (ureg->vs_inputs[i/32] & (1u << (i%32))) { @@ -1876,7 +1904,7 @@ static void emit_decls( struct ureg_program *ureg ) 0, TGSI_WRITEMASK_XYZW, ureg->input[i].array_id, - FALSE); + false); } } else { @@ -1889,7 +1917,7 @@ static void emit_decls( struct ureg_program *ureg ) ureg->input[i].semantic_index + (j - ureg->input[i].first), 0, - TGSI_WRITEMASK_XYZW, 0, FALSE); + TGSI_WRITEMASK_XYZW, 0, false); } } } @@ -1903,7 +1931,7 @@ static void emit_decls( struct ureg_program *ureg ) ureg->system_value[i].semantic_name, ureg->system_value[i].semantic_index, 0, - TGSI_WRITEMASK_XYZW, 0, FALSE); + TGSI_WRITEMASK_XYZW, 0, false); } /* While not required by TGSI spec, virglrenderer has a dependency on the @@ -1980,7 +2008,7 @@ static void emit_decls( struct ureg_program *ureg ) struct const_decl *decl = &ureg->const_decls[i]; if (decl->nr_constant_ranges) { - uint j; + unsigned j; for (j = 0; j < decl->nr_constant_ranges; j++) { emit_decl_range2D(ureg, @@ -1996,7 +2024,12 @@ static void emit_decls( struct ureg_program *ureg ) struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i]; if (decl->nr_hw_atomic_ranges) { - uint j; + unsigned j; + + /* GLSL-to-TGSI generated HW atomic counters in order, and r600 depends + * on it. + */ + qsort(decl->hw_atomic_range, decl->nr_hw_atomic_ranges, sizeof(struct hw_atomic_decl_range), atomic_decl_range_sort); for (j = 0; j < decl->nr_hw_atomic_ranges; j++) { emit_decl_atomic_2d(ureg, @@ -2011,7 +2044,7 @@ static void emit_decls( struct ureg_program *ureg ) if (ureg->nr_temps) { unsigned array = 0; for (i = 0; i < ureg->nr_temps;) { - boolean local = util_bitmask_get(ureg->local_temps, i); + bool local = util_bitmask_get(ureg->local_temps, i); unsigned first = i; i = util_bitmask_get_next_index(ureg->decl_temps, i + 1); if (i == UTIL_BITMASK_INVALID_INDEX) @@ -2098,7 +2131,7 @@ const struct tgsi_token *ureg_finalize( struct ureg_program *ureg ) if (ureg->domain[0].tokens == error_tokens || ureg->domain[1].tokens == error_tokens) { - debug_printf("%s: error in generated shader\n", __FUNCTION__); + debug_printf("%s: error in generated shader\n", __func__); assert(0); return NULL; } @@ -2106,12 +2139,12 @@ const struct tgsi_token *ureg_finalize( struct ureg_program *ureg ) tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token; if (0) { - debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__, + debug_printf("%s: emitted shader %d tokens:\n", __func__, ureg->domain[DOMAIN_DECL].count); tgsi_dump( tokens, 0 ); } -#if DEBUG +#if MESA_DEBUG /* tgsi_sanity doesn't seem to return if there are too many constants. */ bool too_many_constants = false; for (unsigned i = 0; i < ARRAY_SIZE(ureg->const_decls); i++) { @@ -2177,7 +2210,7 @@ const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg, if (nr_tokens) *nr_tokens = ureg->domain[DOMAIN_DECL].count; - ureg->domain[DOMAIN_DECL].tokens = 0; + ureg->domain[DOMAIN_DECL].tokens = NULL; ureg->domain[DOMAIN_DECL].size = 0; ureg->domain[DOMAIN_DECL].order = 0; ureg->domain[DOMAIN_DECL].count = 0; @@ -2203,7 +2236,7 @@ struct ureg_program * ureg_create_with_screen(enum pipe_shader_type processor, struct pipe_screen *screen) { - uint i; + unsigned i; struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); if (!ureg) goto no_ureg; @@ -2282,11 +2315,7 @@ static void ureg_setup_tess_eval_shader(struct ureg_program *ureg, const struct shader_info *info) { - if (info->tess.primitive_mode == GL_ISOLINES) - ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES); - else - ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, - info->tess.primitive_mode); + ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, u_tess_prim_from_shader(info->tess._primitive_mode)); STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL); STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 == @@ -2424,3 +2453,8 @@ void ureg_destroy( struct ureg_program *ureg ) FREE(ureg); } + +void ureg_set_precise( struct ureg_program *ureg, bool precise ) +{ + ureg->precise = precise; +} |