diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c index fc29a23..b1995c0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c @@ -166,6 +166,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 71e7437..1ecfcbc 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 9d73668..3378148 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -1393,10 +1393,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; @@ -1416,6 +1412,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 \"%.10s...\" ", cur ); + return FALSE; + } + } + advance = tgsi_build_full_declaration( &decl, ctx->tokens_cur, diff --git a/src/virgl_hw.h b/src/virgl_hw.h index 7cbbeee..b27b698 100644 --- a/src/virgl_hw.h +++ b/src/virgl_hw.h @@ -290,6 +290,7 @@ struct virgl_caps_v2 { int32_t max_texture_gather_offset; uint32_t texture_buffer_offset_alignment; uint32_t uniform_buffer_offset_alignment; + uint32_t tgsi_invariant; }; union virgl_caps { diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 32a4961..8f5be15 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -6871,6 +6871,8 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version, if (gl_ver >= 43) glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &caps->v2.texture_buffer_offset_alignment); + + caps->v2.tgsi_invariant = 1; } GLint64 vrend_renderer_get_timestamp(void) diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 3f5fb22..bab603e 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -37,6 +37,7 @@ extern int vrend_dump_shaders; /* start convert of tgsi to glsl */ #define INTERP_PREFIX " " +#define INVARI_PREFIX "invariant" struct vrend_shader_io { unsigned name; @@ -46,6 +47,7 @@ struct vrend_shader_io { unsigned interpolate; unsigned first; bool centroid; + bool invariant; bool glsl_predefined_no_emit; bool glsl_no_index; bool glsl_gl_in; @@ -468,6 +470,7 @@ iter_declaration(struct tgsi_iterate_context *iter, ctx->outputs[i].name = decl->Semantic.Name; ctx->outputs[i].sid = decl->Semantic.Index; ctx->outputs[i].interpolate = decl->Interp.Interpolate; + ctx->outputs[i].invariant = decl->Declaration.Invariant; ctx->outputs[i].first = decl->Range.First; ctx->outputs[i].glsl_predefined_no_emit = false; ctx->outputs[i].glsl_no_index = false; @@ -2501,7 +2504,10 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr) } else prefix = ""; /* ugly leave spaces to patch interp in later */ - snprintf(buf, 255, "%sout vec4 %s;\n", prefix, ctx->outputs[i].glsl_name); + snprintf(buf, 255, "%s%sout vec4 %s;\n", prefix, ctx->outputs[i].invariant ? "invariant " : "", ctx->outputs[i].glsl_name); + STRCAT_WITH_RET(glsl_hdr, buf); + } else if (ctx->outputs[i].invariant) { + snprintf(buf, 255, "invariant %s;\n", ctx->outputs[i].glsl_name); STRCAT_WITH_RET(glsl_hdr, buf); } }