From eaff1030de07f3739794207403ea833ee91c0034 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 19 May 2021 21:58:32 -0400 Subject: glsl: Initial backend --- .../backend/glsl/emit_context.cpp | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/shader_recompiler/backend/glsl/emit_context.cpp (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp new file mode 100644 index 000000000..e2a9885f0 --- /dev/null +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -0,0 +1,30 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "shader_recompiler/backend/bindings.h" +#include "shader_recompiler/backend/glsl/emit_context.h" +#include "shader_recompiler/frontend/ir/program.h" + +namespace Shader::Backend::GLSL { + +EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindings, + const Profile& profile_) + : info{program.info}, profile{profile_} { + std::string header = "#version 450 core\n"; + header += "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;"; + code += header; + DefineConstantBuffers(); + code += "void main(){"; +} + +void EmitContext::DefineConstantBuffers() { + if (info.constant_buffer_descriptors.empty()) { + return; + } + for (const auto& desc : info.constant_buffer_descriptors) { + Add("uniform uint c{}[{}];", desc.index, desc.count); + } +} + +} // namespace Shader::Backend::GLSL -- cgit v1.2.3 From 64337f004d9249c4408fec75bd1bbcc0f2a1408d Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 20 May 2021 23:38:38 -0400 Subject: glsl: Fix "reg" allocing based on glasm with some tweaks --- .../backend/glsl/emit_context.cpp | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index e2a9885f0..b0e46cc07 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -11,19 +11,39 @@ namespace Shader::Backend::GLSL { EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindings, const Profile& profile_) : info{program.info}, profile{profile_} { - std::string header = "#version 450 core\n"; - header += "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;"; + std::string header = "#version 450\n"; + if (program.stage == Stage::Compute) { + header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", + program.workgroup_size[0], program.workgroup_size[1], + program.workgroup_size[2]); + } code += header; DefineConstantBuffers(); - code += "void main(){"; + DefineStorageBuffers(); + code += "void main(){\n"; } void EmitContext::DefineConstantBuffers() { if (info.constant_buffer_descriptors.empty()) { return; } + u32 binding{}; for (const auto& desc : info.constant_buffer_descriptors) { - Add("uniform uint c{}[{}];", desc.index, desc.count); + Add("layout(std140,binding={}) uniform cbuf_{}{{uint cbuf{}[];}};", binding, binding, + desc.index, desc.count); + ++binding; + } +} + +void EmitContext::DefineStorageBuffers() { + if (info.storage_buffers_descriptors.empty()) { + return; + } + u32 binding{}; + for (const auto& desc : info.storage_buffers_descriptors) { + Add("layout(std430,binding={}) buffer buff_{}{{uint buff{}[];}};", binding, binding, + desc.cbuf_index, desc.count); + ++binding; } } -- cgit v1.2.3 From faf4cd72c556421966782cece604b64fbafa5714 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 21 May 2021 01:12:58 -0400 Subject: glsl: Fix program linking and cbuf --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index b0e46cc07..8eea6344f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -29,8 +29,8 @@ void EmitContext::DefineConstantBuffers() { } u32 binding{}; for (const auto& desc : info.constant_buffer_descriptors) { - Add("layout(std140,binding={}) uniform cbuf_{}{{uint cbuf{}[];}};", binding, binding, - desc.index, desc.count); + Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, binding, + desc.index, 4 * 1024); ++binding; } } -- cgit v1.2.3 From 0f40b0e61ccc04216e0840e092dfe3051716b8b6 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 21 May 2021 20:56:46 -0400 Subject: glsl: Implement a few Integer instructions --- src/shader_recompiler/backend/glsl/emit_context.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 8eea6344f..b3a3e5647 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -12,6 +12,7 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin const Profile& profile_) : info{program.info}, profile{profile_} { std::string header = "#version 450\n"; + SetupExtensions(header); if (program.stage == Stage::Compute) { header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", program.workgroup_size[0], program.workgroup_size[1], @@ -23,6 +24,12 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin code += "void main(){\n"; } +void EmitContext::SetupExtensions(std::string& header) { + if (info.uses_int64) { + header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; + } +} + void EmitContext::DefineConstantBuffers() { if (info.constant_buffer_descriptors.empty()) { return; -- cgit v1.2.3 From 3064bde4155b865d61258e8fa87df9e6377578b6 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 22 May 2021 15:06:14 -0400 Subject: glsl: FP function fixes --- src/shader_recompiler/backend/glsl/emit_context.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index b3a3e5647..da379360a 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -48,8 +48,11 @@ void EmitContext::DefineStorageBuffers() { } u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - Add("layout(std430,binding={}) buffer buff_{}{{uint buff{}[];}};", binding, binding, + Add("layout(std430,binding={}) buffer ssbo_{}_u32{{uint ssbo{}_u32[];}};", binding, binding, desc.cbuf_index, desc.count); + // TODO: Track ssbo data type usage + Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uvec2 ssbo{}_u64[];}};", binding, + binding, desc.cbuf_index, desc.count); ++binding; } } -- cgit v1.2.3 From ac7b0ebcb77f6c99d054e9d10412e669eefa0de6 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 22 May 2021 23:03:27 -0400 Subject: glsl: More FP fixes --- src/shader_recompiler/backend/glsl/emit_context.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index da379360a..67772c46d 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -48,11 +48,16 @@ void EmitContext::DefineStorageBuffers() { } u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - Add("layout(std430,binding={}) buffer ssbo_{}_u32{{uint ssbo{}_u32[];}};", binding, binding, - desc.cbuf_index, desc.count); - // TODO: Track ssbo data type usage - Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uvec2 ssbo{}_u64[];}};", binding, - binding, desc.cbuf_index, desc.count); + if (True(info.used_storage_buffer_types & IR::Type::U32) || + True(info.used_storage_buffer_types & IR::Type::F32)) { + Add("layout(std430,binding={}) buffer ssbo_{}_u32{{uint ssbo{}_u32[];}};", binding, + binding, desc.cbuf_index, desc.count); + } + if (True(info.used_storage_buffer_types & IR::Type::U32x2) || + True(info.used_storage_buffer_types & IR::Type::F32x2)) { + Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uvec2 ssbo{}_u64[];}};", binding, + binding, desc.cbuf_index, desc.count); + } ++binding; } } -- cgit v1.2.3 From 3d9ecbe99844c44074c26f2db4db376059f50534 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 24 May 2021 18:35:37 -0400 Subject: glsl: Wip storage atomic ops --- .../backend/glsl/emit_context.cpp | 42 +++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 67772c46d..3c610a08a 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -19,8 +19,10 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin program.workgroup_size[2]); } code += header; + DefineConstantBuffers(); DefineStorageBuffers(); + DefineHelperFunctions(); code += "void main(){\n"; } @@ -28,6 +30,15 @@ void EmitContext::SetupExtensions(std::string& header) { if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } + if (info.uses_int64_bit_atomics) { + header += "#extension GL_NV_shader_atomic_int64 : enable\n"; + } + if (info.uses_atomic_f32_add) { + header += "#extension GL_NV_shader_atomic_float : enable\n"; + } + if (info.uses_atomic_f16x2_add || info.uses_atomic_f16x2_min || info.uses_atomic_f16x2_max) { + header += "#extension NV_shader_atomic_fp16_vector : enable\n"; + } } void EmitContext::DefineConstantBuffers() { @@ -48,18 +59,39 @@ void EmitContext::DefineStorageBuffers() { } u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - if (True(info.used_storage_buffer_types & IR::Type::U32) || - True(info.used_storage_buffer_types & IR::Type::F32)) { + if (info.uses_s32_atomics) { + Add("layout(std430,binding={}) buffer ssbo_{}_s32{{int ssbo{}_s32[];}};", binding, + binding, desc.cbuf_index, desc.count); + } + if (True(info.used_storage_buffer_types & IR::Type::U32)) { Add("layout(std430,binding={}) buffer ssbo_{}_u32{{uint ssbo{}_u32[];}};", binding, binding, desc.cbuf_index, desc.count); } - if (True(info.used_storage_buffer_types & IR::Type::U32x2) || - True(info.used_storage_buffer_types & IR::Type::F32x2)) { - Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uvec2 ssbo{}_u64[];}};", binding, + if (True(info.used_storage_buffer_types & IR::Type::F32)) { + Add("layout(std430,binding={}) buffer ssbo_{}_f32{{float ssbo{}_f32[];}};", binding, + binding, desc.cbuf_index, desc.count); + } + if (True(info.used_storage_buffer_types & IR::Type::U32x2)) { + Add("layout(std430,binding={}) buffer ssbo_{}_u32x2{{uvec2 ssbo{}_u32x2[];}};", binding, + binding, desc.cbuf_index, desc.count); + } + if (True(info.used_storage_buffer_types & IR::Type::U64) || + True(info.used_storage_buffer_types & IR::Type::F64)) { + Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uint64_t ssbo{}_u64[];}};", binding, binding, desc.cbuf_index, desc.count); } ++binding; } } +void EmitContext::DefineHelperFunctions() { + if (info.uses_global_increment) { + code += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; + } + if (info.uses_global_decrement) { + code += + "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; + } +} + } // namespace Shader::Backend::GLSL -- cgit v1.2.3 From 11ba190462c7b69a47598b2d1572fac3bccc4adc Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 25 May 2021 01:35:30 -0400 Subject: glsl: Revert ssbo aliasing. Storage Atomics impl --- .../backend/glsl/emit_context.cpp | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 3c610a08a..7986bf78f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -59,27 +59,8 @@ void EmitContext::DefineStorageBuffers() { } u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - if (info.uses_s32_atomics) { - Add("layout(std430,binding={}) buffer ssbo_{}_s32{{int ssbo{}_s32[];}};", binding, - binding, desc.cbuf_index, desc.count); - } - if (True(info.used_storage_buffer_types & IR::Type::U32)) { - Add("layout(std430,binding={}) buffer ssbo_{}_u32{{uint ssbo{}_u32[];}};", binding, - binding, desc.cbuf_index, desc.count); - } - if (True(info.used_storage_buffer_types & IR::Type::F32)) { - Add("layout(std430,binding={}) buffer ssbo_{}_f32{{float ssbo{}_f32[];}};", binding, - binding, desc.cbuf_index, desc.count); - } - if (True(info.used_storage_buffer_types & IR::Type::U32x2)) { - Add("layout(std430,binding={}) buffer ssbo_{}_u32x2{{uvec2 ssbo{}_u32x2[];}};", binding, - binding, desc.cbuf_index, desc.count); - } - if (True(info.used_storage_buffer_types & IR::Type::U64) || - True(info.used_storage_buffer_types & IR::Type::F64)) { - Add("layout(std430,binding={}) buffer ssbo_{}_u64{{uint64_t ssbo{}_u64[];}};", binding, - binding, desc.cbuf_index, desc.count); - } + Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", binding, binding, + desc.cbuf_index, desc.count); ++binding; } } @@ -92,6 +73,25 @@ void EmitContext::DefineHelperFunctions() { code += "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; } + if (info.uses_atomic_f32_add) { + code += "uint CasFloatAdd(uint op_a,uint op_b){return " + "floatBitsToUint(uintBitsToFloat(op_a)+uintBitsToFloat(op_b));}\n"; + } + if (info.uses_atomic_f32x2_add) { + code += "uint CasFloatAdd32x2(uint op_a,uint op_b){return " + "packHalf2x16(unpackHalf2x16(op_a)+unpackHalf2x16(op_b));}\n"; + } + if (info.uses_atomic_f32x2_min) { + code += "uint CasFloatMin32x2(uint op_a,uint op_b){return " + "packHalf2x16(min(unpackHalf2x16(op_a),unpackHalf2x16(op_b)));}\n"; + } + if (info.uses_atomic_f32x2_max) { + code += "uint CasFloatMax32x2(uint op_a,uint op_b){return " + "packHalf2x16(max(unpackHalf2x16(op_a),unpackHalf2x16(op_b)));}\n"; + } + // TODO: Track this usage + code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; + code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; } } // namespace Shader::Backend::GLSL -- cgit v1.2.3 From 9cc1b8a873196dac5a97368df125816b5b195777 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 25 May 2021 01:52:02 -0400 Subject: glsl: F16x2 storage atomics --- src/shader_recompiler/backend/glsl/emit_context.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 7986bf78f..a413219e3 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -39,6 +39,10 @@ void EmitContext::SetupExtensions(std::string& header) { if (info.uses_atomic_f16x2_add || info.uses_atomic_f16x2_min || info.uses_atomic_f16x2_max) { header += "#extension NV_shader_atomic_fp16_vector : enable\n"; } + if (info.uses_fp16) { + // TODO: AMD + header += "#extension GL_NV_gpu_shader5 : enable\n"; + } } void EmitContext::DefineConstantBuffers() { @@ -89,6 +93,18 @@ void EmitContext::DefineHelperFunctions() { code += "uint CasFloatMax32x2(uint op_a,uint op_b){return " "packHalf2x16(max(unpackHalf2x16(op_a),unpackHalf2x16(op_b)));}\n"; } + if (info.uses_atomic_f16x2_add) { + code += "uint CasFloatAdd16x2(uint op_a,uint op_b){return " + "packFloat2x16(unpackFloat2x16(op_a)+unpackFloat2x16(op_b));}\n"; + } + if (info.uses_atomic_f16x2_min) { + code += "uint CasFloatMin16x2(uint op_a,uint op_b){return " + "packFloat2x16(min(unpackFloat2x16(op_a),unpackFloat2x16(op_b)));}\n"; + } + if (info.uses_atomic_f16x2_max) { + code += "uint CasFloatMax16x2(uint op_a,uint op_b){return " + "packFloat2x16(max(unpackFloat2x16(op_a),unpackFloat2x16(op_b)));}\n"; + } // TODO: Track this usage code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; -- cgit v1.2.3 From 3482df1176203b4999353e8266f42032536b561c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 25 May 2021 02:01:32 -0400 Subject: glsl: Simply FP storage atomics --- .../backend/glsl/emit_context.cpp | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index a413219e3..9c3fd44ba 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -78,32 +78,32 @@ void EmitContext::DefineHelperFunctions() { "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; } if (info.uses_atomic_f32_add) { - code += "uint CasFloatAdd(uint op_a,uint op_b){return " - "floatBitsToUint(uintBitsToFloat(op_a)+uintBitsToFloat(op_b));}\n"; + code += "uint CasFloatAdd(uint op_a,float op_b){return " + "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; } if (info.uses_atomic_f32x2_add) { - code += "uint CasFloatAdd32x2(uint op_a,uint op_b){return " - "packHalf2x16(unpackHalf2x16(op_a)+unpackHalf2x16(op_b));}\n"; + code += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; } if (info.uses_atomic_f32x2_min) { - code += "uint CasFloatMin32x2(uint op_a,uint op_b){return " - "packHalf2x16(min(unpackHalf2x16(op_a),unpackHalf2x16(op_b)));}\n"; + code += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f32x2_max) { - code += "uint CasFloatMax32x2(uint op_a,uint op_b){return " - "packHalf2x16(max(unpackHalf2x16(op_a),unpackHalf2x16(op_b)));}\n"; + code += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f16x2_add) { - code += "uint CasFloatAdd16x2(uint op_a,uint op_b){return " - "packFloat2x16(unpackFloat2x16(op_a)+unpackFloat2x16(op_b));}\n"; + code += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; } if (info.uses_atomic_f16x2_min) { - code += "uint CasFloatMin16x2(uint op_a,uint op_b){return " - "packFloat2x16(min(unpackFloat2x16(op_a),unpackFloat2x16(op_b)));}\n"; + code += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f16x2_max) { - code += "uint CasFloatMax16x2(uint op_a,uint op_b){return " - "packFloat2x16(max(unpackFloat2x16(op_a),unpackFloat2x16(op_b)));}\n"; + code += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; } // TODO: Track this usage code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; -- cgit v1.2.3 From bd24fa97138ff1e33a7f8d3c30a4f4482a6482a8 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 25 May 2021 19:55:40 -0400 Subject: glsl: Query GL Device for FP16 extension support --- src/shader_recompiler/backend/glsl/emit_context.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 9c3fd44ba..6f769fa10 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -5,6 +5,7 @@ #include "shader_recompiler/backend/bindings.h" #include "shader_recompiler/backend/glsl/emit_context.h" #include "shader_recompiler/frontend/ir/program.h" +#include "shader_recompiler/profile.h" namespace Shader::Backend::GLSL { @@ -40,8 +41,12 @@ void EmitContext::SetupExtensions(std::string& header) { header += "#extension NV_shader_atomic_fp16_vector : enable\n"; } if (info.uses_fp16) { - // TODO: AMD - header += "#extension GL_NV_gpu_shader5 : enable\n"; + if (profile.support_gl_nv_gpu_shader_5) { + header += "#extension GL_NV_gpu_shader5 : enable\n"; + } + if (profile.support_gl_amd_gpu_shader_half_float) { + header += "#extension GL_AMD_gpu_shader_half_float : enable\n"; + } } } -- cgit v1.2.3 From 5399906c26292634ab3eec5fce88640092e9c4c2 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 25 May 2021 22:13:50 -0400 Subject: glsl: Track S32 atomics --- src/shader_recompiler/backend/glsl/emit_context.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 6f769fa10..7b6c6d22b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -110,9 +110,12 @@ void EmitContext::DefineHelperFunctions() { code += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; } - // TODO: Track this usage - code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; - code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; + if (info.uses_atomic_s32_min) { + code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; + } + if (info.uses_atomic_s32_max) { + code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; + } } } // namespace Shader::Backend::GLSL -- cgit v1.2.3 From 3d086e6130a2c5f0546ccef3b234c65ef2f0c99b Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 26 May 2021 00:16:20 -0400 Subject: glsl: Implement some attribute getters and setters --- .../backend/glsl/emit_context.cpp | 52 ++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 7b6c6d22b..8e5983909 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -14,17 +14,63 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin : info{program.info}, profile{profile_} { std::string header = "#version 450\n"; SetupExtensions(header); - if (program.stage == Stage::Compute) { + stage = program.stage; + switch (program.stage) { + case Stage::VertexA: + case Stage::VertexB: + stage_name = "vertex"; + attrib_name = "vertex"; + // TODO: add only what's used by the shader + header += + "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; + break; + case Stage::TessellationControl: + case Stage::TessellationEval: + stage_name = "primitive"; + attrib_name = "primitive"; + break; + case Stage::Geometry: + stage_name = "primitive"; + attrib_name = "vertex"; + break; + case Stage::Fragment: + stage_name = "fragment"; + attrib_name = "fragment"; + break; + case Stage::Compute: + stage_name = "invocation"; header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", program.workgroup_size[0], program.workgroup_size[1], program.workgroup_size[2]); + break; } code += header; - + const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; + for (size_t index = 0; index < info.input_generics.size(); ++index) { + const auto& generic{info.input_generics[index]}; + if (generic.used) { + Add("layout(location={})in vec4 in_attr{};", index, index); + } + } + for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { + if (!info.stores_frag_color[index]) { + continue; + } + Add("layout(location={})out vec4 frag_color{};", index, index); + } + for (size_t index = 0; index < info.stores_generics.size(); ++index) { + if (info.stores_generics[index]) { + Add("layout(location={}) out vec4 out_attr{};", index, index); + } + } DefineConstantBuffers(); DefineStorageBuffers(); DefineHelperFunctions(); - code += "void main(){\n"; + Add("void main(){{"); + + if (stage == Stage::VertexA || stage == Stage::VertexB) { + Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); + } } void EmitContext::SetupExtensions(std::string& header) { -- cgit v1.2.3 From d171083d53e106c8c5131522fdc81d51360c562d Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 26 May 2021 21:18:17 -0400 Subject: glsl: textures wip --- .../backend/glsl/emit_context.cpp | 54 ++++++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 8e5983909..de19e0fba 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -8,9 +8,21 @@ #include "shader_recompiler/profile.h" namespace Shader::Backend::GLSL { +namespace { +std::string_view InterpDecorator(Interpolation interp) { + switch (interp) { + case Interpolation::Smooth: + return ""; + case Interpolation::Flat: + return "flat"; + case Interpolation::NoPerspective: + return "noperspective"; + } + throw InvalidArgument("Invalid interpolation {}", interp); +} +} // namespace -EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindings, - const Profile& profile_) +EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_) : info{program.info}, profile{profile_} { std::string header = "#version 450\n"; SetupExtensions(header); @@ -49,7 +61,8 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { - Add("layout(location={})in vec4 in_attr{};", index, index); + Add("layout(location={}) {} in vec4 in_attr{};", index, + InterpDecorator(generic.interpolation), index); } } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { @@ -66,6 +79,7 @@ EmitContext::EmitContext(IR::Program& program, [[maybe_unused]] Bindings& bindin DefineConstantBuffers(); DefineStorageBuffers(); DefineHelperFunctions(); + SetupImages(bindings); Add("void main(){{"); if (stage == Stage::VertexA || stage == Stage::VertexB) { @@ -102,7 +116,7 @@ void EmitContext::DefineConstantBuffers() { } u32 binding{}; for (const auto& desc : info.constant_buffer_descriptors) { - Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, binding, + Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, desc.index, 4 * 1024); ++binding; } @@ -164,4 +178,36 @@ void EmitContext::DefineHelperFunctions() { } } +void EmitContext::SetupImages(Bindings& bindings) { + image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); + for (const auto& desc : info.image_buffer_descriptors) { + throw NotImplementedException("image_buffer_descriptors"); + image_buffer_bindings.push_back(bindings.image); + bindings.image += desc.count; + } + image_bindings.reserve(info.image_descriptors.size()); + for (const auto& desc : info.image_descriptors) { + throw NotImplementedException("image_bindings"); + + image_bindings.push_back(bindings.image); + bindings.image += desc.count; + } + texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); + for (const auto& desc : info.texture_buffer_descriptors) { + throw NotImplementedException("TextureType::Buffer"); + + texture_buffer_bindings.push_back(bindings.texture); + bindings.texture += desc.count; + } + texture_bindings.reserve(info.texture_descriptors.size()); + for (const auto& desc : info.texture_descriptors) { + texture_bindings.push_back(bindings.texture); + const auto indices{bindings.texture + desc.count}; + for (u32 index = bindings.texture; index < indices; ++index) { + Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); + } + bindings.texture += desc.count; + } +} + } // namespace Shader::Backend::GLSL -- cgit v1.2.3 From ed14d31f663e126a8f9fe0ea8abff8e27c46248b Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 27 May 2021 00:26:16 -0400 Subject: glsl: Fix non-immediate buffer access and many other misc implementations --- src/shader_recompiler/backend/glsl/emit_context.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index de19e0fba..2bf0def82 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -88,6 +88,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } void EmitContext::SetupExtensions(std::string& header) { + header += "#extension GL_ARB_separate_shader_objects : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } -- cgit v1.2.3 From a752ec88d06c6bcfb13605447a164c6b6915ed6e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 27 May 2021 20:31:03 -0400 Subject: glsl: Implement derivatives and YDirection plus some other misc additions/changed --- src/shader_recompiler/backend/glsl/emit_context.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 2bf0def82..0ddc0443b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -22,9 +22,10 @@ std::string_view InterpDecorator(Interpolation interp) { } } // namespace -EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_) - : info{program.info}, profile{profile_} { - std::string header = "#version 450\n"; +EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, + const RuntimeInfo& runtime_info_) + : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { + std::string header = ""; SetupExtensions(header); stage = program.stage; switch (program.stage) { -- cgit v1.2.3 From 2a713337165df4d5c4228458999a680e9ab65369 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 27 May 2021 22:28:33 -0400 Subject: glsl: Fix bindings, add some CC ops --- .../backend/glsl/emit_context.cpp | 57 +++++++++++++--------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 0ddc0443b..7bd6b3605 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -20,6 +20,20 @@ std::string_view InterpDecorator(Interpolation interp) { } throw InvalidArgument("Invalid interpolation {}", interp); } + +std::string_view SamplerType(TextureType type) { + switch (type) { + case TextureType::Color2D: + return "sampler2D"; + case TextureType::ColorArray2D: + return "sampler2DArray"; + case TextureType::Color3D: + return "sampler3D"; + default: + throw NotImplementedException("Texture type: {}", type); + } +} + } // namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -31,27 +45,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile switch (program.stage) { case Stage::VertexA: case Stage::VertexB: - stage_name = "vertex"; - attrib_name = "vertex"; + stage_name = "vs"; // TODO: add only what's used by the shader header += "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; break; case Stage::TessellationControl: case Stage::TessellationEval: - stage_name = "primitive"; - attrib_name = "primitive"; + stage_name = "ts"; break; case Stage::Geometry: - stage_name = "primitive"; - attrib_name = "vertex"; + stage_name = "gs"; break; case Stage::Fragment: - stage_name = "fragment"; - attrib_name = "fragment"; + stage_name = "fs"; break; case Stage::Compute: - stage_name = "invocation"; + stage_name = "cs"; header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", program.workgroup_size[0], program.workgroup_size[1], program.workgroup_size[2]); @@ -77,12 +87,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile Add("layout(location={}) out vec4 out_attr{};", index, index); } } - DefineConstantBuffers(); - DefineStorageBuffers(); - DefineHelperFunctions(); + DefineConstantBuffers(bindings); + DefineStorageBuffers(bindings); SetupImages(bindings); - Add("void main(){{"); + DefineHelperFunctions(); + Add("void main(){{"); if (stage == Stage::VertexA || stage == Stage::VertexB) { Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); } @@ -112,27 +122,25 @@ void EmitContext::SetupExtensions(std::string& header) { } } -void EmitContext::DefineConstantBuffers() { +void EmitContext::DefineConstantBuffers(Bindings& bindings) { if (info.constant_buffer_descriptors.empty()) { return; } - u32 binding{}; for (const auto& desc : info.constant_buffer_descriptors) { - Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, - desc.index, 4 * 1024); - ++binding; + Add("layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};", + bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024); + bindings.uniform_buffer += desc.count; } } -void EmitContext::DefineStorageBuffers() { +void EmitContext::DefineStorageBuffers(Bindings& bindings) { if (info.storage_buffers_descriptors.empty()) { return; } - u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", binding, binding, - desc.cbuf_index, desc.count); - ++binding; + Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", bindings.storage_buffer, + bindings.storage_buffer, desc.cbuf_index); + bindings.storage_buffer += desc.count; } } @@ -203,10 +211,11 @@ void EmitContext::SetupImages(Bindings& bindings) { } texture_bindings.reserve(info.texture_descriptors.size()); for (const auto& desc : info.texture_descriptors) { + const auto sampler_type{SamplerType(desc.type)}; texture_bindings.push_back(bindings.texture); const auto indices{bindings.texture + desc.count}; for (u32 index = bindings.texture; index < indices; ++index) { - Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); + Add("layout(binding={}) uniform {} tex{};", bindings.texture, sampler_type, index); } bindings.texture += desc.count; } -- cgit v1.2.3 From f6bbc76336942454a862280e5b2158ceab49a173 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 28 May 2021 13:54:09 -0400 Subject: glsl: WIP var forward declaration to fix Loop control flow. --- .../backend/glsl/emit_context.cpp | 64 ++++++++++++---------- 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 7bd6b3605..3530e89e5 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -29,7 +29,10 @@ std::string_view SamplerType(TextureType type) { return "sampler2DArray"; case TextureType::Color3D: return "sampler3D"; + case TextureType::ColorCube: + return "samplerCube"; default: + fmt::print("Texture type: {}", type); throw NotImplementedException("Texture type: {}", type); } } @@ -39,7 +42,6 @@ std::string_view SamplerType(TextureType type) { EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, const RuntimeInfo& runtime_info_) : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { - std::string header = ""; SetupExtensions(header); stage = program.stage; switch (program.stage) { @@ -67,24 +69,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile program.workgroup_size[2]); break; } - code += header; const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { - Add("layout(location={}) {} in vec4 in_attr{};", index, - InterpDecorator(generic.interpolation), index); + header += fmt::format("layout(location={}) {} in vec4 in_attr{};", index, + InterpDecorator(generic.interpolation), index); } } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { if (!info.stores_frag_color[index]) { continue; } - Add("layout(location={})out vec4 frag_color{};", index, index); + header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); } for (size_t index = 0; index < info.stores_generics.size(); ++index) { if (info.stores_generics[index]) { - Add("layout(location={}) out vec4 out_attr{};", index, index); + header += fmt::format("layout(location={}) out vec4 out_attr{};", index, index); } } DefineConstantBuffers(bindings); @@ -92,14 +93,15 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile SetupImages(bindings); DefineHelperFunctions(); - Add("void main(){{"); + header += "void main(){\n"; if (stage == Stage::VertexA || stage == Stage::VertexB) { Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); } } -void EmitContext::SetupExtensions(std::string& header) { +void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_separate_shader_objects : enable\n"; + // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } @@ -127,7 +129,8 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) { return; } for (const auto& desc : info.constant_buffer_descriptors) { - Add("layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};", + header += fmt::format( + "layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};", bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024); bindings.uniform_buffer += desc.count; } @@ -138,53 +141,53 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { return; } for (const auto& desc : info.storage_buffers_descriptors) { - Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", bindings.storage_buffer, - bindings.storage_buffer, desc.cbuf_index); + header += fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", + bindings.storage_buffer, bindings.storage_buffer, desc.cbuf_index); bindings.storage_buffer += desc.count; } } void EmitContext::DefineHelperFunctions() { if (info.uses_global_increment) { - code += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; + header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; } if (info.uses_global_decrement) { - code += + header += "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; } if (info.uses_atomic_f32_add) { - code += "uint CasFloatAdd(uint op_a,float op_b){return " - "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; + header += "uint CasFloatAdd(uint op_a,float op_b){return " + "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; } if (info.uses_atomic_f32x2_add) { - code += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; + header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; } if (info.uses_atomic_f32x2_min) { - code += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; + header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f32x2_max) { - code += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; + header += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " + "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f16x2_add) { - code += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; + header += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; } if (info.uses_atomic_f16x2_min) { - code += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; + header += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; } if (info.uses_atomic_f16x2_max) { - code += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; + header += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " + "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; } if (info.uses_atomic_s32_min) { - code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; + header += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; } if (info.uses_atomic_s32_max) { - code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; + header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; } } @@ -215,7 +218,8 @@ void EmitContext::SetupImages(Bindings& bindings) { texture_bindings.push_back(bindings.texture); const auto indices{bindings.texture + desc.count}; for (u32 index = bindings.texture; index < indices; ++index) { - Add("layout(binding={}) uniform {} tex{};", bindings.texture, sampler_type, index); + header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, + sampler_type, index); } bindings.texture += desc.count; } -- cgit v1.2.3 From 8ba814efb295f0b8494b3679c484c7ceab31c392 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 28 May 2021 21:24:52 -0400 Subject: glsl: Better Storage access and wip warps --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 3530e89e5..db62ba73b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -122,6 +122,10 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_AMD_gpu_shader_half_float : enable\n"; } } + if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || + info.uses_subgroup_shuffles || info.uses_fswzadd) { + header += "#extension GL_ARB_shader_ballot : enable\n"; + } } void EmitContext::DefineConstantBuffers(Bindings& bindings) { -- cgit v1.2.3 From 55e0211a5e520482246273f2cc64388c4b4eff1c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 29 May 2021 01:06:29 -0400 Subject: glsl: Implement TEX ImageSample functions --- src/shader_recompiler/backend/glsl/emit_context.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index db62ba73b..eb1d8266f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -23,6 +23,10 @@ std::string_view InterpDecorator(Interpolation interp) { std::string_view SamplerType(TextureType type) { switch (type) { + case TextureType::Color1D: + return "sampler1D"; + case TextureType::ColorArray1D: + return "sampler1DArray"; case TextureType::Color2D: return "sampler2D"; case TextureType::ColorArray2D: @@ -31,6 +35,10 @@ std::string_view SamplerType(TextureType type) { return "sampler3D"; case TextureType::ColorCube: return "samplerCube"; + case TextureType::ColorArrayCube: + return "samplerCubeArray"; + case TextureType::Buffer: + return "samplerBuffer"; default: fmt::print("Texture type: {}", type); throw NotImplementedException("Texture type: {}", type); @@ -101,6 +109,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_separate_shader_objects : enable\n"; + header += "#extension GL_ARB_sparse_texture2 : enable\n"; // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; -- cgit v1.2.3 From 7619b7d427437cb58df0f9fc57a7d6b3f5c45f9c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 29 May 2021 01:53:32 -0400 Subject: glsl: Implement TEX depth functions --- .../backend/glsl/emit_context.cpp | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index eb1d8266f..94ba9af7c 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -21,7 +21,26 @@ std::string_view InterpDecorator(Interpolation interp) { throw InvalidArgument("Invalid interpolation {}", interp); } -std::string_view SamplerType(TextureType type) { +std::string_view SamplerType(TextureType type, bool is_depth) { + if (is_depth) { + switch (type) { + case TextureType::Color1D: + return "sampler1DShadow"; + case TextureType::ColorArray1D: + return "sampler1DArrayShadow"; + case TextureType::Color2D: + return "sampler2DShadow"; + case TextureType::ColorArray2D: + return "sampler2DArrayShadow"; + case TextureType::ColorCube: + return "samplerCubeShadow"; + case TextureType::ColorArrayCube: + return "samplerCubeArrayShadow"; + default: + fmt::print("Texture type: {}", type); + throw NotImplementedException("Texture type: {}", type); + } + } switch (type) { case TextureType::Color1D: return "sampler1D"; @@ -110,6 +129,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_separate_shader_objects : enable\n"; header += "#extension GL_ARB_sparse_texture2 : enable\n"; + header += "#extension GL_EXT_texture_shadow_lod : enable\n"; // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; @@ -227,7 +247,7 @@ void EmitContext::SetupImages(Bindings& bindings) { } texture_bindings.reserve(info.texture_descriptors.size()); for (const auto& desc : info.texture_descriptors) { - const auto sampler_type{SamplerType(desc.type)}; + const auto sampler_type{SamplerType(desc.type, desc.is_depth)}; texture_bindings.push_back(bindings.texture); const auto indices{bindings.texture + desc.count}; for (u32 index = bindings.texture; index < indices; ++index) { -- cgit v1.2.3 From 57d354b02ced63d7a0fcb01f1f674a910054cdd1 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 29 May 2021 21:12:52 -0400 Subject: glsl: Implement more instructions used by SMO --- src/shader_recompiler/backend/glsl/emit_context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 94ba9af7c..fd0113c8d 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -96,7 +96,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile program.workgroup_size[2]); break; } - const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { @@ -174,8 +173,9 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { return; } for (const auto& desc : info.storage_buffers_descriptors) { - header += fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", - bindings.storage_buffer, bindings.storage_buffer, desc.cbuf_index); + header += + fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", + bindings.storage_buffer, bindings.storage_buffer, bindings.storage_buffer); bindings.storage_buffer += desc.count; } } -- cgit v1.2.3 From 181a4ffdc477e56c82d5de17e242c64ee70275c2 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 29 May 2021 23:31:58 -0400 Subject: glsl: Implement ST{LS} --- src/shader_recompiler/backend/glsl/emit_context.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index fd0113c8d..26969a26d 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -118,11 +118,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile DefineStorageBuffers(bindings); SetupImages(bindings); DefineHelperFunctions(); - - header += "void main(){\n"; - if (stage == Stage::VertexA || stage == Stage::VertexB) { - Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); - } } void EmitContext::SetupExtensions(std::string&) { -- cgit v1.2.3 From 770b754afde60658877c9063704d03ea385d40b5 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 00:08:39 -0400 Subject: glsl: Implement VOTE --- src/shader_recompiler/backend/glsl/emit_context.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 26969a26d..5456d4e5b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -148,6 +148,7 @@ void EmitContext::SetupExtensions(std::string&) { if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || info.uses_subgroup_shuffles || info.uses_fswzadd) { header += "#extension GL_ARB_shader_ballot : enable\n"; + header += "#extension GL_ARB_shader_group_vote : enable\n"; } } -- cgit v1.2.3 From e35ffbbeb0f85f676416fcb8f0bb0207671f379d Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 00:53:26 -0400 Subject: glsl: Implement VOTE for subgroup size potentially larger --- src/shader_recompiler/backend/glsl/emit_context.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 5456d4e5b..c6325e55f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -122,9 +122,11 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_separate_shader_objects : enable\n"; - header += "#extension GL_ARB_sparse_texture2 : enable\n"; - header += "#extension GL_EXT_texture_shadow_lod : enable\n"; - // header += "#extension GL_ARB_texture_cube_map_array : enable\n"; + if (stage != Stage::Compute) { + // TODO: track this usage + header += "#extension GL_ARB_sparse_texture2 : enable\n"; + header += "#extension GL_EXT_texture_shadow_lod : enable\n"; + } if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } @@ -149,6 +151,10 @@ void EmitContext::SetupExtensions(std::string&) { info.uses_subgroup_shuffles || info.uses_fswzadd) { header += "#extension GL_ARB_shader_ballot : enable\n"; header += "#extension GL_ARB_shader_group_vote : enable\n"; + header += "#extension GL_KHR_shader_subgroup_basic : enable\n"; + if (!info.uses_int64) { + header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; + } } } -- cgit v1.2.3 From 68ef3803bfb53454b4d6f1cd163ccbfa29af38c8 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 01:18:20 -0400 Subject: glsl: Use gl_SubGroupInvocationARB --- src/shader_recompiler/backend/glsl/emit_context.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index c6325e55f..02d88b7ad 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -151,7 +151,6 @@ void EmitContext::SetupExtensions(std::string&) { info.uses_subgroup_shuffles || info.uses_fswzadd) { header += "#extension GL_ARB_shader_ballot : enable\n"; header += "#extension GL_ARB_shader_group_vote : enable\n"; - header += "#extension GL_KHR_shader_subgroup_basic : enable\n"; if (!info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } -- cgit v1.2.3 From 9ccbd749914a3371893ee3d6c1bdcb50c7f777ab Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 14:31:59 -0400 Subject: glsl: Fix ATOM and implement ATOMS --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 02d88b7ad..b9594de40 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -182,10 +182,10 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { } void EmitContext::DefineHelperFunctions() { - if (info.uses_global_increment) { + if (info.uses_global_increment || info.uses_shared_increment) { header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; } - if (info.uses_global_decrement) { + if (info.uses_global_decrement || info.uses_shared_decrement) { header += "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; } -- cgit v1.2.3 From 9f3ffb996b0d02ca64b492d22ff158e8f3659257 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 19:13:22 -0400 Subject: glsl: Rework var alloc to not assign unused results --- src/shader_recompiler/backend/glsl/emit_context.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index b9594de40..da29290a2 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -122,11 +122,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_separate_shader_objects : enable\n"; - if (stage != Stage::Compute) { - // TODO: track this usage - header += "#extension GL_ARB_sparse_texture2 : enable\n"; - header += "#extension GL_EXT_texture_shadow_lod : enable\n"; - } + // TODO: track this usage + header += "#extension GL_ARB_sparse_texture2 : enable\n"; + header += "#extension GL_EXT_texture_shadow_lod : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } -- cgit v1.2.3 From 4b5a4ea72e471eaf7d3fae34746e49aa9a6aaf08 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 20:02:44 -0400 Subject: glsl: Fix ssbo indexing and name shadowing between shader stages --- src/shader_recompiler/backend/glsl/emit_context.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index da29290a2..788679f40 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -121,7 +121,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } void EmitContext::SetupExtensions(std::string&) { - header += "#extension GL_ARB_separate_shader_objects : enable\n"; // TODO: track this usage header += "#extension GL_ARB_sparse_texture2 : enable\n"; header += "#extension GL_EXT_texture_shadow_lod : enable\n"; @@ -171,11 +170,13 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { if (info.storage_buffers_descriptors.empty()) { return; } + u32 index{}; for (const auto& desc : info.storage_buffers_descriptors) { - header += - fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", - bindings.storage_buffer, bindings.storage_buffer, bindings.storage_buffer); + header += fmt::format("layout(std430,binding={}) buffer {}_ssbo_{}{{uint {}_ssbo{}[];}};", + bindings.storage_buffer, stage_name, bindings.storage_buffer, + stage_name, index); bindings.storage_buffer += desc.count; + index += desc.count; } } -- cgit v1.2.3 From 14bfb4719ad366745b5d16452914c4c78e43b8ae Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 30 May 2021 22:42:52 -0400 Subject: HACK glsl: Write defaults to unused generic attributes --- src/shader_recompiler/backend/glsl/emit_context.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 788679f40..8de33b582 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -110,8 +110,11 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); } for (size_t index = 0; index < info.stores_generics.size(); ++index) { - if (info.stores_generics[index]) { - header += fmt::format("layout(location={}) out vec4 out_attr{};", index, index); + // TODO: Properly resolve attribute issues + const auto declaration{ + fmt::format("layout(location={}) out vec4 out_attr{};", index, index)}; + if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { + header += declaration; } } DefineConstantBuffers(bindings); -- cgit v1.2.3 From 3a024b302622068f4842715a7f0b31652898a606 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 31 May 2021 01:12:52 -0400 Subject: glsl: Implement gl_ViewportIndex SSBU now working --- src/shader_recompiler/backend/glsl/emit_context.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 8de33b582..2a5ec7414 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -126,6 +126,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage header += "#extension GL_ARB_sparse_texture2 : enable\n"; + header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; + header += "#extension GL_NV_viewport_array2 : enable\n"; header += "#extension GL_EXT_texture_shadow_lod : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; @@ -243,9 +245,13 @@ void EmitContext::SetupImages(Bindings& bindings) { } texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); for (const auto& desc : info.texture_buffer_descriptors) { - throw NotImplementedException("TextureType::Buffer"); - texture_buffer_bindings.push_back(bindings.texture); + const auto sampler_type{SamplerType(TextureType::Buffer, false)}; + const auto indices{bindings.texture + desc.count}; + for (u32 index = bindings.texture; index < indices; ++index) { + header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, + sampler_type, index); + } bindings.texture += desc.count; } texture_bindings.reserve(info.texture_descriptors.size()); -- cgit v1.2.3 From 19247ba4fad59b3d821b099dfbcd60e985041249 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 31 May 2021 13:28:53 -0400 Subject: glsl: Implement geometry shaders --- .../backend/glsl/emit_context.cpp | 50 ++++++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 2a5ec7414..923060386 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -21,6 +21,15 @@ std::string_view InterpDecorator(Interpolation interp) { throw InvalidArgument("Invalid interpolation {}", interp); } +std::string_view ArrayDecorator(Stage stage) { + switch (stage) { + case Stage::Geometry: + return "[1]"; + default: + return ""; + } +} + std::string_view SamplerType(TextureType type, bool is_depth) { if (is_depth) { switch (type) { @@ -64,6 +73,33 @@ std::string_view SamplerType(TextureType type, bool is_depth) { } } +std::string_view InputPrimitive(InputTopology topology) { + switch (topology) { + case InputTopology::Points: + return "points"; + case InputTopology::Lines: + return "lines"; + case InputTopology::LinesAdjacency: + return "lines_adjacency"; + case InputTopology::Triangles: + return "triangles"; + case InputTopology::TrianglesAdjacency: + return "triangles_adjacency"; + } + throw InvalidArgument("Invalid input topology {}", topology); +} + +std::string_view OutputPrimitive(OutputTopology topology) { + switch (topology) { + case OutputTopology::PointList: + return "points"; + case OutputTopology::LineStrip: + return "line_strip"; + case OutputTopology::TriangleStrip: + return "triangle_strip"; + } + throw InvalidArgument("Invalid output topology {}", topology); +} } // namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -85,6 +121,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Geometry: stage_name = "gs"; + header += fmt::format("layout({})in;layout({}, max_vertices={})out;\n", + InputPrimitive(runtime_info.input_topology), + OutputPrimitive(program.output_topology), program.output_vertices); break; case Stage::Fragment: stage_name = "fs"; @@ -99,8 +138,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { - header += fmt::format("layout(location={}) {} in vec4 in_attr{};", index, - InterpDecorator(generic.interpolation), index); + header += + fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, + InterpDecorator(generic.interpolation), index, ArrayDecorator(stage)); } } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { @@ -126,8 +166,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage header += "#extension GL_ARB_sparse_texture2 : enable\n"; - header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; - header += "#extension GL_NV_viewport_array2 : enable\n"; header += "#extension GL_EXT_texture_shadow_lod : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; @@ -157,6 +195,10 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } + if (info.stores_viewport_index) { + header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; + header += "#extension GL_NV_viewport_array2 : enable\n"; + } } void EmitContext::DefineConstantBuffers(Bindings& bindings) { -- cgit v1.2.3 From 8c684b3e2327bc7b0c02f2a22dbf52c11884ecd3 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 31 May 2021 23:07:13 -0400 Subject: glsl: Implement tessellation shaders --- .../backend/glsl/emit_context.cpp | 90 +++++++++++++++++++--- 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 923060386..01403ca17 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -21,10 +21,21 @@ std::string_view InterpDecorator(Interpolation interp) { throw InvalidArgument("Invalid interpolation {}", interp); } -std::string_view ArrayDecorator(Stage stage) { +std::string_view InputArrayDecorator(Stage stage) { switch (stage) { case Stage::Geometry: - return "[1]"; + case Stage::TessellationControl: + case Stage::TessellationEval: + return "[]"; + default: + return ""; + } +} + +std::string OutputDecorator(Stage stage, u32 size) { + switch (stage) { + case Stage::TessellationControl: + return fmt::format("[{}]", size); default: return ""; } @@ -73,6 +84,30 @@ std::string_view SamplerType(TextureType type, bool is_depth) { } } +std::string_view GetTessMode(TessPrimitive primitive) { + switch (primitive) { + case TessPrimitive::Triangles: + return "triangles"; + case TessPrimitive::Quads: + return "quads"; + case TessPrimitive::Isolines: + return "isolines"; + } + throw InvalidArgument("Invalid tessellation primitive {}", primitive); +} + +std::string_view GetTessSpacing(TessSpacing spacing) { + switch (spacing) { + case TessSpacing::Equal: + return "equal_spacing"; + case TessSpacing::FractionalOdd: + return "fractional_odd_spacing"; + case TessSpacing::FractionalEven: + return "fractional_even_spacing"; + } + throw InvalidArgument("Invalid tessellation spacing {}", spacing); +} + std::string_view InputPrimitive(InputTopology topology) { switch (topology) { case InputTopology::Points: @@ -100,6 +135,23 @@ std::string_view OutputPrimitive(OutputTopology topology) { } throw InvalidArgument("Invalid output topology {}", topology); } + +void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { + if (stage != Stage::VertexA && stage != Stage::VertexB && stage != Stage::Geometry) { + return; + } + header += "out gl_PerVertex{"; + if (info.stores_position) { + header += "vec4 gl_Position;"; + } + if (info.stores_point_size) { + header += "float gl_PointSize;"; + } + if (info.stores_clip_distance) { + header += "float gl_ClipDistance[];"; + } + header += "};"; +} } // namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -111,17 +163,20 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile case Stage::VertexA: case Stage::VertexB: stage_name = "vs"; - // TODO: add only what's used by the shader - header += - "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; break; case Stage::TessellationControl: + stage_name = "tsc"; + header += fmt::format("layout(vertices={})out;\n", program.invocations); + break; case Stage::TessellationEval: - stage_name = "ts"; + stage_name = "tse"; + header += fmt::format("layout({},{},{})in;\n", GetTessMode(runtime_info.tess_primitive), + GetTessSpacing(runtime_info.tess_spacing), + runtime_info.tess_clockwise ? "cw" : "ccw"); break; case Stage::Geometry: stage_name = "gs"; - header += fmt::format("layout({})in;layout({}, max_vertices={})out;\n", + header += fmt::format("layout({})in;layout({},max_vertices={})out;\n", InputPrimitive(runtime_info.input_topology), OutputPrimitive(program.output_topology), program.output_vertices); break; @@ -135,12 +190,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile program.workgroup_size[2]); break; } + SetupOutPerVertex(stage, info, header); for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { - header += - fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, - InterpDecorator(generic.interpolation), index, ArrayDecorator(stage)); + header += fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, + InterpDecorator(generic.interpolation), index, + InputArrayDecorator(stage)); + } + } + for (size_t index = 0; index < info.uses_patches.size(); ++index) { + if (!info.uses_patches[index]) { + continue; + } + if (stage == Stage::TessellationControl) { + header += fmt::format("layout(location={})patch out vec4 patch{};", index, index); + } else { + header += fmt::format("layout(location={})patch in vec4 patch{};", index, index); } } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { @@ -151,8 +217,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } for (size_t index = 0; index < info.stores_generics.size(); ++index) { // TODO: Properly resolve attribute issues - const auto declaration{ - fmt::format("layout(location={}) out vec4 out_attr{};", index, index)}; + const auto declaration{fmt::format("layout(location={}) out vec4 out_attr{}{};", index, + index, OutputDecorator(stage, program.invocations))}; if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { header += declaration; } -- cgit v1.2.3 From 59576b82a8c06943e6b9fafbff6ed1884a4132a7 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 1 Jun 2021 00:07:14 -0400 Subject: glsl: Fix precise variable declaration and add some more separation in the shader for better debugability when dumped --- src/shader_recompiler/backend/glsl/emit_context.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 01403ca17..2375b7a06 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -150,7 +150,7 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { if (info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } - header += "};"; + header += "};\n"; } } // namespace @@ -223,6 +223,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile header += declaration; } } + header += "\n"; DefineConstantBuffers(bindings); DefineStorageBuffers(bindings); SetupImages(bindings); -- cgit v1.2.3 From 9f3970f837eebf290c03988ef00dee68ca68f07b Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 1 Jun 2021 01:04:32 -0400 Subject: glsl: Add gl_ViewportIndex out attribute --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 2375b7a06..6e164b958 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -151,6 +151,9 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { header += "float gl_ClipDistance[];"; } header += "};\n"; + if (info.stores_viewport_index) { + header += "out int gl_ViewportIndex;"; + } } } // namespace @@ -264,7 +267,6 @@ void EmitContext::SetupExtensions(std::string&) { } if (info.stores_viewport_index) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; - header += "#extension GL_NV_viewport_array2 : enable\n"; } } -- cgit v1.2.3 From 31147ffe69882141cb83bf83d5e01890524ab85a Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 1 Jun 2021 01:49:24 -0400 Subject: glsl: Yet another gl_ViewportIndex fix attempt --- .../backend/glsl/emit_context.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 6e164b958..6f10002fe 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -32,6 +32,19 @@ std::string_view InputArrayDecorator(Stage stage) { } } +bool StoresPerVertexAttributes(Stage stage) { + switch (stage) { + case Stage::VertexA: + case Stage::VertexB: + case Stage::Geometry: + case Stage::TessellationControl: + case Stage::TessellationEval: + return true; + default: + return false; + } +} + std::string OutputDecorator(Stage stage, u32 size) { switch (stage) { case Stage::TessellationControl: @@ -137,7 +150,7 @@ std::string_view OutputPrimitive(OutputTopology topology) { } void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { - if (stage != Stage::VertexA && stage != Stage::VertexB && stage != Stage::Geometry) { + if (!StoresPerVertexAttributes(stage)) { return; } header += "out gl_PerVertex{"; @@ -150,8 +163,11 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { if (info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } + if (info.stores_viewport_index && stage != Stage::Geometry) { + header += "int gl_ViewportIndex;"; + } header += "};\n"; - if (info.stores_viewport_index) { + if (info.stores_viewport_index && stage == Stage::Geometry) { header += "out int gl_ViewportIndex;"; } } @@ -265,7 +281,7 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } - if (info.stores_viewport_index) { + if (info.stores_viewport_index && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } } -- cgit v1.2.3 From f4799e8fa15b92d8d5607dc5dfca4974901ee06c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 2 Jun 2021 00:33:03 -0400 Subject: glsl: Implement transform feedback --- .../backend/glsl/emit_context.cpp | 53 ++++++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 6f10002fe..58355d5e3 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -37,7 +37,6 @@ bool StoresPerVertexAttributes(Stage stage) { case Stage::VertexA: case Stage::VertexB: case Stage::Geometry: - case Stage::TessellationControl: case Stage::TessellationEval: return true; default: @@ -154,9 +153,7 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { return; } header += "out gl_PerVertex{"; - if (info.stores_position) { - header += "vec4 gl_Position;"; - } + header += "vec4 gl_Position;"; if (info.stores_point_size) { header += "float gl_PointSize;"; } @@ -236,10 +233,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } for (size_t index = 0; index < info.stores_generics.size(); ++index) { // TODO: Properly resolve attribute issues - const auto declaration{fmt::format("layout(location={}) out vec4 out_attr{}{};", index, - index, OutputDecorator(stage, program.invocations))}; if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { - header += declaration; + DefineGenericOutput(index, program.invocations); } } header += "\n"; @@ -312,13 +307,53 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) { } } +void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { + static constexpr std::string_view swizzle{"xyzw"}; + const size_t base_index{static_cast(IR::Attribute::Generic0X) + index * 4}; + u32 element{0}; + while (element < 4) { + std::string definition{fmt::format("layout(location={}", index)}; + const u32 remainder{4 - element}; + const TransformFeedbackVarying* xfb_varying{}; + if (!runtime_info.xfb_varyings.empty()) { + xfb_varying = &runtime_info.xfb_varyings[base_index + element]; + xfb_varying = xfb_varying && xfb_varying->components > 0 ? xfb_varying : nullptr; + } + const u32 num_components{xfb_varying ? xfb_varying->components : remainder}; + if (element > 0) { + definition += fmt::format(",component={}", element); + } + if (xfb_varying) { + definition += + fmt::format(",xfb_buffer={},xfb_stride={},xfb_offset={}", xfb_varying->buffer, + xfb_varying->stride, xfb_varying->offset); + } + std::string name{fmt::format("out_attr{}", index)}; + if (num_components < 4 || element > 0) { + name += fmt::format("_{}", swizzle.substr(element, num_components)); + } + const auto type{num_components == 1 ? "float" : fmt::format("vec{}", num_components)}; + definition += fmt::format(")out {} {}{};", type, name, OutputDecorator(stage, invocations)); + header += definition; + + const GenericElementInfo element_info{ + .name = name, + .first_element = element, + .num_components = num_components, + }; + std::fill_n(output_generics[index].begin() + element, num_components, element_info); + element += num_components; + } + header += "\n"; +} + void EmitContext::DefineHelperFunctions() { if (info.uses_global_increment || info.uses_shared_increment) { header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; } if (info.uses_global_decrement || info.uses_shared_decrement) { - header += - "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; + header += "uint CasDecrement(uint op_a,uint " + "op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; } if (info.uses_atomic_f32_add) { header += "uint CasFloatAdd(uint op_a,float op_b){return " -- cgit v1.2.3 From 6577a63d368afa57d5f29df40e524af30eaabffa Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 2 Jun 2021 00:48:49 -0400 Subject: glsl: skip gl_ViewportIndex write if device does not support it --- src/shader_recompiler/backend/glsl/emit_context.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 58355d5e3..846d38bfc 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -148,23 +148,24 @@ std::string_view OutputPrimitive(OutputTopology topology) { throw InvalidArgument("Invalid output topology {}", topology); } -void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { - if (!StoresPerVertexAttributes(stage)) { +void SetupOutPerVertex(EmitContext& ctx, std::string& header) { + if (!StoresPerVertexAttributes(ctx.stage)) { return; } header += "out gl_PerVertex{"; header += "vec4 gl_Position;"; - if (info.stores_point_size) { + if (ctx.info.stores_point_size) { header += "float gl_PointSize;"; } - if (info.stores_clip_distance) { + if (ctx.info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } - if (info.stores_viewport_index && stage != Stage::Geometry) { + if (ctx.info.stores_viewport_index && ctx.supports_viewport_layer && + ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } header += "};\n"; - if (info.stores_viewport_index && stage == Stage::Geometry) { + if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { header += "out int gl_ViewportIndex;"; } } @@ -173,6 +174,7 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, const RuntimeInfo& runtime_info_) : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { + supports_viewport_layer = profile.support_gl_vertex_viewport_layer; SetupExtensions(header); stage = program.stage; switch (program.stage) { @@ -206,7 +208,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile program.workgroup_size[2]); break; } - SetupOutPerVertex(stage, info, header); + SetupOutPerVertex(*this, header); for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { @@ -276,7 +278,7 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } - if (info.stores_viewport_index && stage != Stage::Geometry) { + if (info.stores_viewport_index && supports_viewport_layer && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } } -- cgit v1.2.3 From af9696059cc24e07fba2920814725e56c3c61df0 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 2 Jun 2021 20:37:24 -0400 Subject: glsl: Implement Images --- .../backend/glsl/emit_context.cpp | 50 ++++++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 846d38bfc..5048c8b68 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -91,11 +91,42 @@ std::string_view SamplerType(TextureType type, bool is_depth) { case TextureType::Buffer: return "samplerBuffer"; default: - fmt::print("Texture type: {}", type); throw NotImplementedException("Texture type: {}", type); } } +std::string_view ImageType(TextureType type) { + switch (type) { + case TextureType::Color2D: + return "uimage2D"; + default: + throw NotImplementedException("Image type: {}", type); + } +} + +std::string_view ImageFormatString(ImageFormat format) { + switch (format) { + case ImageFormat::Typeless: + return ""; + case ImageFormat::R8_UINT: + return ",r8ui"; + case ImageFormat::R8_SINT: + return ",r8i"; + case ImageFormat::R16_UINT: + return ",r16ui"; + case ImageFormat::R16_SINT: + return ",r16i"; + case ImageFormat::R32_UINT: + return ",r32ui"; + case ImageFormat::R32G32_UINT: + return ",rg32ui"; + case ImageFormat::R32G32B32A32_UINT: + return ",rgba32ui"; + default: + throw NotImplementedException("Image format: {}", format); + } +} + std::string_view GetTessMode(TessPrimitive primitive) { switch (primitive) { case TessPrimitive::Triangles: @@ -250,6 +281,7 @@ void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage header += "#extension GL_ARB_sparse_texture2 : enable\n"; header += "#extension GL_EXT_texture_shadow_lod : enable\n"; + header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } @@ -396,15 +428,25 @@ void EmitContext::DefineHelperFunctions() { void EmitContext::SetupImages(Bindings& bindings) { image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); for (const auto& desc : info.image_buffer_descriptors) { - throw NotImplementedException("image_buffer_descriptors"); + const auto indices{bindings.image + desc.count}; + for (u32 index = bindings.image; index < indices; ++index) { + header += fmt::format("layout(binding={}) uniform uimageBuffer img{};", bindings.image, + index); + } image_buffer_bindings.push_back(bindings.image); bindings.image += desc.count; } image_bindings.reserve(info.image_descriptors.size()); for (const auto& desc : info.image_descriptors) { - throw NotImplementedException("image_bindings"); - image_bindings.push_back(bindings.image); + const auto format{ImageFormatString(desc.format)}; + const auto image_type{ImageType(desc.type)}; + const auto qualifier{desc.is_written ? "" : "readonly "}; + const auto indices{bindings.image + desc.count}; + for (u32 index = bindings.image; index < indices; ++index) { + header += fmt::format("layout(binding={}{})uniform {}{} img{};", bindings.image, format, + qualifier, image_type, index); + } bindings.image += desc.count; } texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); -- cgit v1.2.3 From 8d8ce24f20649be639dbb3cc0f3edc90c6a6481e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 3 Jun 2021 19:15:36 -0400 Subject: glsl: Implement Load/WriteGlobal along with some other misc changes and fixes --- .../backend/glsl/emit_context.cpp | 86 +++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 5048c8b68..f68f33212 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -9,6 +9,14 @@ namespace Shader::Backend::GLSL { namespace { +u32 CbufIndex(u32 offset) { + return (offset / 4) % 4; +} + +char OffsetSwizzle(u32 offset) { + return "xyzw"[CbufIndex(offset)]; +} + std::string_view InterpDecorator(Interpolation interp) { switch (interp) { case Interpolation::Smooth: @@ -382,6 +390,8 @@ void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { } void EmitContext::DefineHelperFunctions() { + header += "\n#define ftoi floatBitsToInt\n#define ftou floatBitsToUint\n" + "#define itof intBitsToFloat\n#define utof uintBitsToFloat\n"; if (info.uses_global_increment || info.uses_shared_increment) { header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; } @@ -391,7 +401,7 @@ void EmitContext::DefineHelperFunctions() { } if (info.uses_atomic_f32_add) { header += "uint CasFloatAdd(uint op_a,float op_b){return " - "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; + "ftou(utof(op_a)+op_b);}\n"; } if (info.uses_atomic_f32x2_add) { header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " @@ -423,6 +433,80 @@ void EmitContext::DefineHelperFunctions() { if (info.uses_atomic_s32_max) { header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; } + if (info.uses_global_memory) { + std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; + std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; + std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; + + std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; + std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; + std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; + const size_t num_buffers{info.storage_buffers_descriptors.size()}; + for (size_t index = 0; index < num_buffers; ++index) { + if (!info.nvn_buffer_used[index]) { + continue; + } + const auto& ssbo{info.storage_buffers_descriptors[index]}; + const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; + const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; + const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)}; + const auto cbuf_value{fmt::format( + "uint64_t {}=packUint2x32(uvec2(ftou({}[{}].{}),ftou({}[{}].{})));", ssbo_addr, + cbuf, ssbo.cbuf_offset / 16, OffsetSwizzle(ssbo.cbuf_offset), cbuf, + (ssbo.cbuf_offset + 4) / 16, OffsetSwizzle(ssbo.cbuf_offset + 4))}; + + write_func += cbuf_value; + write_func_64 += cbuf_value; + write_func_128 += cbuf_value; + load_func += cbuf_value; + load_func_64 += cbuf_value; + load_func_128 += cbuf_value; + const auto ssbo_size{fmt::format("ftou({}[{}].{}),ftou({}[{}].{})", cbuf, + size_cbuf_offset / 16, OffsetSwizzle(size_cbuf_offset), + cbuf, (size_cbuf_offset + 4) / 16, + OffsetSwizzle(size_cbuf_offset + 4))}; + const auto comparison{fmt::format("if((addr>={})&&(addr<({}+\nuint64_t(uvec2({}))))){{", + ssbo_addr, ssbo_addr, ssbo_size)}; + write_func += comparison; + write_func_64 += comparison; + write_func_128 += comparison; + load_func += comparison; + load_func_64 += comparison; + load_func_128 += comparison; + + const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; + write_func += fmt::format("{}[uint(addr-{})>>2]=data;return;}}", ssbo_name, ssbo_addr); + write_func_64 += + fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}", + ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); + write_func_128 += + fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" + "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}", + ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, + ssbo_name, ssbo_addr); + load_func += fmt::format("return {}[uint(addr-{})>>2];}}", ssbo_name, ssbo_addr); + load_func_64 += + fmt::format("return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}", + ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); + load_func_128 += fmt::format("return " + "uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}[" + "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}", + ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, + ssbo_addr, ssbo_name, ssbo_addr); + } + write_func += "}\n"; + write_func_64 += "}\n"; + write_func_128 += "}\n"; + load_func += "return 0u;}\n"; + load_func_64 += "return uvec2(0);}\n"; + load_func_128 += "return uvec4(0);}\n"; + header += write_func; + header += write_func_64; + header += write_func_128; + header += load_func; + header += load_func_64; + header += load_func_128; + } } void EmitContext::SetupImages(Bindings& bindings) { -- cgit v1.2.3 From 5355568a2dbbb5bc4122109e2bd04ce6903adff1 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 3 Jun 2021 20:24:56 -0400 Subject: glsl: Refactor Global memory functions --- .../backend/glsl/emit_context.cpp | 143 +++++++++++---------- 1 file changed, 72 insertions(+), 71 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index f68f33212..fbc4b9c0f 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -9,11 +9,11 @@ namespace Shader::Backend::GLSL { namespace { -u32 CbufIndex(u32 offset) { +u32 CbufIndex(size_t offset) { return (offset / 4) % 4; } -char OffsetSwizzle(u32 offset) { +char CbufSwizzle(size_t offset) { return "xyzw"[CbufIndex(offset)]; } @@ -434,79 +434,80 @@ void EmitContext::DefineHelperFunctions() { header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; } if (info.uses_global_memory) { - std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; - std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; - std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; + header += DefineGlobalMemoryFunctions(); + } +} - std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; - std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; - std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; - const size_t num_buffers{info.storage_buffers_descriptors.size()}; - for (size_t index = 0; index < num_buffers; ++index) { - if (!info.nvn_buffer_used[index]) { - continue; - } - const auto& ssbo{info.storage_buffers_descriptors[index]}; - const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; - const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; - const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)}; - const auto cbuf_value{fmt::format( - "uint64_t {}=packUint2x32(uvec2(ftou({}[{}].{}),ftou({}[{}].{})));", ssbo_addr, - cbuf, ssbo.cbuf_offset / 16, OffsetSwizzle(ssbo.cbuf_offset), cbuf, - (ssbo.cbuf_offset + 4) / 16, OffsetSwizzle(ssbo.cbuf_offset + 4))}; +std::string EmitContext::DefineGlobalMemoryFunctions() { + const auto define_body{[&](std::string& func, size_t index, u32 num_components, + std::string_view return_statement) { + const auto& ssbo{info.storage_buffers_descriptors[index]}; + const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; + const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; + const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)}; + std::array addr_xy; + std::array size_xy; + for (size_t i = 0; i < addr_xy.size(); ++i) { + const auto addr_loc{ssbo.cbuf_offset + 4 * i}; + const auto size_loc{size_cbuf_offset + 4 * i}; + addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, CbufSwizzle(addr_loc)); + size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, CbufSwizzle(size_loc)); + } + const auto addr_pack{fmt::format("packUint2x32(uvec2({},{}))", addr_xy[0], addr_xy[1])}; + const auto addr_statment{fmt::format("uint64_t {}={};", ssbo_addr, addr_pack)}; + func += addr_statment; - write_func += cbuf_value; - write_func_64 += cbuf_value; - write_func_128 += cbuf_value; - load_func += cbuf_value; - load_func_64 += cbuf_value; - load_func_128 += cbuf_value; - const auto ssbo_size{fmt::format("ftou({}[{}].{}),ftou({}[{}].{})", cbuf, - size_cbuf_offset / 16, OffsetSwizzle(size_cbuf_offset), - cbuf, (size_cbuf_offset + 4) / 16, - OffsetSwizzle(size_cbuf_offset + 4))}; - const auto comparison{fmt::format("if((addr>={})&&(addr<({}+\nuint64_t(uvec2({}))))){{", - ssbo_addr, ssbo_addr, ssbo_size)}; - write_func += comparison; - write_func_64 += comparison; - write_func_128 += comparison; - load_func += comparison; - load_func_64 += comparison; - load_func_128 += comparison; + const auto size_vec{fmt::format("uvec2({},{})", size_xy[0], size_xy[1])}; + const auto comp_lhs{fmt::format("(addr>={})", ssbo_addr)}; + const auto comp_rhs{fmt::format("(addr<({}+uint64_t({})))", ssbo_addr, size_vec)}; + const auto comparison{fmt::format("if({}&&{}){{", comp_lhs, comp_rhs)}; + func += comparison; - const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; - write_func += fmt::format("{}[uint(addr-{})>>2]=data;return;}}", ssbo_name, ssbo_addr); - write_func_64 += - fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}", - ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); - write_func_128 += - fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" - "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}", - ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, - ssbo_name, ssbo_addr); - load_func += fmt::format("return {}[uint(addr-{})>>2];}}", ssbo_name, ssbo_addr); - load_func_64 += - fmt::format("return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}", - ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); - load_func_128 += fmt::format("return " - "uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}[" - "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}", - ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, - ssbo_addr, ssbo_name, ssbo_addr); + const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; + switch (num_components) { + case 1: + func += fmt::format(return_statement, ssbo_name, ssbo_addr); + break; + case 2: + func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); + break; + case 4: + func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, + ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); + break; } - write_func += "}\n"; - write_func_64 += "}\n"; - write_func_128 += "}\n"; - load_func += "return 0u;}\n"; - load_func_64 += "return uvec2(0);}\n"; - load_func_128 += "return uvec4(0);}\n"; - header += write_func; - header += write_func_64; - header += write_func_128; - header += load_func; - header += load_func_64; - header += load_func_128; - } + }}; + std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; + std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; + std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; + std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; + std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; + std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; + const size_t num_buffers{info.storage_buffers_descriptors.size()}; + for (size_t index = 0; index < num_buffers; ++index) { + if (!info.nvn_buffer_used[index]) { + continue; + } + define_body(write_func, index, 1, "{}[uint(addr-{})>>2]=data;return;}}"); + define_body(write_func_64, index, 2, + "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}"); + define_body(write_func_128, index, 4, + "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" + "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}"); + define_body(load_func, index, 1, "return {}[uint(addr-{})>>2];}}"); + define_body(load_func_64, index, 2, + "return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}"); + define_body(load_func_128, index, 4, + "return uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}[" + "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}"); + } + write_func += "}"; + write_func_64 += "}"; + write_func_128 += "}"; + load_func += "return 0u;}"; + load_func_64 += "return uvec2(0);}"; + load_func_128 += "return uvec4(0);}"; + return write_func + write_func_64 + write_func_128 + load_func + load_func_64 + load_func_128; } void EmitContext::SetupImages(Bindings& bindings) { -- cgit v1.2.3 From 34fdb6471d6050b438fd53a0406aedbf6b690600 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 3 Jun 2021 20:57:52 -0400 Subject: glsl: Cleanup and address feedback --- .../backend/glsl/emit_context.cpp | 73 +++++++++++----------- 1 file changed, 35 insertions(+), 38 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') 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) { case Interpolation::Smooth: return ""; case Interpolation::Flat: - return "flat"; + return "flat "; case Interpolation::NoPerspective: - return "noperspective"; + return "noperspective "; } throw InvalidArgument("Invalid interpolation {}", interp); } @@ -77,7 +77,6 @@ std::string_view SamplerType(TextureType type, bool is_depth) { case TextureType::ColorArrayCube: return "samplerCubeArrayShadow"; default: - fmt::print("Texture type: {}", type); throw NotImplementedException("Texture type: {}", type); } } @@ -191,29 +190,27 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { if (!StoresPerVertexAttributes(ctx.stage)) { return; } - header += "out gl_PerVertex{"; - header += "vec4 gl_Position;"; + header += "out gl_PerVertex{vec4 gl_Position;"; if (ctx.info.stores_point_size) { header += "float gl_PointSize;"; } if (ctx.info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } - if (ctx.info.stores_viewport_index && ctx.supports_viewport_layer && + if (ctx.info.stores_viewport_index && ctx.profile.support_gl_vertex_viewport_layer && ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } - header += "};\n"; + header += "};"; if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { header += "out int gl_ViewportIndex;"; } } -} // namespace +} // 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_} { - supports_viewport_layer = profile.support_gl_vertex_viewport_layer; SetupExtensions(header); stage = program.stage; switch (program.stage) { @@ -222,18 +219,18 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile stage_name = "vs"; break; case Stage::TessellationControl: - stage_name = "tsc"; - header += fmt::format("layout(vertices={})out;\n", program.invocations); + stage_name = "tcs"; + header += fmt::format("layout(vertices={})out;", program.invocations); break; case Stage::TessellationEval: - stage_name = "tse"; - header += fmt::format("layout({},{},{})in;\n", GetTessMode(runtime_info.tess_primitive), + stage_name = "tes"; + header += fmt::format("layout({},{},{})in;", GetTessMode(runtime_info.tess_primitive), GetTessSpacing(runtime_info.tess_spacing), runtime_info.tess_clockwise ? "cw" : "ccw"); break; case Stage::Geometry: stage_name = "gs"; - header += fmt::format("layout({})in;layout({},max_vertices={})out;\n", + header += fmt::format("layout({})in;layout({},max_vertices={})out;", InputPrimitive(runtime_info.input_topology), OutputPrimitive(program.output_topology), program.output_vertices); break; @@ -242,7 +239,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Compute: stage_name = "cs"; - header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", + header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;", program.workgroup_size[0], program.workgroup_size[1], program.workgroup_size[2]); break; @@ -251,7 +248,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; if (generic.used) { - header += fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, + header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, InterpDecorator(generic.interpolation), index, InputArrayDecorator(stage)); } @@ -260,11 +257,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile if (!info.uses_patches[index]) { continue; } - if (stage == Stage::TessellationControl) { - header += fmt::format("layout(location={})patch out vec4 patch{};", index, index); - } else { - header += fmt::format("layout(location={})patch in vec4 patch{};", index, index); - } + const auto qualifier{stage == Stage::TessellationControl ? "out" : "in"}; + header += fmt::format("layout(location={})patch {} vec4 patch{};", index, qualifier, index); } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { if (!info.stores_frag_color[index]) { @@ -278,18 +272,18 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile DefineGenericOutput(index, program.invocations); } } - header += "\n"; DefineConstantBuffers(bindings); DefineStorageBuffers(bindings); SetupImages(bindings); + SetupTextures(bindings); DefineHelperFunctions(); } void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage - header += "#extension GL_ARB_sparse_texture2 : enable\n"; - header += "#extension GL_EXT_texture_shadow_lod : enable\n"; - header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; + header += "#extension GL_ARB_sparse_texture2 : enable\n" + "#extension GL_EXT_texture_shadow_lod : enable\n" + "#extension GL_EXT_shader_image_load_formatted : enable\n"; if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } @@ -312,13 +306,14 @@ void EmitContext::SetupExtensions(std::string&) { } if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || info.uses_subgroup_shuffles || info.uses_fswzadd) { - header += "#extension GL_ARB_shader_ballot : enable\n"; - header += "#extension GL_ARB_shader_group_vote : enable\n"; + header += "#extension GL_ARB_shader_ballot : enable\n" + "#extension GL_ARB_shader_group_vote : enable\n"; if (!info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } - if (info.stores_viewport_index && supports_viewport_layer && stage != Stage::Geometry) { + if (info.stores_viewport_index && profile.support_gl_vertex_viewport_layer && + stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } } @@ -386,46 +381,45 @@ void EmitContext::DefineGenericOutput(size_t index, u32 invocations) { std::fill_n(output_generics[index].begin() + element, num_components, element_info); element += num_components; } - header += "\n"; } void EmitContext::DefineHelperFunctions() { header += "\n#define ftoi floatBitsToInt\n#define ftou floatBitsToUint\n" "#define itof intBitsToFloat\n#define utof uintBitsToFloat\n"; if (info.uses_global_increment || info.uses_shared_increment) { - header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; + header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; } if (info.uses_global_decrement || info.uses_shared_decrement) { header += "uint CasDecrement(uint op_a,uint " - "op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; + "op_b){return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; } if (info.uses_atomic_f32_add) { header += "uint CasFloatAdd(uint op_a,float op_b){return " - "ftou(utof(op_a)+op_b);}\n"; + "ftou(utof(op_a)+op_b);}"; } if (info.uses_atomic_f32x2_add) { header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; + "packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; } if (info.uses_atomic_f32x2_min) { header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; + "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}"; } if (info.uses_atomic_f32x2_max) { header += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; + "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}"; } if (info.uses_atomic_f16x2_add) { header += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; + "packFloat2x16(unpackFloat2x16(op_a)+op_b);}"; } if (info.uses_atomic_f16x2_min) { header += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; + "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}"; } if (info.uses_atomic_f16x2_max) { header += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " - "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; + "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}"; } if (info.uses_atomic_s32_min) { 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) { } bindings.image += desc.count; } +} + +void EmitContext::SetupTextures(Bindings& bindings) { texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); for (const auto& desc : info.texture_buffer_descriptors) { texture_buffer_bindings.push_back(bindings.texture); -- cgit v1.2.3 From 0a0b0a73d82057a309b6b0427c29c7e15e2b356f Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 3 Jun 2021 22:25:06 -0400 Subject: glsl: Fix <32-bit SSBO writes and more cleanup --- .../backend/glsl/emit_context.cpp | 52 +++++++++------------- 1 file changed, 20 insertions(+), 32 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index ae5ac752d..ecc7335ba 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -433,8 +433,7 @@ void EmitContext::DefineHelperFunctions() { } std::string EmitContext::DefineGlobalMemoryFunctions() { - const auto define_body{[&](std::string& func, size_t index, u32 num_components, - std::string_view return_statement) { + const auto define_body{[&](std::string& func, size_t index, std::string_view return_statement) { const auto& ssbo{info.storage_buffers_descriptors[index]}; const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; @@ -458,42 +457,31 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { func += comparison; const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; - switch (num_components) { - case 1: - func += fmt::format(return_statement, ssbo_name, ssbo_addr); - break; - case 2: - func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); - break; - case 4: - func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, - ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); - break; - } + func += fmt::format(return_statement, ssbo_name, ssbo_addr); }}; - std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; - std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; - std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; - std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; - std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; - std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; + std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){"}; + std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){"}; + std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){"}; + std::string load_func{"uint LoadGlobal32(uint64_t addr){"}; + std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){"}; + std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){"}; const size_t num_buffers{info.storage_buffers_descriptors.size()}; for (size_t index = 0; index < num_buffers; ++index) { if (!info.nvn_buffer_used[index]) { continue; } - define_body(write_func, index, 1, "{}[uint(addr-{})>>2]=data;return;}}"); - define_body(write_func_64, index, 2, - "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}"); - define_body(write_func_128, index, 4, - "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" - "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}"); - define_body(load_func, index, 1, "return {}[uint(addr-{})>>2];}}"); - define_body(load_func_64, index, 2, - "return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}"); - define_body(load_func_128, index, 4, - "return uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}[" - "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}"); + define_body(write_func, index, "{0}[uint(addr-{1})>>2]=data;return;}}"); + define_body(write_func_64, index, + "{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;return;}}"); + define_body(write_func_128, index, + "{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;{0}[uint(" + "addr-{1}+8)>>2]=data.z;{0}[uint(addr-{1}+12)>>2]=data.w;return;}}"); + define_body(load_func, index, "return {0}[uint(addr-{1})>>2];}}"); + define_body(load_func_64, index, + "return uvec2({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2]);}}"); + define_body(load_func_128, index, + "return uvec4({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2],{0}[" + "uint(addr-{1}+8)>>2],{0}[uint(addr-{1}+12)>>2]);}}"); } write_func += "}"; write_func_64 += "}"; -- cgit v1.2.3 From 747b8556a4611791c1b0afbb500c77de57adfc54 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 4 Jun 2021 00:46:46 -0400 Subject: glsl: Use textureGrad fallback when EXT_texture_shadow_lod is unsupported --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index ecc7335ba..76cf0bdf0 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -282,8 +282,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage header += "#extension GL_ARB_sparse_texture2 : enable\n" - "#extension GL_EXT_texture_shadow_lod : enable\n" "#extension GL_EXT_shader_image_load_formatted : enable\n"; + if (profile.support_gl_texture_shadow_lod) { + header += "#extension GL_EXT_texture_shadow_lod : enable\n"; + } if (info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } -- cgit v1.2.3 From 421847cf1e33d5b95c9aa272bf3cf69afda3d964 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 5 Jun 2021 02:41:29 -0400 Subject: glsl: Implement image atomics and set layer along with some more cleanup/oversight fixes --- src/shader_recompiler/backend/glsl/emit_context.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 76cf0bdf0..50a7a7447 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -197,7 +197,7 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { if (ctx.info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } - if (ctx.info.stores_viewport_index && ctx.profile.support_gl_vertex_viewport_layer && + if (ctx.info.stores_viewport_index && ctx.profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } @@ -314,7 +314,7 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } - if (info.stores_viewport_index && profile.support_gl_vertex_viewport_layer && + if (info.stores_viewport_index && profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } @@ -497,12 +497,13 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { void EmitContext::SetupImages(Bindings& bindings) { image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); for (const auto& desc : info.image_buffer_descriptors) { + image_buffer_bindings.push_back(bindings.image); const auto indices{bindings.image + desc.count}; + const auto format{ImageFormatString(desc.format)}; for (u32 index = bindings.image; index < indices; ++index) { - header += fmt::format("layout(binding={}) uniform uimageBuffer img{};", bindings.image, - index); + header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{};", + bindings.image, format, index); } - image_buffer_bindings.push_back(bindings.image); bindings.image += desc.count; } image_bindings.reserve(info.image_descriptors.size()); -- cgit v1.2.3 From fc0db612abedbba8245f94d03049f65d78819b26 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 7 Jun 2021 18:29:13 -0400 Subject: glsl: Conditionally use GL_EXT_shader_image_load_formatted Fix for SULD.D --- src/shader_recompiler/backend/glsl/emit_context.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 50a7a7447..8cbb2ec57 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -206,6 +206,20 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { header += "out int gl_ViewportIndex;"; } } + +bool UsesTyplessImage(const Info& info) { + for (const auto& desc : info.image_buffer_descriptors) { + if (desc.format == ImageFormat::Typeless) { + return true; + } + } + for (const auto& desc : info.image_descriptors) { + if (desc.format == ImageFormat::Typeless) { + return true; + } + } + return false; +} } // Anonymous namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -281,8 +295,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile void EmitContext::SetupExtensions(std::string&) { // TODO: track this usage - header += "#extension GL_ARB_sparse_texture2 : enable\n" - "#extension GL_EXT_shader_image_load_formatted : enable\n"; + header += "#extension GL_ARB_sparse_texture2 : enable\n"; if (profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; } @@ -318,6 +331,9 @@ void EmitContext::SetupExtensions(std::string&) { stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } + if (UsesTyplessImage(info)) { + header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; + } } void EmitContext::DefineConstantBuffers(Bindings& bindings) { -- cgit v1.2.3 From 2a504b4765320882be8b4f2bde5f90262f76fd9f Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 7 Jun 2021 19:20:32 -0400 Subject: glsl: Conditionally add GL_ARB_sparse_texture2 --- src/shader_recompiler/backend/glsl/emit_context.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 8cbb2ec57..d6b3c7aba 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -294,8 +294,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } void EmitContext::SetupExtensions(std::string&) { - // TODO: track this usage - header += "#extension GL_ARB_sparse_texture2 : enable\n"; if (profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; } @@ -331,6 +329,9 @@ void EmitContext::SetupExtensions(std::string&) { stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } + if (info.uses_sparse_residency) { + header += "#extension GL_ARB_sparse_texture2 : enable\n"; + } if (UsesTyplessImage(info)) { header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; } -- cgit v1.2.3 From c5422041134ed2645e7cd32152e36f9d04c66da3 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 7 Jun 2021 20:39:30 -0400 Subject: glsl: Implement indexed attribute loads --- .../backend/glsl/emit_context.cpp | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index d6b3c7aba..ed0955da0 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -104,8 +104,22 @@ std::string_view SamplerType(TextureType type, bool is_depth) { std::string_view ImageType(TextureType type) { switch (type) { + case TextureType::Color1D: + return "uimage1D"; + case TextureType::ColorArray1D: + return "uimage1DArray"; case TextureType::Color2D: return "uimage2D"; + case TextureType::ColorArray2D: + return "uimage2DArray"; + case TextureType::Color3D: + return "uimage3D"; + case TextureType::ColorCube: + return "uimageCube"; + case TextureType::ColorArrayCube: + return "uimageCubeArray"; + case TextureType::Buffer: + return "uimageBuffer"; default: throw NotImplementedException("Image type: {}", type); } @@ -250,6 +264,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Fragment: stage_name = "fs"; + position_name = "gl_FragCoord"; break; case Stage::Compute: stage_name = "cs"; @@ -449,6 +464,33 @@ void EmitContext::DefineHelperFunctions() { if (info.uses_global_memory) { header += DefineGlobalMemoryFunctions(); } + if (info.loads_indexed_attributes) { + const bool is_array{stage == Stage::Geometry}; + const auto vertex_arg{is_array ? ",uint vertex" : ""}; + std::string func{ + fmt::format("float IndexedAttrLoad(int offset{}){{int base_index=offset>>2;uint " + "masked_index=uint(base_index)&3u;switch(base_index>>2){{", + vertex_arg)}; + if (info.loads_position) { + func += fmt::format("case {}:", static_cast(IR::Attribute::PositionX) >> 2); + const auto position_idx{is_array ? "gl_in[vertex]." : ""}; + func += fmt::format("return {}{}[masked_index];", position_idx, position_name); + } + const u32 base_attribute_value = static_cast(IR::Attribute::Generic0X) >> 2; + for (u32 i = 0; i < info.input_generics.size(); ++i) { + if (!info.input_generics[i].used) { + continue; + } + const auto vertex_idx{is_array ? "[vertex]" : ""}; + func += fmt::format("case {}:", base_attribute_value + i); + func += fmt::format("return in_attr{}{}[masked_index];", i, vertex_idx); + } + func += "default: return 0.0;}}"; + header += func; + } + if (info.stores_indexed_attributes) { + // TODO + } } std::string EmitContext::DefineGlobalMemoryFunctions() { -- cgit v1.2.3 From 8bb8bbf4ae2ef259857efe49436dfd71758ea092 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 8 Jun 2021 01:55:12 -0400 Subject: glsl: Implement fswzadd and wip nv thread shuffle impl --- src/shader_recompiler/backend/glsl/emit_context.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index ed0955da0..6c2828644 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -306,6 +306,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile SetupImages(bindings); SetupTextures(bindings); DefineHelperFunctions(); + DefineConstants(); } void EmitContext::SetupExtensions(std::string&) { @@ -339,6 +340,9 @@ void EmitContext::SetupExtensions(std::string&) { if (!info.uses_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } + if (profile.support_gl_warp_intrinsics) { + header += "#extension GL_NV_shader_thread_shuffle : enable\n"; + } } if (info.stores_viewport_index && profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { @@ -605,4 +609,11 @@ void EmitContext::SetupTextures(Bindings& bindings) { } } +void EmitContext::DefineConstants() { + if (info.uses_fswzadd) { + header += "const float FSWZ_A[]=float[4](-1.f,1.f,-1.f,0.f);" + "const float FSWZ_B[]=float[4](-1.f,-1.f,1.f,-1.f);"; + } +} + } // namespace Shader::Backend::GLSL -- cgit v1.2.3 From 3f31a547e04b9899f1e572faa7a830aca107033e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 8 Jun 2021 21:22:50 -0400 Subject: glsl: Implement more attribute getters and setters --- src/shader_recompiler/backend/glsl/emit_context.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 6c2828644..e0d678554 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -239,6 +239,7 @@ bool UsesTyplessImage(const Info& info) { 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); stage = program.stage; switch (program.stage) { @@ -351,6 +352,9 @@ void EmitContext::SetupExtensions(std::string&) { if (info.uses_sparse_residency) { header += "#extension GL_ARB_sparse_texture2 : enable\n"; } + if (info.stores_viewport_mask && profile.support_viewport_mask) { + header += "#extension GL_NV_viewport_array2 : enable\n"; + } if (UsesTyplessImage(info)) { header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; } -- cgit v1.2.3 From 14bd73db360c0cec61dd2e211dcde49b2197e425 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 9 Jun 2021 01:16:25 -0400 Subject: glsl: Enable early fragment tests --- src/shader_recompiler/backend/glsl/emit_context.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index e0d678554..a24fa46c5 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -266,6 +266,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile case Stage::Fragment: stage_name = "fs"; position_name = "gl_FragCoord"; + if (runtime_info.force_early_z) { + header += "layout(early_fragment_tests)in;"; + } break; case Stage::Compute: stage_name = "cs"; -- cgit v1.2.3 From a92669523483eba151d07f7e9655fc5f25af7fcd Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 9 Jun 2021 01:55:36 -0400 Subject: glsl: Use existing tracking for enabling EXT_shader_image_load_formatted --- src/shader_recompiler/backend/glsl/emit_context.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index a24fa46c5..e69a56d46 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -220,20 +220,6 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { header += "out int gl_ViewportIndex;"; } } - -bool UsesTyplessImage(const Info& info) { - for (const auto& desc : info.image_buffer_descriptors) { - if (desc.format == ImageFormat::Typeless) { - return true; - } - } - for (const auto& desc : info.image_descriptors) { - if (desc.format == ImageFormat::Typeless) { - return true; - } - } - return false; -} } // Anonymous namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -358,7 +344,7 @@ void EmitContext::SetupExtensions(std::string&) { if (info.stores_viewport_mask && profile.support_viewport_mask) { header += "#extension GL_NV_viewport_array2 : enable\n"; } - if (UsesTyplessImage(info)) { + if (info.uses_typeless_image_reads || info.uses_typeless_image_writes) { header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; } } -- cgit v1.2.3 From d1a68f7997ce4986e022031e02f6062c370a56a0 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 9 Jun 2021 23:11:08 -0400 Subject: glsl: Add gl_PerVertex in for GS --- src/shader_recompiler/backend/glsl/emit_context.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index e69a56d46..fdbe2986c 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -245,7 +245,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Geometry: stage_name = "gs"; - header += fmt::format("layout({})in;layout({},max_vertices={})out;", + header += fmt::format("layout({})in;layout({},max_vertices={})out;" + "in gl_PerVertex{{vec4 gl_Position;}}gl_in[];", InputPrimitive(runtime_info.input_topology), OutputPrimitive(program.output_topology), program.output_vertices); break; -- cgit v1.2.3 From e7c8f8911f38b29c0725b76db75ce6d6d857c5f9 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 10 Jun 2021 00:01:56 -0400 Subject: glsl: Implement SampleId and SetSampleMask plus some minor refactoring of implementations --- src/shader_recompiler/backend/glsl/emit_context.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index fdbe2986c..484548467 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -256,6 +256,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile if (runtime_info.force_early_z) { header += "layout(early_fragment_tests)in;"; } + if (info.uses_sample_id) { + header += "in int gl_SampleID;"; + } + if (info.stores_sample_mask) { + header += "out int gl_SampleMask[];"; + } break; case Stage::Compute: stage_name = "cs"; -- cgit v1.2.3 From 4759db28d0b98c79f9a630b63ba13c4cd0df9109 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 11 Jun 2021 00:33:33 -0400 Subject: glsl: Address Rodrigo's feedback --- .../backend/glsl/emit_context.cpp | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 484548467..cbcf0a1eb 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -13,7 +13,7 @@ u32 CbufIndex(size_t offset) { return (offset / 4) % 4; } -char CbufSwizzle(size_t offset) { +char Swizzle(size_t offset) { return "xyzw"[CbufIndex(offset)]; } @@ -341,8 +341,8 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_NV_shader_thread_shuffle : enable\n"; } } - if (info.stores_viewport_index && profile.support_viewport_index_layer_non_geometry && - stage != Stage::Geometry) { + if ((info.stores_viewport_index || info.stores_layer) && + profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } if (info.uses_sparse_residency) { @@ -428,16 +428,16 @@ void EmitContext::DefineHelperFunctions() { header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; } if (info.uses_global_decrement || info.uses_shared_decrement) { - header += "uint CasDecrement(uint op_a,uint " - "op_b){return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; + header += "uint CasDecrement(uint op_a,uint op_b){" + "return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; } if (info.uses_atomic_f32_add) { - header += "uint CasFloatAdd(uint op_a,float op_b){return " - "ftou(utof(op_a)+op_b);}"; + header += "uint CasFloatAdd(uint op_a,float op_b){" + "return ftou(utof(op_a)+op_b);}"; } if (info.uses_atomic_f32x2_add) { - header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " - "packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; + header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){" + "return packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; } if (info.uses_atomic_f32x2_min) { header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " @@ -476,9 +476,10 @@ void EmitContext::DefineHelperFunctions() { "masked_index=uint(base_index)&3u;switch(base_index>>2){{", vertex_arg)}; if (info.loads_position) { - func += fmt::format("case {}:", static_cast(IR::Attribute::PositionX) >> 2); const auto position_idx{is_array ? "gl_in[vertex]." : ""}; - func += fmt::format("return {}{}[masked_index];", position_idx, position_name); + func += fmt::format("case {}:return {}{}[masked_index];", + static_cast(IR::Attribute::PositionX) >> 2, position_idx, + position_name); } const u32 base_attribute_value = static_cast(IR::Attribute::Generic0X) >> 2; for (u32 i = 0; i < info.input_generics.size(); ++i) { @@ -486,8 +487,8 @@ void EmitContext::DefineHelperFunctions() { continue; } const auto vertex_idx{is_array ? "[vertex]" : ""}; - func += fmt::format("case {}:", base_attribute_value + i); - func += fmt::format("return in_attr{}{}[masked_index];", i, vertex_idx); + func += fmt::format("case {}:return in_attr{}{}[masked_index];", + base_attribute_value + i, i, vertex_idx); } func += "default: return 0.0;}}"; header += func; @@ -508,8 +509,8 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { for (size_t i = 0; i < addr_xy.size(); ++i) { const auto addr_loc{ssbo.cbuf_offset + 4 * i}; const auto size_loc{size_cbuf_offset + 4 * i}; - addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, CbufSwizzle(addr_loc)); - size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, CbufSwizzle(size_loc)); + addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, Swizzle(addr_loc)); + size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, Swizzle(size_loc)); } const auto addr_pack{fmt::format("packUint2x32(uvec2({},{}))", addr_xy[0], addr_xy[1])}; const auto addr_statment{fmt::format("uint64_t {}={};", ssbo_addr, addr_pack)}; -- cgit v1.2.3 From e81c73a8748ccfcde56acfee5630116c3950e479 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 11 Jun 2021 02:50:30 -0400 Subject: glsl: Address more feedback. Implement indexed texture reads --- .../backend/glsl/emit_context.cpp | 48 +++++++++------------- 1 file changed, 20 insertions(+), 28 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index cbcf0a1eb..ed10eca8a 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -559,53 +559,45 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { } void EmitContext::SetupImages(Bindings& bindings) { - image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); + image_buffers.reserve(info.image_buffer_descriptors.size()); for (const auto& desc : info.image_buffer_descriptors) { - image_buffer_bindings.push_back(bindings.image); - const auto indices{bindings.image + desc.count}; + image_buffers.push_back({bindings.image, desc.count}); const auto format{ImageFormatString(desc.format)}; - for (u32 index = bindings.image; index < indices; ++index) { - header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{};", - bindings.image, format, index); - } + const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; + header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{}{};", bindings.image, + format, bindings.image, array_decorator); bindings.image += desc.count; } - image_bindings.reserve(info.image_descriptors.size()); + images.reserve(info.image_descriptors.size()); for (const auto& desc : info.image_descriptors) { - image_bindings.push_back(bindings.image); + images.push_back({bindings.image, desc.count}); const auto format{ImageFormatString(desc.format)}; const auto image_type{ImageType(desc.type)}; const auto qualifier{desc.is_written ? "" : "readonly "}; - const auto indices{bindings.image + desc.count}; - for (u32 index = bindings.image; index < indices; ++index) { - header += fmt::format("layout(binding={}{})uniform {}{} img{};", bindings.image, format, - qualifier, image_type, index); - } + const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; + header += fmt::format("layout(binding={}{})uniform {}{} img{}{};", bindings.image, format, + qualifier, image_type, bindings.image, array_decorator); bindings.image += desc.count; } } void EmitContext::SetupTextures(Bindings& bindings) { - texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); + texture_buffers.reserve(info.texture_buffer_descriptors.size()); for (const auto& desc : info.texture_buffer_descriptors) { - texture_buffer_bindings.push_back(bindings.texture); + texture_buffers.push_back({bindings.texture, desc.count}); const auto sampler_type{SamplerType(TextureType::Buffer, false)}; - const auto indices{bindings.texture + desc.count}; - for (u32 index = bindings.texture; index < indices; ++index) { - header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, - sampler_type, index); - } + const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; + header += fmt::format("layout(binding={}) uniform {} tex{}{};", bindings.texture, + sampler_type, bindings.texture, array_decorator); bindings.texture += desc.count; } - texture_bindings.reserve(info.texture_descriptors.size()); + textures.reserve(info.texture_descriptors.size()); for (const auto& desc : info.texture_descriptors) { + textures.push_back({bindings.texture, desc.count}); const auto sampler_type{SamplerType(desc.type, desc.is_depth)}; - texture_bindings.push_back(bindings.texture); - const auto indices{bindings.texture + desc.count}; - for (u32 index = bindings.texture; index < indices; ++index) { - header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, - sampler_type, index); - } + const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; + header += fmt::format("layout(binding={}) uniform {} tex{}{};", bindings.texture, + sampler_type, bindings.texture, array_decorator); bindings.texture += desc.count; } } -- cgit v1.2.3 From 6aa1bf7b6ff86bb7325e5b50709ddf5477b1e855 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 12 Jun 2021 20:14:56 -0400 Subject: glsl: Implement legacy varyings --- .../backend/glsl/emit_context.cpp | 43 +++++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') 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"; } -- cgit v1.2.3 From 5e7b2b9661bf685c3950d7c4065d0d35b488f95c Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 13 Jun 2021 00:05:19 -0400 Subject: glsl: Add stubs for sparse queries and variable aoffi when not supported --- src/shader_recompiler/backend/glsl/emit_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index f0e9dffc2..d0880bdcb 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -384,7 +384,7 @@ void EmitContext::SetupExtensions() { profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } - if (info.uses_sparse_residency) { + if (info.uses_sparse_residency && profile.support_gl_sparse_textures) { header += "#extension GL_ARB_sparse_texture2 : enable\n"; } if (info.stores_viewport_mask && profile.support_viewport_mask) { -- cgit v1.2.3 From a0d0704affa0f86ba29ef59d90fa06c1b7c974da Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 13 Jun 2021 19:12:03 -0400 Subject: glsl: Conditionally add EXT_texture_shadow_lod --- src/shader_recompiler/backend/glsl/emit_context.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index d0880bdcb..e18f8257e 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -302,9 +302,11 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Compute: stage_name = "cs"; + const u32 local_x{std::max(program.workgroup_size[0], 1u)}; + const u32 local_y{std::max(program.workgroup_size[1], 1u)}; + const u32 local_z{std::max(program.workgroup_size[2], 1u)}; header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;", - program.workgroup_size[0], program.workgroup_size[1], - program.workgroup_size[2]); + local_x, local_y, local_z); break; } SetupOutPerVertex(*this, header); @@ -346,7 +348,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } void EmitContext::SetupExtensions() { - if (profile.support_gl_texture_shadow_lod) { + if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; } if (info.uses_int64) { -- cgit v1.2.3 From 3b339fbbf65a50ec2ec8baacd175ca7577c3b8bd Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 14 Jun 2021 23:33:26 -0400 Subject: glsl: Conditionally use fine/coarse derivatives based on device support --- src/shader_recompiler/backend/glsl/emit_context.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index e18f8257e..0e8fe017d 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -395,6 +395,9 @@ void EmitContext::SetupExtensions() { if (info.uses_typeless_image_reads || info.uses_typeless_image_writes) { header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; } + if (info.uses_derivatives && profile.support_gl_derivative_control) { + header += "#extension GL_ARB_derivative_control : enable\n"; + } } void EmitContext::DefineConstantBuffers(Bindings& bindings) { -- cgit v1.2.3 From d36f667bc0adaa9f50d53efb4c908aadc38921a6 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 15 Jun 2021 17:23:57 -0400 Subject: glsl: Address rest of feedback --- .../backend/glsl/emit_context.cpp | 44 +++++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 0e8fe017d..d224c4d84 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -148,6 +148,16 @@ std::string_view ImageFormatString(ImageFormat format) { } } +std::string_view ImageAccessQualifier(bool is_written, bool is_read) { + if (is_written && !is_read) { + return "writeonly "; + } + if (is_read && !is_written) { + return "readonly "; + } + return ""; +} + std::string_view GetTessMode(TessPrimitive primitive) { switch (primitive) { case TessPrimitive::Triangles: @@ -262,7 +272,9 @@ void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) { 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"; + if (profile.need_fastmath_off) { + header += "#pragma optionNV(fastmath off)\n"; + } SetupExtensions(); stage = program.stage; switch (program.stage) { @@ -335,7 +347,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } for (size_t index = 0; index < info.stores_generics.size(); ++index) { // TODO: Properly resolve attribute issues - if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { + if (info.stores_generics[index] || StageInitializesVaryings()) { DefineGenericOutput(index, program.invocations); } } @@ -347,6 +359,17 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile DefineConstants(); } +bool EmitContext::StageInitializesVaryings() const noexcept { + switch (stage) { + case Stage::VertexA: + case Stage::VertexB: + case Stage::Geometry: + return true; + default: + return false; + } +} + void EmitContext::SetupExtensions() { if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; @@ -361,7 +384,7 @@ void EmitContext::SetupExtensions() { header += "#extension GL_NV_shader_atomic_float : enable\n"; } if (info.uses_atomic_f16x2_add || info.uses_atomic_f16x2_min || info.uses_atomic_f16x2_max) { - header += "#extension NV_shader_atomic_fp16_vector : enable\n"; + header += "#extension GL_NV_shader_atomic_fp16_vector : enable\n"; } if (info.uses_fp16) { if (profile.support_gl_nv_gpu_shader_5) { @@ -392,7 +415,7 @@ void EmitContext::SetupExtensions() { if (info.stores_viewport_mask && profile.support_viewport_mask) { header += "#extension GL_NV_viewport_array2 : enable\n"; } - if (info.uses_typeless_image_reads || info.uses_typeless_image_writes) { + if (info.uses_typeless_image_reads) { header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; } if (info.uses_derivatives && profile.support_gl_derivative_control) { @@ -593,9 +616,9 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { "return uvec4({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2],{0}[" "uint(addr-{1}+8)>>2],{0}[uint(addr-{1}+12)>>2]);}}"); } - write_func += "}"; - write_func_64 += "}"; - write_func_128 += "}"; + write_func += '}'; + write_func_64 += '}'; + write_func_128 += '}'; load_func += "return 0u;}"; load_func_64 += "return uvec2(0);}"; load_func_128 += "return uvec4(0);}"; @@ -607,9 +630,10 @@ void EmitContext::SetupImages(Bindings& bindings) { for (const auto& desc : info.image_buffer_descriptors) { image_buffers.push_back({bindings.image, desc.count}); const auto format{ImageFormatString(desc.format)}; + const auto qualifier{ImageAccessQualifier(desc.is_written, desc.is_read)}; const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; - header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{}{};", bindings.image, - format, bindings.image, array_decorator); + header += fmt::format("layout(binding={}{}) uniform {}uimageBuffer img{}{};", + bindings.image, format, qualifier, bindings.image, array_decorator); bindings.image += desc.count; } images.reserve(info.image_descriptors.size()); @@ -617,7 +641,7 @@ void EmitContext::SetupImages(Bindings& bindings) { images.push_back({bindings.image, desc.count}); const auto format{ImageFormatString(desc.format)}; const auto image_type{ImageType(desc.type)}; - const auto qualifier{desc.is_written ? "" : "readonly "}; + const auto qualifier{ImageAccessQualifier(desc.is_written, desc.is_read)}; const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; header += fmt::format("layout(binding={}{})uniform {}{} img{}{};", bindings.image, format, qualifier, image_type, bindings.image, array_decorator); -- cgit v1.2.3 From 12ef06ba8bca5b20069e24b36f9216d01d4fe904 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 15 Jun 2021 21:01:44 -0400 Subject: glsl: Obey need_declared_frag_colors to declare and initialize all frag_color Fixes Ori and the blind forest title screen --- src/shader_recompiler/backend/glsl/emit_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index d224c4d84..54aa88b63 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -340,7 +340,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile header += fmt::format("layout(location={})patch {} vec4 patch{};", index, qualifier, index); } for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { - if (!info.stores_frag_color[index]) { + if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { continue; } header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); -- cgit v1.2.3 From 0ffea97e2ea2c8f58928e13dc2488d620ea98ea8 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 16 Jun 2021 03:22:56 -0300 Subject: shader: Split profile and runtime info headers --- src/shader_recompiler/backend/glsl/emit_context.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 54aa88b63..93057ebb9 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -6,6 +6,7 @@ #include "shader_recompiler/backend/glsl/emit_context.h" #include "shader_recompiler/frontend/ir/program.h" #include "shader_recompiler/profile.h" +#include "shader_recompiler/runtime_info.h" namespace Shader::Backend::GLSL { namespace { -- cgit v1.2.3 From 892b8aa2adbadf1935aa5e9d87abbc686702cb2c Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 16 Jun 2021 04:48:05 -0300 Subject: glsl: Only declare fragment outputs on fragment shaders --- src/shader_recompiler/backend/glsl/emit_context.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 93057ebb9..bd40356a1 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -340,11 +340,13 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile const auto qualifier{stage == Stage::TessellationControl ? "out" : "in"}; header += fmt::format("layout(location={})patch {} vec4 patch{};", index, qualifier, index); } - for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { - if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { - continue; + if (stage == Stage::Fragment) { + for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { + if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) { + continue; + } + header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); } - header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); } for (size_t index = 0; index < info.stores_generics.size(); ++index) { // TODO: Properly resolve attribute issues -- cgit v1.2.3 From 374eeda1a35f6a1dc81cf22122c701be68e89c0f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 16 Jun 2021 04:59:30 -0300 Subject: shader: Properly manage attributes not written from previous stages --- .../backend/glsl/emit_context.cpp | 26 +++++++--------------- 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index bd40356a1..14c009535 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -327,11 +327,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile for (size_t index = 0; index < info.input_generics.size(); ++index) { const auto& generic{info.input_generics[index]}; - if (generic.used) { - header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, - InterpDecorator(generic.interpolation), index, - InputArrayDecorator(stage)); + if (!generic.used || !runtime_info.previous_stage_stores_generic[index]) { + continue; } + header += + fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, + InterpDecorator(generic.interpolation), index, InputArrayDecorator(stage)); } for (size_t index = 0; index < info.uses_patches.size(); ++index) { if (!info.uses_patches[index]) { @@ -349,10 +350,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } } for (size_t index = 0; index < info.stores_generics.size(); ++index) { - // TODO: Properly resolve attribute issues - if (info.stores_generics[index] || StageInitializesVaryings()) { - DefineGenericOutput(index, program.invocations); + if (!info.stores_generics[index]) { + continue; } + DefineGenericOutput(index, program.invocations); } DefineConstantBuffers(bindings); DefineStorageBuffers(bindings); @@ -362,17 +363,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile DefineConstants(); } -bool EmitContext::StageInitializesVaryings() const noexcept { - switch (stage) { - case Stage::VertexA: - case Stage::VertexB: - case Stage::Geometry: - return true; - default: - return false; - } -} - void EmitContext::SetupExtensions() { if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; -- cgit v1.2.3 From 7dafa96ab59892b7f1fbffdb61e4326e6443955f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 24 Jun 2021 02:41:09 -0300 Subject: shader: Rework varyings and implement passthrough geometry shaders Put all varyings into a single std::bitset with helpers to access it. Implement passthrough geometry shaders using host's. --- .../backend/glsl/emit_context.cpp | 58 +++++++++++----------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 14c009535..0d7f7bc3b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -212,22 +212,22 @@ std::string_view OutputPrimitive(OutputTopology topology) { } void SetupLegacyOutPerVertex(EmitContext& ctx, std::string& header) { - if (!ctx.info.stores_legacy_varyings) { + if (!ctx.info.stores.Legacy()) { return; } - if (ctx.info.stores_fixed_fnc_textures) { + if (ctx.info.stores.FixedFunctionTexture()) { header += "vec4 gl_TexCoord[8];"; } - if (ctx.info.stores_color_front_diffuse) { + if (ctx.info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { header += "vec4 gl_FrontColor;"; } - if (ctx.info.stores_color_front_specular) { + if (ctx.info.stores.AnyComponent(IR::Attribute::ColorFrontSpecularR)) { header += "vec4 gl_FrontSecondaryColor;"; } - if (ctx.info.stores_color_back_diffuse) { + if (ctx.info.stores.AnyComponent(IR::Attribute::ColorBackDiffuseR)) { header += "vec4 gl_BackColor;"; } - if (ctx.info.stores_color_back_specular) { + if (ctx.info.stores.AnyComponent(IR::Attribute::ColorBackSpecularR)) { header += "vec4 gl_BackSecondaryColor;"; } } @@ -237,32 +237,32 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { return; } header += "out gl_PerVertex{vec4 gl_Position;"; - if (ctx.info.stores_point_size) { + if (ctx.info.stores[IR::Attribute::PointSize]) { header += "float gl_PointSize;"; } - if (ctx.info.stores_clip_distance) { + if (ctx.info.stores.ClipDistances()) { header += "float gl_ClipDistance[];"; } - if (ctx.info.stores_viewport_index && ctx.profile.support_viewport_index_layer_non_geometry && - ctx.stage != Stage::Geometry) { + if (ctx.info.stores[IR::Attribute::ViewportIndex] && + ctx.profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } SetupLegacyOutPerVertex(ctx, header); header += "};"; - if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { + if (ctx.info.stores[IR::Attribute::ViewportIndex] && ctx.stage == Stage::Geometry) { header += "out int gl_ViewportIndex;"; } } void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) { - if (!ctx.info.loads_legacy_varyings) { + if (!ctx.info.loads.Legacy()) { return; } header += "in gl_PerFragment{"; - if (ctx.info.loads_fixed_fnc_textures) { + if (ctx.info.loads.FixedFunctionTexture()) { header += "vec4 gl_TexCoord[8];"; } - if (ctx.info.loads_color_front_diffuse) { + if (ctx.info.loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { header += "vec4 gl_Color;"; } header += "};"; @@ -325,14 +325,13 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile 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 || !runtime_info.previous_stage_stores_generic[index]) { + for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { + if (!info.loads.Generic(index) || !runtime_info.previous_stage_stores.Generic(index)) { continue; } - header += - fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, - InterpDecorator(generic.interpolation), index, InputArrayDecorator(stage)); + header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, + InterpDecorator(info.interpolation[index]), index, + InputArrayDecorator(stage)); } for (size_t index = 0; index < info.uses_patches.size(); ++index) { if (!info.uses_patches[index]) { @@ -349,11 +348,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile header += fmt::format("layout(location={})out vec4 frag_color{};", index, index); } } - for (size_t index = 0; index < info.stores_generics.size(); ++index) { - if (!info.stores_generics[index]) { - continue; + for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { + if (info.stores.Generic(index)) { + DefineGenericOutput(index, program.invocations); } - DefineGenericOutput(index, program.invocations); } DefineConstantBuffers(bindings); DefineStorageBuffers(bindings); @@ -398,14 +396,14 @@ void EmitContext::SetupExtensions() { header += "#extension GL_NV_shader_thread_shuffle : enable\n"; } } - if ((info.stores_viewport_index || info.stores_layer) && + if ((info.stores[IR::Attribute::ViewportIndex] || info.stores[IR::Attribute::Layer]) && profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } if (info.uses_sparse_residency && profile.support_gl_sparse_textures) { header += "#extension GL_ARB_sparse_texture2 : enable\n"; } - if (info.stores_viewport_mask && profile.support_viewport_mask) { + if (info.stores[IR::Attribute::ViewportMask] && profile.support_viewport_mask) { header += "#extension GL_NV_viewport_array2 : enable\n"; } if (info.uses_typeless_image_reads) { @@ -535,20 +533,20 @@ void EmitContext::DefineHelperFunctions() { fmt::format("float IndexedAttrLoad(int offset{}){{int base_index=offset>>2;uint " "masked_index=uint(base_index)&3u;switch(base_index>>2){{", vertex_arg)}; - if (info.loads_position) { + if (info.loads.AnyComponent(IR::Attribute::PositionX)) { const auto position_idx{is_array ? "gl_in[vertex]." : ""}; func += fmt::format("case {}:return {}{}[masked_index];", static_cast(IR::Attribute::PositionX) >> 2, position_idx, position_name); } const u32 base_attribute_value = static_cast(IR::Attribute::Generic0X) >> 2; - for (u32 i = 0; i < info.input_generics.size(); ++i) { - if (!info.input_generics[i].used) { + for (u32 index = 0; index < IR::NUM_GENERICS; ++index) { + if (!info.loads.Generic(index)) { continue; } const auto vertex_idx{is_array ? "[vertex]" : ""}; func += fmt::format("case {}:return in_attr{}{}[masked_index];", - base_attribute_value + i, i, vertex_idx); + base_attribute_value + index, index, vertex_idx); } func += "default: return 0.0;}}"; header += func; -- cgit v1.2.3 From f7352411f08c3a099b753d290540bb7c02fecac3 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 24 Jun 2021 20:13:21 -0400 Subject: glsl: Add passthrough geometry shader support --- .../backend/glsl/emit_context.cpp | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 0d7f7bc3b..36527bbd4 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -236,6 +236,9 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { if (!StoresPerVertexAttributes(ctx.stage)) { return; } + if (ctx.uses_geometry_passthrough) { + return; + } header += "out gl_PerVertex{vec4 gl_Position;"; if (ctx.info.stores[IR::Attribute::PointSize]) { header += "float gl_PointSize;"; @@ -272,12 +275,13 @@ void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) { EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, const RuntimeInfo& runtime_info_) - : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { + : info{program.info}, profile{profile_}, runtime_info{runtime_info_}, stage{program.stage}, + uses_geometry_passthrough{program.is_geometry_passthrough && + profile.support_geometry_shader_passthrough} { if (profile.need_fastmath_off) { header += "#pragma optionNV(fastmath off)\n"; } SetupExtensions(); - stage = program.stage; switch (program.stage) { case Stage::VertexA: case Stage::VertexB: @@ -295,10 +299,17 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; case Stage::Geometry: stage_name = "gs"; - header += fmt::format("layout({})in;layout({},max_vertices={})out;" - "in gl_PerVertex{{vec4 gl_Position;}}gl_in[];", - InputPrimitive(runtime_info.input_topology), - OutputPrimitive(program.output_topology), program.output_vertices); + header += fmt::format("layout({})in;", InputPrimitive(runtime_info.input_topology)); + if (uses_geometry_passthrough) { + header += "layout(passthrough)in gl_PerVertex{vec4 gl_Position;};"; + break; + } else if (program.is_geometry_passthrough && + !profile.support_geometry_shader_passthrough) { + LOG_WARNING(Shader_GLSL, "Passthrough geometry program used but not supported"); + } + header += fmt::format( + "layout({},max_vertices={})out;in gl_PerVertex{{vec4 gl_Position;}}gl_in[];", + OutputPrimitive(program.output_topology), program.output_vertices); break; case Stage::Fragment: stage_name = "fs"; @@ -329,7 +340,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile if (!info.loads.Generic(index) || !runtime_info.previous_stage_stores.Generic(index)) { continue; } - header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, + const auto qualifier{uses_geometry_passthrough ? "passthrough" + : fmt::format("location={}", index)}; + header += fmt::format("layout({}){}in vec4 in_attr{}{};", qualifier, InterpDecorator(info.interpolation[index]), index, InputArrayDecorator(stage)); } @@ -412,6 +425,9 @@ void EmitContext::SetupExtensions() { if (info.uses_derivatives && profile.support_gl_derivative_control) { header += "#extension GL_ARB_derivative_control : enable\n"; } + if (uses_geometry_passthrough) { + header += "#extension GL_NV_geometry_shader_passthrough : enable\n"; + } } void EmitContext::DefineConstantBuffers(Bindings& bindings) { -- cgit v1.2.3 From 2e5af95541adf581364ee3864be57f9b2b9a230f Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 28 Jun 2021 23:44:03 -0400 Subject: shader: GCC fmt 8.0.0 fixes --- src/shader_recompiler/backend/glsl/emit_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 36527bbd4..0dcdff152 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -597,7 +597,7 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { func += comparison; const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; - func += fmt::format(return_statement, ssbo_name, ssbo_addr); + func += fmt::format(fmt::runtime(return_statement), ssbo_name, ssbo_addr); }}; std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){"}; std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){"}; -- cgit v1.2.3 From 11f04f1022d0820a1fdba38221ecd38f19d86d9e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sun, 4 Jul 2021 00:34:53 -0400 Subject: shader: Ignore global memory ops on devices lacking int64 support --- src/shader_recompiler/backend/glsl/emit_context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 0dcdff152..e08d2d2eb 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -378,7 +378,7 @@ void EmitContext::SetupExtensions() { if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; } - if (info.uses_int64) { + if (info.uses_int64 && profile.support_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } if (info.uses_int64_bit_atomics) { @@ -402,7 +402,7 @@ void EmitContext::SetupExtensions() { info.uses_subgroup_shuffles || info.uses_fswzadd) { header += "#extension GL_ARB_shader_ballot : enable\n" "#extension GL_ARB_shader_group_vote : enable\n"; - if (!info.uses_int64) { + if (!info.uses_int64 && profile.support_int64) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } if (profile.support_gl_warp_intrinsics) { @@ -539,7 +539,7 @@ void EmitContext::DefineHelperFunctions() { if (info.uses_atomic_s32_max) { header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; } - if (info.uses_global_memory) { + if (info.uses_global_memory && profile.support_int64) { header += DefineGlobalMemoryFunctions(); } if (info.loads_indexed_attributes) { -- cgit v1.2.3 From 79d26842611107e784cae0dc63b6111fc0c7d5fb Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 15 Jul 2021 18:37:24 -0400 Subject: glsl: Update TessellationControl gl_in Adheres to GL_ARB_separate_shader_objects requirements --- .../backend/glsl/emit_context.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp') diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index e08d2d2eb..4e6f2c0fe 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -257,6 +257,32 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { } } +void SetupInPerVertex(EmitContext& ctx, std::string& header) { + // Currently only required for TessellationControl to adhere to + // ARB_separate_shader_objects requirements + if (ctx.stage != Stage::TessellationControl) { + return; + } + const bool loads_position{ctx.info.loads.AnyComponent(IR::Attribute::PositionX)}; + const bool loads_point_size{ctx.info.loads[IR::Attribute::PointSize]}; + const bool loads_clip_distance{ctx.info.loads.ClipDistances()}; + const bool loads_per_vertex{loads_position || loads_point_size || loads_clip_distance}; + if (!loads_per_vertex) { + return; + } + header += "in gl_PerVertex{"; + if (loads_position) { + header += "vec4 gl_Position;"; + } + if (loads_point_size) { + header += "float gl_PointSize;"; + } + if (loads_clip_distance) { + header += "float gl_ClipDistance[];"; + } + header += "}gl_in[gl_MaxPatchVertices];"; +} + void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) { if (!ctx.info.loads.Legacy()) { return; @@ -334,6 +360,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile break; } SetupOutPerVertex(*this, header); + SetupInPerVertex(*this, header); SetupLegacyInPerFragment(*this, header); for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { @@ -375,6 +402,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } void EmitContext::SetupExtensions() { + header += "#extension GL_ARB_separate_shader_objects : enable\n"; if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { header += "#extension GL_EXT_texture_shadow_lod : enable\n"; } -- cgit v1.2.3