early-access version 1491
This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
			
		||||
yuzu emulator early access
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
This is the source code for early-access 1490.
 | 
			
		||||
This is the source code for early-access 1491.
 | 
			
		||||
 | 
			
		||||
## Legal Notice
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,11 @@ const float fswzadd_modifiers_a[] = float[4](-1.0f,  1.0f, -1.0f,  0.0f );
 | 
			
		||||
const float fswzadd_modifiers_b[] = float[4](-1.0f, -1.0f,  1.0f, -1.0f );
 | 
			
		||||
)";
 | 
			
		||||
 | 
			
		||||
enum class HelperFunction {
 | 
			
		||||
    SignedAtomic = 0,
 | 
			
		||||
    Total,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ShaderWriter final {
 | 
			
		||||
public:
 | 
			
		||||
    void AddExpression(std::string_view text) {
 | 
			
		||||
@@ -434,6 +439,7 @@ public:
 | 
			
		||||
        DeclareInternalFlags();
 | 
			
		||||
        DeclareCustomVariables();
 | 
			
		||||
        DeclarePhysicalAttributeReader();
 | 
			
		||||
        DeclareHelpersForward();
 | 
			
		||||
 | 
			
		||||
        const auto& subfunctions = ir.GetSubFunctions();
 | 
			
		||||
        auto it = subfunctions.rbegin();
 | 
			
		||||
@@ -471,6 +477,9 @@ public:
 | 
			
		||||
 | 
			
		||||
        --code.scope;
 | 
			
		||||
        code.AddLine("}}");
 | 
			
		||||
 | 
			
		||||
        code.AddNewLine();
 | 
			
		||||
        DeclareHelpers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string GetResult() {
 | 
			
		||||
@@ -620,7 +629,7 @@ private:
 | 
			
		||||
                size = limit;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            code.AddLine("shared uint smem[{}];", size / 4);
 | 
			
		||||
            code.AddLine("shared uint {}[{}];", GetSharedMemory(), size / 4);
 | 
			
		||||
            code.AddNewLine();
 | 
			
		||||
        }
 | 
			
		||||
        code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;",
 | 
			
		||||
@@ -1004,6 +1013,27 @@ private:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void DeclareHelpersForward() {
 | 
			
		||||
        code.AddLine("int Helpers_AtomicShared(uint offset, int value, bool is_min);");
 | 
			
		||||
        code.AddNewLine();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void DeclareHelpers() {
 | 
			
		||||
        if (IsHelperEnabled(HelperFunction::SignedAtomic)) {
 | 
			
		||||
            code.AddLine(
 | 
			
		||||
                R"(int Helpers_AtomicShared(uint offset, int value, bool is_min) {{
 | 
			
		||||
    uint oldValue, newValue;
 | 
			
		||||
    do {{
 | 
			
		||||
        oldValue = {}[offset];
 | 
			
		||||
        newValue = is_min ? uint(min(int(oldValue), value)) : uint(max(int(oldValue), value));
 | 
			
		||||
    }} while (atomicCompSwap({}[offset], newValue, oldValue) != oldValue);
 | 
			
		||||
    return int(oldValue);
 | 
			
		||||
}})",
 | 
			
		||||
                GetSharedMemory(), GetSharedMemory());
 | 
			
		||||
            code.AddNewLine();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void VisitBlock(const NodeBlock& bb) {
 | 
			
		||||
        for (const auto& node : bb) {
 | 
			
		||||
            Visit(node).CheckVoid();
 | 
			
		||||
@@ -1130,7 +1160,9 @@ private:
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const auto smem = std::get_if<SmemNode>(&*node)) {
 | 
			
		||||
            return {fmt::format("smem[{} >> 2]", Visit(smem->GetAddress()).AsUint()), Type::Uint};
 | 
			
		||||
            return {
 | 
			
		||||
                fmt::format("{}[{} >> 2]", GetSharedMemory(), Visit(smem->GetAddress()).AsUint()),
 | 
			
		||||
                Type::Uint};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (const auto internal_flag = std::get_if<InternalFlagNode>(&*node)) {
 | 
			
		||||
@@ -1624,7 +1656,9 @@ private:
 | 
			
		||||
                Type::Uint};
 | 
			
		||||
        } else if (const auto smem = std::get_if<SmemNode>(&*dest)) {
 | 
			
		||||
            ASSERT(stage == ShaderType::Compute);
 | 
			
		||||
            target = {fmt::format("smem[{} >> 2]", Visit(smem->GetAddress()).AsUint()), Type::Uint};
 | 
			
		||||
            target = {
 | 
			
		||||
                fmt::format("{}[{} >> 2]", GetSharedMemory(), Visit(smem->GetAddress()).AsUint()),
 | 
			
		||||
                Type::Uint};
 | 
			
		||||
        } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) {
 | 
			
		||||
            const std::string real = Visit(gmem->GetRealAddress()).AsUint();
 | 
			
		||||
            const std::string base = Visit(gmem->GetBaseAddress()).AsUint();
 | 
			
		||||
@@ -2141,7 +2175,14 @@ private:
 | 
			
		||||
        UNIMPLEMENTED_IF(meta->sampler.is_array);
 | 
			
		||||
        const std::size_t count = operation.GetOperandsCount();
 | 
			
		||||
 | 
			
		||||
        std::string expr = "texelFetch(";
 | 
			
		||||
        std::string expr = "texelFetch";
 | 
			
		||||
 | 
			
		||||
        if (!meta->aoffi.empty()) {
 | 
			
		||||
            expr += "Offset";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        expr += '(';
 | 
			
		||||
 | 
			
		||||
        expr += GetSampler(meta->sampler);
 | 
			
		||||
        expr += ", ";
 | 
			
		||||
 | 
			
		||||
@@ -2163,6 +2204,20 @@ private:
 | 
			
		||||
            expr += ", ";
 | 
			
		||||
            expr += Visit(meta->lod).AsInt();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!meta->aoffi.empty()) {
 | 
			
		||||
            expr += ", ";
 | 
			
		||||
            expr += constructors.at(meta->aoffi.size() - 1);
 | 
			
		||||
            expr += '(';
 | 
			
		||||
            for (size_t i = 0; i < meta->aoffi.size(); ++i) {
 | 
			
		||||
                if (i > 0) {
 | 
			
		||||
                    expr += ", ";
 | 
			
		||||
                }
 | 
			
		||||
                expr += Visit(meta->aoffi[i]).AsInt();
 | 
			
		||||
            }
 | 
			
		||||
            expr += ')';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        expr += ')';
 | 
			
		||||
        expr += GetSwizzle(meta->element);
 | 
			
		||||
 | 
			
		||||
@@ -2209,8 +2264,11 @@ private:
 | 
			
		||||
    template <const std::string_view& opname, Type type>
 | 
			
		||||
    Expression Atomic(Operation operation) {
 | 
			
		||||
        if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) {
 | 
			
		||||
            UNIMPLEMENTED_MSG("Unimplemented Min & Max for atomic operations");
 | 
			
		||||
            return {};
 | 
			
		||||
            // Use a helper as a workaround due to memory being uint
 | 
			
		||||
            SetHelperEnabled(HelperFunction::SignedAtomic, true);
 | 
			
		||||
            return {fmt::format("Helpers_AtomicShared({}, {}, {})", Visit(operation[0]).AsInt(),
 | 
			
		||||
                                Visit(operation[1]).AsInt(), opname == Func::Min),
 | 
			
		||||
                    Type::Int};
 | 
			
		||||
        }
 | 
			
		||||
        return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(),
 | 
			
		||||
                            Visit(operation[1]).AsUint()),
 | 
			
		||||
@@ -2737,6 +2795,10 @@ private:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constexpr std::string_view GetSharedMemory() const {
 | 
			
		||||
        return "shared_mem";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string GetInternalFlag(InternalFlag flag) const {
 | 
			
		||||
        constexpr std::array InternalFlagNames = {"zero_flag", "sign_flag", "carry_flag",
 | 
			
		||||
                                                  "overflow_flag"};
 | 
			
		||||
@@ -2778,6 +2840,14 @@ private:
 | 
			
		||||
        return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SetHelperEnabled(HelperFunction hf, bool enabled) {
 | 
			
		||||
        helper_functions_enabled[static_cast<size_t>(hf)] = enabled;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool IsHelperEnabled(HelperFunction hf) const {
 | 
			
		||||
        return helper_functions_enabled[static_cast<size_t>(hf)];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Device& device;
 | 
			
		||||
    const ShaderIR& ir;
 | 
			
		||||
    const Registry& registry;
 | 
			
		||||
@@ -2792,6 +2862,8 @@ private:
 | 
			
		||||
    ShaderWriter code;
 | 
			
		||||
 | 
			
		||||
    std::optional<u32> max_input_vertices;
 | 
			
		||||
 | 
			
		||||
    std::array<bool, static_cast<size_t>(HelperFunction::Total)> helper_functions_enabled{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::string GetFlowVariable(u32 index) {
 | 
			
		||||
 
 | 
			
		||||
@@ -339,8 +339,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
 | 
			
		||||
        const TextureType texture_type{instr.tlds.GetTextureType()};
 | 
			
		||||
        const bool is_array{instr.tlds.IsArrayTexture()};
 | 
			
		||||
 | 
			
		||||
        UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI),
 | 
			
		||||
                             "AOFFI is not implemented");
 | 
			
		||||
        UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented");
 | 
			
		||||
 | 
			
		||||
        const Node4 components = GetTldsCode(instr, texture_type, is_array);
 | 
			
		||||
@@ -822,7 +820,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
 | 
			
		||||
    for (std::size_t i = 0; i < type_coord_count; ++i) {
 | 
			
		||||
        const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
 | 
			
		||||
        coords.push_back(
 | 
			
		||||
            GetRegister(last && !aoffi_enabled ? last_coord_register : coord_register + i));
 | 
			
		||||
            GetRegister(last && !aoffi_enabled ? last_coord_register : (coord_register + i)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Node array = is_array ? GetRegister(array_register) : nullptr;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user