From: Joe M. Kniss Date: Thu, 21 Jun 2018 00:55:10 +0000 (-0700) Subject: gallium: plumb invariant output attrib thru TGSI X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=70425bcfe63c4e9191809659d019ec4af923595d;p=mesa.git gallium: plumb invariant output attrib thru TGSI Add support for glsl 'invariant' modifier for output data declarations. Gallium drivers that use TGSI serialization currently loose invariant modifiers in glsl shaders. v2: use boolean for invariant instead of unsigned. Tested: chromiumos on qemu with virglrenderer. Reviewed-by: Marek Olšák Signed-off-by: Dave Airlie --- diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c index 4f28b49ce8a..434871273f2 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c @@ -185,6 +185,8 @@ const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT] = "SAMPLE", }; +const char *tgsi_invariant_name = "INVARIANT"; + const char *tgsi_primitive_names[PIPE_PRIM_MAX] = { "POINTS", diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h b/src/gallium/auxiliary/tgsi/tgsi_strings.h index bb2d3458dde..20e3f7127f6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.h +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h @@ -52,6 +52,8 @@ extern const char *tgsi_interpolate_names[TGSI_INTERPOLATE_COUNT]; extern const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT]; +extern const char *tgsi_invariant_name; + extern const char *tgsi_primitive_names[PIPE_PRIM_MAX]; extern const char *tgsi_fs_coord_origin_names[2]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 55a814994e0..9779f212cb1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -1586,10 +1586,6 @@ static boolean parse_declaration( struct translate_ctx *ctx ) break; } } - if (i == TGSI_INTERPOLATE_COUNT) { - report_error( ctx, "Expected semantic or interpolate attribute" ); - return FALSE; - } } cur = ctx->cur; @@ -1609,6 +1605,20 @@ static boolean parse_declaration( struct translate_ctx *ctx ) } } + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',' && !is_vs_input) { + cur++; + eat_opt_white( &cur ); + if (str_match_nocase_whole( &cur, tgsi_invariant_name )) { + decl.Declaration.Invariant = 1; + ctx->cur = cur; + } else { + report_error( ctx, "Expected semantic, interpolate attribute, or invariant "); + return FALSE; + } + } + advance = tgsi_build_full_declaration( &decl, ctx->tokens_cur, diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 02fbf0181f0..c0f60985f79 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -140,6 +140,7 @@ struct ureg_program unsigned first; unsigned last; unsigned array_id; + boolean invariant; } output[UREG_MAX_OUTPUT]; unsigned nr_outputs, nr_output_regs; @@ -427,7 +428,8 @@ ureg_DECL_output_layout(struct ureg_program *ureg, unsigned index, unsigned usage_mask, unsigned array_id, - unsigned array_size) + unsigned array_size, + boolean invariant) { unsigned i; @@ -455,6 +457,7 @@ ureg_DECL_output_layout(struct ureg_program *ureg, ureg->output[i].first = index; ureg->output[i].last = index + array_size - 1; ureg->output[i].array_id = array_id; + ureg->output[i].invariant = invariant; ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size); ureg->nr_outputs++; } @@ -480,7 +483,8 @@ ureg_DECL_output_masked(struct ureg_program *ureg, unsigned array_size) { return ureg_DECL_output_layout(ureg, name, index, 0, - ureg->nr_output_regs, usage_mask, array_id, array_size); + ureg->nr_output_regs, usage_mask, array_id, + array_size, FALSE); } @@ -1511,7 +1515,8 @@ emit_decl_semantic(struct ureg_program *ureg, unsigned semantic_index, unsigned streams, unsigned usage_mask, - unsigned array_id) + unsigned array_id, + boolean invariant) { union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); @@ -1522,6 +1527,7 @@ emit_decl_semantic(struct ureg_program *ureg, out[0].decl.UsageMask = usage_mask; out[0].decl.Semantic = 1; out[0].decl.Array = array_id != 0; + out[0].decl.Invariant = invariant; out[1].value = 0; out[1].decl_range.First = first; @@ -1869,7 +1875,8 @@ static void emit_decls( struct ureg_program *ureg ) ureg->input[i].semantic_index, 0, TGSI_WRITEMASK_XYZW, - ureg->input[i].array_id); + ureg->input[i].array_id, + FALSE); } } else { @@ -1882,7 +1889,7 @@ static void emit_decls( struct ureg_program *ureg ) ureg->input[i].semantic_index + (j - ureg->input[i].first), 0, - TGSI_WRITEMASK_XYZW, 0); + TGSI_WRITEMASK_XYZW, 0, FALSE); } } } @@ -1896,7 +1903,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); + TGSI_WRITEMASK_XYZW, 0, FALSE); } if (ureg->supports_any_inout_decl_range) { @@ -1909,7 +1916,8 @@ static void emit_decls( struct ureg_program *ureg ) ureg->output[i].semantic_index, ureg->output[i].streams, ureg->output[i].usage_mask, - ureg->output[i].array_id); + ureg->output[i].array_id, + ureg->output[i].invariant); } } else { @@ -1922,7 +1930,9 @@ static void emit_decls( struct ureg_program *ureg ) ureg->output[i].semantic_index + (j - ureg->output[i].first), ureg->output[i].streams, - ureg->output[i].usage_mask, 0); + ureg->output[i].usage_mask, + 0, + ureg->output[i].invariant); } } } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index ac46da55080..4d4a954529b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -79,6 +79,7 @@ struct ureg_dst unsigned DimIndirect : 1; /* BOOL */ unsigned Dimension : 1; /* BOOL */ unsigned Saturate : 1; /* BOOL */ + unsigned Invariant : 1; /* BOOL */ int Index : 16; /* SINT */ int IndirectIndex : 16; /* SINT */ unsigned IndirectFile : 4; /* TGSI_FILE_ */ @@ -250,7 +251,8 @@ ureg_DECL_output_layout(struct ureg_program *, unsigned index, unsigned usage_mask, unsigned array_id, - unsigned array_size); + unsigned array_size, + boolean invariant); struct ureg_dst ureg_DECL_output_masked(struct ureg_program *, diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 673c0f6b67a..00799b4a872 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -123,6 +123,7 @@ struct inout_decl { enum glsl_interp_mode interp; enum glsl_base_type base_type; ubyte usage_mask; /* GLSL-style usage-mask, i.e. single bit per double */ + bool invariant; }; static struct inout_decl * @@ -2508,6 +2509,8 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) unsigned num_components; num_outputs++; + decl->invariant = var->data.invariant; + if (type_without_array->is_64bit()) component = component / 2; if (type_without_array->vector_elements) @@ -6443,14 +6446,15 @@ st_translate_program( (enum tgsi_semantic) outputSemanticName[slot], outputSemanticIndex[slot], decl->gs_out_streams, - slot, tgsi_usage_mask, decl->array_id, decl->size); - + slot, tgsi_usage_mask, decl->array_id, decl->size, decl->invariant); + dst.Invariant = decl->invariant; for (unsigned j = 0; j < decl->size; ++j) { if (t->outputs[slot + j].File != TGSI_FILE_OUTPUT) { /* The ArrayID is set up in dst_register */ t->outputs[slot + j] = dst; t->outputs[slot + j].ArrayID = 0; t->outputs[slot + j].Index += j; + t->outputs[slot + j].Invariant = decl->invariant; } } }