glsl: Rework var alloc to not assign unused results
This commit is contained in:
parent
1269a0cf8b
commit
9f3ffb996b
|
@ -122,11 +122,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
|
||||||
|
|
||||||
void EmitContext::SetupExtensions(std::string&) {
|
void EmitContext::SetupExtensions(std::string&) {
|
||||||
header += "#extension GL_ARB_separate_shader_objects : enable\n";
|
header += "#extension GL_ARB_separate_shader_objects : enable\n";
|
||||||
if (stage != Stage::Compute) {
|
// TODO: track this usage
|
||||||
// TODO: track this usage
|
header += "#extension GL_ARB_sparse_texture2 : enable\n";
|
||||||
header += "#extension GL_ARB_sparse_texture2 : enable\n";
|
header += "#extension GL_EXT_texture_shadow_lod : enable\n";
|
||||||
header += "#extension GL_EXT_texture_shadow_lod : enable\n";
|
|
||||||
}
|
|
||||||
if (info.uses_int64) {
|
if (info.uses_int64) {
|
||||||
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
|
header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,13 @@ public:
|
||||||
|
|
||||||
template <GlslVarType type, typename... Args>
|
template <GlslVarType type, typename... Args>
|
||||||
void Add(const char* format_str, IR::Inst& inst, Args&&... 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
|
// TODO: Remove this
|
||||||
code += '\n';
|
code += '\n';
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,7 @@
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
namespace Shader::Backend::GLSL {
|
||||||
namespace {
|
namespace {
|
||||||
static constexpr std::string_view cas_loop{R"({};
|
static constexpr std::string_view cas_loop{R"(for (;;){{
|
||||||
for (;;){{
|
|
||||||
uint old_value={};
|
uint old_value={};
|
||||||
{}=atomicCompSwap({},old_value,{}({},{}));
|
{}=atomicCompSwap({},old_value,{}({},{}));
|
||||||
if ({}==old_value){{break;}}
|
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) {
|
std::string_view value, std::string_view function) {
|
||||||
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
|
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
|
||||||
const std::string smem{fmt::format("smem[{}/4]", offset)};
|
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,
|
void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
|
||||||
const IR::Value& offset, std::string_view value, std::string_view function) {
|
const IR::Value& offset, std::string_view value, std::string_view function) {
|
||||||
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
|
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)};
|
||||||
const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.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,
|
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) {
|
std::string_view function) {
|
||||||
const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
|
const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())};
|
||||||
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::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);
|
ctx.AddF32("{}=uintBitsToFloat({});", inst, ret);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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) {
|
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) {
|
void EmitBitCastU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst) {
|
||||||
|
|
|
@ -9,8 +9,14 @@
|
||||||
#include "shader_recompiler/frontend/ir/value.h"
|
#include "shader_recompiler/frontend/ir/value.h"
|
||||||
|
|
||||||
namespace Shader::Backend::GLSL {
|
namespace Shader::Backend::GLSL {
|
||||||
|
namespace {
|
||||||
static constexpr std::string_view SWIZZLE{"xyzw"};
|
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,
|
void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
|
||||||
std::string_view e2) {
|
std::string_view e2) {
|
||||||
ctx.AddU32x2("{}=uvec2({},{});", inst, e1, 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]);
|
ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
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,
|
void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
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,
|
void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x4)};
|
||||||
|
CompositeInsert(ctx, ret, composite, object, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCompositeConstructF16x2([[maybe_unused]] EmitContext& ctx,
|
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]);
|
ctx.AddF32("{}={}.{};", inst, composite, SWIZZLE[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
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,
|
void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
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,
|
void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index) {
|
std::string_view object, u32 index) {
|
||||||
ctx.Add("{}.{}={};", composite, SWIZZLE[index], object);
|
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x4)};
|
||||||
|
CompositeInsert(ctx, ret, composite, object, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) {
|
void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst);
|
||||||
void EmitVoid(EmitContext& ctx);
|
void EmitVoid(EmitContext& ctx);
|
||||||
void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
|
void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
|
||||||
void EmitConditionRef(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 EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value);
|
||||||
void EmitBranch(EmitContext& ctx, std::string_view label);
|
void EmitBranch(EmitContext& ctx, std::string_view label);
|
||||||
void EmitBranchConditional(EmitContext& ctx, std::string_view condition,
|
void EmitBranchConditional(EmitContext& ctx, std::string_view condition,
|
||||||
|
@ -165,12 +165,12 @@ void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie
|
||||||
u32 index);
|
u32 index);
|
||||||
void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
u32 index);
|
||||||
void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeInsertU32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeConstructF16x2(EmitContext& ctx, std::string_view e1, std::string_view e2);
|
void EmitCompositeConstructF16x2(EmitContext& ctx, std::string_view e1, std::string_view e2);
|
||||||
void EmitCompositeConstructF16x3(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);
|
std::string_view e3);
|
||||||
|
@ -197,12 +197,12 @@ void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie
|
||||||
u32 index);
|
u32 index);
|
||||||
void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
u32 index);
|
||||||
void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeInsertF32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeInsertF32x4(EmitContext& ctx, std::string_view composite, std::string_view object,
|
void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
|
||||||
u32 index);
|
std::string_view object, u32 index);
|
||||||
void EmitCompositeConstructF64x2(EmitContext& ctx);
|
void EmitCompositeConstructF64x2(EmitContext& ctx);
|
||||||
void EmitCompositeConstructF64x3(EmitContext& ctx);
|
void EmitCompositeConstructF64x3(EmitContext& ctx);
|
||||||
void EmitCompositeConstructF64x4(EmitContext& ctx);
|
void EmitCompositeConstructF64x4(EmitContext& ctx);
|
||||||
|
|
|
@ -25,7 +25,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) {
|
||||||
}
|
}
|
||||||
if (!phi.Definition<Id>().is_valid) {
|
if (!phi.Definition<Id>().is_valid) {
|
||||||
// The phi node wasn't forward defined
|
// 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();
|
// NotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitReference(EmitContext&) {
|
void EmitReference(EmitContext& ctx, const IR::Value& value) {
|
||||||
// NotImplemented();
|
ctx.var_alloc.Consume(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& 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()};
|
const auto phi_type{phi.Arg(0).Type()};
|
||||||
if (!phi.Definition<Id>().is_valid) {
|
if (!phi.Definition<Id>().is_valid) {
|
||||||
// The phi node wasn't forward defined
|
// 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 phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})};
|
||||||
const auto val_reg{ctx.var_alloc.Consume(value)};
|
const auto val_reg{ctx.var_alloc.Consume(value)};
|
||||||
|
|
|
@ -110,7 +110,6 @@ std::string VarAlloc::Define(IR::Inst& inst, GlslVarType type) {
|
||||||
} else {
|
} else {
|
||||||
Id id{};
|
Id id{};
|
||||||
id.type.Assign(type);
|
id.type.Assign(type);
|
||||||
// id.is_null.Assign(1);
|
|
||||||
GetUseTracker(type).uses_temp = true;
|
GetUseTracker(type).uses_temp = true;
|
||||||
inst.SetDefinition<Id>(id);
|
inst.SetDefinition<Id>(id);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +120,20 @@ std::string VarAlloc::Define(IR::Inst& inst, IR::Type type) {
|
||||||
return Define(inst, RegType(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) {
|
std::string VarAlloc::Consume(const IR::Value& value) {
|
||||||
return value.IsImmediate() ? MakeImm(value) : ConsumeInst(*value.InstRecursive());
|
return value.IsImmediate() ? MakeImm(value) : ConsumeInst(*value.InstRecursive());
|
||||||
}
|
}
|
||||||
|
@ -223,6 +236,8 @@ VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GlslVarType::U1:
|
case GlslVarType::U1:
|
||||||
return var_bool;
|
return var_bool;
|
||||||
|
case GlslVarType::F16x2:
|
||||||
|
return var_f16x2;
|
||||||
case GlslVarType::U32:
|
case GlslVarType::U32:
|
||||||
return var_u32;
|
return var_u32;
|
||||||
case GlslVarType::S32:
|
case GlslVarType::S32:
|
||||||
|
|
|
@ -62,9 +62,15 @@ public:
|
||||||
bool uses_temp{};
|
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, GlslVarType type);
|
||||||
std::string Define(IR::Inst& inst, IR::Type 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 Consume(const IR::Value& value);
|
||||||
std::string ConsumeInst(IR::Inst& inst);
|
std::string ConsumeInst(IR::Inst& inst);
|
||||||
|
|
||||||
|
|
Reference in New Issue