glsl: Rework var alloc to not assign unused results
This commit is contained in:
parent
1269a0cf8b
commit
9f3ffb996b
9 changed files with 91 additions and 49 deletions
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue