From dff35d290dcf2c2c6e701a17a2bc29e706696e6f Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Mon, 1 Mar 2021 03:52:01 +0100 Subject: [PATCH] early-access version 1491 --- README.md | 2 +- .../renderer_opengl/gl_shader_decompiler.cpp | 84 +++++++++++++++++-- src/video_core/shader/decode/texture.cpp | 4 +- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e37f1c83a..b6db83790 100755 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index fa6b10ac3..fd49014b9 100755 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -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(&*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(&*node)) { @@ -1624,7 +1656,9 @@ private: Type::Uint}; } else if (const auto smem = std::get_if(&*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(&*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 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(device.GetMaxVaryings(), Maxwell::NumVaryings); } + void SetHelperEnabled(HelperFunction hf, bool enabled) { + helper_functions_enabled[static_cast(hf)] = enabled; + } + + bool IsHelperEnabled(HelperFunction hf) const { + return helper_functions_enabled[static_cast(hf)]; + } + const Device& device; const ShaderIR& ir; const Registry& registry; @@ -2792,6 +2862,8 @@ private: ShaderWriter code; std::optional max_input_vertices; + + std::array(HelperFunction::Total)> helper_functions_enabled{}; }; std::string GetFlowVariable(u32 index) { diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index c69681e8d..43a166b6f 100755 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -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;