diff options
| author | 2021-06-03 20:57:52 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:37 -0400 | |
| commit | 34fdb6471d6050b438fd53a0406aedbf6b690600 (patch) | |
| tree | 0f483ab7f1e38bff1b03db30b9a000730df95913 /src | |
| parent | glsl: Refactor Global memory functions (diff) | |
| download | yuzu-34fdb6471d6050b438fd53a0406aedbf6b690600.tar.gz yuzu-34fdb6471d6050b438fd53a0406aedbf6b690600.tar.xz yuzu-34fdb6471d6050b438fd53a0406aedbf6b690600.zip | |
glsl: Cleanup and address feedback
Diffstat (limited to 'src')
10 files changed, 69 insertions, 86 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index fbc4b9c0f..ae5ac752d 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -22,9 +22,9 @@ std::string_view InterpDecorator(Interpolation interp) { | |||
| 22 | case Interpolation::Smooth: | 22 | case Interpolation::Smooth: |
| 23 | return ""; | 23 | return ""; |
| 24 | case Interpolation::Flat: | 24 | case Interpolation::Flat: |
| 25 | return "flat"; | 25 | return "flat "; |
| 26 | case Interpolation::NoPerspective: | 26 | case Interpolation::NoPerspective: |
| 27 | return "noperspective"; | 27 | return "noperspective "; |
| 28 | } | 28 | } |
| 29 | throw InvalidArgument("Invalid interpolation {}", interp); | 29 | throw InvalidArgument("Invalid interpolation {}", interp); |
| 30 | } | 30 | } |
| @@ -77,7 +77,6 @@ std::string_view SamplerType(TextureType type, bool is_depth) { | |||
| 77 | case TextureType::ColorArrayCube: | 77 | case TextureType::ColorArrayCube: |
| 78 | return "samplerCubeArrayShadow"; | 78 | return "samplerCubeArrayShadow"; |
| 79 | default: | 79 | default: |
| 80 | fmt::print("Texture type: {}", type); | ||
| 81 | throw NotImplementedException("Texture type: {}", type); | 80 | throw NotImplementedException("Texture type: {}", type); |
| 82 | } | 81 | } |
| 83 | } | 82 | } |
| @@ -191,29 +190,27 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { | |||
| 191 | if (!StoresPerVertexAttributes(ctx.stage)) { | 190 | if (!StoresPerVertexAttributes(ctx.stage)) { |
| 192 | return; | 191 | return; |
| 193 | } | 192 | } |
| 194 | header += "out gl_PerVertex{"; | 193 | header += "out gl_PerVertex{vec4 gl_Position;"; |
| 195 | header += "vec4 gl_Position;"; | ||
| 196 | if (ctx.info.stores_point_size) { | 194 | if (ctx.info.stores_point_size) { |
| 197 | header += "float gl_PointSize;"; | 195 | header += "float gl_PointSize;"; |
| 198 | } | 196 | } |
| 199 | if (ctx.info.stores_clip_distance) { | 197 | if (ctx.info.stores_clip_distance) { |
| 200 | header += "float gl_ClipDistance[];"; | 198 | header += "float gl_ClipDistance[];"; |
| 201 | } | 199 | } |
| 202 | if (ctx.info.stores_viewport_index && ctx.supports_viewport_layer && | 200 | if (ctx.info.stores_viewport_index && ctx.profile.support_gl_vertex_viewport_layer && |
| 203 | ctx.stage != Stage::Geometry) { | 201 | ctx.stage != Stage::Geometry) { |
| 204 | header += "int gl_ViewportIndex;"; | 202 | header += "int gl_ViewportIndex;"; |
| 205 | } | 203 | } |
| 206 | header += "};\n"; | 204 | header += "};"; |
| 207 | if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { | 205 | if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { |
| 208 | header += "out int gl_ViewportIndex;"; | 206 | header += "out int gl_ViewportIndex;"; |
| 209 | } | 207 | } |
| 210 | } | 208 | } |
| 211 | } // namespace | 209 | } // Anonymous namespace |
| 212 | 210 | ||
| 213 | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, | 211 | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, |
| 214 | const RuntimeInfo& runtime_info_) | 212 | const RuntimeInfo& runtime_info_) |
| 215 | : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { | 213 | : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { |
| 216 | supports_viewport_layer = profile.support_gl_vertex_viewport_layer; | ||
| 217 | SetupExtensions(header); | 214 | SetupExtensions(header); |
| 218 | stage = program.stage; | 215 | stage = program.stage; |
| 219 | switch (program.stage) { | 216 | switch (program.stage) { |
| @@ -222,18 +219,18 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 222 | stage_name = "vs"; | 219 | stage_name = "vs"; |
| 223 | break; | 220 | break; |
| 224 | case Stage::TessellationControl: | 221 | case Stage::TessellationControl: |
| 225 | stage_name = "tsc"; | 222 | stage_name = "tcs"; |
| 226 | header += fmt::format("layout(vertices={})out;\n", program.invocations); | 223 | header += fmt::format("layout(vertices={})out;", program.invocations); |
| 227 | break; | 224 | break; |
| 228 | case Stage::TessellationEval: | 225 | case Stage::TessellationEval: |
| 229 | stage_name = "tse"; | 226 | stage_name = "tes"; |
| 230 | header += fmt::format("layout({},{},{})in;\n", GetTessMode(runtime_info.tess_primitive), | 227 | header += fmt::format("layout({},{},{})in;", GetTessMode(runtime_info.tess_primitive), |
| 231 | GetTessSpacing(runtime_info.tess_spacing), | 228 | GetTessSpacing(runtime_info.tess_spacing), |
| 232 | runtime_info.tess_clockwise ? "cw" : "ccw"); | 229 | runtime_info.tess_clockwise ? "cw" : "ccw"); |
| 233 | break; | 230 | break; |
| 234 | case Stage::Geometry: | 231 | case Stage::Geometry: |
| 235 | stage_name = "gs"; | 232 | stage_name = "gs"; |
| 236 | header += fmt::format("layout({})in;layout({},max_vertices={})out;\n", | 233 | header += fmt::format("layout({})in;layout({},max_vertices={})out;", |
| 237 | InputPrimitive(runtime_info.input_topology), | 234 | InputPrimitive(runtime_info.input_topology), |
| 238 | OutputPrimitive(program.output_topology), program.output_vertices); | 235 | OutputPrimitive(program.output_topology), program.output_vertices); |
| 239 | break; | 236 | break; |
| @@ -242,7 +239,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 242 | break; | 239 | break; |
| 243 | case Stage::Compute: | 240 | case Stage::Compute: |
| 244 | stage_name = "cs"; | 241 | stage_name = "cs"; |
| 245 | header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", | 242 | header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;", |
| 246 | program.workgroup_size[0], program.workgroup_size[1], | 243 | program.workgroup_size[0], program.workgroup_size[1], |
| 247 | program.workgroup_size[2]); | 244 | program.workgroup_size[2]); |
| 248 | break; | 245 | break; |
| @@ -251,7 +248,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 251 | for (size_t index = 0; index < info.input_generics.size(); ++index) { | 248 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 252 | const auto& generic{info.input_generics[index]}; | 249 | const auto& generic{info.input_generics[index]}; |
| 253 | if (generic.used) { | 250 | if (generic.used) { |
| 254 | header += fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, | 251 | header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, |
| 255 | InterpDecorator(generic.interpolation), index, | 252 | InterpDecorator(generic.interpolation), index, |
| 256 | InputArrayDecorator(stage)); | 253 | InputArrayDecorator(stage)); |
| 257 | } | 254 | } |
| @@ -260,11 +257,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 260 | if (!info.uses_patches[index]) { | 257 | if (!info.uses_patches[index]) { |
| 261 | continue; | 258 | continue; |
| 262 | } | 259 | } |
| 263 | if (stage == Stage::TessellationControl) { | 260 | const auto qualifier{stage == Stage::TessellationControl ? "out" : "in"}; |
| 264 | header += fmt::format("layout(location={})patch out vec4 patch{};", index, index); | 261 | header += fmt::format("layout(location={})patch {} vec4 patch{};", index, qualifier, index); |
| 265 | } else { | ||
| 266 | header += fmt::format("layout(location={})patch in vec4 patch{};", index, index); | ||
| 267 | } | ||
| 268 | } | 262 | } |
| 269 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { | 263 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { |
| 270 | if (!info.stores_frag_color[index]) { | 264 | if (!info.stores_frag_color[index]) { |
| @@ -278,18 +272,18 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 278 | DefineGenericOutput(index, program.invocations); | 272 | DefineGenericOutput(index, program.invocations); |
| 279 | } | 273 | } |
| 280 | } | 274 | } |
| 281 | header += "\n"; | ||
| 282 | DefineConstantBuffers(bindings); | 275 | DefineConstantBuffers(bindings); |
| 283 | DefineStorageBuffers(bindings); | 276 | DefineStorageBuffers(bindings); |
| 284 | SetupImages(bindings); | 277 | SetupImages(bindings); |
| 278 | SetupTextures(bindings); | ||
| 285 | DefineHelperFunctions(); | 279 | DefineHelperFunctions(); |
| 286 | } | 280 | } |
| 287 | 281 | ||
| 288 | void EmitContext::SetupExtensions(std::string&) { | 282 | void EmitContext::SetupExtensions(std::string&) { |
| 289 | // TODO: track this usage | 283 | // TODO: track this usage |
| 290 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; | 284 | header += "#extension GL_ARB_sparse_texture2 : enable\n" |
| 291 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | 285 | "#extension GL_EXT_texture_shadow_lod : enable\n" |
| 292 | header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; | 286 | "#extension GL_EXT_shader_image_load_formatted : enable\n"; |
| 293 | if (info.uses_int64) { | 287 | if (info.uses_int64) { |
| 294 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | 288 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |
| 295 | } | 289 | } |
| @@ -312,13 +306,14 @@ void EmitContext::SetupExtensions(std::string&) { | |||
| 312 | } | 306 | } |
| 313 | if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || | 307 | if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || |
| 314 | info.uses_subgroup_shuffles || info.uses_fswzadd) { | 308 | info.uses_subgroup_shuffles || info.uses_fswzadd) { |
| 315 | header += "#extension GL_ARB_shader_ballot : enable\n"; | 309 | header += "#extension GL_ARB_shader_ballot : enable\n" |
| 316 | header += "#extension GL_ARB_shader_group_vote : enable\n"; | 310 | "#extension GL_ARB_shader_group_vote : enable\n"; |
| 317 | if (!info.uses_int64) { | 311 | if (!info.uses_int64) { |
| 318 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | 312 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |
| 319 | } | 313 | } |
| 320 | } | 314 | } |
| 321 | if (info.stores_viewport_index && supports_viewport_layer && stage != Stage::Geometry) { | 315 | if (info.stores_viewport_index && profile.support_gl_vertex_viewport_layer && |
| 316 | stage != Stage::Geometry) { | ||
| 322 | header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; | 317 | header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; |
| 323 | } | 318 | } |
| 324 | } | 319 | } |
| @@ -386,46 +381,45 @@ void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { | |||
| 386 | std::fill_n(output_generics[index].begin() + element, num_components, element_info); | 381 | std::fill_n(output_generics[index].begin() + element, num_components, element_info); |
| 387 | element += num_components; | 382 | element += num_components; |
| 388 | } | 383 | } |
| 389 | header += "\n"; | ||
| 390 | } | 384 | } |
| 391 | 385 | ||
| 392 | void EmitContext::DefineHelperFunctions() { | 386 | void EmitContext::DefineHelperFunctions() { |
| 393 | header += "\n#define ftoi floatBitsToInt\n#define ftou floatBitsToUint\n" | 387 | header += "\n#define ftoi floatBitsToInt\n#define ftou floatBitsToUint\n" |
| 394 | "#define itof intBitsToFloat\n#define utof uintBitsToFloat\n"; | 388 | "#define itof intBitsToFloat\n#define utof uintBitsToFloat\n"; |
| 395 | if (info.uses_global_increment || info.uses_shared_increment) { | 389 | if (info.uses_global_increment || info.uses_shared_increment) { |
| 396 | header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; | 390 | header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; |
| 397 | } | 391 | } |
| 398 | if (info.uses_global_decrement || info.uses_shared_decrement) { | 392 | if (info.uses_global_decrement || info.uses_shared_decrement) { |
| 399 | header += "uint CasDecrement(uint op_a,uint " | 393 | header += "uint CasDecrement(uint op_a,uint " |
| 400 | "op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; | 394 | "op_b){return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; |
| 401 | } | 395 | } |
| 402 | if (info.uses_atomic_f32_add) { | 396 | if (info.uses_atomic_f32_add) { |
| 403 | header += "uint CasFloatAdd(uint op_a,float op_b){return " | 397 | header += "uint CasFloatAdd(uint op_a,float op_b){return " |
| 404 | "ftou(utof(op_a)+op_b);}\n"; | 398 | "ftou(utof(op_a)+op_b);}"; |
| 405 | } | 399 | } |
| 406 | if (info.uses_atomic_f32x2_add) { | 400 | if (info.uses_atomic_f32x2_add) { |
| 407 | header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " | 401 | header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " |
| 408 | "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; | 402 | "packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; |
| 409 | } | 403 | } |
| 410 | if (info.uses_atomic_f32x2_min) { | 404 | if (info.uses_atomic_f32x2_min) { |
| 411 | header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " | 405 | header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " |
| 412 | "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; | 406 | "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}"; |
| 413 | } | 407 | } |
| 414 | if (info.uses_atomic_f32x2_max) { | 408 | if (info.uses_atomic_f32x2_max) { |
| 415 | header += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " | 409 | header += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " |
| 416 | "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; | 410 | "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}"; |
| 417 | } | 411 | } |
| 418 | if (info.uses_atomic_f16x2_add) { | 412 | if (info.uses_atomic_f16x2_add) { |
| 419 | header += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " | 413 | header += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " |
| 420 | "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; | 414 | "packFloat2x16(unpackFloat2x16(op_a)+op_b);}"; |
| 421 | } | 415 | } |
| 422 | if (info.uses_atomic_f16x2_min) { | 416 | if (info.uses_atomic_f16x2_min) { |
| 423 | header += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " | 417 | header += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " |
| 424 | "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; | 418 | "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}"; |
| 425 | } | 419 | } |
| 426 | if (info.uses_atomic_f16x2_max) { | 420 | if (info.uses_atomic_f16x2_max) { |
| 427 | header += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " | 421 | header += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " |
| 428 | "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; | 422 | "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}"; |
| 429 | } | 423 | } |
| 430 | if (info.uses_atomic_s32_min) { | 424 | if (info.uses_atomic_s32_min) { |
| 431 | header += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; | 425 | header += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; |
| @@ -534,6 +528,9 @@ void EmitContext::SetupImages(Bindings& bindings) { | |||
| 534 | } | 528 | } |
| 535 | bindings.image += desc.count; | 529 | bindings.image += desc.count; |
| 536 | } | 530 | } |
| 531 | } | ||
| 532 | |||
| 533 | void EmitContext::SetupTextures(Bindings& bindings) { | ||
| 537 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); | 534 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); |
| 538 | for (const auto& desc : info.texture_buffer_descriptors) { | 535 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 539 | texture_buffer_bindings.push_back(bindings.texture); | 536 | texture_buffer_bindings.push_back(bindings.texture); |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index daca1b6f9..9bdca184f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h | |||
| @@ -31,7 +31,7 @@ struct Program; | |||
| 31 | namespace Shader::Backend::GLSL { | 31 | namespace Shader::Backend::GLSL { |
| 32 | 32 | ||
| 33 | struct GenericElementInfo { | 33 | struct GenericElementInfo { |
| 34 | std::string name{}; | 34 | std::string name; |
| 35 | u32 first_element{}; | 35 | u32 first_element{}; |
| 36 | u32 num_components{}; | 36 | u32 num_components{}; |
| 37 | }; | 37 | }; |
| @@ -159,7 +159,6 @@ public: | |||
| 159 | 159 | ||
| 160 | bool uses_y_direction{}; | 160 | bool uses_y_direction{}; |
| 161 | bool uses_cc_carry{}; | 161 | bool uses_cc_carry{}; |
| 162 | bool supports_viewport_layer{}; | ||
| 163 | 162 | ||
| 164 | private: | 163 | private: |
| 165 | void SetupExtensions(std::string& header); | 164 | void SetupExtensions(std::string& header); |
| @@ -169,6 +168,7 @@ private: | |||
| 169 | void DefineHelperFunctions(); | 168 | void DefineHelperFunctions(); |
| 170 | std::string DefineGlobalMemoryFunctions(); | 169 | std::string DefineGlobalMemoryFunctions(); |
| 171 | void SetupImages(Bindings& bindings); | 170 | void SetupImages(Bindings& bindings); |
| 171 | void SetupTextures(Bindings& bindings); | ||
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | } // namespace Shader::Backend::GLSL | 174 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp index bfc42e1b4..7b57c1e91 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp | |||
| @@ -83,7 +83,6 @@ void Invoke(EmitContext& ctx, IR::Inst* inst) { | |||
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void EmitInst(EmitContext& ctx, IR::Inst* inst) { | 85 | void EmitInst(EmitContext& ctx, IR::Inst* inst) { |
| 86 | // ctx.Add("/* $ {} $ */", inst->GetOpcode()); | ||
| 87 | switch (inst->GetOpcode()) { | 86 | switch (inst->GetOpcode()) { |
| 88 | #define OPCODE(name, result_type, ...) \ | 87 | #define OPCODE(name, result_type, ...) \ |
| 89 | case IR::Opcode::name: \ | 88 | case IR::Opcode::name: \ |
| @@ -134,7 +133,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||
| 134 | } | 133 | } |
| 135 | break; | 134 | break; |
| 136 | case IR::AbstractSyntaxNode::Type::If: | 135 | case IR::AbstractSyntaxNode::Type::If: |
| 137 | ctx.Add("if ({}){{", ctx.var_alloc.Consume(node.data.if_node.cond)); | 136 | ctx.Add("if({}){{", ctx.var_alloc.Consume(node.data.if_node.cond)); |
| 138 | break; | 137 | break; |
| 139 | case IR::AbstractSyntaxNode::Type::EndIf: | 138 | case IR::AbstractSyntaxNode::Type::EndIf: |
| 140 | ctx.Add("}}"); | 139 | ctx.Add("}}"); |
| @@ -156,12 +155,10 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||
| 156 | ctx.Add("for(;;){{"); | 155 | ctx.Add("for(;;){{"); |
| 157 | break; | 156 | break; |
| 158 | case IR::AbstractSyntaxNode::Type::Repeat: | 157 | case IR::AbstractSyntaxNode::Type::Repeat: |
| 159 | ctx.Add("if({}){{", ctx.var_alloc.Consume(node.data.repeat.cond)); | 158 | ctx.Add("if({}){{continue;}}else{{break;}}}}", |
| 160 | ctx.Add("continue;\n}}else{{"); | 159 | ctx.var_alloc.Consume(node.data.repeat.cond)); |
| 161 | ctx.Add("break;\n}}\n}}"); | ||
| 162 | break; | 160 | break; |
| 163 | default: | 161 | default: |
| 164 | fmt::print("{}", node.type); | ||
| 165 | throw NotImplementedException("AbstractSyntaxNode::Type {}", node.type); | 162 | throw NotImplementedException("AbstractSyntaxNode::Type {}", node.type); |
| 166 | break; | 163 | break; |
| 167 | } | 164 | } |
| @@ -200,7 +197,7 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR | |||
| 200 | EmitContext ctx{program, bindings, profile, runtime_info}; | 197 | EmitContext ctx{program, bindings, profile, runtime_info}; |
| 201 | Precolor(program); | 198 | Precolor(program); |
| 202 | EmitCode(ctx, program); | 199 | EmitCode(ctx, program); |
| 203 | const std::string version{fmt::format("#version 460{}\n", GlslVersionSpecifier(ctx))}; | 200 | const std::string version{fmt::format("#version 450{}\n", GlslVersionSpecifier(ctx))}; |
| 204 | ctx.header.insert(0, version); | 201 | ctx.header.insert(0, version); |
| 205 | if (program.local_memory_size > 0) { | 202 | if (program.local_memory_size > 0) { |
| 206 | ctx.header += fmt::format("uint lmem[{}];", program.local_memory_size / 4); | 203 | ctx.header += fmt::format("uint lmem[{}];", program.local_memory_size / 4); |
| @@ -225,10 +222,8 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR | |||
| 225 | if (program.info.uses_subgroup_shuffles) { | 222 | if (program.info.uses_subgroup_shuffles) { |
| 226 | ctx.header += "bool shfl_in_bounds;"; | 223 | ctx.header += "bool shfl_in_bounds;"; |
| 227 | } | 224 | } |
| 228 | ctx.header += "\n"; | ||
| 229 | ctx.code.insert(0, ctx.header); | 225 | ctx.code.insert(0, ctx.header); |
| 230 | ctx.code += "}"; | 226 | ctx.code += '}'; |
| 231 | // fmt::print("\n{}\n", ctx.code); | ||
| 232 | return ctx.code; | 227 | return ctx.code; |
| 233 | } | 228 | } |
| 234 | 229 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp index f8d2c12db..5ba39261b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | namespace Shader::Backend::GLSL { | 12 | namespace Shader::Backend::GLSL { |
| 13 | namespace { | 13 | namespace { |
| 14 | static constexpr std::string_view cas_loop{R"(for (;;){{ | 14 | constexpr const char cas_loop[]{R"(for (;;){{ |
| 15 | uint old_value={}; | 15 | uint old_value={}; |
| 16 | {}=atomicCompSwap({},old_value,{}({},{})); | 16 | {}=atomicCompSwap({},old_value,{}({},{})); |
| 17 | if ({}==old_value){{break;}} | 17 | if ({}==old_value){{break;}} |
| @@ -21,7 +21,7 @@ void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset | |||
| 21 | std::string_view value, std::string_view function) { | 21 | std::string_view value, std::string_view function) { |
| 22 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 22 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 23 | const std::string smem{fmt::format("smem[{}>>2]", offset)}; | 23 | const std::string smem{fmt::format("smem[{}>>2]", offset)}; |
| 24 | ctx.Add(cas_loop.data(), smem, ret, smem, function, smem, value, ret); | 24 | ctx.Add(cas_loop, smem, ret, smem, function, smem, value, ret); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 27 | void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -29,7 +29,7 @@ void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | |||
| 29 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 29 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 30 | const std::string ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), | 30 | const std::string ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), |
| 31 | ctx.var_alloc.Consume(offset))}; | 31 | ctx.var_alloc.Consume(offset))}; |
| 32 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | 32 | ctx.Add(cas_loop, ssbo, ret, ssbo, function, ssbo, value, ret); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 35 | void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -38,10 +38,10 @@ void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi | |||
| 38 | const std::string ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), | 38 | const std::string ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), |
| 39 | ctx.var_alloc.Consume(offset))}; | 39 | ctx.var_alloc.Consume(offset))}; |
| 40 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 40 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 41 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | 41 | ctx.Add(cas_loop, ssbo, ret, ssbo, function, ssbo, value, ret); |
| 42 | ctx.AddF32("{}=utof({});", inst, ret); | 42 | ctx.AddF32("{}=utof({});", inst, ret); |
| 43 | } | 43 | } |
| 44 | } // namespace | 44 | } // Anonymous namespace |
| 45 | 45 | ||
| 46 | void EmitSharedAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, | 46 | void EmitSharedAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view pointer_offset, |
| 47 | std::string_view value) { | 47 | std::string_view value) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp index 0e617c8d8..eff672cc4 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
| 12 | namespace { | 12 | namespace { |
| 13 | static void Alias(IR::Inst& inst, const IR::Value& value) { | 13 | void Alias(IR::Inst& inst, const IR::Value& value) { |
| 14 | if (value.IsImmediate()) { | 14 | if (value.IsImmediate()) { |
| 15 | return; | 15 | return; |
| 16 | } | 16 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp index 3697e1a34..954fc67b1 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp | |||
| @@ -10,13 +10,14 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
| 12 | namespace { | 12 | namespace { |
| 13 | static constexpr std::string_view SWIZZLE{"xyzw"}; | 13 | constexpr std::string_view SWIZZLE{"xyzw"}; |
| 14 | void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite, | 14 | void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite, |
| 15 | std::string_view object, u32 index) { | 15 | std::string_view object, u32 index) { |
| 16 | ctx.Add("{}={};", result, composite); | 16 | ctx.Add("{}={};", result, composite); |
| 17 | ctx.Add("{}.{}={};", result, SWIZZLE[index], object); | 17 | ctx.Add("{}.{}={};", result, SWIZZLE[index], object); |
| 18 | } | 18 | } |
| 19 | } // namespace | 19 | } // Anonymous namespace |
| 20 | |||
| 20 | void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1, | 21 | void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1, |
| 21 | std::string_view e2) { | 22 | std::string_view e2) { |
| 22 | ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2); | 23 | ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2); |
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 19b51a813..d986e1b1a 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 | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | 7 | #include "shader_recompiler/backend/glsl/emit_context.h" |
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | ||
| 10 | 11 | ||
| 11 | namespace Shader::Backend::GLSL { | 12 | namespace Shader::Backend::GLSL { |
| 12 | namespace { | 13 | namespace { |
| @@ -39,11 +40,10 @@ std::string OutputVertexIndex(EmitContext& ctx, std::string_view vertex) { | |||
| 39 | return ""; | 40 | return ""; |
| 40 | } | 41 | } |
| 41 | } | 42 | } |
| 42 | } // namespace | 43 | } // Anonymous namespace |
| 43 | 44 | ||
| 44 | void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 45 | void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 45 | [[maybe_unused]] const IR::Value& binding, | 46 | const IR::Value& offset) { |
| 46 | [[maybe_unused]] const IR::Value& offset) { | ||
| 47 | if (offset.IsImmediate()) { | 47 | if (offset.IsImmediate()) { |
| 48 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, | 48 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, |
| 49 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 49 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| @@ -55,9 +55,8 @@ void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& | |||
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void EmitGetCbufS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 58 | void EmitGetCbufS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 59 | [[maybe_unused]] const IR::Value& binding, | 59 | const IR::Value& offset) { |
| 60 | [[maybe_unused]] const IR::Value& offset) { | ||
| 61 | if (offset.IsImmediate()) { | 60 | if (offset.IsImmediate()) { |
| 62 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, | 61 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, |
| 63 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 62 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| @@ -69,9 +68,8 @@ void EmitGetCbufS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& | |||
| 69 | } | 68 | } |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | void EmitGetCbufU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 71 | void EmitGetCbufU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 73 | [[maybe_unused]] const IR::Value& binding, | 72 | const IR::Value& offset) { |
| 74 | [[maybe_unused]] const IR::Value& offset) { | ||
| 75 | if (offset.IsImmediate()) { | 73 | if (offset.IsImmediate()) { |
| 76 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, | 74 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, |
| 77 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 75 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| @@ -84,9 +82,8 @@ void EmitGetCbufU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 84 | } | 82 | } |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 85 | void EmitGetCbufS16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 88 | [[maybe_unused]] const IR::Value& binding, | 86 | const IR::Value& offset) { |
| 89 | [[maybe_unused]] const IR::Value& offset) { | ||
| 90 | if (offset.IsImmediate()) { | 87 | if (offset.IsImmediate()) { |
| 91 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, | 88 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, |
| 92 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 89 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| @@ -196,7 +193,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 196 | } | 193 | } |
| 197 | 194 | ||
| 198 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, | 195 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, |
| 199 | [[maybe_unused]] std::string_view vertex) { | 196 | std::string_view vertex) { |
| 200 | if (IR::IsGeneric(attr)) { | 197 | if (IR::IsGeneric(attr)) { |
| 201 | const u32 index{IR::GenericAttributeIndex(attr)}; | 198 | const u32 index{IR::GenericAttributeIndex(attr)}; |
| 202 | const u32 element{IR::GenericAttributeElement(attr)}; | 199 | const u32 element{IR::GenericAttributeElement(attr)}; |
| @@ -223,7 +220,7 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val | |||
| 223 | ctx.Add("gl_Position.{}={};", swizzle, value); | 220 | ctx.Add("gl_Position.{}={};", swizzle, value); |
| 224 | break; | 221 | break; |
| 225 | case IR::Attribute::ViewportIndex: | 222 | case IR::Attribute::ViewportIndex: |
| 226 | if (ctx.stage != Stage::Geometry && !ctx.supports_viewport_layer) { | 223 | if (ctx.stage != Stage::Geometry && !ctx.profile.support_gl_vertex_viewport_layer) { |
| 227 | // LOG_WARNING(..., "Shader stores viewport index but device does not support viewport | 224 | // LOG_WARNING(..., "Shader stores viewport index but device does not support viewport |
| 228 | // layer extension"); | 225 | // layer extension"); |
| 229 | break; | 226 | break; |
| @@ -247,8 +244,7 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val | |||
| 247 | } | 244 | } |
| 248 | } | 245 | } |
| 249 | 246 | ||
| 250 | void EmitGetPatch([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 247 | void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) { |
| 251 | [[maybe_unused]] IR::Patch patch) { | ||
| 252 | if (!IR::IsGeneric(patch)) { | 248 | if (!IR::IsGeneric(patch)) { |
| 253 | throw NotImplementedException("Non-generic patch load"); | 249 | throw NotImplementedException("Non-generic patch load"); |
| 254 | } | 250 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp index f4b81407a..adeafdd3d 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp | |||
| @@ -25,7 +25,7 @@ void Compare(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, std::string | |||
| 25 | bool Precise(IR::Inst& inst) { | 25 | bool Precise(IR::Inst& inst) { |
| 26 | return {inst.Flags<IR::FpControl>().no_contraction}; | 26 | return {inst.Flags<IR::FpControl>().no_contraction}; |
| 27 | } | 27 | } |
| 28 | } // namespace | 28 | } // Anonymous namespace |
| 29 | 29 | ||
| 30 | void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 30 | void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 31 | [[maybe_unused]] std::string_view value) { | 31 | [[maybe_unused]] std::string_view value) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 37ddd57d3..ce3a82656 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -102,7 +102,7 @@ IR::Inst* PrepareSparse(IR::Inst& inst) { | |||
| 102 | } | 102 | } |
| 103 | return sparse_inst; | 103 | return sparse_inst; |
| 104 | } | 104 | } |
| 105 | } // namespace | 105 | } // Anonymous namespace |
| 106 | 106 | ||
| 107 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 107 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 108 | [[maybe_unused]] const IR::Value& index, | 108 | [[maybe_unused]] const IR::Value& index, |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index cac803146..c64d4325d 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -25,9 +25,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | |||
| 25 | } | 25 | } |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void EmitVoid(EmitContext& ctx) { | 28 | void EmitVoid(EmitContext& ctx) {} |
| 29 | // NotImplemented(); | ||
| 30 | } | ||
| 31 | 29 | ||
| 32 | void EmitReference(EmitContext& ctx, const IR::Value& value) { | 30 | void EmitReference(EmitContext& ctx, const IR::Value& value) { |
| 33 | ctx.var_alloc.Consume(value); | 31 | ctx.var_alloc.Consume(value); |
| @@ -94,13 +92,9 @@ void EmitDeviceMemoryBarrier(EmitContext& ctx) { | |||
| 94 | NotImplemented(); | 92 | NotImplemented(); |
| 95 | } | 93 | } |
| 96 | 94 | ||
| 97 | void EmitPrologue(EmitContext& ctx) { | 95 | void EmitPrologue(EmitContext& ctx) {} |
| 98 | // NotImplemented(); | ||
| 99 | } | ||
| 100 | 96 | ||
| 101 | void EmitEpilogue(EmitContext& ctx) { | 97 | void EmitEpilogue(EmitContext& ctx) {} |
| 102 | // NotImplemented(); | ||
| 103 | } | ||
| 104 | 98 | ||
| 105 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | 99 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { |
| 106 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); | 100 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); |