summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl
diff options
context:
space:
mode:
authorGravatar ameerj2021-05-24 19:33:11 -0400
committerGravatar ameerj2021-07-22 21:51:36 -0400
commite99d01ff5308bb239aa2007ba4363d3a77f4d202 (patch)
treed01d0c54c42b15a140fa51f409d187ebe44016eb /src/shader_recompiler/backend/glsl
parentglsl: Wip storage atomic ops (diff)
downloadyuzu-e99d01ff5308bb239aa2007ba4363d3a77f4d202.tar.gz
yuzu-e99d01ff5308bb239aa2007ba4363d3a77f4d202.tar.xz
yuzu-e99d01ff5308bb239aa2007ba4363d3a77f4d202.zip
glsl: implement phi nodes
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp48
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp7
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.cpp17
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.h2
4 files changed, 54 insertions, 20 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index e48f152d0..e5aaf81a7 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <ranges>
5#include <string> 6#include <string>
6#include <tuple> 7#include <tuple>
7 8
@@ -9,6 +10,7 @@
9#include "shader_recompiler/backend/glsl/emit_context.h" 10#include "shader_recompiler/backend/glsl/emit_context.h"
10#include "shader_recompiler/backend/glsl/emit_glsl.h" 11#include "shader_recompiler/backend/glsl/emit_glsl.h"
11#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" 12#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
13#include "shader_recompiler/frontend/ir/ir_emitter.h"
12#include "shader_recompiler/frontend/ir/program.h" 14#include "shader_recompiler/frontend/ir/program.h"
13#include "shader_recompiler/profile.h" 15#include "shader_recompiler/profile.h"
14 16
@@ -96,6 +98,22 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) {
96 throw LogicError("Invalid opcode {}", inst->GetOpcode()); 98 throw LogicError("Invalid opcode {}", inst->GetOpcode());
97} 99}
98 100
101void Precolor(EmitContext& ctx, const IR::Program& program) {
102 for (IR::Block* const block : program.blocks) {
103 for (IR::Inst& phi : block->Instructions() | std::views::take_while(IR::IsPhi)) {
104 ctx.Add("{};", ctx.reg_alloc.Define(phi, phi.Arg(0).Type()));
105 const size_t num_args{phi.NumArgs()};
106 for (size_t i = 0; i < num_args; ++i) {
107 IR::IREmitter{*phi.PhiBlock(i)}.PhiMove(phi, phi.Arg(i));
108 }
109 // Add reference to the phi node on the phi predecessor to avoid overwritting it
110 for (size_t i = 0; i < num_args; ++i) {
111 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi});
112 }
113 }
114 }
115}
116
99void EmitCode(EmitContext& ctx, const IR::Program& program) { 117void EmitCode(EmitContext& ctx, const IR::Program& program) {
100 for (const IR::AbstractSyntaxNode& node : program.syntax_list) { 118 for (const IR::AbstractSyntaxNode& node : program.syntax_list) {
101 switch (node.type) { 119 switch (node.type) {
@@ -105,37 +123,31 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
105 } 123 }
106 break; 124 break;
107 case IR::AbstractSyntaxNode::Type::If: 125 case IR::AbstractSyntaxNode::Type::If:
108 ctx.Add("if ("); 126 ctx.Add("if ({}){{", ctx.reg_alloc.Consume(node.data.if_node.cond));
109 break; 127 break;
110 case IR::AbstractSyntaxNode::Type::EndIf: 128 case IR::AbstractSyntaxNode::Type::EndIf:
111 ctx.Add("){{"); 129 ctx.Add("}}");
112 break;
113 case IR::AbstractSyntaxNode::Type::Loop:
114 ctx.Add("while (");
115 break;
116 case IR::AbstractSyntaxNode::Type::Repeat:
117 if (node.data.repeat.cond.IsImmediate()) {
118 if (node.data.repeat.cond.U1()) {
119 ctx.Add("ENDREP;");
120 } else {
121 ctx.Add("BRK;"
122 "ENDREP;");
123 }
124 }
125 break; 130 break;
126 case IR::AbstractSyntaxNode::Type::Break: 131 case IR::AbstractSyntaxNode::Type::Break:
127 if (node.data.break_node.cond.IsImmediate()) { 132 if (node.data.break_node.cond.IsImmediate()) {
128 if (node.data.break_node.cond.U1()) { 133 if (node.data.break_node.cond.U1()) {
129 ctx.Add("break;"); 134 ctx.Add("break;");
130 } 135 }
136 } else {
137 // TODO: implement this
138 ctx.Add("MOV.S.CC RC,{};"
139 "BRK (NE.x);",
140 0);
131 } 141 }
132 break; 142 break;
133 case IR::AbstractSyntaxNode::Type::Return: 143 case IR::AbstractSyntaxNode::Type::Return:
134 case IR::AbstractSyntaxNode::Type::Unreachable: 144 case IR::AbstractSyntaxNode::Type::Unreachable:
135 ctx.Add("return;"); 145 ctx.Add("return;\n}}");
136 break; 146 break;
147 case IR::AbstractSyntaxNode::Type::Loop:
148 case IR::AbstractSyntaxNode::Type::Repeat:
137 default: 149 default:
138 ctx.Add("UNAHNDLED {}", node.type); 150 throw NotImplementedException("{}", node.type);
139 break; 151 break;
140 } 152 }
141 } 153 }
@@ -146,8 +158,8 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
146std::string EmitGLSL(const Profile& profile, const RuntimeInfo&, IR::Program& program, 158std::string EmitGLSL(const Profile& profile, const RuntimeInfo&, IR::Program& program,
147 Bindings& bindings) { 159 Bindings& bindings) {
148 EmitContext ctx{program, bindings, profile}; 160 EmitContext ctx{program, bindings, profile};
161 Precolor(ctx, program);
149 EmitCode(ctx, program); 162 EmitCode(ctx, program);
150 ctx.code += "}";
151 return ctx.code; 163 return ctx.code;
152} 164}
153 165
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 65eccaece..d67a1d81f 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -28,11 +28,14 @@ void EmitVoid(EmitContext& ctx) {
28} 28}
29 29
30void EmitReference(EmitContext&) { 30void EmitReference(EmitContext&) {
31 NotImplemented(); 31 // NotImplemented();
32} 32}
33 33
34void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { 34void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) {
35 NotImplemented(); 35 if (phi == value) {
36 return;
37 }
38 ctx.Add("{}={};", ctx.reg_alloc.Consume(phi), ctx.reg_alloc.Consume(value));
36} 39}
37 40
38void EmitBranch(EmitContext& ctx, std::string_view label) { 41void EmitBranch(EmitContext& ctx, std::string_view label) {
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
index 8db1391fd..58c2c408e 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
@@ -74,6 +74,23 @@ std::string RegAlloc::Define(IR::Inst& inst, Type type) {
74 return type_str + Representation(id); 74 return type_str + Representation(id);
75} 75}
76 76
77std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) {
78 switch (type) {
79 case IR::Type::U1:
80 return Define(inst, Type::U1);
81 case IR::Type::U32:
82 return Define(inst, Type::U32);
83 case IR::Type::F32:
84 return Define(inst, Type::F32);
85 case IR::Type::U64:
86 return Define(inst, Type::U64);
87 case IR::Type::F64:
88 return Define(inst, Type::F64);
89 default:
90 throw NotImplementedException("IR type {}", type);
91 }
92}
93
77std::string RegAlloc::Consume(const IR::Value& value) { 94std::string RegAlloc::Consume(const IR::Value& value) {
78 return value.IsImmediate() ? MakeImm(value) : Consume(*value.InstRecursive()); 95 return value.IsImmediate() ? MakeImm(value) : Consume(*value.InstRecursive());
79} 96}
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.h b/src/shader_recompiler/backend/glsl/reg_alloc.h
index 7891c30e0..581954e44 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.h
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.h
@@ -12,6 +12,7 @@
12namespace Shader::IR { 12namespace Shader::IR {
13class Inst; 13class Inst;
14class Value; 14class Value;
15enum class Type;
15} // namespace Shader::IR 16} // namespace Shader::IR
16 17
17namespace Shader::Backend::GLSL { 18namespace Shader::Backend::GLSL {
@@ -50,6 +51,7 @@ class RegAlloc {
50public: 51public:
51 std::string Define(IR::Inst& inst); 52 std::string Define(IR::Inst& inst);
52 std::string Define(IR::Inst& inst, Type type); 53 std::string Define(IR::Inst& inst, Type type);
54 std::string Define(IR::Inst& inst, IR::Type type);
53 55
54 std::string Consume(const IR::Value& value); 56 std::string Consume(const IR::Value& value);
55 57