summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl
diff options
context:
space:
mode:
authorGravatar ameerj2021-05-28 13:54:09 -0400
committerGravatar ameerj2021-07-22 21:51:36 -0400
commitf6bbc76336942454a862280e5b2158ceab49a173 (patch)
treeb81e925154bfa7dbbd1aedc50d167fa87905b3db /src/shader_recompiler/backend/glsl
parentglsl: Fix bindings, add some CC ops (diff)
downloadyuzu-f6bbc76336942454a862280e5b2158ceab49a173.tar.gz
yuzu-f6bbc76336942454a862280e5b2158ceab49a173.tar.xz
yuzu-f6bbc76336942454a862280e5b2158ceab49a173.zip
glsl: WIP var forward declaration
to fix Loop control flow.
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp64
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h1
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp23
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp8
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.h9
6 files changed, 60 insertions, 49 deletions
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) {
29 return "sampler2DArray"; 29 return "sampler2DArray";
30 case TextureType::Color3D: 30 case TextureType::Color3D:
31 return "sampler3D"; 31 return "sampler3D";
32 case TextureType::ColorCube:
33 return "samplerCube";
32 default: 34 default:
35 fmt::print("Texture type: {}", type);
33 throw NotImplementedException("Texture type: {}", type); 36 throw NotImplementedException("Texture type: {}", type);
34 } 37 }
35} 38}
@@ -39,7 +42,6 @@ std::string_view SamplerType(TextureType type) {
39EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 42EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
40 const RuntimeInfo& runtime_info_) 43 const RuntimeInfo& runtime_info_)
41 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} { 44 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
42 std::string header = "";
43 SetupExtensions(header); 45 SetupExtensions(header);
44 stage = program.stage; 46 stage = program.stage;
45 switch (program.stage) { 47 switch (program.stage) {
@@ -67,24 +69,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
67 program.workgroup_size[2]); 69 program.workgroup_size[2]);
68 break; 70 break;
69 } 71 }
70 code += header;
71 const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; 72 const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"};
72 for (size_t index = 0; index < info.input_generics.size(); ++index) { 73 for (size_t index = 0; index < info.input_generics.size(); ++index) {
73 const auto& generic{info.input_generics[index]}; 74 const auto& generic{info.input_generics[index]};
74 if (generic.used) { 75 if (generic.used) {
75 Add("layout(location={}) {} in vec4 in_attr{};", index, 76 header += fmt::format("layout(location={}) {} in vec4 in_attr{};", index,
76 InterpDecorator(generic.interpolation), index); 77 InterpDecorator(generic.interpolation), index);
77 } 78 }
78 } 79 }
79 for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { 80 for (size_t index = 0; index < info.stores_frag_color.size(); ++index) {
80 if (!info.stores_frag_color[index]) { 81 if (!info.stores_frag_color[index]) {
81 continue; 82 continue;
82 } 83 }
83 Add("layout(location={})out vec4 frag_color{};", index, index); 84 header += fmt::format("layout(location={})out vec4 frag_color{};", index, index);
84 } 85 }
85 for (size_t index = 0; index < info.stores_generics.size(); ++index) { 86 for (size_t index = 0; index < info.stores_generics.size(); ++index) {
86 if (info.stores_generics[index]) { 87 if (info.stores_generics[index]) {
87 Add("layout(location={}) out vec4 out_attr{};", index, index); 88 header += fmt::format("layout(location={}) out vec4 out_attr{};", index, index);
88 } 89 }
89 } 90 }
90 DefineConstantBuffers(bindings); 91 DefineConstantBuffers(bindings);
@@ -92,14 +93,15 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
92 SetupImages(bindings); 93 SetupImages(bindings);
93 DefineHelperFunctions(); 94 DefineHelperFunctions();
94 95
95 Add("void main(){{"); 96 header += "void main(){\n";
96 if (stage == Stage::VertexA || stage == Stage::VertexB) { 97 if (stage == Stage::VertexA || stage == Stage::VertexB) {
97 Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); 98 Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);");
98 } 99 }
99} 100}
100 101
101void EmitContext::SetupExtensions(std::string& header) { 102void EmitContext::SetupExtensions(std::string&) {
102 header += "#extension GL_ARB_separate_shader_objects : enable\n"; 103 header += "#extension GL_ARB_separate_shader_objects : enable\n";
104 // header += "#extension GL_ARB_texture_cube_map_array : enable\n";
103 if (info.uses_int64) { 105 if (info.uses_int64) {
104 header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; 106 header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
105 } 107 }
@@ -127,7 +129,8 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) {
127 return; 129 return;
128 } 130 }
129 for (const auto& desc : info.constant_buffer_descriptors) { 131 for (const auto& desc : info.constant_buffer_descriptors) {
130 Add("layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};", 132 header += fmt::format(
133 "layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};",
131 bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024); 134 bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024);
132 bindings.uniform_buffer += desc.count; 135 bindings.uniform_buffer += desc.count;
133 } 136 }
@@ -138,53 +141,53 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) {
138 return; 141 return;
139 } 142 }
140 for (const auto& desc : info.storage_buffers_descriptors) { 143 for (const auto& desc : info.storage_buffers_descriptors) {
141 Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", bindings.storage_buffer, 144 header += fmt::format("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};",
142 bindings.storage_buffer, desc.cbuf_index); 145 bindings.storage_buffer, bindings.storage_buffer, desc.cbuf_index);
143 bindings.storage_buffer += desc.count; 146 bindings.storage_buffer += desc.count;
144 } 147 }
145} 148}
146 149
147void EmitContext::DefineHelperFunctions() { 150void EmitContext::DefineHelperFunctions() {
148 if (info.uses_global_increment) { 151 if (info.uses_global_increment) {
149 code += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; 152 header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n";
150 } 153 }
151 if (info.uses_global_decrement) { 154 if (info.uses_global_decrement) {
152 code += 155 header +=
153 "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; 156 "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n";
154 } 157 }
155 if (info.uses_atomic_f32_add) { 158 if (info.uses_atomic_f32_add) {
156 code += "uint CasFloatAdd(uint op_a,float op_b){return " 159 header += "uint CasFloatAdd(uint op_a,float op_b){return "
157 "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; 160 "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n";
158 } 161 }
159 if (info.uses_atomic_f32x2_add) { 162 if (info.uses_atomic_f32x2_add) {
160 code += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " 163 header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return "
161 "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n"; 164 "packHalf2x16(unpackHalf2x16(op_a)+op_b);}\n";
162 } 165 }
163 if (info.uses_atomic_f32x2_min) { 166 if (info.uses_atomic_f32x2_min) {
164 code += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " 167 header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return "
165 "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n"; 168 "packHalf2x16(min(unpackHalf2x16(op_a),op_b));}\n";
166 } 169 }
167 if (info.uses_atomic_f32x2_max) { 170 if (info.uses_atomic_f32x2_max) {
168 code += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return " 171 header += "uint CasFloatMax32x2(uint op_a,vec2 op_b){return "
169 "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n"; 172 "packHalf2x16(max(unpackHalf2x16(op_a),op_b));}\n";
170 } 173 }
171 if (info.uses_atomic_f16x2_add) { 174 if (info.uses_atomic_f16x2_add) {
172 code += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return " 175 header += "uint CasFloatAdd16x2(uint op_a,f16vec2 op_b){return "
173 "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n"; 176 "packFloat2x16(unpackFloat2x16(op_a)+op_b);}\n";
174 } 177 }
175 if (info.uses_atomic_f16x2_min) { 178 if (info.uses_atomic_f16x2_min) {
176 code += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return " 179 header += "uint CasFloatMin16x2(uint op_a,f16vec2 op_b){return "
177 "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n"; 180 "packFloat2x16(min(unpackFloat2x16(op_a),op_b));}\n";
178 } 181 }
179 if (info.uses_atomic_f16x2_max) { 182 if (info.uses_atomic_f16x2_max) {
180 code += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return " 183 header += "uint CasFloatMax16x2(uint op_a,f16vec2 op_b){return "
181 "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n"; 184 "packFloat2x16(max(unpackFloat2x16(op_a),op_b));}\n";
182 } 185 }
183 if (info.uses_atomic_s32_min) { 186 if (info.uses_atomic_s32_min) {
184 code += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}"; 187 header += "uint CasMinS32(uint op_a,uint op_b){return uint(min(int(op_a),int(op_b)));}";
185 } 188 }
186 if (info.uses_atomic_s32_max) { 189 if (info.uses_atomic_s32_max) {
187 code += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; 190 header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}";
188 } 191 }
189} 192}
190 193
@@ -215,7 +218,8 @@ void EmitContext::SetupImages(Bindings& bindings) {
215 texture_bindings.push_back(bindings.texture); 218 texture_bindings.push_back(bindings.texture);
216 const auto indices{bindings.texture + desc.count}; 219 const auto indices{bindings.texture + desc.count};
217 for (u32 index = bindings.texture; index < indices; ++index) { 220 for (u32 index = bindings.texture; index < indices; ++index) {
218 Add("layout(binding={}) uniform {} tex{};", bindings.texture, sampler_type, index); 221 header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture,
222 sampler_type, index);
219 } 223 }
220 bindings.texture += desc.count; 224 bindings.texture += desc.count;
221 } 225 }
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 9dff921db..c9d629c40 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -119,6 +119,7 @@ public:
119 code += '\n'; 119 code += '\n';
120 } 120 }
121 121
122 std::string header;
122 std::string code; 123 std::string code;
123 RegAlloc reg_alloc; 124 RegAlloc reg_alloc;
124 const Info& info; 125 const Info& info;
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index 56738bcc5..feb3ede1a 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -83,6 +83,7 @@ void Invoke(EmitContext& ctx, IR::Inst* inst) {
83} 83}
84 84
85void EmitInst(EmitContext& ctx, IR::Inst* inst) { 85void EmitInst(EmitContext& ctx, IR::Inst* inst) {
86 // ctx.Add("/* {} */", inst->GetOpcode());
86 switch (inst->GetOpcode()) { 87 switch (inst->GetOpcode()) {
87#define OPCODE(name, result_type, ...) \ 88#define OPCODE(name, result_type, ...) \
88 case IR::Opcode::name: \ 89 case IR::Opcode::name: \
@@ -108,12 +109,9 @@ void PrecolorInst(IR::Inst& phi) {
108 if (arg.IsImmediate()) { 109 if (arg.IsImmediate()) {
109 ir.PhiMove(phi, arg); 110 ir.PhiMove(phi, arg);
110 } else { 111 } else {
111 ir.PhiMove(phi, IR::Value{&*arg.InstRecursive()}); 112 ir.PhiMove(phi, IR::Value{arg.InstRecursive()});
112 } 113 }
113 } 114 }
114 for (size_t i = 0; i < num_args; ++i) {
115 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi});
116 }
117} 115}
118 116
119void Precolor(const IR::Program& program) { 117void Precolor(const IR::Program& program) {
@@ -144,10 +142,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
144 ctx.Add("break;"); 142 ctx.Add("break;");
145 } 143 }
146 } else { 144 } else {
147 // TODO: implement this 145 ctx.Add("if({}){{break;}}", ctx.reg_alloc.Consume(node.data.break_node.cond));
148 ctx.Add("MOV.S.CC RC,{};"
149 "BRK (NE.x);",
150 0);
151 } 146 }
152 break; 147 break;
153 case IR::AbstractSyntaxNode::Type::Return: 148 case IR::AbstractSyntaxNode::Type::Return:
@@ -155,10 +150,12 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
155 ctx.Add("return;"); 150 ctx.Add("return;");
156 break; 151 break;
157 case IR::AbstractSyntaxNode::Type::Loop: 152 case IR::AbstractSyntaxNode::Type::Loop:
158 ctx.Add("do{{"); 153 ctx.Add("for(;;){{");
159 break; 154 break;
160 case IR::AbstractSyntaxNode::Type::Repeat: 155 case IR::AbstractSyntaxNode::Type::Repeat:
161 ctx.Add("}}while({});", ctx.reg_alloc.Consume(node.data.repeat.cond)); 156 ctx.Add("if({}){{", ctx.reg_alloc.Consume(node.data.repeat.cond));
157 ctx.Add("continue;\n}}else{{");
158 ctx.Add("break;\n}}\n}}");
162 break; 159 break;
163 default: 160 default:
164 fmt::print("{}", node.type); 161 fmt::print("{}", node.type);
@@ -182,7 +179,11 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR
182 Precolor(program); 179 Precolor(program);
183 EmitCode(ctx, program); 180 EmitCode(ctx, program);
184 const std::string version{fmt::format("#version 450{}\n", GlslVersionSpecifier(ctx))}; 181 const std::string version{fmt::format("#version 450{}\n", GlslVersionSpecifier(ctx))};
185 ctx.code.insert(0, version); 182 ctx.header.insert(0, version);
183 for (size_t index = 0; index < ctx.reg_alloc.num_used_registers; ++index) {
184 ctx.header += fmt::format("{} R{};", ctx.reg_alloc.reg_types[index], index);
185 }
186 ctx.code.insert(0, ctx.header);
186 ctx.code += "}"; 187 ctx.code += "}";
187 fmt::print("\n{}\n", ctx.code); 188 fmt::print("\n{}\n", ctx.code);
188 return ctx.code; 189 return ctx.code;
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
index 84e01b151..6654fce81 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp
@@ -28,8 +28,8 @@ void SetSignFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) {
28} 28}
29} // Anonymous namespace 29} // Anonymous namespace
30void 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) {
31 const auto result{ctx.reg_alloc.Define(inst)}; 31 const auto result{ctx.reg_alloc.Define(inst, Type::U32)};
32 ctx.Add("uint {}={}+{};", result, a, b); 32 ctx.Add("{}={}+{};", result, a, b);
33 SetZeroFlag(ctx, inst, result); 33 SetZeroFlag(ctx, inst, result);
34 SetSignFlag(ctx, inst, result); 34 SetSignFlag(ctx, inst, result);
35} 35}
@@ -120,8 +120,8 @@ void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, std::string_view bas
120 120
121void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, std::string_view base, 121void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, std::string_view base,
122 std::string_view offset, std::string_view count) { 122 std::string_view offset, std::string_view count) {
123 const auto result{ctx.reg_alloc.Define(inst)}; 123 const auto result{ctx.reg_alloc.Define(inst, Type::U32)};
124 ctx.Add("uint {}=bitfieldExtract({},int({}),int({}));", result, base, offset, count); 124 ctx.Add("{}=bitfieldExtract({},int({}),int({}));", result, base, offset, count);
125 SetZeroFlag(ctx, inst, result); 125 SetZeroFlag(ctx, inst, result);
126 SetSignFlag(ctx, inst, result); 126 SetSignFlag(ctx, inst, result);
127} 127}
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
index a987ce543..b287b870a 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
@@ -74,7 +74,9 @@ std::string RegAlloc::Define(IR::Inst& inst, Type type) {
74 std::string type_str = ""; 74 std::string type_str = "";
75 if (!register_defined[id.index]) { 75 if (!register_defined[id.index]) {
76 register_defined[id.index] = true; 76 register_defined[id.index] = true;
77 type_str = GetGlslType(type); 77 // type_str = GetGlslType(type);
78 reg_types.push_back(GetGlslType(type));
79 ++num_used_registers;
78 } 80 }
79 inst.SetDefinition<Id>(id); 81 inst.SetDefinition<Id>(id);
80 return type_str + Representation(id); 82 return type_str + Representation(id);
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.h b/src/shader_recompiler/backend/glsl/reg_alloc.h
index 2dc506c58..6c293f9d1 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.h
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <bitset> 7#include <bitset>
8#include <vector>
8 9
9#include "common/bit_field.h" 10#include "common/bit_field.h"
10#include "common/common_types.h" 11#include "common/common_types.h"
@@ -61,19 +62,21 @@ public:
61 std::string Define(IR::Inst& inst, IR::Type type); 62 std::string Define(IR::Inst& inst, IR::Type type);
62 63
63 std::string Consume(const IR::Value& value); 64 std::string Consume(const IR::Value& value);
65 std::string Consume(IR::Inst& inst);
66
64 std::string GetGlslType(Type type); 67 std::string GetGlslType(Type type);
65 std::string GetGlslType(IR::Type type); 68 std::string GetGlslType(IR::Type type);
66 69
70 size_t num_used_registers{};
71 std::vector<std::string> reg_types;
72
67private: 73private:
68 static constexpr size_t NUM_REGS = 4096; 74 static constexpr size_t NUM_REGS = 4096;
69 static constexpr size_t NUM_ELEMENTS = 4;
70 75
71 std::string Consume(IR::Inst& inst);
72 Type RegType(IR::Type type); 76 Type RegType(IR::Type type);
73 Id Alloc(); 77 Id Alloc();
74 void Free(Id id); 78 void Free(Id id);
75 79
76 size_t num_used_registers{};
77 std::bitset<NUM_REGS> register_use{}; 80 std::bitset<NUM_REGS> register_use{};
78 std::bitset<NUM_REGS> register_defined{}; 81 std::bitset<NUM_REGS> register_defined{};
79}; 82};