summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp57
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h5
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp33
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp11
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h4
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp29
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_select.cpp7
8 files changed, 91 insertions, 57 deletions
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) {
20 } 20 }
21 throw InvalidArgument("Invalid interpolation {}", interp); 21 throw InvalidArgument("Invalid interpolation {}", interp);
22} 22}
23
24std::string_view SamplerType(TextureType type) {
25 switch (type) {
26 case TextureType::Color2D:
27 return "sampler2D";
28 case TextureType::ColorArray2D:
29 return "sampler2DArray";
30 case TextureType::Color3D:
31 return "sampler3D";
32 default:
33 throw NotImplementedException("Texture type: {}", type);
34 }
35}
36
23} // namespace 37} // namespace
24 38
25EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 39EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
@@ -31,27 +45,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
31 switch (program.stage) { 45 switch (program.stage) {
32 case Stage::VertexA: 46 case Stage::VertexA:
33 case Stage::VertexB: 47 case Stage::VertexB:
34 stage_name = "vertex"; 48 stage_name = "vs";
35 attrib_name = "vertex";
36 // TODO: add only what's used by the shader 49 // TODO: add only what's used by the shader
37 header += 50 header +=
38 "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; 51 "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};";
39 break; 52 break;
40 case Stage::TessellationControl: 53 case Stage::TessellationControl:
41 case Stage::TessellationEval: 54 case Stage::TessellationEval:
42 stage_name = "primitive"; 55 stage_name = "ts";
43 attrib_name = "primitive";
44 break; 56 break;
45 case Stage::Geometry: 57 case Stage::Geometry:
46 stage_name = "primitive"; 58 stage_name = "gs";
47 attrib_name = "vertex";
48 break; 59 break;
49 case Stage::Fragment: 60 case Stage::Fragment:
50 stage_name = "fragment"; 61 stage_name = "fs";
51 attrib_name = "fragment";
52 break; 62 break;
53 case Stage::Compute: 63 case Stage::Compute:
54 stage_name = "invocation"; 64 stage_name = "cs";
55 header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", 65 header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n",
56 program.workgroup_size[0], program.workgroup_size[1], 66 program.workgroup_size[0], program.workgroup_size[1],
57 program.workgroup_size[2]); 67 program.workgroup_size[2]);
@@ -77,12 +87,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
77 Add("layout(location={}) out vec4 out_attr{};", index, index); 87 Add("layout(location={}) out vec4 out_attr{};", index, index);
78 } 88 }
79 } 89 }
80 DefineConstantBuffers(); 90 DefineConstantBuffers(bindings);
81 DefineStorageBuffers(); 91 DefineStorageBuffers(bindings);
82 DefineHelperFunctions();
83 SetupImages(bindings); 92 SetupImages(bindings);
84 Add("void main(){{"); 93 DefineHelperFunctions();
85 94
95 Add("void main(){{");
86 if (stage == Stage::VertexA || stage == Stage::VertexB) { 96 if (stage == Stage::VertexA || stage == Stage::VertexB) {
87 Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); 97 Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);");
88 } 98 }
@@ -112,27 +122,25 @@ void EmitContext::SetupExtensions(std::string& header) {
112 } 122 }
113} 123}
114 124
115void EmitContext::DefineConstantBuffers() { 125void EmitContext::DefineConstantBuffers(Bindings& bindings) {
116 if (info.constant_buffer_descriptors.empty()) { 126 if (info.constant_buffer_descriptors.empty()) {
117 return; 127 return;
118 } 128 }
119 u32 binding{};
120 for (const auto& desc : info.constant_buffer_descriptors) { 129 for (const auto& desc : info.constant_buffer_descriptors) {
121 Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, 130 Add("layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};",
122 desc.index, 4 * 1024); 131 bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024);
123 ++binding; 132 bindings.uniform_buffer += desc.count;
124 } 133 }
125} 134}
126 135
127void EmitContext::DefineStorageBuffers() { 136void EmitContext::DefineStorageBuffers(Bindings& bindings) {
128 if (info.storage_buffers_descriptors.empty()) { 137 if (info.storage_buffers_descriptors.empty()) {
129 return; 138 return;
130 } 139 }
131 u32 binding{};
132 for (const auto& desc : info.storage_buffers_descriptors) { 140 for (const auto& desc : info.storage_buffers_descriptors) {
133 Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", binding, binding, 141 Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", bindings.storage_buffer,
134 desc.cbuf_index, desc.count); 142 bindings.storage_buffer, desc.cbuf_index);
135 ++binding; 143 bindings.storage_buffer += desc.count;
136 } 144 }
137} 145}
138 146
@@ -203,10 +211,11 @@ void EmitContext::SetupImages(Bindings& bindings) {
203 } 211 }
204 texture_bindings.reserve(info.texture_descriptors.size()); 212 texture_bindings.reserve(info.texture_descriptors.size());
205 for (const auto& desc : info.texture_descriptors) { 213 for (const auto& desc : info.texture_descriptors) {
214 const auto sampler_type{SamplerType(desc.type)};
206 texture_bindings.push_back(bindings.texture); 215 texture_bindings.push_back(bindings.texture);
207 const auto indices{bindings.texture + desc.count}; 216 const auto indices{bindings.texture + desc.count};
208 for (u32 index = bindings.texture; index < indices; ++index) { 217 for (u32 index = bindings.texture; index < indices; ++index) {
209 Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); 218 Add("layout(binding={}) uniform {} tex{};", bindings.texture, sampler_type, index);
210 } 219 }
211 bindings.texture += desc.count; 220 bindings.texture += desc.count;
212 } 221 }
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 07dad6e57..9dff921db 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -127,7 +127,6 @@ public:
127 127
128 Stage stage{}; 128 Stage stage{};
129 std::string_view stage_name = "invalid"; 129 std::string_view stage_name = "invalid";
130 std::string_view attrib_name = "invalid";
131 130
132 std::vector<u32> texture_buffer_bindings; 131 std::vector<u32> texture_buffer_bindings;
133 std::vector<u32> image_buffer_bindings; 132 std::vector<u32> image_buffer_bindings;
@@ -138,8 +137,8 @@ public:
138 137
139private: 138private:
140 void SetupExtensions(std::string& header); 139 void SetupExtensions(std::string& header);
141 void DefineConstantBuffers(); 140 void DefineConstantBuffers(Bindings& bindings);
142 void DefineStorageBuffers(); 141 void DefineStorageBuffers(Bindings& bindings);
143 void DefineHelperFunctions(); 142 void DefineHelperFunctions();
144 void SetupImages(Bindings& bindings); 143 void SetupImages(Bindings& bindings);
145}; 144};
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
index 38ad9de35..67d308c49 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
@@ -43,23 +43,24 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR
43void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 43void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
44 const IR::Value& offset) { 44 const IR::Value& offset) {
45 if (offset.IsImmediate()) { 45 if (offset.IsImmediate()) {
46 ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}].{});", inst, binding.U32(), offset.U32() / 16, 46 ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}].{});", inst, ctx.stage_name, binding.U32(),
47 OffsetSwizzle(offset.U32())); 47 offset.U32() / 16, OffsetSwizzle(offset.U32()));
48 } else { 48 } else {
49 const auto offset_var{ctx.reg_alloc.Consume(offset)}; 49 const auto offset_var{ctx.reg_alloc.Consume(offset)};
50 ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}/16][({}/4)%4]);", inst, binding.U32(), offset_var, 50 ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}/16][({}/4)%4]);", inst, ctx.stage_name,
51 offset_var); 51 binding.U32(), offset_var, offset_var);
52 } 52 }
53} 53}
54 54
55void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 55void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
56 const IR::Value& offset) { 56 const IR::Value& offset) {
57 if (offset.IsImmediate()) { 57 if (offset.IsImmediate()) {
58 ctx.AddF32("{}=cbuf{}[{}].{};", inst, binding.U32(), offset.U32() / 16, 58 ctx.AddF32("{}={}_cbuf{}[{}].{};", inst, ctx.stage_name, binding.U32(), offset.U32() / 16,
59 OffsetSwizzle(offset.U32())); 59 OffsetSwizzle(offset.U32()));
60 } else { 60 } else {
61 const auto offset_var{ctx.reg_alloc.Consume(offset)}; 61 const auto offset_var{ctx.reg_alloc.Consume(offset)};
62 ctx.AddF32("{}=cbuf{}[{}/16][({}/4)%4];", inst, binding.U32(), offset_var, offset_var); 62 ctx.AddF32("{}={}_cbuf{}[{}/16][({}/4)%4];", inst, ctx.stage_name, binding.U32(),
63 offset_var, offset_var);
63 } 64 }
64} 65}
65 66
@@ -68,15 +69,17 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding
68 if (offset.IsImmediate()) { 69 if (offset.IsImmediate()) {
69 const auto u32_offset{offset.U32()}; 70 const auto u32_offset{offset.U32()};
70 const auto index{(u32_offset / 4) % 4}; 71 const auto index{(u32_offset / 4) % 4};
71 ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}].{}),floatBitsToUint(cbuf{}[{}].{}));", 72 ctx.AddU32x2(
72 inst, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), 73 "{}=uvec2(floatBitsToUint({}_cbuf{}[{}].{}),floatBitsToUint({}_cbuf{}[{}].{}));", inst,
73 binding.U32(), (offset.U32() + 1) / 16, OffsetSwizzle(offset.U32() + 1)); 74 ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()),
75 ctx.stage_name, binding.U32(), (offset.U32() + 1) / 16,
76 OffsetSwizzle(offset.U32() + 1));
74 } else { 77 } else {
75 const auto offset_var{ctx.reg_alloc.Consume(offset)}; 78 const auto offset_var{ctx.reg_alloc.Consume(offset)};
76 ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}/16][({}/" 79 ctx.AddU32x2("{}=uvec2(floatBitsToUint({}_cbuf{}[{}/16][({}/"
77 "4)%4]),floatBitsToUint(cbuf{}[({}+1)/16][(({}+1/4))%4]));", 80 "4)%4]),floatBitsToUint({}_cbuf{}[({}+1)/16][(({}+1/4))%4]));",
78 inst, binding.U32(), offset_var, offset_var, binding.U32(), offset_var, 81 inst, ctx.stage_name, binding.U32(), offset_var, offset_var, ctx.stage_name,
79 offset_var); 82 binding.U32(), offset_var, offset_var);
80 } 83 }
81} 84}
82 85
@@ -107,10 +110,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
107 } 110 }
108 break; 111 break;
109 case IR::Attribute::InstanceId: 112 case IR::Attribute::InstanceId:
110 ctx.AddS32("{}=gl_InstanceID;", inst, ctx.attrib_name); 113 ctx.AddS32("{}=gl_InstanceID;", inst);
111 break; 114 break;
112 case IR::Attribute::VertexId: 115 case IR::Attribute::VertexId:
113 ctx.AddS32("{}=gl_VertexID;", inst, ctx.attrib_name); 116 ctx.AddS32("{}=gl_VertexID;", inst);
114 break; 117 break;
115 default: 118 default:
116 fmt::print("Get attribute {}", attr); 119 fmt::print("Get attribute {}", attr);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
index 6b7f1eaad..c070fba0e 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
@@ -32,14 +32,13 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse
32 if (info.has_lod_clamp) { 32 if (info.has_lod_clamp) {
33 throw NotImplementedException("Lod clamp samples"); 33 throw NotImplementedException("Lod clamp samples");
34 } 34 }
35 const auto texture{Texture(ctx, info, index)};
35 if (!offset.IsEmpty()) { 36 if (!offset.IsEmpty()) {
36 throw NotImplementedException("Offset"); 37 ctx.AddF32x4("{}=textureOffset({},{},ivec2({}));", inst, texture, coords,
37 } 38 ctx.reg_alloc.Consume(offset));
38 if (info.type != TextureType::Color2D) { 39 } else {
39 throw NotImplementedException("Texture type: {}", info.type.Value()); 40 ctx.AddF32x4("{}=texture({},{});", inst, texture, coords);
40 } 41 }
41 const auto texture{Texture(ctx, info, index)};
42 ctx.AddF32x4("{}=texture({},{});", inst, texture, coords);
43} 42}
44 43
45void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 44void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
index f08ed0ece..b54fe684e 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
@@ -207,8 +207,8 @@ void EmitCompositeInsertF64x3(EmitContext& ctx, std::string_view composite, std:
207 u32 index); 207 u32 index);
208void EmitCompositeInsertF64x4(EmitContext& ctx, std::string_view composite, std::string_view object, 208void EmitCompositeInsertF64x4(EmitContext& ctx, std::string_view composite, std::string_view object,
209 u32 index); 209 u32 index);
210void EmitSelectU1(EmitContext& ctx, std::string_view cond, std::string_view true_value, 210void EmitSelectU1(EmitContext& ctx, IR::Inst& inst, std::string_view cond,
211 std::string_view false_value); 211 std::string_view true_value, std::string_view false_value);
212void EmitSelectU8(EmitContext& ctx, std::string_view cond, std::string_view true_value, 212void EmitSelectU8(EmitContext& ctx, std::string_view cond, std::string_view true_value,
213 std::string_view false_value); 213 std::string_view false_value);
214void EmitSelectU16(EmitContext& ctx, std::string_view cond, std::string_view true_value, 214void EmitSelectU16(EmitContext& ctx, std::string_view cond, std::string_view true_value,
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
index ce6e12623..84e01b151 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
@@ -8,8 +8,30 @@
8#include "shader_recompiler/frontend/ir/value.h" 8#include "shader_recompiler/frontend/ir/value.h"
9 9
10namespace Shader::Backend::GLSL { 10namespace Shader::Backend::GLSL {
11namespace {
12void SetZeroFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) {
13 IR::Inst* const zero{inst.GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)};
14 if (!zero) {
15 return;
16 }
17 ctx.AddU1("{}={}==0;", *zero, result);
18 zero->Invalidate();
19}
20
21void SetSignFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) {
22 IR::Inst* const sign{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)};
23 if (!sign) {
24 return;
25 }
26 ctx.AddU1("{}=int({})<0;", *sign, result);
27 sign->Invalidate();
28}
29} // Anonymous namespace
11void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 30void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
12 ctx.AddU32("{}={}+{};", inst, a, b); 31 const auto result{ctx.reg_alloc.Define(inst)};
32 ctx.Add("uint {}={}+{};", result, a, b);
33 SetZeroFlag(ctx, inst, result);
34 SetSignFlag(ctx, inst, result);
13} 35}
14 36
15void EmitIAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 37void EmitIAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
@@ -98,7 +120,10 @@ void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, std::string_view bas
98 120
99void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, std::string_view base, 121void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, std::string_view base,
100 std::string_view offset, std::string_view count) { 122 std::string_view offset, std::string_view count) {
101 ctx.AddU32("{}=bitfieldExtract({}, int({}), int({}));", inst, base, offset, count); 123 const auto result{ctx.reg_alloc.Define(inst)};
124 ctx.Add("uint {}=bitfieldExtract({},int({}),int({}));", result, base, offset, count);
125 SetZeroFlag(ctx, inst, result);
126 SetSignFlag(ctx, inst, result);
102} 127}
103 128
104void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { 129void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, std::string_view value) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
index 110d3322e..3bac8899b 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -29,7 +29,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) {
29} 29}
30 30
31void EmitVoid(EmitContext& ctx) { 31void EmitVoid(EmitContext& ctx) {
32 NotImplemented(); 32 // NotImplemented();
33} 33}
34 34
35void EmitReference(EmitContext&) { 35void EmitReference(EmitContext&) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp
index 1f2790b7d..ad3713f2d 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp
@@ -8,10 +8,9 @@
8#include "shader_recompiler/frontend/ir/value.h" 8#include "shader_recompiler/frontend/ir/value.h"
9 9
10namespace Shader::Backend::GLSL { 10namespace Shader::Backend::GLSL {
11void EmitSelectU1([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, 11void EmitSelectU1(EmitContext& ctx, IR::Inst& inst, std::string_view cond,
12 [[maybe_unused]] std::string_view true_value, 12 std::string_view true_value, std::string_view false_value) {
13 [[maybe_unused]] std::string_view false_value) { 13 ctx.AddU1("{}={}?{}:{};", inst, cond, true_value, false_value);
14 throw NotImplementedException("GLSL Instruction");
15} 14}
16 15
17void EmitSelectU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, 16void EmitSelectU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond,