diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 3fc79abec..b2c5b752e 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -1029,7 +1029,7 @@ s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marke if (cmdbuf && marker) { const auto len = std::strlen(marker); - const u32 packet_size = ((len + 8) >> 2) + ((len + 0xc) >> 3); + const u32 packet_size = ((len + 8) >> 2) + ((len + 0xc) >> 3) * 2; if (packet_size + 2 == size) { auto* nop = reinterpret_cast(cmdbuf); nop->header = diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 3d0857c0a..cb6d16c34 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -396,6 +396,7 @@ void Translate(IR::Block* block, u32 block_base, std::span inst_l case Opcode::IMAGE_SAMPLE_L: case Opcode::IMAGE_SAMPLE_C_O: case Opcode::IMAGE_SAMPLE_B: + case Opcode::IMAGE_SAMPLE_C_LZ_O: translator.IMAGE_SAMPLE(inst); break; case Opcode::IMAGE_ATOMIC_ADD: diff --git a/src/shader_recompiler/ir/breadth_first_search.h b/src/shader_recompiler/ir/breadth_first_search.h new file mode 100644 index 000000000..21a34a903 --- /dev/null +++ b/src/shader_recompiler/ir/breadth_first_search.h @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include "shader_recompiler/ir/value.h" + +namespace Shader::IR { + +template +auto BreadthFirstSearch(const Value& value, Pred&& pred) + -> std::invoke_result_t { + if (value.IsImmediate()) { + // Nothing to do with immediates + return std::nullopt; + } + // Breadth-first search visiting the right most arguments first + boost::container::small_vector visited; + std::queue queue; + queue.push(value.InstRecursive()); + + while (!queue.empty()) { + // Pop one instruction from the queue + const Inst* const inst{queue.front()}; + queue.pop(); + if (const std::optional result = pred(inst)) { + // This is the instruction we were looking for + return result; + } + // Visit the right most arguments first + for (size_t arg = inst->NumArgs(); arg--;) { + const Value arg_value{inst->Arg(arg)}; + if (arg_value.IsImmediate()) { + continue; + } + // Queue instruction if it hasn't been visited + const Inst* const arg_inst{arg_value.InstRecursive()}; + if (std::ranges::find(visited, arg_inst) == visited.end()) { + visited.push_back(arg_inst); + queue.push(arg_inst); + } + } + } + // SSA tree has been traversed and the result hasn't been found + return std::nullopt; +} + +} // namespace Shader::IR diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index 4382bff31..b7d6a7221 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -4,8 +4,8 @@ #include #include #include - #include "shader_recompiler/ir/basic_block.h" +#include "shader_recompiler/ir/breadth_first_search.h" #include "shader_recompiler/ir/ir_emitter.h" #include "shader_recompiler/ir/program.h" #include "shader_recompiler/runtime_info.h" @@ -244,22 +244,19 @@ SharpLocation TrackSharp(const IR::Inst* inst) { const IR::Inst* spgpr_base = inst->Arg(0).InstRecursive(); // Retrieve SGPR pair that holds sbase - const IR::Inst* sbase0 = spgpr_base->Arg(0).InstRecursive(); - const IR::Inst* sbase1 = spgpr_base->Arg(1).InstRecursive(); - while (sbase0->GetOpcode() == IR::Opcode::Phi) { - sbase0 = sbase0->Arg(0).TryInstRecursive(); - } - while (sbase1->GetOpcode() == IR::Opcode::Phi) { - sbase1 = sbase1->Arg(0).TryInstRecursive(); - } - ASSERT_MSG(sbase0->GetOpcode() == IR::Opcode::GetUserData && - sbase1->GetOpcode() == IR::Opcode::GetUserData, - "Nested resource loads not supported"); - const IR::ScalarReg base = sbase0->Arg(0).ScalarReg(); + const auto pred = [](const IR::Inst* inst) -> std::optional { + if (inst->GetOpcode() == IR::Opcode::GetUserData) { + return inst->Arg(0).ScalarReg(); + } + return std::nullopt; + }; + const auto base0 = IR::BreadthFirstSearch(spgpr_base->Arg(0), pred); + const auto base1 = IR::BreadthFirstSearch(spgpr_base->Arg(1), pred); + ASSERT_MSG(base0 && base1, "Nested resource loads not supported"); // Return retrieved location. return SharpLocation{ - .sgpr_base = u32(base), + .sgpr_base = u32(base0.value()), .dword_offset = dword_offset, }; } diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 2509467f0..dca7ff3d2 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -422,6 +422,13 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu num_format == AmdGpu::NumberFormat::Sint) { return vk::Format::eR16G16Sint; } + if (data_format == AmdGpu::DataFormat::Format8_8_8_8 && + num_format == AmdGpu::NumberFormat::Uscaled) { + return vk::Format::eR8G8B8A8Uscaled; + } + if (data_format == AmdGpu::DataFormat::Format16 && num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eR16Unorm; + } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); }