summaryrefslogtreecommitdiff
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-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) {
200 throw InvalidArgument("Invalid output topology {}", topology); 200 throw InvalidArgument("Invalid output topology {}", topology);
201} 201}
202 202
203void SetupLegacyOutPerVertex(EmitContext& ctx, std::string& header) {
204 if (!ctx.info.stores_legacy_varyings) {
205 return;
206 }
207 if (ctx.info.stores_fixed_fnc_textures) {
208 header += "vec4 gl_TexCoord[8];";
209 }
210 if (ctx.info.stores_color_front_diffuse) {
211 header += "vec4 gl_FrontColor;";
212 }
213 if (ctx.info.stores_color_front_specular) {
214 header += "vec4 gl_FrontSecondaryColor;";
215 }
216 if (ctx.info.stores_color_back_diffuse) {
217 header += "vec4 gl_BackColor;";
218 }
219 if (ctx.info.stores_color_back_specular) {
220 header += "vec4 gl_BackSecondaryColor;";
221 }
222}
223
203void SetupOutPerVertex(EmitContext& ctx, std::string& header) { 224void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
204 if (!StoresPerVertexAttributes(ctx.stage)) { 225 if (!StoresPerVertexAttributes(ctx.stage)) {
205 return; 226 return;
@@ -215,18 +236,34 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
215 ctx.stage != Stage::Geometry) { 236 ctx.stage != Stage::Geometry) {
216 header += "int gl_ViewportIndex;"; 237 header += "int gl_ViewportIndex;";
217 } 238 }
239 SetupLegacyOutPerVertex(ctx, header);
218 header += "};"; 240 header += "};";
219 if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { 241 if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) {
220 header += "out int gl_ViewportIndex;"; 242 header += "out int gl_ViewportIndex;";
221 } 243 }
222} 244}
245
246void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) {
247 if (!ctx.info.loads_legacy_varyings) {
248 return;
249 }
250 header += "in gl_PerFragment{";
251 if (ctx.info.loads_fixed_fnc_textures) {
252 header += "vec4 gl_TexCoord[8];";
253 }
254 if (ctx.info.loads_color_front_diffuse) {
255 header += "vec4 gl_Color;";
256 }
257 header += "};";
258}
259
223} // Anonymous namespace 260} // Anonymous namespace
224 261
225EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 262EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
226 const RuntimeInfo& runtime_info_) 263 const RuntimeInfo& runtime_info_)
227 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { 264 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
228 header += "#pragma optionNV(fastmath off)\n"; 265 header += "#pragma optionNV(fastmath off)\n";
229 SetupExtensions(header); 266 SetupExtensions();
230 stage = program.stage; 267 stage = program.stage;
231 switch (program.stage) { 268 switch (program.stage) {
232 case Stage::VertexA: 269 case Stage::VertexA:
@@ -271,6 +308,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
271 break; 308 break;
272 } 309 }
273 SetupOutPerVertex(*this, header); 310 SetupOutPerVertex(*this, header);
311 SetupLegacyInPerFragment(*this, header);
312
274 for (size_t index = 0; index < info.input_generics.size(); ++index) { 313 for (size_t index = 0; index < info.input_generics.size(); ++index) {
275 const auto& generic{info.input_generics[index]}; 314 const auto& generic{info.input_generics[index]};
276 if (generic.used) { 315 if (generic.used) {
@@ -306,7 +345,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
306 DefineConstants(); 345 DefineConstants();
307} 346}
308 347
309void EmitContext::SetupExtensions(std::string&) { 348void EmitContext::SetupExtensions() {
310 if (profile.support_gl_texture_shadow_lod) { 349 if (profile.support_gl_texture_shadow_lod) {
311 header += "#extension GL_EXT_texture_shadow_lod : enable\n"; 350 header += "#extension GL_EXT_texture_shadow_lod : enable\n";
312 } 351 }
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:
157 bool uses_cc_carry{}; 157 bool uses_cc_carry{};
158 158
159private: 159private:
160 void SetupExtensions(std::string& header); 160 void SetupExtensions();
161 void DefineConstantBuffers(Bindings& bindings); 161 void DefineConstantBuffers(Bindings& bindings);
162 void DefineStorageBuffers(Bindings& bindings); 162 void DefineStorageBuffers(Bindings& bindings);
163 void DefineGenericOutput(size_t index, u32 invocations); 163 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) {
166} 166}
167 167
168std::string GlslVersionSpecifier(const EmitContext& ctx) { 168std::string GlslVersionSpecifier(const EmitContext& ctx) {
169 if (ctx.uses_y_direction) { 169 if (ctx.uses_y_direction || ctx.info.stores_legacy_varyings) {
170 return " compatibility"; 170 return " compatibility";
171 } 171 }
172 return ""; 172 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
98 bit_offset); 98 bit_offset);
99 } 99 }
100} 100}
101
102u32 TexCoordIndex(IR::Attribute attr) {
103 return (static_cast<u32>(attr) - static_cast<u32>(IR::Attribute::FixedFncTexture0S)) / 4;
104}
101} // Anonymous namespace 105} // Anonymous namespace
102 106
103void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 107void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -178,6 +182,17 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
178 ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); 182 ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle);
179 return; 183 return;
180 } 184 }
185 // GLSL only exposes 8 legacy texcoords
186 if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
187 // LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
188 ctx.AddF32("{}=0.f;", inst);
189 return;
190 }
191 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
192 const u32 index{TexCoordIndex(attr)};
193 ctx.AddF32("{}=gl_TexCoord[{}].{};", inst, index, swizzle);
194 return;
195 }
181 switch (attr) { 196 switch (attr) {
182 case IR::Attribute::PrimitiveId: 197 case IR::Attribute::PrimitiveId:
183 ctx.AddF32("{}=itof(gl_PrimitiveID);", inst); 198 ctx.AddF32("{}=itof(gl_PrimitiveID);", inst);
@@ -227,19 +242,29 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
227 [[maybe_unused]] std::string_view vertex) { 242 [[maybe_unused]] std::string_view vertex) {
228 if (IR::IsGeneric(attr)) { 243 if (IR::IsGeneric(attr)) {
229 const u32 index{IR::GenericAttributeIndex(attr)}; 244 const u32 index{IR::GenericAttributeIndex(attr)};
230 const u32 element{IR::GenericAttributeElement(attr)}; 245 const u32 attr_element{IR::GenericAttributeElement(attr)};
231 const GenericElementInfo& info{ctx.output_generics.at(index).at(element)}; 246 const GenericElementInfo& info{ctx.output_generics.at(index).at(attr_element)};
232 const auto output_decorator{OutputVertexIndex(ctx)}; 247 const auto output_decorator{OutputVertexIndex(ctx)};
233 if (info.num_components == 1) { 248 if (info.num_components == 1) {
234 ctx.Add("{}{}={};", info.name, output_decorator, value); 249 ctx.Add("{}{}={};", info.name, output_decorator, value);
235 } else { 250 } else {
236 const u32 index_element{element - info.first_element}; 251 const u32 index_element{attr_element - info.first_element};
237 ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value); 252 ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value);
238 } 253 }
239 return; 254 return;
240 } 255 }
241 const u32 element{static_cast<u32>(attr) % 4}; 256 const u32 element{static_cast<u32>(attr) % 4};
242 const char swizzle{"xyzw"[element]}; 257 const char swizzle{"xyzw"[element]};
258 // GLSL only exposes 8 legacy texcoords
259 if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
260 // LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
261 return;
262 }
263 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
264 const u32 index{TexCoordIndex(attr)};
265 ctx.Add("gl_TexCoord[{}].{}={};", index, swizzle, value);
266 return;
267 }
243 switch (attr) { 268 switch (attr) {
244 case IR::Attribute::Layer: 269 case IR::Attribute::Layer:
245 if (ctx.stage != Stage::Geometry && 270 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) {
35 } 35 }
36 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { 36 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
37 info.loads_fixed_fnc_textures = true; 37 info.loads_fixed_fnc_textures = true;
38 info.loads_legacy_varyings = true;
38 return; 39 return;
39 } 40 }
40 switch (attr) { 41 switch (attr) {
@@ -52,6 +53,7 @@ void GetAttribute(Info& info, IR::Attribute attr) {
52 case IR::Attribute::ColorFrontDiffuseB: 53 case IR::Attribute::ColorFrontDiffuseB:
53 case IR::Attribute::ColorFrontDiffuseA: 54 case IR::Attribute::ColorFrontDiffuseA:
54 info.loads_color_front_diffuse = true; 55 info.loads_color_front_diffuse = true;
56 info.loads_legacy_varyings = true;
55 break; 57 break;
56 case IR::Attribute::PointSpriteS: 58 case IR::Attribute::PointSpriteS:
57 case IR::Attribute::PointSpriteT: 59 case IR::Attribute::PointSpriteT:
@@ -82,6 +84,7 @@ void SetAttribute(Info& info, IR::Attribute attr) {
82 } 84 }
83 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { 85 if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
84 info.stores_fixed_fnc_textures = true; 86 info.stores_fixed_fnc_textures = true;
87 info.stores_legacy_varyings = true;
85 return; 88 return;
86 } 89 }
87 switch (attr) { 90 switch (attr) {
@@ -105,24 +108,28 @@ void SetAttribute(Info& info, IR::Attribute attr) {
105 case IR::Attribute::ColorFrontDiffuseB: 108 case IR::Attribute::ColorFrontDiffuseB:
106 case IR::Attribute::ColorFrontDiffuseA: 109 case IR::Attribute::ColorFrontDiffuseA:
107 info.stores_color_front_diffuse = true; 110 info.stores_color_front_diffuse = true;
111 info.stores_legacy_varyings = true;
108 break; 112 break;
109 case IR::Attribute::ColorFrontSpecularR: 113 case IR::Attribute::ColorFrontSpecularR:
110 case IR::Attribute::ColorFrontSpecularG: 114 case IR::Attribute::ColorFrontSpecularG:
111 case IR::Attribute::ColorFrontSpecularB: 115 case IR::Attribute::ColorFrontSpecularB:
112 case IR::Attribute::ColorFrontSpecularA: 116 case IR::Attribute::ColorFrontSpecularA:
113 info.stores_color_front_specular = true; 117 info.stores_color_front_specular = true;
118 info.stores_legacy_varyings = true;
114 break; 119 break;
115 case IR::Attribute::ColorBackDiffuseR: 120 case IR::Attribute::ColorBackDiffuseR:
116 case IR::Attribute::ColorBackDiffuseG: 121 case IR::Attribute::ColorBackDiffuseG:
117 case IR::Attribute::ColorBackDiffuseB: 122 case IR::Attribute::ColorBackDiffuseB:
118 case IR::Attribute::ColorBackDiffuseA: 123 case IR::Attribute::ColorBackDiffuseA:
119 info.stores_color_back_diffuse = true; 124 info.stores_color_back_diffuse = true;
125 info.stores_legacy_varyings = true;
120 break; 126 break;
121 case IR::Attribute::ColorBackSpecularR: 127 case IR::Attribute::ColorBackSpecularR:
122 case IR::Attribute::ColorBackSpecularG: 128 case IR::Attribute::ColorBackSpecularG:
123 case IR::Attribute::ColorBackSpecularB: 129 case IR::Attribute::ColorBackSpecularB:
124 case IR::Attribute::ColorBackSpecularA: 130 case IR::Attribute::ColorBackSpecularA:
125 info.stores_color_front_specular = true; 131 info.stores_color_back_specular = true;
132 info.stores_legacy_varyings = true;
126 break; 133 break;
127 case IR::Attribute::ClipDistance0: 134 case IR::Attribute::ClipDistance0:
128 case IR::Attribute::ClipDistance1: 135 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 {
128 bool loads_instance_id{}; 128 bool loads_instance_id{};
129 bool loads_vertex_id{}; 129 bool loads_vertex_id{};
130 bool loads_front_face{}; 130 bool loads_front_face{};
131 bool loads_legacy_varyings{};
131 132
132 bool loads_tess_coord{}; 133 bool loads_tess_coord{};
133 134
@@ -150,6 +151,7 @@ struct Info {
150 bool stores_clip_distance{}; 151 bool stores_clip_distance{};
151 bool stores_fog_coordinate{}; 152 bool stores_fog_coordinate{};
152 bool stores_viewport_mask{}; 153 bool stores_viewport_mask{};
154 bool stores_legacy_varyings{};
153 155
154 bool stores_tess_level_outer{}; 156 bool stores_tess_level_outer{};
155 bool stores_tess_level_inner{}; 157 bool stores_tess_level_inner{};