summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
authorameerj <52414509+ameerj@users.noreply.github.com>2021-05-27 03:18:17 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:36 +0200
commitd171083d53e106c8c5131522fdc81d51360c562d (patch)
tree282cbd1306616e969166e9ddc926bc51c1c15803 /src/shader_recompiler/backend
parentglsl: Implement some attribute getters and setters (diff)
downloadyuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar.gz
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar.bz2
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar.lz
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar.xz
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.tar.zst
yuzu-d171083d53e106c8c5131522fdc81d51360c562d.zip
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp54
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h8
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp6
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp24
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h10
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp27
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.cpp72
-rw-r--r--src/shader_recompiler/backend/glsl/reg_alloc.h11
9 files changed, 139 insertions, 75 deletions
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
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 087eaff6a..1cd051b24 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -6,6 +6,8 @@
#include <string>
#include <utility>
+#include <vector>
+
#include <fmt/format.h>
#include "shader_recompiler/backend/glsl/reg_alloc.h"
@@ -109,11 +111,17 @@ public:
std::string_view stage_name = "invalid";
std::string_view attrib_name = "invalid";
+ std::vector<u32> texture_buffer_bindings;
+ std::vector<u32> image_buffer_bindings;
+ std::vector<u32> texture_bindings;
+ std::vector<u32> image_bindings;
+
private:
void SetupExtensions(std::string& header);
void DefineConstantBuffers();
void DefineStorageBuffers();
void DefineHelperFunctions();
+ void SetupImages(Bindings& bindings);
};
} // namespace Shader::Backend::GLSL
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index a8e53cf66..35dbe19ec 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -113,7 +113,7 @@ void PrecolorInst(IR::Inst& phi) {
if (arg.IsImmediate()) {
ir.PhiMove(phi, arg);
} else {
- ir.PhiMove(phi, IR::Value{&RegAlloc::AliasInst(*arg.Inst())});
+ ir.PhiMove(phi, IR::Value{&*arg.InstRecursive()});
}
}
for (size_t i = 0; i < num_args; ++i) {
@@ -157,7 +157,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
break;
case IR::AbstractSyntaxNode::Type::Return:
case IR::AbstractSyntaxNode::Type::Unreachable:
- ctx.Add("return;\n}}");
+ ctx.Add("return;");
break;
case IR::AbstractSyntaxNode::Type::Loop:
case IR::AbstractSyntaxNode::Type::Repeat:
@@ -175,6 +175,8 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo&, IR::Program& pr
EmitContext ctx{program, bindings, profile};
Precolor(program);
EmitCode(ctx, program);
+ ctx.code += "}";
+ fmt::print("\n{}\n", ctx.code);
return ctx.code;
}
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
index 742f394d4..8512147e2 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
@@ -15,7 +15,7 @@ static void Alias(IR::Inst& inst, const IR::Value& value) {
if (value.IsImmediate()) {
return;
}
- IR::Inst& value_inst{RegAlloc::AliasInst(*value.Inst())};
+ IR::Inst& value_inst{*value.InstRecursive()};
value_inst.DestructiveAddUsage(inst.UseCount());
value_inst.DestructiveRemoveUsage();
inst.SetDefinition(value_inst.Definition<Id>());
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
index 109938e0e..cc5afc048 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
@@ -6,17 +6,39 @@
#include "shader_recompiler/backend/glsl/emit_context.h"
#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
+#include "shader_recompiler/frontend/ir/modifiers.h"
#include "shader_recompiler/frontend/ir/value.h"
#include "shader_recompiler/profile.h"
namespace Shader::Backend::GLSL {
+namespace {
+std::string Texture(EmitContext& ctx, IR::TextureInstInfo info,
+ [[maybe_unused]] const IR::Value& index) {
+ if (info.type == TextureType::Buffer) {
+ throw NotImplementedException("TextureType::Buffer");
+ } else {
+ return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index));
+ }
+}
+} // namespace
void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
[[maybe_unused]] const IR::Value& index,
[[maybe_unused]] std::string_view coords,
[[maybe_unused]] std::string_view bias_lc,
[[maybe_unused]] const IR::Value& offset) {
- throw NotImplementedException("GLSL Instruction");
+ const auto info{inst.Flags<IR::TextureInstInfo>()};
+ if (info.has_bias) {
+ throw NotImplementedException("Bias texture samples");
+ }
+ if (info.has_lod_clamp) {
+ throw NotImplementedException("Lod clamp samples");
+ }
+ if (!offset.IsEmpty()) {
+ throw NotImplementedException("Offset");
+ }
+ const auto texture{Texture(ctx, info, index)};
+ ctx.AddF32x4("{}=texture({},{});", inst, texture, coords);
}
void 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 49ab108bb..c9b53bae2 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
@@ -89,11 +89,11 @@ void EmitIsHelperInvocation(EmitContext& ctx);
void EmitYDirection(EmitContext& ctx);
void EmitLoadLocal(EmitContext& ctx, std::string_view word_offset);
void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_view value);
-void EmitUndefU1(EmitContext& ctx);
-void EmitUndefU8(EmitContext& ctx);
-void EmitUndefU16(EmitContext& ctx);
-void EmitUndefU32(EmitContext& ctx);
-void EmitUndefU64(EmitContext& ctx);
+void EmitUndefU1(EmitContext& ctx, IR::Inst& inst);
+void EmitUndefU8(EmitContext& ctx, IR::Inst& inst);
+void EmitUndefU16(EmitContext& ctx, IR::Inst& inst);
+void EmitUndefU32(EmitContext& ctx, IR::Inst& inst);
+void EmitUndefU64(EmitContext& ctx, IR::Inst& inst);
void EmitLoadGlobalU8(EmitContext& ctx);
void EmitLoadGlobalS8(EmitContext& ctx);
void EmitLoadGlobalU16(EmitContext& ctx);
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 14a2edd74..42b1e8764 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -39,17 +39,26 @@ void EmitReference(EmitContext&) {
}
void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) {
- IR::Inst& phi{RegAlloc::AliasInst(*phi_value.Inst())};
+ IR::Inst& phi{*phi_value.InstRecursive()};
+ const auto phi_type{phi.Arg(0).Type()};
if (!phi.Definition<Id>().is_valid) {
// The phi node wasn't forward defined
- ctx.Add("{};", ctx.reg_alloc.Define(phi, phi.Arg(0).Type()));
+ ctx.Add("{};", ctx.reg_alloc.Define(phi, phi_type));
}
const auto phi_reg{ctx.reg_alloc.Consume(IR::Value{&phi})};
const auto val_reg{ctx.reg_alloc.Consume(value)};
if (phi_reg == val_reg) {
return;
}
- ctx.Add("{}={};", phi_reg, val_reg);
+ if (phi_type == value.Type()) {
+ ctx.Add("{}={}; // PHI MOVE", phi_reg, val_reg);
+ } else if (phi_type == IR::Type::U32 && value.Type() == IR::Type::F32) {
+ ctx.Add("{}=floatBitsToUint({}); // CAST PHI MOVE", phi_reg, val_reg);
+ } else {
+ throw NotImplementedException("{} to {} move", phi_type, value.Type());
+ const auto cast{ctx.reg_alloc.GetGlslType(phi_type)};
+ ctx.Add("{}={}({}); // CAST PHI MOVE", phi_reg, cast, val_reg);
+ }
}
void EmitBranch(EmitContext& ctx, std::string_view label) {
@@ -235,23 +244,23 @@ void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_
NotImplemented();
}
-void EmitUndefU1(EmitContext& ctx) {
+void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) {
NotImplemented();
}
-void EmitUndefU8(EmitContext& ctx) {
+void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) {
NotImplemented();
}
-void EmitUndefU16(EmitContext& ctx) {
+void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) {
NotImplemented();
}
-void EmitUndefU32(EmitContext& ctx) {
- NotImplemented();
+void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) {
+ ctx.AddU32("{}=0u;", inst);
}
-void EmitUndefU64(EmitContext& ctx) {
+void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) {
NotImplemented();
}
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
index a080d5341..06f1965b5 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
@@ -71,26 +71,17 @@ std::string RegAlloc::Define(IR::Inst& inst) {
std::string RegAlloc::Define(IR::Inst& inst, Type type) {
const Id id{Alloc()};
- const auto type_str{GetType(type, id.index)};
+ std::string type_str = "";
+ if (!register_defined[id.index]) {
+ register_defined[id.index] = true;
+ type_str = GetGlslType(type);
+ }
inst.SetDefinition<Id>(id);
return type_str + Representation(id);
}
std::string RegAlloc::Define(IR::Inst& inst, IR::Type type) {
- switch (type) {
- case IR::Type::U1:
- return Define(inst, Type::U1);
- case IR::Type::U32:
- return Define(inst, Type::U32);
- case IR::Type::F32:
- return Define(inst, Type::F32);
- case IR::Type::U64:
- return Define(inst, Type::U64);
- case IR::Type::F64:
- return Define(inst, Type::F64);
- default:
- throw NotImplementedException("IR type {}", type);
- }
+ return Define(inst, RegType(type));
}
std::string RegAlloc::Consume(const IR::Value& value) {
@@ -107,11 +98,24 @@ std::string RegAlloc::Consume(IR::Inst& inst) {
return Representation(inst.Definition<Id>());
}
-std::string RegAlloc::GetType(Type type, u32 index) {
- if (register_defined[index]) {
- return "";
+Type RegAlloc::RegType(IR::Type type) {
+ switch (type) {
+ case IR::Type::U1:
+ return Type::U1;
+ case IR::Type::U32:
+ return Type::U32;
+ case IR::Type::F32:
+ return Type::F32;
+ case IR::Type::U64:
+ return Type::U64;
+ case IR::Type::F64:
+ return Type::F64;
+ default:
+ throw NotImplementedException("IR type {}", type);
}
- register_defined[index] = true;
+}
+
+std::string RegAlloc::GetGlslType(Type type) {
switch (type) {
case Type::U1:
return "bool ";
@@ -144,6 +148,10 @@ std::string RegAlloc::GetType(Type type, u32 index) {
}
}
+std::string RegAlloc::GetGlslType(IR::Type type) {
+ return GetGlslType(RegType(type));
+}
+
Id RegAlloc::Alloc() {
if (num_used_registers < NUM_REGS) {
for (size_t reg = 0; reg < NUM_REGS; ++reg) {
@@ -170,30 +178,4 @@ void RegAlloc::Free(Id id) {
register_use[id.index] = false;
}
-/*static*/ bool RegAlloc::IsAliased(const IR::Inst& inst) {
- switch (inst.GetOpcode()) {
- case IR::Opcode::Identity:
- case IR::Opcode::BitCastU16F16:
- case IR::Opcode::BitCastU32F32:
- case IR::Opcode::BitCastU64F64:
- case IR::Opcode::BitCastF16U16:
- case IR::Opcode::BitCastF32U32:
- case IR::Opcode::BitCastF64U64:
- return true;
- default:
- return false;
- }
-}
-
-/*static*/ IR::Inst& RegAlloc::AliasInst(IR::Inst& inst) {
- IR::Inst* it{&inst};
- while (IsAliased(*it)) {
- const IR::Value arg{it->Arg(0)};
- if (arg.IsImmediate()) {
- break;
- }
- it = arg.InstRecursive();
- }
- return *it;
-}
} // namespace Shader::Backend::GLSL
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.h b/src/shader_recompiler/backend/glsl/reg_alloc.h
index df067d3ad..419d0bde0 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.h
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.h
@@ -59,20 +59,15 @@ public:
std::string Define(IR::Inst& inst, IR::Type type);
std::string Consume(const IR::Value& value);
-
- /// Returns true if the instruction is expected to be aliased to another
- static bool IsAliased(const IR::Inst& inst);
-
- /// Returns the underlying value out of an alias sequence
- static IR::Inst& AliasInst(IR::Inst& inst);
+ std::string GetGlslType(Type type);
+ std::string GetGlslType(IR::Type type);
private:
static constexpr size_t NUM_REGS = 4096;
static constexpr size_t NUM_ELEMENTS = 4;
std::string Consume(IR::Inst& inst);
- std::string GetType(Type type, u32 index);
-
+ Type RegType(IR::Type type);
Id Alloc();
void Free(Id id);