summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorameerj <52414509+ameerj@users.noreply.github.com>2021-05-31 01:13:22 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:37 +0200
commit9f3ffb996b0d02ca64b492d22ff158e8f3659257 (patch)
tree48993eaf320484cf042071a81a1a6b1dcc829eb9
parentglsl: Rework variable allocator to allow for variable reuse (diff)
downloadyuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar.gz
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar.bz2
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar.lz
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar.xz
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.tar.zst
yuzu-9f3ffb996b0d02ca64b492d22ff158e8f3659257.zip
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp8
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h8
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp9
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp8
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp50
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h26
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp8
-rw-r--r--src/shader_recompiler/backend/glsl/var_alloc.cpp17
-rw-r--r--src/shader_recompiler/backend/glsl/var_alloc.h6
9 files changed, 91 insertions, 49 deletions
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";
}
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 2f1062954..423fc6104 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -37,7 +37,13 @@ public:
template <GlslVarType type, typename... Args>
void Add(const char* format_str, IR::Inst& inst, Args&&... args) {
- code += fmt::format(format_str, var_alloc.Define(inst, type), std::forward<Args>(args)...);
+ const auto var_def{var_alloc.AddDefine(inst, type)};
+ if (var_def.empty()) {
+ // skip assigment.
+ code += fmt::format(&format_str[3], std::forward<Args>(args)...);
+ } else {
+ code += fmt::format(format_str, var_def, std::forward<Args>(args)...);
+ }
// TODO: Remove this
code += '\n';
}
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
index 918f90058..db4c60002 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
@@ -11,8 +11,7 @@
namespace Shader::Backend::GLSL {
namespace {
-static constexpr std::string_view cas_loop{R"({};
-for (;;){{
+static constexpr std::string_view cas_loop{R"(for (;;){{
uint old_value={};
{}=atomicCompSwap({},old_value,{}({},{}));
if ({}==old_value){{break;}}
@@ -22,14 +21,14 @@ void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset
std::string_view value, std::string_view function) {
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
const std::string smem{fmt::format("smem[{}/4]", offset)};
- ctx.Add(cas_loop.data(), ret, smem, ret, smem, function, smem, value, ret);
+ ctx.Add(cas_loop.data(), smem, ret, smem, function, smem, value, ret);
}
void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
const IR::Value& offset, std::string_view value, std::string_view function) {
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
- ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret);
+ ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret);
}
void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -37,7 +36,7 @@ void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi
std::string_view function) {
const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
- ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret);
+ ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret);
ctx.AddF32("{}=uintBitsToFloat({});", inst, ret);
}
} // namespace
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 2b08aa593..9d844b831 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp
@@ -26,7 +26,13 @@ void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) {
}
void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value) {
- ctx.AddU1("{}={};", inst, ctx.var_alloc.Consume(value));
+ // Fake one usage to get a real variable out of the condition
+ inst.DestructiveAddUsage(1);
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U1)};
+ const auto input{ctx.var_alloc.Consume(value)};
+ if (ret != input) {
+ ctx.Add("{}={};", ret, input);
+ }
}
void EmitBitCastU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp
index 0fd667c8f..44a719fc3 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp
@@ -9,8 +9,14 @@
#include "shader_recompiler/frontend/ir/value.h"
namespace Shader::Backend::GLSL {
+namespace {
static constexpr std::string_view SWIZZLE{"xyzw"};
-
+void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite,
+ std::string_view object, u32 index) {
+ ctx.Add("{}={};", result, composite);
+ ctx.Add("{}.{}={};", result, SWIZZLE[index], object);
+}
+} // namespace
void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
std::string_view e2) {
ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2);
@@ -41,19 +47,22 @@ void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_vie
ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
}
-void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
-void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x3)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
-void EmitCompositeInsertU32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x4)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
void EmitCompositeConstructF16x2([[maybe_unused]] EmitContext& ctx,
@@ -146,19 +155,22 @@ void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_vie
ctx.AddF32("{}={}.{};", inst, composite, SWIZZLE[index]);
}
-void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x2)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
-void EmitCompositeInsertF32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x3)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
-void EmitCompositeInsertF32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index) {
- ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
+void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index) {
+ const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x4)};
+ CompositeInsert(ctx, ret, composite, object, index);
}
void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
index 703db80ee..c2e5aff16 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
@@ -26,7 +26,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst);
void EmitVoid(EmitContext& ctx);
void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
-void EmitReference(EmitContext&);
+void EmitReference(EmitContext& ctx, const IR::Value& value);
void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value);
void EmitBranch(EmitContext& ctx, std::string_view label);
void EmitBranchConditional(EmitContext& ctx, std::string_view condition,
@@ -165,12 +165,12 @@ void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie
u32 index);
void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
u32 index);
-void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
-void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
-void EmitCompositeInsertU32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
+void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
+void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
+void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
void EmitCompositeConstructF16x2(EmitContext& ctx, std::string_view e1, std::string_view e2);
void EmitCompositeConstructF16x3(EmitContext& ctx, std::string_view e1, std::string_view e2,
std::string_view e3);
@@ -197,12 +197,12 @@ void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie
u32 index);
void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
u32 index);
-void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
-void EmitCompositeInsertF32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
-void EmitCompositeInsertF32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
- u32 index);
+void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
+void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
+void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+ std::string_view object, u32 index);
void EmitCompositeConstructF64x2(EmitContext& ctx);
void EmitCompositeConstructF64x3(EmitContext& ctx);
void EmitCompositeConstructF64x4(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 806c4777b..599ff90e0 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -25,7 +25,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) {
}
if (!phi.Definition<Id>().is_valid) {
// The phi node wasn't forward defined
- ctx.Add("{};", ctx.var_alloc.Define(phi, phi.Arg(0).Type()));
+ ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type());
}
}
@@ -33,8 +33,8 @@ void EmitVoid(EmitContext& ctx) {
// NotImplemented();
}
-void EmitReference(EmitContext&) {
- // NotImplemented();
+void EmitReference(EmitContext& ctx, const IR::Value& value) {
+ ctx.var_alloc.Consume(value);
}
void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) {
@@ -42,7 +42,7 @@ void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value&
const auto phi_type{phi.Arg(0).Type()};
if (!phi.Definition<Id>().is_valid) {
// The phi node wasn't forward defined
- ctx.Add("{};", ctx.var_alloc.Define(phi, phi_type));
+ ctx.var_alloc.PhiDefine(phi, phi_type);
}
const auto phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})};
const auto val_reg{ctx.var_alloc.Consume(value)};
diff --git a/src/shader_recompiler/backend/glsl/var_alloc.cpp b/src/shader_recompiler/backend/glsl/var_alloc.cpp
index 8c6944f07..896457248 100644
--- a/src/shader_recompiler/backend/glsl/var_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/var_alloc.cpp
@@ -110,7 +110,6 @@ std::string VarAlloc::Define(IR::Inst& inst, GlslVarType type) {
} else {
Id id{};
id.type.Assign(type);
- // id.is_null.Assign(1);
GetUseTracker(type).uses_temp = true;
inst.SetDefinition<Id>(id);
}
@@ -121,6 +120,20 @@ std::string VarAlloc::Define(IR::Inst& inst, IR::Type type) {
return Define(inst, RegType(type));
}
+std::string VarAlloc::PhiDefine(IR::Inst& inst, IR::Type type) {
+ return AddDefine(inst, RegType(type));
+}
+
+std::string VarAlloc::AddDefine(IR::Inst& inst, GlslVarType type) {
+ if (inst.HasUses()) {
+ inst.SetDefinition<Id>(Alloc(type));
+ return Representation(inst.Definition<Id>());
+ } else {
+ return "";
+ }
+ return Representation(inst.Definition<Id>());
+}
+
std::string VarAlloc::Consume(const IR::Value& value) {
return value.IsImmediate() ? MakeImm(value) : ConsumeInst(*value.InstRecursive());
}
@@ -223,6 +236,8 @@ VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) {
switch (type) {
case GlslVarType::U1:
return var_bool;
+ case GlslVarType::F16x2:
+ return var_f16x2;
case GlslVarType::U32:
return var_u32;
case GlslVarType::S32:
diff --git a/src/shader_recompiler/backend/glsl/var_alloc.h b/src/shader_recompiler/backend/glsl/var_alloc.h
index 29d78a571..574960b1a 100644
--- a/src/shader_recompiler/backend/glsl/var_alloc.h
+++ b/src/shader_recompiler/backend/glsl/var_alloc.h
@@ -62,9 +62,15 @@ public:
bool uses_temp{};
};
+ /// Used for explicit usages of variables, may revert to temporaries
std::string Define(IR::Inst& inst, GlslVarType type);
std::string Define(IR::Inst& inst, IR::Type type);
+ /// Used to assign variables used by the IR. May return a blank string if
+ /// the instruction's result is unused in the IR.
+ std::string AddDefine(IR::Inst& inst, GlslVarType type);
+ std::string PhiDefine(IR::Inst& inst, IR::Type type);
+
std::string Consume(const IR::Value& value);
std::string ConsumeInst(IR::Inst& inst);