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