summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp43
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp31
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp9
-rw-r--r--src/shader_recompiler/shader_info.h2
6 files changed, 81 insertions, 8 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index ed10eca8a..f0e9dffc2 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -200,6 +200,27 @@ std::string_view OutputPrimitive(OutputTopology topology) {
throw InvalidArgument("Invalid output topology {}", topology);
}
+void SetupLegacyOutPerVertex(EmitContext& ctx, std::string& header) {
+ if (!ctx.info.stores_legacy_varyings) {
+ return;
+ }
+ if (ctx.info.stores_fixed_fnc_textures) {
+ header += "vec4 gl_TexCoord[8];";
+ }
+ if (ctx.info.stores_color_front_diffuse) {
+ header += "vec4 gl_FrontColor;";
+ }
+ if (ctx.info.stores_color_front_specular) {
+ header += "vec4 gl_FrontSecondaryColor;";
+ }
+ if (ctx.info.stores_color_back_diffuse) {
+ header += "vec4 gl_BackColor;";
+ }
+ if (ctx.info.stores_color_back_specular) {
+ header += "vec4 gl_BackSecondaryColor;";
+ }
+}
+
void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
if (!StoresPerVertexAttributes(ctx.stage)) {
return;
@@ -215,18 +236,34 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
ctx.stage != Stage::Geometry) {
header += "int gl_ViewportIndex;";
}
+ SetupLegacyOutPerVertex(ctx, header);
header += "};";
if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) {
header += "out int gl_ViewportIndex;";
}
}
+
+void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) {
+ if (!ctx.info.loads_legacy_varyings) {
+ return;
+ }
+ header += "in gl_PerFragment{";
+ if (ctx.info.loads_fixed_fnc_textures) {
+ header += "vec4 gl_TexCoord[8];";
+ }
+ if (ctx.info.loads_color_front_diffuse) {
+ header += "vec4 gl_Color;";
+ }
+ header += "};";
+}
+
} // Anonymous namespace
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
const RuntimeInfo& runtime_info_)
: info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
header += "#pragma optionNV(fastmath off)\n";
- SetupExtensions(header);
+ SetupExtensions();
stage = program.stage;
switch (program.stage) {
case Stage::VertexA:
@@ -271,6 +308,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
break;
}
SetupOutPerVertex(*this, header);
+ SetupLegacyInPerFragment(*this, header);
+
for (size_t index = 0; index < info.input_generics.size(); ++index) {
const auto& generic{info.input_generics[index]};
if (generic.used) {
@@ -306,7 +345,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
DefineConstants();
}
-void EmitContext::SetupExtensions(std::string&) {
+void EmitContext::SetupExtensions() {
if (profile.support_gl_texture_shadow_lod) {
header += "#extension GL_EXT_texture_shadow_lod : enable\n";
}
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 685f56089..8fa87c02c 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -157,7 +157,7 @@ public:
bool uses_cc_carry{};
private:
- void SetupExtensions(std::string& header);
+ void SetupExtensions();
void DefineConstantBuffers(Bindings& bindings);
void DefineStorageBuffers(Bindings& bindings);
void DefineGenericOutput(size_t index, u32 invocations);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index 3e6add7cd..d76b63b2d 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -166,7 +166,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
}
std::string GlslVersionSpecifier(const EmitContext& ctx) {
- if (ctx.uses_y_direction) {
+ if (ctx.uses_y_direction || ctx.info.stores_legacy_varyings) {
return " compatibility";
}
return "";
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
index 96296ad28..3eeccfb3c 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
@@ -98,6 +98,10 @@ void GetCbuf16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const
bit_offset);
}
}
+
+u32 TexCoordIndex(IR::Attribute attr) {
+ return (static_cast<u32>(attr) - static_cast<u32>(IR::Attribute::FixedFncTexture0S)) / 4;
+}
} // Anonymous namespace
void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -178,6 +182,17 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle);
return;
}
+ // GLSL only exposes 8 legacy texcoords
+ if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
+ // LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
+ ctx.AddF32("{}=0.f;", inst);
+ return;
+ }
+ if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
+ const u32 index{TexCoordIndex(attr)};
+ ctx.AddF32("{}=gl_TexCoord[{}].{};", inst, index, swizzle);
+ return;
+ }
switch (attr) {
case IR::Attribute::PrimitiveId:
ctx.AddF32("{}=itof(gl_PrimitiveID);", inst);
@@ -227,19 +242,29 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
[[maybe_unused]] std::string_view vertex) {
if (IR::IsGeneric(attr)) {
const u32 index{IR::GenericAttributeIndex(attr)};
- const u32 element{IR::GenericAttributeElement(attr)};
- const GenericElementInfo& info{ctx.output_generics.at(index).at(element)};
+ const u32 attr_element{IR::GenericAttributeElement(attr)};
+ const GenericElementInfo& info{ctx.output_generics.at(index).at(attr_element)};
const auto output_decorator{OutputVertexIndex(ctx)};
if (info.num_components == 1) {
ctx.Add("{}{}={};", info.name, output_decorator, value);
} else {
- const u32 index_element{element - info.first_element};
+ const u32 index_element{attr_element - info.first_element};
ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value);
}
return;
}
const u32 element{static_cast<u32>(attr) % 4};
const char swizzle{"xyzw"[element]};
+ // GLSL only exposes 8 legacy texcoords
+ if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
+ // LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
+ return;
+ }
+ if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
+ const u32 index{TexCoordIndex(attr)};
+ ctx.Add("gl_TexCoord[{}].{}={};", index, swizzle, value);
+ return;
+ }
switch (attr) {
case IR::Attribute::Layer:
if (ctx.stage != Stage::Geometry &&
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index dc78cdefb..10d2822ae 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -35,6 +35,7 @@ void GetAttribute(Info& info, IR::Attribute attr) {
}
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
info.loads_fixed_fnc_textures = true;
+ info.loads_legacy_varyings = true;
return;
}
switch (attr) {
@@ -52,6 +53,7 @@ void GetAttribute(Info& info, IR::Attribute attr) {
case IR::Attribute::ColorFrontDiffuseB:
case IR::Attribute::ColorFrontDiffuseA:
info.loads_color_front_diffuse = true;
+ info.loads_legacy_varyings = true;
break;
case IR::Attribute::PointSpriteS:
case IR::Attribute::PointSpriteT:
@@ -82,6 +84,7 @@ void SetAttribute(Info& info, IR::Attribute attr) {
}
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
info.stores_fixed_fnc_textures = true;
+ info.stores_legacy_varyings = true;
return;
}
switch (attr) {
@@ -105,24 +108,28 @@ void SetAttribute(Info& info, IR::Attribute attr) {
case IR::Attribute::ColorFrontDiffuseB:
case IR::Attribute::ColorFrontDiffuseA:
info.stores_color_front_diffuse = true;
+ info.stores_legacy_varyings = true;
break;
case IR::Attribute::ColorFrontSpecularR:
case IR::Attribute::ColorFrontSpecularG:
case IR::Attribute::ColorFrontSpecularB:
case IR::Attribute::ColorFrontSpecularA:
info.stores_color_front_specular = true;
+ info.stores_legacy_varyings = true;
break;
case IR::Attribute::ColorBackDiffuseR:
case IR::Attribute::ColorBackDiffuseG:
case IR::Attribute::ColorBackDiffuseB:
case IR::Attribute::ColorBackDiffuseA:
info.stores_color_back_diffuse = true;
+ info.stores_legacy_varyings = true;
break;
case IR::Attribute::ColorBackSpecularR:
case IR::Attribute::ColorBackSpecularG:
case IR::Attribute::ColorBackSpecularB:
case IR::Attribute::ColorBackSpecularA:
- info.stores_color_front_specular = true;
+ info.stores_color_back_specular = true;
+ info.stores_legacy_varyings = true;
break;
case IR::Attribute::ClipDistance0:
case IR::Attribute::ClipDistance1:
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index 9f7f0b42c..7536c9caf 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -128,6 +128,7 @@ struct Info {
bool loads_instance_id{};
bool loads_vertex_id{};
bool loads_front_face{};
+ bool loads_legacy_varyings{};
bool loads_tess_coord{};
@@ -150,6 +151,7 @@ struct Info {
bool stores_clip_distance{};
bool stores_fog_coordinate{};
bool stores_viewport_mask{};
+ bool stores_legacy_varyings{};
bool stores_tess_level_outer{};
bool stores_tess_level_inner{};