mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	glsl: Rework var alloc to not assign unused results
This commit is contained in:
		@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user