From 921e91ed75ff32bf8da93d1cf9d55a0d6ca4805b Mon Sep 17 00:00:00 2001 From: mazes-80 <1608580+mazes-80@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:39:54 +0100 Subject: [PATCH 1/5] build: Add missing includes required for gcc 14 (#1730) --- src/Common/SysAllocator.h | 4 ++++ src/Common/cpu_features.h | 5 +++-- src/config/ConfigValue.h | 3 +++ src/gui/wxgui/MemorySearcherTool.h | 1 + src/util/helpers/helpers.h | 1 + 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Common/SysAllocator.h b/src/Common/SysAllocator.h index 80afc129..4d59d7c6 100644 --- a/src/Common/SysAllocator.h +++ b/src/Common/SysAllocator.h @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + uint32 coreinit_allocFromSysArea(uint32 size, uint32 alignment); class SysAllocatorBase; diff --git a/src/Common/cpu_features.h b/src/Common/cpu_features.h index 130b51a8..f6c06130 100644 --- a/src/Common/cpu_features.h +++ b/src/Common/cpu_features.h @@ -1,4 +1,3 @@ - #ifdef __GNUC__ #define ATTRIBUTE_AVX2 __attribute__((target("avx2"))) #define ATTRIBUTE_SSE41 __attribute__((target("sse4.1"))) @@ -9,6 +8,8 @@ #define ATTRIBUTE_AESNI #endif +#include + class CPUFeaturesImpl { public: @@ -33,4 +34,4 @@ private: char m_cpuBrandName[0x40]{ 0 }; }; -extern CPUFeaturesImpl g_CPUFeatures; \ No newline at end of file +extern CPUFeaturesImpl g_CPUFeatures; diff --git a/src/config/ConfigValue.h b/src/config/ConfigValue.h index ecffc119..7e50d63e 100644 --- a/src/config/ConfigValue.h +++ b/src/config/ConfigValue.h @@ -4,6 +4,9 @@ #include #include +#include +#include +#include template class ConfigValueAtomic diff --git a/src/gui/wxgui/MemorySearcherTool.h b/src/gui/wxgui/MemorySearcherTool.h index 77820524..3d6c0d87 100644 --- a/src/gui/wxgui/MemorySearcherTool.h +++ b/src/gui/wxgui/MemorySearcherTool.h @@ -3,6 +3,7 @@ #include #include #include +#include #include diff --git a/src/util/helpers/helpers.h b/src/util/helpers/helpers.h index f4728f28..359602b4 100644 --- a/src/util/helpers/helpers.h +++ b/src/util/helpers/helpers.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "util/math/vector2.h" #include "util/math/vector3.h" From 85c8f95b69098e2fc6fce7daf0005c5a2e6967c8 Mon Sep 17 00:00:00 2001 From: mazes-80 <1608580+mazes-80@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:41:06 +0100 Subject: [PATCH 2/5] build: Fixes to how ENABLE_BLUEZ=OFF is handled (#1731) --- src/gui/wxgui/CMakeLists.txt | 9 +++++++-- src/gui/wxgui/input/InputSettings2.cpp | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gui/wxgui/CMakeLists.txt b/src/gui/wxgui/CMakeLists.txt index 9e24a59e..5a74787e 100644 --- a/src/gui/wxgui/CMakeLists.txt +++ b/src/gui/wxgui/CMakeLists.txt @@ -76,8 +76,6 @@ add_library(CemuWxGui STATIC input/InputAPIAddWindow.h input/InputSettings2.cpp input/InputSettings2.h - input/PairingDialog.cpp - input/PairingDialog.h input/panels/ClassicControllerInputPanel.cpp input/panels/ClassicControllerInputPanel.h input/panels/InputPanel.cpp @@ -118,6 +116,13 @@ add_library(CemuWxGui STATIC wxHelper.h ) +if (ENABLE_BLUEZ) + target_sources(CemuWxGui PRIVATE + input/PairingDialog.cpp + input/PairingDialog.h + ) +endif() + set_property(TARGET CemuWxGui PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") diff --git a/src/gui/wxgui/input/InputSettings2.cpp b/src/gui/wxgui/input/InputSettings2.cpp index 8fbc5027..16a7381d 100644 --- a/src/gui/wxgui/input/InputSettings2.cpp +++ b/src/gui/wxgui/input/InputSettings2.cpp @@ -21,7 +21,9 @@ #include "wxgui/input/InputAPIAddWindow.h" #include "input/ControllerFactory.h" +#ifdef HAS_BLUEZ #include "wxgui/input/PairingDialog.h" +#endif #include "wxgui/input/panels/VPADInputPanel.h" #include "wxgui/input/panels/ProControllerInputPanel.h" @@ -255,12 +257,14 @@ wxWindow* InputSettings2::initialize_page(size_t index) page_data.m_controller_api_remove = remove_api; } +#ifdef HAS_BLUEZ auto* pairingDialog = new wxButton(page, wxID_ANY, _("Pair Wii/Wii U Controller")); pairingDialog->Bind(wxEVT_BUTTON, [this](wxEvent&) { PairingDialog pairing_dialog(this); pairing_dialog.ShowModal(); }); sizer->Add(pairingDialog, wxGBPosition(5, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL | wxALL, 5); +#endif // controller auto* controller_bttns = new wxBoxSizer(wxHORIZONTAL); From bb3fb81fb61cb3d809d6f512671e57df7ee00e49 Mon Sep 17 00:00:00 2001 From: Joshua de Reeper Date: Thu, 27 Nov 2025 17:42:00 +0100 Subject: [PATCH 3/5] nsyshid/libusb: Don't attempt kernel driver detach on MacOS (#1736) --- src/Cafe/OS/libs/nsyshid/BackendLibusb.cpp | 38 ++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Cafe/OS/libs/nsyshid/BackendLibusb.cpp b/src/Cafe/OS/libs/nsyshid/BackendLibusb.cpp index b5dd0e0f..e105c145 100644 --- a/src/Cafe/OS/libs/nsyshid/BackendLibusb.cpp +++ b/src/Cafe/OS/libs/nsyshid/BackendLibusb.cpp @@ -14,7 +14,7 @@ namespace nsyshid::backend::libusb { m_ctx = nullptr; cemuLog_logDebug(LogType::Force, "nsyshid::BackendLibusb: failed to initialize libusb, return code: {}", - m_initReturnCode); + m_initReturnCode); return; } @@ -33,8 +33,8 @@ namespace nsyshid::backend::libusb if (ret != LIBUSB_SUCCESS) { cemuLog_logDebug(LogType::Force, - "nsyshid::BackendLibusb: failed to register hotplug callback with return code {}", - ret); + "nsyshid::BackendLibusb: failed to register hotplug callback with return code {}", + ret); } else { @@ -51,8 +51,8 @@ namespace nsyshid::backend::libusb if (ret != 0) { cemuLog_logDebug(LogType::Force, - "nsyshid::BackendLibusb: hotplug thread: error handling events: {}", - ret); + "nsyshid::BackendLibusb: hotplug thread: error handling events: {}", + ret); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } @@ -137,8 +137,8 @@ namespace nsyshid::backend::libusb case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: { cemuLog_logDebug(LogType::Force, "nsyshid::BackendLibusb::OnHotplug(): device arrived: {:04x}:{:04x}", - desc.idVendor, - desc.idProduct); + desc.idVendor, + desc.idProduct); auto device = CheckAndCreateDevice(dev); if (device != nullptr) { @@ -165,8 +165,8 @@ namespace nsyshid::backend::libusb case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: { cemuLog_logDebug(LogType::Force, "nsyshid::BackendLibusb::OnHotplug(): device left: {:04x}:{:04x}", - desc.idVendor, - desc.idProduct); + desc.idVendor, + desc.idProduct); auto device = FindLibusbDevice(dev); if (device != nullptr) { @@ -202,7 +202,7 @@ namespace nsyshid::backend::libusb if (ret < 0) { cemuLog_logDebug(LogType::Force, - "nsyshid::BackendLibusb::FindLibusbDevice(): failed to get device descriptor"); + "nsyshid::BackendLibusb::FindLibusbDevice(): failed to get device descriptor"); return nullptr; } uint8 busNumber = libusb_get_bus_number(dev); @@ -267,7 +267,7 @@ namespace nsyshid::backend::libusb if (desc.idVendor == 0x0e6f && desc.idProduct == 0x0241) { cemuLog_logDebug(LogType::Force, - "nsyshid::BackendLibusb::CheckAndCreateDevice(): lego dimensions portal detected"); + "nsyshid::BackendLibusb::CheckAndCreateDevice(): lego dimensions portal detected"); } auto device = std::make_shared(m_ctx, desc.idVendor, @@ -492,7 +492,7 @@ namespace nsyshid::backend::libusb if (!handleLock->IsValid()) { cemuLog_logDebug(LogType::Force, - "nsyshid::DeviceLibusb::read(): cannot read from a non-opened device\n"); + "nsyshid::DeviceLibusb::read(): cannot read from a non-opened device\n"); return ReadResult::Error; } @@ -525,8 +525,8 @@ namespace nsyshid::backend::libusb return ReadResult::Success; } cemuLog_logDebug(LogType::Force, - "nsyshid::DeviceLibusb::read(): failed at endpoint 0x{:02x} with error message: {}", this->m_libusbEndpointIn, - libusb_error_name(ret)); + "nsyshid::DeviceLibusb::read(): failed at endpoint 0x{:02x} with error message: {}", this->m_libusbEndpointIn, + libusb_error_name(ret)); return ReadResult::Error; } @@ -536,7 +536,7 @@ namespace nsyshid::backend::libusb if (!handleLock->IsValid()) { cemuLog_logDebug(LogType::Force, - "nsyshid::DeviceLibusb::write(): cannot write to a non-opened device\n"); + "nsyshid::DeviceLibusb::write(): cannot write to a non-opened device\n"); return WriteResult::Error; } @@ -565,8 +565,8 @@ namespace nsyshid::backend::libusb return WriteResult::Success; } cemuLog_logDebug(LogType::Force, - "nsyshid::DeviceLibusb::write(): failed with error code: {}", - ret); + "nsyshid::DeviceLibusb::write(): failed with error code: {}", + ret); return WriteResult::Error; } @@ -763,6 +763,9 @@ namespace nsyshid::backend::libusb int DeviceLibusb::ClaimAllInterfaces(uint8 config_num) { const int ret = DoForEachInterface(m_config_descriptors, config_num, [this](uint8 i) { + // On macos detaching would fail without root or entitlement. + // We assume user is using GCAdapterDriver and therefore don't want to detach anything +#if !defined(__APPLE__) if (libusb_kernel_driver_active(this->m_libusbHandle, i)) { const int ret2 = libusb_detach_kernel_driver(this->m_libusbHandle, i); @@ -773,6 +776,7 @@ namespace nsyshid::backend::libusb return ret2; } } +#endif return libusb_claim_interface(this->m_libusbHandle, i); }); if (ret < LIBUSB_SUCCESS) From 51c1e80ba787ecf9a0e2dafc184db986daddba03 Mon Sep 17 00:00:00 2001 From: Crementif <26669564+Crementif@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:46:42 +0100 Subject: [PATCH 4/5] Vulkan: Always embed shader source code when RenderDoc, Nsight or other frame debuggers are attached (#1733) --- .../Latte/Renderer/Vulkan/LatteTextureVk.cpp | 2 +- .../Renderer/Vulkan/RendererShaderVk.cpp | 41 +++++++++---------- .../Latte/Renderer/Vulkan/VulkanRenderer.cpp | 21 ++++++---- .../HW/Latte/Renderer/Vulkan/VulkanRenderer.h | 6 ++- .../Renderer/Vulkan/VulkanRendererCore.cpp | 2 +- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp index a62741e4..80dcb4d7 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp @@ -87,7 +87,7 @@ LatteTextureVk::LatteTextureVk(class VulkanRenderer* vkRenderer, Latte::E_DIM di if (vkCreateImage(m_vkr->GetLogicalDevice(), &imageInfo, nullptr, &vkObjTex->m_image) != VK_SUCCESS) m_vkr->UnrecoverableError("Failed to create texture image"); - if (m_vkr->IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT) + if (m_vkr->IsDebugMarkersEnabled()) { VkDebugUtilsObjectNameInfoEXT objName{}; objName.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp index 403db5bf..f6549e3c 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp @@ -271,7 +271,7 @@ void RendererShaderVk::CreateVkShaderModule(std::span spirvBuffer) } // set debug name - if (vkr->IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT) + if (vkr->IsDebugMarkersEnabled()) { VkDebugUtilsObjectNameInfoEXT objName{}; objName.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; @@ -292,8 +292,10 @@ void RendererShaderVk::FinishCompilation() void RendererShaderVk::CompileInternal(bool isRenderThread) { + const bool compileWithDebugInfo = ((VulkanRenderer*)g_renderer.get())->IsTracingToolEnabled(); + // try to retrieve SPIR-V module from cache - if (s_isLoadingShadersVk && (m_isGameShader && !m_isGfxPackShader) && s_spirvCache) + if (s_isLoadingShadersVk && (m_isGameShader && !m_isGfxPackShader) && s_spirvCache && !compileWithDebugInfo) { cemu_assert_debug(m_baseHash != 0); uint64 h1, h2; @@ -329,21 +331,12 @@ void RendererShaderVk::CompileInternal(bool isRenderThread) Shader.setStrings(&cstr, 1); Shader.setEnvInput(glslang::EShSourceGlsl, state, glslang::EShClientVulkan, 100); Shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetClientVersion::EShTargetVulkan_1_1); - Shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetLanguageVersion::EShTargetSpv_1_3); - TBuiltInResource Resources = GetDefaultBuiltInResource(); std::string PreprocessedGLSL; - - VulkanRenderer* vkr = (VulkanRenderer*)g_renderer.get(); - - EShMessages messagesPreprocess; - if (vkr->IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT) - messagesPreprocess = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules | EShMsgDebugInfo); - else - messagesPreprocess = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); - glslang::TShader::ForbidIncluder Includer; + TBuiltInResource Resources = GetDefaultBuiltInResource(); + EShMessages messagesPreprocess = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); if (!Shader.preprocess(&Resources, 450, ENoProfile, false, false, messagesPreprocess, &PreprocessedGLSL, Includer)) { cemuLog_log(LogType::Force, fmt::format("GLSL Preprocessing Failed For {:016x}_{:016x}: \"{}\"", m_baseHash, m_auxHash, Shader.getInfoLog())); @@ -351,14 +344,9 @@ void RendererShaderVk::CompileInternal(bool isRenderThread) return; } - EShMessages messagesParseLink; - if (vkr->IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT) - messagesParseLink = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules | EShMsgDebugInfo); - else - messagesParseLink = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); - const char* PreprocessedCStr = PreprocessedGLSL.c_str(); Shader.setStrings(&PreprocessedCStr, 1); + EShMessages messagesParseLink = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); if (!Shader.parse(&Resources, 100, false, messagesParseLink)) { cemuLog_log(LogType::Force, fmt::format("GLSL parsing failed for {:016x}_{:016x}: \"{}\"", m_baseHash, m_auxHash, Shader.getInfoLog())); @@ -392,9 +380,17 @@ void RendererShaderVk::CompileInternal(bool isRenderThread) glslang::SpvOptions spvOptions; spvOptions.disableOptimizer = false; - spvOptions.generateDebugInfo = (vkr->IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT); spvOptions.validate = false; spvOptions.optimizeSize = true; + if (compileWithDebugInfo) + { + spvOptions.generateDebugInfo = true; + spvOptions.emitNonSemanticShaderDebugInfo = true; + spvOptions.emitNonSemanticShaderDebugSource = true; + + Shader.addSourceText(m_glslCode.c_str(), (uint32)m_glslCode.size()); + Shader.setSourceFile(fmt::format("shader_{:016x}_{:016x}.glsl", m_baseHash, m_auxHash).c_str()); + } //auto beginTime = benchmarkTimer_start(); @@ -402,8 +398,9 @@ void RendererShaderVk::CompileInternal(bool isRenderThread) //double timeDur = benchmarkTimer_stop(beginTime); //forceLogRemoveMe_printf("Shader GLSL-to-SPIRV compilation took %lfms Size %08x", timeDur, spirvBuffer.size()*4); - - if (s_spirvCache && m_isGameShader && m_isGfxPackShader == false) + + // store in cache, unless it got compiled with debug info or is a modified shader from a gfx pack + if (s_spirvCache && m_isGameShader && m_isGfxPackShader == false && !compileWithDebugInfo) { uint64 h1, h2; GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index 5a7d8f4e..a1340a94 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -446,8 +446,6 @@ VulkanRenderer::VulkanRenderer() } CheckDeviceExtensionSupport(m_physicalDevice, m_featureControl); // todo - merge this with GetDeviceFeatures and separate from IsDeviceSuitable? - if (m_featureControl.debugMarkersSupported) - cemuLog_log(LogType::Force, "Debug: Frame debugger attached, will use vkDebugMarkerSetObjectNameEXT"); DetermineVendor(); GetDeviceFeatures(); @@ -582,10 +580,14 @@ VulkanRenderer::VulkanRenderer() debugCallback.pfnUserCallback = &DebugUtilsCallback; vkCreateDebugUtilsMessengerEXT(m_instance, &debugCallback, nullptr, &m_debugCallback); + + cemuLog_log(LogType::Force, "Debug: Vulkan validation layer enabled, vkCreateDebugUtilsMessengerEXT will be used to log validation errors"); } - if (m_featureControl.instanceExtensions.debug_utils) - cemuLog_log(LogType::Force, "Using available debug function: vkCreateDebugUtilsMessengerEXT()"); + if (this->IsTracingToolEnabled()) + cemuLog_log(LogType::Force, "Debug: Tracing tool detected, will recompile all shaders with debug info enabled. This disables the SPIR-V cache."); + if (this->IsDebugMarkersEnabled()) + cemuLog_log(LogType::Force, "Debug: Detected tool capable of using debug markers, will use vkDebugMarkerSetObjectNameEXT to identify Vulkan objects"); // set initial viewport and scissor box size m_state.currentViewport.width = 4; @@ -1256,8 +1258,9 @@ bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device, // dynamic rendering doesn't provide any benefits for us right now. Driver implementations are very unoptimized as of Feb 2022 info.deviceExtensions.present_wait = isExtensionAvailable(VK_KHR_PRESENT_WAIT_EXTENSION_NAME) && isExtensionAvailable(VK_KHR_PRESENT_ID_EXTENSION_NAME); - // check for framedebuggers - info.debugMarkersSupported = false; + // check for validation layers and frame debuggers + info.usingDebugMarkerTool = false; + info.usingTracingTool = false; if (info.deviceExtensions.tooling_info && vkGetPhysicalDeviceToolPropertiesEXT) { uint32_t toolCount = 0; @@ -1268,8 +1271,10 @@ bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device, { for (auto& itr : toolProperties) { - if ((itr.purposes & VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT) != 0) - info.debugMarkersSupported = true; + if ((itr.purposes & VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT) != 0 && info.instanceExtensions.debug_utils && vkSetDebugUtilsObjectNameEXT) + info.usingDebugMarkerTool = true; + if ((itr.purposes & VK_TOOL_PURPOSE_TRACING_BIT) != 0) + info.usingTracingTool = true; } } } diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h index 7290fdd7..fabf7490 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h @@ -482,7 +482,8 @@ private: uint32 nonCoherentAtomSize = 256; }limits; - bool debugMarkersSupported{ false }; // frame debugger is attached + bool usingDebugMarkerTool{ false }; // validation layer or other tool capable of handling debug markers is used + bool usingTracingTool{ false }; // frame debugger or other API replaying tool is used bool disableMultithreadedCompilation{ false }; // for old nvidia drivers }m_featureControl{}; @@ -937,7 +938,8 @@ public: bool GetDisableMultithreadedCompilation() const { return m_featureControl.disableMultithreadedCompilation; } bool UseTFViaSSBO() const { return m_featureControl.mode.useTFEmulationViaSSBO; } bool HasSPRIVRoundingModeRTE32() const { return m_featureControl.shaderFloatControls.shaderRoundingModeRTEFloat32; } - bool IsDebugUtilsEnabled() const { return m_featureControl.debugMarkersSupported && m_featureControl.instanceExtensions.debug_utils; } + bool IsDebugMarkersEnabled() const { return m_featureControl.usingDebugMarkerTool; } + bool IsTracingToolEnabled() const { return m_featureControl.usingTracingTool; } private: diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp index 32ef7007..03e0d2bf 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp @@ -245,7 +245,7 @@ void compilePipelineThread_queue(PipelineCompiler* v) bool VulkanRenderer::IsAsyncPipelineAllowed(uint32 numIndices) { // frame debuggers dont handle async well (as of 2020) - if (IsDebugUtilsEnabled() && vkSetDebugUtilsObjectNameEXT) + if (IsTracingToolEnabled()) return false; CachedFBOVk* currentFBO = m_state.activeFBO; From 5bf58c3d20aa7196042338bc0c55ef794c6d9535 Mon Sep 17 00:00:00 2001 From: Carlos Estrague / Mrc_munir Date: Thu, 27 Nov 2025 17:50:03 +0100 Subject: [PATCH 5/5] Vulkan: Added support for implementations which only expose host-visible buffers as device-local (#1737) --- src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index a1340a94..32df160e 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -614,6 +614,8 @@ VulkanRenderer::VulkanRenderer() m_uniformVarBufferMemoryIsCoherent = true; // unified memory else if (memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory)) m_uniformVarBufferMemoryIsCoherent = true; + else if (memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory)) + m_uniformVarBufferMemoryIsCoherent = true; else { memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory); @@ -626,7 +628,10 @@ VulkanRenderer::VulkanRenderer() m_uniformVarBufferPtr = (uint8*)bufferPtr; // texture readback buffer - memoryManager->CreateBuffer(TEXTURE_READBACK_SIZE, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_textureReadbackBuffer, m_textureReadbackBufferMemory); + if (!memoryManager->CreateBuffer(TEXTURE_READBACK_SIZE, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_textureReadbackBuffer, m_textureReadbackBufferMemory)) + { + memoryManager->CreateBuffer(TEXTURE_READBACK_SIZE, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_textureReadbackBuffer, m_textureReadbackBufferMemory); + } bufferPtr = nullptr; vkMapMemory(m_logicalDevice, m_textureReadbackBufferMemory, 0, VK_WHOLE_SIZE, 0, &bufferPtr); m_textureReadbackBufferPtr = (uint8*)bufferPtr; @@ -635,7 +640,10 @@ VulkanRenderer::VulkanRenderer() memoryManager->CreateBuffer(LatteStreamout_GetRingBufferSize(), VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | (m_featureControl.mode.useTFEmulationViaSSBO ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0), 0, m_xfbRingBuffer, m_xfbRingBufferMemory); // occlusion query result buffer - memoryManager->CreateBuffer(OCCLUSION_QUERY_POOL_SIZE * sizeof(uint64), VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_occlusionQueries.bufferQueryResults, m_occlusionQueries.memoryQueryResults); + if (!memoryManager->CreateBuffer(OCCLUSION_QUERY_POOL_SIZE * sizeof(uint64), VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_occlusionQueries.bufferQueryResults, m_occlusionQueries.memoryQueryResults)) + { + memoryManager->CreateBuffer(OCCLUSION_QUERY_POOL_SIZE * sizeof(uint64), VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_occlusionQueries.bufferQueryResults, m_occlusionQueries.memoryQueryResults); + } bufferPtr = nullptr; vkMapMemory(m_logicalDevice, m_occlusionQueries.memoryQueryResults, 0, VK_WHOLE_SIZE, 0, &bufferPtr); m_occlusionQueries.ptrQueryResults = (uint64*)bufferPtr;