diff options
Diffstat (limited to 'src/video_core')
40 files changed, 242 insertions, 161 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 6a6325e38..14de7bc89 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -258,10 +258,6 @@ if (MSVC) target_compile_options(video_core PRIVATE /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data - /we4456 # Declaration of 'identifier' hides previous local declaration - /we4457 # Declaration of 'identifier' hides function parameter - /we4458 # Declaration of 'identifier' hides class member - /we4459 # Declaration of 'identifier' hides global declaration ) else() target_compile_options(video_core PRIVATE @@ -269,7 +265,6 @@ else() -Wno-error=sign-conversion -Werror=pessimizing-move -Werror=redundant-move - -Werror=shadow -Werror=type-limits $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> @@ -277,3 +272,7 @@ else() $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> ) endif() + +if (ARCHITECTURE_x86_64) + target_link_libraries(video_core PRIVATE dynarmic) +endif() diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 83b2e0fc4..a5eb97b7f 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp @@ -224,7 +224,7 @@ void Codec::Decode() { vp9_hidden_frame = vp9_decoder->WasFrameHidden(); return vp9_decoder->GetFrameBytes(); default: - UNREACHABLE(); + ASSERT(false); return std::vector<u8>{}; } }(); diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index a95618913..c01431441 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp @@ -153,7 +153,7 @@ constexpr Vp9EntropyProbs default_probs{ .high_precision{128, 128}, }; -constexpr std::array<s32, 256> norm_lut{ +constexpr std::array<u8, 256> norm_lut{ 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -164,7 +164,7 @@ constexpr std::array<s32, 256> norm_lut{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -constexpr std::array<s32, 254> map_lut{ +constexpr std::array<u8, 254> map_lut{ 20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 2, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 3, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, @@ -232,7 +232,7 @@ constexpr std::array<s32, 254> map_lut{ std::max(0, RecenterNonNeg(0xff - 1 - new_prob, 0xff - 1 - old_prob) - 1)); } - return map_lut[index]; + return static_cast<s32>(map_lut[index]); } } // Anonymous namespace @@ -819,7 +819,7 @@ void VpxRangeEncoder::Write(bool bit, s32 probability) { local_range = range - split; } - s32 shift = norm_lut[local_range]; + s32 shift = static_cast<s32>(norm_lut[local_range]); local_range <<= shift; count += shift; diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index bef321b6e..7c17df353 100644 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp @@ -228,7 +228,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) { break; } default: - UNREACHABLE(); + ASSERT(false); break; } gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(), diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index d4652b167..3a4646289 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -173,6 +173,8 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume case MAXWELL3D_REG_INDEX(shadow_ram_control): shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument); return; + case MAXWELL3D_REG_INDEX(macros.upload_address): + return macro_engine->ClearCode(regs.macros.upload_address); case MAXWELL3D_REG_INDEX(macros.data): return macro_engine->AddCode(regs.macros.upload_address, argument); case MAXWELL3D_REG_INDEX(macros.bind): @@ -593,8 +595,8 @@ void Maxwell3D::DrawArrays() { std::optional<u64> Maxwell3D::GetQueryResult() { switch (regs.query.query_get.select) { - case Regs::QuerySelect::Zero: - return 0; + case Regs::QuerySelect::Payload: + return regs.query.query_sequence; case Regs::QuerySelect::SamplesPassed: // Deferred. rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed, diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index c0c2c7d96..5f9eb208c 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -93,7 +93,7 @@ public: }; enum class QuerySelect : u32 { - Zero = 0, + Payload = 0, TimeElapsed = 2, TransformFeedbackPrimitivesGenerated = 11, PrimitivesGenerated = 18, @@ -202,7 +202,7 @@ public: case Size::Size_11_11_10: return 3; default: - UNREACHABLE(); + ASSERT(false); return 1; } } @@ -238,7 +238,7 @@ public: case Size::Size_11_11_10: return 4; default: - UNREACHABLE(); + ASSERT(false); return 1; } } @@ -274,7 +274,7 @@ public: case Size::Size_11_11_10: return "11_11_10"; default: - UNREACHABLE(); + ASSERT(false); return {}; } } @@ -296,7 +296,7 @@ public: case Type::Float: return "FLOAT"; } - UNREACHABLE(); + ASSERT(false); return {}; } @@ -336,7 +336,7 @@ public: case 3: return {x3, y3}; default: - UNREACHABLE(); + ASSERT(false); return {0, 0}; } } @@ -1193,7 +1193,7 @@ public: case IndexFormat::UnsignedInt: return 4; } - UNREACHABLE(); + ASSERT(false); return 1; } diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 76e8bc656..0efe58282 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -62,7 +62,7 @@ void MaxwellDMA::Launch() { if (!is_src_pitch && !is_dst_pitch) { // If both the source and the destination are in block layout, assert. - UNREACHABLE_MSG("Tiled->Tiled DMA transfers are not yet implemented"); + UNIMPLEMENTED_MSG("Tiled->Tiled DMA transfers are not yet implemented"); return; } @@ -134,7 +134,8 @@ void MaxwellDMA::CopyBlockLinearToPitch() { // Deswizzle the input and copy it over. UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0); - const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in; + const u32 bytes_per_pixel = + regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1; const Parameters& src_params = regs.src_params; const u32 width = src_params.width; const u32 height = src_params.height; @@ -166,7 +167,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() { UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0); const auto& dst_params = regs.dst_params; - const u32 bytes_per_pixel = regs.pitch_in / regs.line_length_in; + const u32 bytes_per_pixel = + regs.launch_dma.remap_enable ? regs.pitch_in / regs.line_length_in : 1; const u32 width = dst_params.width; const u32 height = dst_params.height; const u32 depth = dst_params.depth; @@ -210,7 +212,8 @@ void MaxwellDMA::CopyPitchToBlockLinear() { } void MaxwellDMA::FastCopyBlockLinearToPitch() { - const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in; + const u32 bytes_per_pixel = + regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1; const size_t src_size = GOB_SIZE; const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count; u32 pos_x = regs.src_params.origin.x; @@ -257,7 +260,7 @@ void MaxwellDMA::ReleaseSemaphore() { memory_manager.Write<u64>(address + 8, system.GPU().GetTicks()); break; default: - UNREACHABLE_MSG("Unknown semaphore type: {}", static_cast<u32>(type.Value())); + ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value())); } } diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index b79a73132..b0ce9f000 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -31,7 +31,8 @@ static void RunThread(std::stop_token stop_token, Core::System& system, VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer(); while (!stop_token.stop_requested()) { - CommandDataContainer next = state.queue.PopWait(stop_token); + CommandDataContainer next; + state.queue.Pop(next, stop_token); if (stop_token.stop_requested()) { break; } @@ -49,7 +50,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system, } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); } else { - UNREACHABLE(); + ASSERT(false); } state.signaled_fence.store(next.fence); if (next.block) { diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 71cd35756..ad9fd5eff 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -10,7 +10,7 @@ #include <thread> #include <variant> -#include "common/threadsafe_queue.h" +#include "common/bounded_threadsafe_queue.h" #include "video_core/framebuffer_config.h" namespace Tegra { @@ -96,9 +96,9 @@ struct CommandDataContainer { /// Struct used to synchronize the GPU thread struct SynchState final { - using CommandQueue = Common::SPSCQueue<CommandDataContainer, true>; + using CommandQueue = Common::MPSCQueue<CommandDataContainer>; std::mutex write_lock; - CommandQueue queue; + CommandQueue queue{512}; // size must be 2^n u64 last_fence{}; std::atomic<u64> signaled_fence{}; std::condition_variable_any cv; diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp index a033d03be..43f8b5904 100644 --- a/src/video_core/macro/macro.cpp +++ b/src/video_core/macro/macro.cpp @@ -2,11 +2,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <cstring> +#include <fstream> #include <optional> +#include <span> #include <boost/container_hash/hash.hpp> #include "common/assert.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/settings.h" #include "video_core/macro/macro.h" #include "video_core/macro/macro_hle.h" @@ -15,6 +19,23 @@ namespace Tegra { +static void Dump(u64 hash, std::span<const u32> code) { + const auto base_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)}; + const auto macro_dir{base_dir / "macros"}; + if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) { + LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories"); + return; + } + const auto name{macro_dir / fmt::format("{:016x}.macro", hash)}; + std::fstream macro_file(name, std::ios::out | std::ios::binary); + if (!macro_file) { + LOG_ERROR(Common_Filesystem, "Unable to open or create file at {}", + Common::FS::PathToUTF8String(name)); + return; + } + macro_file.write(reinterpret_cast<const char*>(code.data()), code.size_bytes()); +} + MacroEngine::MacroEngine(Engines::Maxwell3D& maxwell3d) : hle_macros{std::make_unique<Tegra::HLEMacro>(maxwell3d)} {} @@ -24,6 +45,11 @@ void MacroEngine::AddCode(u32 method, u32 data) { uploaded_macro_code[method].push_back(data); } +void MacroEngine::ClearCode(u32 method) { + macro_cache.erase(method); + uploaded_macro_code.erase(method); +} + void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { auto compiled_macro = macro_cache.find(method); if (compiled_macro != macro_cache.end()) { @@ -45,7 +71,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { } } if (!mid_method.has_value()) { - UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method); + ASSERT_MSG(false, "Macro 0x{0:x} was not uploaded", method); return; } } @@ -54,6 +80,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { if (!mid_method.has_value()) { cache_info.lle_program = Compile(macro_code->second); cache_info.hash = boost::hash_value(macro_code->second); + if (Settings::values.dump_macros) { + Dump(cache_info.hash, macro_code->second); + } } else { const auto& macro_cached = uploaded_macro_code[mid_method.value()]; const auto rebased_method = method - mid_method.value(); @@ -63,6 +92,9 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) { code.size() * sizeof(u32)); cache_info.hash = boost::hash_value(code); cache_info.lle_program = Compile(code); + if (Settings::values.dump_macros) { + Dump(cache_info.hash, code); + } } if (auto hle_program = hle_macros->GetHLEProgram(cache_info.hash)) { diff --git a/src/video_core/macro/macro.h b/src/video_core/macro/macro.h index 7e12c16dc..07d97ba39 100644 --- a/src/video_core/macro/macro.h +++ b/src/video_core/macro/macro.h @@ -117,6 +117,9 @@ public: // Store the uploaded macro code to compile them when they're called. void AddCode(u32 method, u32 data); + // Clear the code associated with a method. + void ClearCode(u32 method); + // Compiles the macro if its not in the cache, and executes the compiled macro void Execute(u32 method, const std::vector<u32>& parameters); diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp index 87d2e8721..f670b1bca 100644 --- a/src/video_core/macro/macro_interpreter.cpp +++ b/src/video_core/macro/macro_interpreter.cpp @@ -308,7 +308,6 @@ bool MacroInterpreterImpl::EvaluateBranchCondition(Macro::BranchCondition cond, return value != 0; } UNREACHABLE(); - return true; } Macro::Opcode MacroInterpreterImpl::GetOpcode() const { diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index dc2b490d4..aca25d902 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp @@ -23,7 +23,8 @@ MICROPROFILE_DEFINE(MacroJitExecute, "GPU", "Execute macro JIT", MP_RGB(255, 255 namespace Tegra { namespace { constexpr Xbyak::Reg64 STATE = Xbyak::util::rbx; -constexpr Xbyak::Reg32 RESULT = Xbyak::util::ebp; +constexpr Xbyak::Reg32 RESULT = Xbyak::util::r10d; +constexpr Xbyak::Reg64 MAX_PARAMETER = Xbyak::util::r11; constexpr Xbyak::Reg64 PARAMETERS = Xbyak::util::r12; constexpr Xbyak::Reg32 METHOD_ADDRESS = Xbyak::util::r14d; constexpr Xbyak::Reg64 BRANCH_HOLDER = Xbyak::util::r15; @@ -31,6 +32,7 @@ constexpr Xbyak::Reg64 BRANCH_HOLDER = Xbyak::util::r15; constexpr std::bitset<32> PERSISTENT_REGISTERS = Common::X64::BuildRegSet({ STATE, RESULT, + MAX_PARAMETER, PARAMETERS, METHOD_ADDRESS, BRANCH_HOLDER, @@ -80,7 +82,7 @@ private: u32 carry_flag{}; }; static_assert(offsetof(JITState, maxwell3d) == 0, "Maxwell3D is not at 0x0"); - using ProgramType = void (*)(JITState*, const u32*); + using ProgramType = void (*)(JITState*, const u32*, const u32*); struct OptimizerState { bool can_skip_carry{}; @@ -112,7 +114,7 @@ void MacroJITx64Impl::Execute(const std::vector<u32>& parameters, u32 method) { JITState state{}; state.maxwell3d = &maxwell3d; state.registers = {}; - program(&state, parameters.data()); + program(&state, parameters.data(), parameters.data() + parameters.size()); } void MacroJITx64Impl::Compile_ALU(Macro::Opcode opcode) { @@ -409,7 +411,7 @@ void MacroJITx64Impl::Compile_Branch(Macro::Opcode opcode) { Xbyak::Label end; auto value = Compile_GetRegister(opcode.src_a, eax); - test(value, value); + cmp(value, 0); // test(value, value); if (optimizer.has_delayed_pc) { switch (opcode.branch_condition) { case Macro::BranchCondition::Zero: @@ -488,6 +490,7 @@ void MacroJITx64Impl::Compile() { // JIT state mov(STATE, Common::X64::ABI_PARAM1); mov(PARAMETERS, Common::X64::ABI_PARAM2); + mov(MAX_PARAMETER, Common::X64::ABI_PARAM3); xor_(RESULT, RESULT); xor_(METHOD_ADDRESS, METHOD_ADDRESS); xor_(BRANCH_HOLDER, BRANCH_HOLDER); @@ -598,7 +601,22 @@ bool MacroJITx64Impl::Compile_NextInstruction() { return true; } +static void WarnInvalidParameter(uintptr_t parameter, uintptr_t max_parameter) { + LOG_CRITICAL(HW_GPU, + "Macro JIT: invalid parameter access 0x{:x} (0x{:x} is the last parameter)", + parameter, max_parameter - sizeof(u32)); +} + Xbyak::Reg32 MacroJITx64Impl::Compile_FetchParameter() { + Xbyak::Label parameter_ok{}; + cmp(PARAMETERS, MAX_PARAMETER); + jb(parameter_ok, T_NEAR); + Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); + mov(Common::X64::ABI_PARAM1, PARAMETERS); + mov(Common::X64::ABI_PARAM2, MAX_PARAMETER); + Common::X64::CallFarFunction(*this, &WarnInvalidParameter); + Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0); + L(parameter_ok); mov(eax, dword[PARAMETERS]); add(PARAMETERS, sizeof(u32)); return eax; diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index c8d99fdb5..d373be0ba 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -67,7 +67,7 @@ void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) { ASSERT(it->first == gpu_addr); map_ranges.erase(it); } else { - UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr); + ASSERT_MSG(false, "Unmapping non-existent GPU address=0x{:x}", gpu_addr); } const auto submapped_ranges = GetSubmappedRange(gpu_addr, size); @@ -206,7 +206,7 @@ T MemoryManager::Read(GPUVAddr addr) const { return value; } - UNREACHABLE(); + ASSERT(false); return {}; } @@ -219,7 +219,7 @@ void MemoryManager::Write(GPUVAddr addr, T data) { return; } - UNREACHABLE(); + ASSERT(false); } template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 35f42f2f8..67eae369d 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -48,7 +48,7 @@ GLenum Stage(size_t stage_index) { case 4: return GL_FRAGMENT_SHADER; } - UNREACHABLE_MSG("{}", stage_index); + ASSERT_MSG(false, "{}", stage_index); return GL_NONE; } @@ -65,7 +65,7 @@ GLenum AssemblyStage(size_t stage_index) { case 4: return GL_FRAGMENT_PROGRAM_NV; } - UNREACHABLE_MSG("{}", stage_index); + ASSERT_MSG(false, "{}", stage_index); return GL_NONE; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8ef79753f..159b71161 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -563,12 +563,11 @@ void RasterizerOpenGL::SyncViewport() { flags[Dirty::FrontFace] = false; GLenum mode = MaxwellToGL::FrontFace(regs.front_face); - bool flip_faces = false; - if (regs.screen_y_control.triangle_rast_flip != 0 && - regs.viewport_transform[0].scale_y < 0.0f) { + bool flip_faces = true; + if (regs.screen_y_control.triangle_rast_flip != 0) { flip_faces = !flip_faces; } - if (regs.viewport_transform[0].scale_z < 0.0f) { + if (regs.viewport_transform[0].scale_y < 0.0f) { flip_faces = !flip_faces; } if (flip_faces) { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index cd48fef26..07d4b7cf0 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -85,7 +85,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, case Maxwell::TessellationPrimitive::Quads: return Shader::TessPrimitive::Quads; } - UNREACHABLE(); + ASSERT(false); return Shader::TessPrimitive::Triangles; }(); info.tess_spacing = [&] { @@ -97,7 +97,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, case Maxwell::TessellationSpacing::FractionalEven: return Shader::TessSpacing::FractionalEven; } - UNREACHABLE(); + ASSERT(false); return Shader::TessSpacing::Equal; }(); break; diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 29ff736fb..8c0fffc67 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -83,7 +83,7 @@ GLenum ImageTarget(const VideoCommon::ImageInfo& info) { case ImageType::Buffer: return GL_TEXTURE_BUFFER; } - UNREACHABLE_MSG("Invalid image type={}", info.type); + ASSERT_MSG(false, "Invalid image type={}", info.type); return GL_NONE; } @@ -107,7 +107,7 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) { case Shader::TextureType::Buffer: return GL_TEXTURE_BUFFER; } - UNREACHABLE_MSG("Invalid image view type={}", type); + ASSERT_MSG(false, "Invalid image view type={}", type); return GL_NONE; } @@ -119,7 +119,7 @@ GLenum TextureMode(PixelFormat format, bool is_first) { case PixelFormat::S8_UINT_D24_UNORM: return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT; default: - UNREACHABLE(); + ASSERT(false); return GL_DEPTH_COMPONENT; } } @@ -140,7 +140,7 @@ GLint Swizzle(SwizzleSource source) { case SwizzleSource::OneFloat: return GL_ONE; } - UNREACHABLE_MSG("Invalid swizzle source={}", source); + ASSERT_MSG(false, "Invalid swizzle source={}", source); return GL_NONE; } @@ -197,7 +197,7 @@ GLint ConvertA5B5G5R1_UNORM(SwizzleSource source) { case SwizzleSource::OneFloat: return GL_ONE; } - UNREACHABLE_MSG("Invalid swizzle source={}", source); + ASSERT_MSG(false, "Invalid swizzle source={}", source); return GL_NONE; } @@ -381,10 +381,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth); break; case GL_TEXTURE_BUFFER: - UNREACHABLE(); + ASSERT(false); break; default: - UNREACHABLE_MSG("Invalid target=0x{:x}", target); + ASSERT_MSG(false, "Invalid target=0x{:x}", target); break; } return texture; @@ -420,7 +420,7 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form case Shader::ImageFormat::R32G32B32A32_UINT: return GL_RGBA32UI; } - UNREACHABLE_MSG("Invalid image format={}", format); + ASSERT_MSG(false, "Invalid image format={}", format); return GL_R32UI; } @@ -579,7 +579,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src, } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) { format_conversion_pass.ConvertImage(dst, src, copies); } else { - UNREACHABLE(); + ASSERT(false); } } @@ -620,7 +620,7 @@ void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferM case ImageType::Linear: return util_shaders.PitchUpload(image, map, swizzles); default: - UNREACHABLE(); + ASSERT(false); break; } } @@ -639,7 +639,7 @@ FormatProperties TextureCacheRuntime::FormatInfo(ImageType type, GLenum internal case ImageType::e3D: return format_properties[2].at(internal_format); default: - UNREACHABLE(); + ASSERT(false); return FormatProperties{}; } } @@ -888,7 +888,7 @@ void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t b } break; default: - UNREACHABLE(); + ASSERT(false); } } @@ -924,7 +924,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b depth = copy.image_extent.depth; break; default: - UNREACHABLE(); + ASSERT(false); } // Compressed formats don't have a pixel format or type const bool is_compressed = gl_format == GL_NONE; @@ -950,7 +950,7 @@ void Image::Scale(bool up_scale) { case SurfaceType::DepthStencil: return GL_DEPTH_STENCIL_ATTACHMENT; default: - UNREACHABLE(); + ASSERT(false); return GL_COLOR_ATTACHMENT0; } }(); @@ -965,7 +965,7 @@ void Image::Scale(bool up_scale) { case SurfaceType::DepthStencil: return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; default: - UNREACHABLE(); + ASSERT(false); return GL_COLOR_BUFFER_BIT; } }(); @@ -980,7 +980,7 @@ void Image::Scale(bool up_scale) { case SurfaceType::DepthStencil: return 3; default: - UNREACHABLE(); + ASSERT(false); return 0; } }(); @@ -1045,7 +1045,7 @@ bool Image::ScaleUp(bool ignore) { return false; } if (info.type == ImageType::Linear) { - UNREACHABLE(); + ASSERT(false); return false; } flags |= ImageFlagBits::Rescaled; @@ -1139,7 +1139,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI UNIMPLEMENTED(); break; case ImageViewType::Buffer: - UNREACHABLE(); + ASSERT(false); break; } switch (info.type) { @@ -1319,7 +1319,7 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; break; default: - UNREACHABLE(); + ASSERT(false); buffer_bits |= GL_DEPTH_BUFFER_BIT; break; } diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index c2a6da5a7..644b60d73 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -206,7 +206,7 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) { case Maxwell::IndexFormat::UnsignedInt: return GL_UNSIGNED_INT; } - UNREACHABLE_MSG("Invalid index_format={}", index_format); + ASSERT_MSG(false, "Invalid index_format={}", index_format); return {}; } @@ -243,7 +243,7 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) { case Maxwell::PrimitiveTopology::Patches: return GL_PATCHES; } - UNREACHABLE_MSG("Invalid topology={}", topology); + ASSERT_MSG(false, "Invalid topology={}", topology); return GL_POINTS; } @@ -271,8 +271,8 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode, } break; } - UNREACHABLE_MSG("Invalid texture filter mode={} and mipmap filter mode={}", filter_mode, - mipmap_filter_mode); + ASSERT_MSG(false, "Invalid texture filter mode={} and mipmap filter mode={}", filter_mode, + mipmap_filter_mode); return GL_NEAREST; } @@ -550,7 +550,7 @@ inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) { case Maxwell::PolygonMode::Fill: return GL_FILL; } - UNREACHABLE_MSG("Invalid polygon mode={}", polygon_mode); + ASSERT_MSG(false, "Invalid polygon mode={}", polygon_mode); return GL_FILL; } @@ -563,7 +563,7 @@ inline GLenum ReductionFilter(Tegra::Texture::SamplerReduction filter) { case Tegra::Texture::SamplerReduction::Max: return GL_MAX; } - UNREACHABLE_MSG("Invalid reduction filter={}", static_cast<int>(filter)); + ASSERT_MSG(false, "Invalid reduction filter={}", static_cast<int>(filter)); return GL_WEIGHTED_AVERAGE_ARB; } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3a3c213bb..9a9243544 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -79,7 +79,7 @@ const char* GetSource(GLenum source) { case GL_DEBUG_SOURCE_OTHER: return "OTHER"; default: - UNREACHABLE(); + ASSERT(false); return "Unknown source"; } } @@ -101,7 +101,7 @@ const char* GetType(GLenum type) { case GL_DEBUG_TYPE_MARKER: return "MARKER"; default: - UNREACHABLE(); + ASSERT(false); return "Unknown type"; } } diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp index 837825737..404def62e 100644 --- a/src/video_core/renderer_opengl/util_shaders.cpp +++ b/src/video_core/renderer_opengl/util_shaders.cpp @@ -282,7 +282,7 @@ GLenum StoreFormat(u32 bytes_per_block) { case 16: return GL_RGBA32UI; } - UNREACHABLE(); + ASSERT(false); return GL_R8UI; } diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index ea360f339..193cbe15e 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -25,7 +25,7 @@ VkFilter Filter(Tegra::Texture::TextureFilter filter) { case Tegra::Texture::TextureFilter::Linear: return VK_FILTER_LINEAR; } - UNREACHABLE_MSG("Invalid sampler filter={}", filter); + ASSERT_MSG(false, "Invalid sampler filter={}", filter); return {}; } @@ -42,7 +42,7 @@ VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter case Tegra::Texture::TextureMipmapFilter::Linear: return VK_SAMPLER_MIPMAP_MODE_LINEAR; } - UNREACHABLE_MSG("Invalid sampler mipmap mode={}", mipmap_filter); + ASSERT_MSG(false, "Invalid sampler mipmap mode={}", mipmap_filter); return {}; } @@ -70,7 +70,7 @@ VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wra case Tegra::Texture::TextureFilter::Linear: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; } - UNREACHABLE(); + ASSERT(false); return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; case Tegra::Texture::WrapMode::MirrorOnceClampToEdge: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; @@ -744,7 +744,7 @@ VkViewportCoordinateSwizzleNV ViewportSwizzle(Maxwell::ViewportSwizzle swizzle) case Maxwell::ViewportSwizzle::NegativeW: return VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV; } - UNREACHABLE_MSG("Invalid swizzle={}", swizzle); + ASSERT_MSG(false, "Invalid swizzle={}", swizzle); return {}; } @@ -757,7 +757,7 @@ VkSamplerReductionMode SamplerReduction(Tegra::Texture::SamplerReduction reducti case Tegra::Texture::SamplerReduction::Max: return VK_SAMPLER_REDUCTION_MODE_MAX_EXT; } - UNREACHABLE_MSG("Invalid sampler mode={}", static_cast<int>(reduction)); + ASSERT_MSG(false, "Invalid sampler mode={}", static_cast<int>(reduction)); return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT; } @@ -780,7 +780,7 @@ VkSampleCountFlagBits MsaaMode(Tegra::Texture::MsaaMode msaa_mode) { case Tegra::Texture::MsaaMode::Msaa4x4: return VK_SAMPLE_COUNT_16_BIT; default: - UNREACHABLE_MSG("Invalid msaa_mode={}", static_cast<int>(msaa_mode)); + ASSERT_MSG(false, "Invalid msaa_mode={}", static_cast<int>(msaa_mode)); return VK_SAMPLE_COUNT_1_BIT; } } diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 0aeb37538..450905197 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -46,7 +46,7 @@ size_t BytesPerIndex(VkIndexType index_type) { case VK_INDEX_TYPE_UINT32: return 4; default: - UNREACHABLE_MSG("Invalid index type={}", index_type); + ASSERT_MSG(false, "Invalid index type={}", index_type); return 1; } } @@ -366,7 +366,7 @@ void BufferCacheRuntime::ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle std::memcpy(staging_data, MakeQuadIndices<u32>(quad, first).data(), quad_size); break; default: - UNREACHABLE(); + ASSERT(false); break; } staging_data += quad_size; diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 29481a102..4cba777e6 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -265,7 +265,7 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedInt: return 2; } - UNREACHABLE(); + ASSERT(false); return 2; }(); const u32 input_size = num_vertices << index_shift; @@ -328,31 +328,32 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, const VkImageAspectFlags aspect_mask = image.AspectMask(); const VkImage vk_image = image.Handle(); const bool is_initialized = image.ExchangeInitialization(); - scheduler.Record( - [vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf) { - const VkImageMemoryBarrier image_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = is_initialized ? VK_ACCESS_SHADER_WRITE_BIT : VkAccessFlags{}, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, - .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = vk_image, - .subresourceRange{ - .aspectMask = aspect_mask, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }, - }; - cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT - : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); - }); + scheduler.Record([vk_pipeline, vk_image, aspect_mask, + is_initialized](vk::CommandBuffer cmdbuf) { + const VkImageMemoryBarrier image_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT + : VK_ACCESS_NONE), + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = vk_image, + .subresourceRange{ + .aspectMask = aspect_mask, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT + : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); + }); for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { const size_t input_offset = swizzle.buffer_offset + map.offset; const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 5196bdcf2..978e827f5 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -174,7 +174,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program case Maxwell::TessellationPrimitive::Quads: return Shader::TessPrimitive::Quads; } - UNREACHABLE(); + ASSERT(false); return Shader::TessPrimitive::Triangles; }(); info.tess_spacing = [&] { @@ -187,7 +187,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program case Maxwell::TessellationSpacing::FractionalEven: return Shader::TessSpacing::FractionalEven; } - UNREACHABLE(); + ASSERT(false); return Shader::TessSpacing::Equal; }(); break; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index fd27581ce..ce6c853c1 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -784,8 +784,8 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) }); } else { // Front face defines both faces - scheduler.Record([ref = regs.stencil_back_func_ref, write_mask = regs.stencil_back_mask, - test_mask = regs.stencil_back_func_mask](vk::CommandBuffer cmdbuf) { + scheduler.Record([ref = regs.stencil_front_func_ref, write_mask = regs.stencil_front_mask, + test_mask = regs.stencil_front_func_mask](vk::CommandBuffer cmdbuf) { cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref); cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask); cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask); diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp index 31ce2f815..9a6afaca6 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp @@ -263,7 +263,7 @@ StagingBufferPool::StagingBuffersCache& StagingBufferPool::GetCache(MemoryUsage case MemoryUsage::Download: return download_cache; default: - UNREACHABLE_MSG("Invalid memory usage={}", usage); + ASSERT_MSG(false, "Invalid memory usage={}", usage); return upload_cache; } } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 353594293..43ecb9647 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -70,7 +70,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { case ImageType::Buffer: break; } - UNREACHABLE_MSG("Invalid image type={}", type); + ASSERT_MSG(false, "Invalid image type={}", type); return {}; } @@ -87,7 +87,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { case 16: return VK_SAMPLE_COUNT_16_BIT; default: - UNREACHABLE_MSG("Invalid number of samples={}", num_samples); + ASSERT_MSG(false, "Invalid number of samples={}", num_samples); return VK_SAMPLE_COUNT_1_BIT; } } @@ -107,7 +107,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; break; default: - UNREACHABLE_MSG("Invalid surface type"); + ASSERT_MSG(false, "Invalid surface type"); } } if (info.storage) { @@ -179,7 +179,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { case VideoCore::Surface::SurfaceType::DepthStencil: return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; default: - UNREACHABLE_MSG("Invalid surface type"); + ASSERT_MSG(false, "Invalid surface type"); return VkImageAspectFlags{}; } } @@ -221,7 +221,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { case SwizzleSource::OneInt: return VK_COMPONENT_SWIZZLE_ONE; } - UNREACHABLE_MSG("Invalid swizzle={}", swizzle); + ASSERT_MSG(false, "Invalid swizzle={}", swizzle); return VK_COMPONENT_SWIZZLE_ZERO; } @@ -242,10 +242,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { case Shader::TextureType::ColorArrayCube: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; case Shader::TextureType::Buffer: - UNREACHABLE_MSG("Texture buffers can't be image views"); + ASSERT_MSG(false, "Texture buffers can't be image views"); return VK_IMAGE_VIEW_TYPE_1D; } - UNREACHABLE_MSG("Invalid image view type={}", type); + ASSERT_MSG(false, "Invalid image view type={}", type); return VK_IMAGE_VIEW_TYPE_2D; } @@ -269,10 +269,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { UNIMPLEMENTED_MSG("Rect image view"); return VK_IMAGE_VIEW_TYPE_2D; case VideoCommon::ImageViewType::Buffer: - UNREACHABLE_MSG("Texture buffers can't be image views"); + ASSERT_MSG(false, "Texture buffers can't be image views"); return VK_IMAGE_VIEW_TYPE_1D; } - UNREACHABLE_MSG("Invalid image view type={}", type); + ASSERT_MSG(false, "Invalid image view type={}", type); return VK_IMAGE_VIEW_TYPE_2D; } @@ -644,7 +644,7 @@ struct RangedBarrierRange { case Shader::ImageFormat::R32G32B32A32_UINT: return VK_FORMAT_R32G32B32A32_UINT; } - UNREACHABLE_MSG("Invalid image format={}", format); + ASSERT_MSG(false, "Invalid image format={}", format); return VK_FORMAT_R32_UINT; } @@ -1596,7 +1596,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI UNIMPLEMENTED(); break; case VideoCommon::ImageViewType::Buffer: - UNREACHABLE(); + ASSERT(false); break; } } @@ -1822,7 +1822,7 @@ void TextureCacheRuntime::AccelerateImageUpload( if (IsPixelFormatASTC(image.info.format)) { return astc_decoder_pass.Assemble(image, map, swizzles); } - UNREACHABLE(); + ASSERT(false); } } // namespace Vulkan diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp index d469964f6..c4e923bbf 100644 --- a/src/video_core/shader_environment.cpp +++ b/src/video_core/shader_environment.cpp @@ -280,7 +280,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, stage_index = 4; break; default: - UNREACHABLE_MSG("Invalid program={}", program); + ASSERT_MSG(false, "Invalid program={}", program); break; } const u64 local_size{sph.LocalMemorySize()}; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 5f428d35d..69c1b1e6d 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -29,7 +29,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t return SurfaceTarget::Texture2DArray; default: LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", texture_type); - UNREACHABLE(); + ASSERT(false); return SurfaceTarget::Texture2D; } } @@ -48,7 +48,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) { return true; default: LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); - UNREACHABLE(); + ASSERT(false); return false; } } @@ -67,7 +67,7 @@ bool SurfaceTargetIsArray(SurfaceTarget target) { return true; default: LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target); - UNREACHABLE(); + ASSERT(false); return false; } } diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 86fea61ae..75e055592 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -147,7 +147,7 @@ enum class SurfaceTarget { TextureCubeArray, }; -constexpr std::array<u32, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{ +constexpr std::array<u8, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{ 1, // A8B8G8R8_UNORM 1, // A8B8G8R8_SNORM 1, // A8B8G8R8_SINT @@ -249,7 +249,7 @@ constexpr u32 DefaultBlockWidth(PixelFormat format) { return BLOCK_WIDTH_TABLE[static_cast<std::size_t>(format)]; } -constexpr std::array<u32, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{ +constexpr std::array<u8, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{ 1, // A8B8G8R8_UNORM 1, // A8B8G8R8_SNORM 1, // A8B8G8R8_SINT @@ -351,7 +351,7 @@ constexpr u32 DefaultBlockHeight(PixelFormat format) { return BLOCK_HEIGHT_TABLE[static_cast<std::size_t>(format)]; } -constexpr std::array<u32, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{ +constexpr std::array<u8, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{ 32, // A8B8G8R8_UNORM 32, // A8B8G8R8_SNORM 32, // A8B8G8R8_SINT diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 802939f6c..6c073ee57 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -94,7 +94,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { resources.layers = 1; break; default: - UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); + ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); break; } if (type != ImageType::Linear) { diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp index 0cee5e45f..f47885147 100644 --- a/src/video_core/texture_cache/image_view_info.cpp +++ b/src/video_core/texture_cache/image_view_info.cpp @@ -71,7 +71,7 @@ ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept range.extent.layers = config.Depth() * 6; break; default: - UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); + ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value())); break; } } diff --git a/src/video_core/texture_cache/samples_helper.h b/src/video_core/texture_cache/samples_helper.h index 91fec60bd..d552bccf0 100644 --- a/src/video_core/texture_cache/samples_helper.h +++ b/src/video_core/texture_cache/samples_helper.h @@ -23,7 +23,7 @@ namespace VideoCommon { case 16: return {2, 2}; } - UNREACHABLE_MSG("Invalid number of samples={}", num_samples); + ASSERT_MSG(false, "Invalid number of samples={}", num_samples); return {1, 1}; } @@ -47,7 +47,7 @@ namespace VideoCommon { case MsaaMode::Msaa4x4: return 16; } - UNREACHABLE_MSG("Invalid MSAA mode={}", static_cast<int>(msaa_mode)); + ASSERT_MSG(false, "Invalid MSAA mode={}", static_cast<int>(msaa_mode)); return 1; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6622d7818..cf3ca06a6 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1485,14 +1485,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) { const auto page_it = selected_page_table.find(page); if (page_it == selected_page_table.end()) { - UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); + ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); return; } std::vector<ImageId>& image_ids = page_it->second; const auto vector_it = std::ranges::find(image_ids, image_id); if (vector_it == image_ids.end()) { - UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}", - page << PAGE_BITS); + ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", + page << PAGE_BITS); return; } image_ids.erase(vector_it); @@ -1504,14 +1504,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { ForEachCPUPage(image.cpu_addr, image.guest_size_bytes, [this, map_id](u64 page) { const auto page_it = page_table.find(page); if (page_it == page_table.end()) { - UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); + ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); return; } std::vector<ImageMapId>& image_map_ids = page_it->second; const auto vector_it = std::ranges::find(image_map_ids, map_id); if (vector_it == image_map_ids.end()) { - UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}", - page << PAGE_BITS); + ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}", + page << PAGE_BITS); return; } image_map_ids.erase(vector_it); @@ -1532,7 +1532,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) { ForEachCPUPage(cpu_addr, size, [this, image_id](u64 page) { const auto page_it = page_table.find(page); if (page_it == page_table.end()) { - UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS); + ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS); return; } std::vector<ImageMapId>& image_map_ids = page_it->second; @@ -1616,15 +1616,15 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) { const GPUVAddr gpu_addr = image.gpu_addr; const auto alloc_it = image_allocs_table.find(gpu_addr); if (alloc_it == image_allocs_table.end()) { - UNREACHABLE_MSG("Trying to delete an image alloc that does not exist in address 0x{:x}", - gpu_addr); + ASSERT_MSG(false, "Trying to delete an image alloc that does not exist in address 0x{:x}", + gpu_addr); return; } const ImageAllocId alloc_id = alloc_it->second; std::vector<ImageId>& alloc_images = slot_image_allocs[alloc_id].images; const auto alloc_image_it = std::ranges::find(alloc_images, image_id); if (alloc_image_it == alloc_images.end()) { - UNREACHABLE_MSG("Trying to delete an image that does not exist"); + ASSERT_MSG(false, "Trying to delete an image that does not exist"); return; } ASSERT_MSG(False(image.flags & ImageFlagBits::Tracked), "Image was not untracked"); diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index c81343850..9b6b8527b 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -87,7 +87,7 @@ void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixe BPP_CASE(16) #undef BPP_CASE default: - UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); + ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); } } @@ -209,7 +209,7 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 BPP_CASE(16) #undef BPP_CASE default: - UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); + ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); } } @@ -230,7 +230,7 @@ void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, BPP_CASE(16) #undef BPP_CASE default: - UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); + ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); } } @@ -253,7 +253,7 @@ void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 widt BPP_CASE(16) #undef BPP_CASE default: - UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel); + ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); } } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7b2ca8046..11ce865a7 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -566,7 +566,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroup_layout; - if (khr_workgroup_memory_explicit_layout) { + if (khr_workgroup_memory_explicit_layout && is_shader_int16_supported) { workgroup_layout = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR, @@ -577,6 +577,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR .workgroupMemoryExplicitLayout16BitAccess = VK_TRUE, }; SetNext(next, workgroup_layout); + } else if (khr_workgroup_memory_explicit_layout) { + // TODO(lat9nq): Find a proper fix for this + LOG_WARNING(Render_Vulkan, "Disabling VK_KHR_workgroup_memory_explicit_layout due to a " + "yuzu bug when host driver does not support 16-bit integers"); + khr_workgroup_memory_explicit_layout = false; } VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR executable_properties; @@ -664,6 +669,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_amd = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; if (is_amd) { + // TODO(lat9nq): Add an upper bound when AMD fixes their VK_KHR_push_descriptor + const bool has_broken_push_descriptor = VK_VERSION_MAJOR(properties.driverVersion) == 2 && + VK_VERSION_MINOR(properties.driverVersion) == 0 && + VK_VERSION_PATCH(properties.driverVersion) >= 226; + if (khr_push_descriptor && has_broken_push_descriptor) { + LOG_WARNING( + Render_Vulkan, + "Disabling AMD driver 2.0.226 and later from broken VK_KHR_push_descriptor"); + khr_push_descriptor = false; + } + // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. sets_per_pool = 96; // Disable VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT on AMD GCN4 and lower as it is broken. @@ -722,9 +738,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags // The wanted format is not supported by hardware, search for alternatives const VkFormat* alternatives = GetFormatAlternatives(wanted_format); if (alternatives == nullptr) { - UNREACHABLE_MSG("Format={} with usage={} and type={} has no defined alternatives and host " - "hardware does not support it", - wanted_format, wanted_usage, format_type); + ASSERT_MSG(false, + "Format={} with usage={} and type={} has no defined alternatives and host " + "hardware does not support it", + wanted_format, wanted_usage, format_type); return wanted_format; } @@ -740,9 +757,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags } // No alternatives found, panic - UNREACHABLE_MSG("Format={} with usage={} and type={} is not supported by the host hardware and " - "doesn't support any of the alternatives", - wanted_format, wanted_usage, format_type); + ASSERT_MSG(false, + "Format={} with usage={} and type={} is not supported by the host hardware and " + "doesn't support any of the alternatives", + wanted_format, wanted_usage, format_type); return wanted_format; } diff --git a/src/video_core/vulkan_common/vulkan_library.cpp b/src/video_core/vulkan_common/vulkan_library.cpp index a5dd33fb2..4eb3913ee 100644 --- a/src/video_core/vulkan_common/vulkan_library.cpp +++ b/src/video_core/vulkan_common/vulkan_library.cpp @@ -5,11 +5,13 @@ #include "common/dynamic_library.h" #include "common/fs/path_util.h" +#include "common/logging/log.h" #include "video_core/vulkan_common/vulkan_library.h" namespace Vulkan { Common::DynamicLibrary OpenLibrary() { + LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); Common::DynamicLibrary library; #ifdef __APPLE__ // Check if a path to a specific Vulkan library has been specified. @@ -22,9 +24,11 @@ Common::DynamicLibrary OpenLibrary() { } #else std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); + LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename); if (!library.Open(filename.c_str())) { // Android devices may not have libvulkan.so.1, only libvulkan.so. filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); + LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename); void(library.Open(filename.c_str())); } #endif diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index caae6dfdc..6442898bd 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -49,7 +49,7 @@ struct Range { return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; } - UNREACHABLE_MSG("Invalid memory usage={}", usage); + ASSERT_MSG(false, "Invalid memory usage={}", usage); return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } @@ -325,7 +325,7 @@ VkMemoryPropertyFlags MemoryAllocator::MemoryPropertyFlags(u32 type_mask, // Remove device local, if it's not supported by the requested resource return MemoryPropertyFlags(type_mask, flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } - UNREACHABLE_MSG("No compatible memory types found"); + ASSERT_MSG(false, "No compatible memory types found"); return 0; } @@ -349,7 +349,7 @@ bool IsHostVisible(MemoryUsage usage) noexcept { case MemoryUsage::Download: return true; } - UNREACHABLE_MSG("Invalid memory usage={}", usage); + ASSERT_MSG(false, "Invalid memory usage={}", usage); return false; } diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index b1ea6075a..2ad98dcfe 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp @@ -325,6 +325,8 @@ const char* ToString(VkResult result) noexcept { return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; case VkResult::VK_RESULT_MAX_ENUM: return "VK_RESULT_MAX_ENUM"; + case VkResult::VK_ERROR_COMPRESSION_EXHAUSTED_EXT: + return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; } return "Unknown"; } |
