diff --git a/BUILD.md b/BUILD.md index a23ea66a..5be890b3 100644 --- a/BUILD.md +++ b/BUILD.md @@ -244,7 +244,7 @@ Example usage: `cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DENABLE_SDL=ON - | CEMU_CXX_FLAGS | | Flags passed straight to the compiler, e.g. `-march=native`, `-Wall`, `/W3` | "" | | | ENABLE_CUBEB | | Enable cubeb audio backend | ON | | | ENABLE_DISCORD_RPC | | Enable Discord Rich presence support | ON | | -| ENABLE_OPENGL | | Enable OpenGL graphics backend | ON | Currently required | +| ENABLE_OPENGL | | Enable OpenGL graphics backend | ON | | | ENABLE_HIDAPI | | Enable HIDAPI (used for Wiimote controller API) | ON | | | ENABLE_SDL | | Enable SDLController controller API | ON | Currently required | | ENABLE_VCPKG | | Use VCPKG package manager to obtain dependencies | ON | | diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b1e86d5..e44b0208 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,11 +110,13 @@ endif() if (APPLE) set(ENABLE_METAL_DEFAULT ON) + set(ENABLE_OPENGL_DEFAULT OFF) else() set(ENABLE_METAL_DEFAULT OFF) + set(ENABLE_OPENGL_DEFAULT ON) endif() -option(ENABLE_OPENGL "Enables the OpenGL backend" ON) +option(ENABLE_OPENGL "Enables the OpenGL backend" ${ENABLE_OPENGL_DEFAULT}) option(ENABLE_VULKAN "Enables the Vulkan backend" ON) option(ENABLE_METAL "Enables the Metal backend" ${ENABLE_METAL_DEFAULT}) option(ENABLE_DISCORD_RPC "Enables the Discord Rich Presence feature" ON) @@ -189,16 +191,18 @@ endif() if (ENABLE_VULKAN) include_directories("dependencies/Vulkan-Headers/include") + add_compile_definitions(ENABLE_VULKAN) endif() if (ENABLE_OPENGL) find_package(OpenGL REQUIRED) + add_compile_definitions(ENABLE_OPENGL) endif() if (ENABLE_METAL) include_directories(${CMAKE_SOURCE_DIR}/dependencies/metal-cpp) - add_definitions(-DENABLE_METAL=1) + add_compile_definitions(ENABLE_METAL) endif() if (ENABLE_DISCORD_RPC) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 291cc612..8cb622f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,18 +13,24 @@ if(MSVC) add_compile_definitions(WIN32_LEAN_AND_MEAN CURL_STATICLIB) elseif(UNIX) if(APPLE) - add_compile_definitions( - _XOPEN_SOURCE - VK_USE_PLATFORM_MACOS_MVK - VK_USE_PLATFORM_METAL_EXT - ) + if (ENABLE_VULKAN) + add_compile_definitions( + _XOPEN_SOURCE + VK_USE_PLATFORM_MACOS_MVK + VK_USE_PLATFORM_METAL_EXT + ) + else() + add_compile_definitions(_XOPEN_SOURCE) + endif() else() - add_compile_definitions( - VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces? - VK_USE_PLATFORM_XCB_KHR - ) - if (ENABLE_WAYLAND) - add_compile_definitions(VK_USE_PLATFORM_WAYLAND_KHR) + if (ENABLE_VULKAN) + add_compile_definitions( + VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces? + VK_USE_PLATFORM_XCB_KHR + ) + if (ENABLE_WAYLAND) + add_compile_definitions(VK_USE_PLATFORM_WAYLAND_KHR) + endif() endif() endif() # warnings @@ -35,7 +41,9 @@ elseif(UNIX) add_compile_options(-Wno-multichar -Wno-invalid-offsetof -Wno-switch -Wno-ignored-attributes -Wno-deprecated-enum-enum-conversion) endif() -add_compile_definitions(VK_NO_PROTOTYPES) +if (ENABLE_VULKAN) + add_compile_definitions(VK_NO_PROTOTYPES) +endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -119,29 +127,27 @@ if (MACOS_BUNDLE) COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory "${CMAKE_SOURCE_DIR}/bin/${folder}" "$/Contents/SharedSupport/${folder}") endforeach(folder) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/debug/lib/libusb-1.0.0.dylib") - else() - set(LIBUSB_PATH "${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/lib/libusb-1.0.0.dylib") - endif() + if (ENABLE_VULKAN) + if (EXISTS "/usr/local/lib/libMoltenVK.dylib") + set(MOLTENVK_PATH "/usr/local/lib/libMoltenVK.dylib") + elseif (EXISTS "/opt/homebrew/lib/libMoltenVK.dylib") + set(MOLTENVK_PATH "/opt/homebrew/lib/libMoltenVK.dylib") + else() + message(FATAL_ERROR "failed to find libMoltenVK.dylib") + endif () + endif() - if (EXISTS "/usr/local/lib/libMoltenVK.dylib") - set(MOLTENVK_PATH "/usr/local/lib/libMoltenVK.dylib") - elseif (EXISTS "/opt/homebrew/lib/libMoltenVK.dylib") - set(MOLTENVK_PATH "/opt/homebrew/lib/libMoltenVK.dylib") - else() - message(FATAL_ERROR "failed to find libMoltenVK.dylib") - endif () set(UPDATE_SH_PATH "${CMAKE_SOURCE_DIR}/src/resource/update.sh") - set(APP_BUNDLE_DIR "$") set(FRAMEWORKS_DIR "${APP_BUNDLE_DIR}/Contents/Frameworks") set(RESOURCES_DIR "${APP_BUNDLE_DIR}/Contents/Resources") add_custom_command(TARGET CemuBin POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - "${MOLTENVK_PATH}" - "${FRAMEWORKS_DIR}/libMoltenVK.dylib" + if (ENABLE_VULKAN) + COMMAND ${CMAKE_COMMAND} -E copy + "${MOLTENVK_PATH}" + "${FRAMEWORKS_DIR}/libMoltenVK.dylib" + endif() COMMAND ${CMAKE_COMMAND} -E copy "${LIBUSB_PATH}" "${FRAMEWORKS_DIR}/libusb-1.0.0.dylib" @@ -165,20 +171,22 @@ if (MACOS_BUNDLE) ) else() if(APPLE) - find_library(MOLTENVK_LIBRARY - NAMES MoltenVK moltenvk libMoltenVK.dylib - PATHS /usr/local/lib /opt/homebrew/lib - ) - if(MOLTENVK_LIBRARY) - message(STATUS "Found MoltenVK: ${MOLTENVK_LIBRARY}") - target_link_libraries(CemuBin PRIVATE ${MOLTENVK_LIBRARY}) - else() - message(WARNING "libMoltenVK.dylib not found") - endif() - set_target_properties(CemuBin PROPERTIES - BUILD_WITH_INSTALL_RPATH TRUE - INSTALL_RPATH "/usr/local/lib;/opt/homebrew/lib" - ) + if (ENABLE_VULKAN) + find_library(MOLTENVK_LIBRARY + NAMES MoltenVK moltenvk libMoltenVK.dylib + PATHS /usr/local/lib /opt/homebrew/lib + ) + if(MOLTENVK_LIBRARY) + message(STATUS "Found MoltenVK: ${MOLTENVK_LIBRARY}") + target_link_libraries(CemuBin PRIVATE ${MOLTENVK_LIBRARY}) + else() + message(WARNING "libMoltenVK.dylib not found") + endif() + set_target_properties(CemuBin PROPERTIES + BUILD_WITH_INSTALL_RPATH TRUE + INSTALL_RPATH "/usr/local/lib;/opt/homebrew/lib" + ) + endif() endif() endif() diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 78a8cce0..0df1e847 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -106,8 +106,6 @@ add_library(CemuCafe HW/Latte/Core/LatteCachedFBO.h HW/Latte/Core/LatteCommandProcessor.cpp HW/Latte/Core/LatteConst.h - HW/Latte/Core/LatteDefaultShaders.cpp - HW/Latte/Core/LatteDefaultShaders.h HW/Latte/Core/LatteDraw.h HW/Latte/Core/LatteGSCopyShaderParser.cpp HW/Latte/Core/Latte.h @@ -127,7 +125,6 @@ add_library(CemuCafe HW/Latte/Core/LatteShaderCache.cpp HW/Latte/Core/LatteShaderCache.h HW/Latte/Core/LatteShader.cpp - HW/Latte/Core/LatteShaderGL.cpp HW/Latte/Core/LatteShader.h HW/Latte/Core/LatteSoftware.cpp HW/Latte/Core/LatteSoftware.h @@ -162,58 +159,14 @@ add_library(CemuCafe HW/Latte/LegacyShaderDecompiler/LatteDecompilerInstructions.h HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h HW/Latte/LegacyShaderDecompiler/LatteDecompilerRegisterDataTypeTracker.cpp - HW/Latte/Renderer/OpenGL/CachedFBOGL.h - HW/Latte/Renderer/OpenGL/LatteTextureGL.cpp - HW/Latte/Renderer/OpenGL/LatteTextureGL.h - HW/Latte/Renderer/OpenGL/LatteTextureViewGL.cpp - HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h - HW/Latte/Renderer/OpenGL/OpenGLQuery.cpp - HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp - HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp - HW/Latte/Renderer/OpenGL/OpenGLRenderer.h - HW/Latte/Renderer/OpenGL/OpenGLRendererStreamout.cpp - HW/Latte/Renderer/OpenGL/OpenGLRendererUniformData.cpp - HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp - HW/Latte/Renderer/OpenGL/OpenGLTextureReadback.h - HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp - HW/Latte/Renderer/OpenGL/RendererShaderGL.h - HW/Latte/Renderer/OpenGL/TextureReadbackGL.cpp HW/Latte/Renderer/Renderer.cpp HW/Latte/Renderer/Renderer.h + HW/Latte/Renderer/RendererCore.cpp + HW/Latte/Renderer/RendererCore.h HW/Latte/Renderer/RendererOuputShader.cpp HW/Latte/Renderer/RendererOuputShader.h HW/Latte/Renderer/RendererShader.cpp HW/Latte/Renderer/RendererShader.h - HW/Latte/Renderer/Vulkan/CachedFBOVk.cpp - HW/Latte/Renderer/Vulkan/CachedFBOVk.h - HW/Latte/Renderer/Vulkan/CocoaSurface.h - HW/Latte/Renderer/Vulkan/LatteTextureViewVk.cpp - HW/Latte/Renderer/Vulkan/LatteTextureViewVk.h - HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp - HW/Latte/Renderer/Vulkan/LatteTextureVk.h - HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp - HW/Latte/Renderer/Vulkan/RendererShaderVk.h - HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp - HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h - HW/Latte/Renderer/Vulkan/TextureReadbackVk.cpp - HW/Latte/Renderer/Vulkan/VKRBase.h - HW/Latte/Renderer/Vulkan/VKRMemoryManager.cpp - HW/Latte/Renderer/Vulkan/VKRMemoryManager.h - HW/Latte/Renderer/Vulkan/VKRPipelineInfo.cpp - HW/Latte/Renderer/Vulkan/VsyncDriver.cpp - HW/Latte/Renderer/Vulkan/VsyncDriver.h - HW/Latte/Renderer/Vulkan/VulkanAPI.cpp - HW/Latte/Renderer/Vulkan/VulkanAPI.h - HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp - HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.h - HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp - HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.h - HW/Latte/Renderer/Vulkan/VulkanQuery.cpp - HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp - HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp - HW/Latte/Renderer/Vulkan/VulkanRenderer.h - HW/Latte/Renderer/Vulkan/VulkanSurfaceCopy.cpp - HW/Latte/Renderer/Vulkan/VulkanTextureReadback.h HW/Latte/ShaderInfo/ShaderDescription.cpp HW/Latte/ShaderInfo/ShaderInfo.h HW/Latte/ShaderInfo/ShaderInstanceInfo.cpp @@ -539,12 +492,73 @@ add_library(CemuCafe TitleList/TitleList.h ) +if (ENABLE_OPENGL) + target_sources(CemuCafe PRIVATE + HW/Latte/Renderer/OpenGL/CachedFBOGL.h + HW/Latte/Renderer/OpenGL/LatteShaderGL.cpp + HW/Latte/Renderer/OpenGL/LatteTextureGL.cpp + HW/Latte/Renderer/OpenGL/LatteTextureGL.h + HW/Latte/Renderer/OpenGL/LatteTextureViewGL.cpp + HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h + HW/Latte/Renderer/OpenGL/OpenGLQuery.cpp + HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp + HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp + HW/Latte/Renderer/OpenGL/OpenGLRenderer.h + HW/Latte/Renderer/OpenGL/OpenGLRendererStreamout.cpp + HW/Latte/Renderer/OpenGL/OpenGLRendererUniformData.cpp + HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp + HW/Latte/Renderer/OpenGL/OpenGLTextureReadback.h + HW/Latte/Renderer/OpenGL/RendererShaderGL.cpp + HW/Latte/Renderer/OpenGL/RendererShaderGL.h + HW/Latte/Renderer/OpenGL/TextureReadbackGL.cpp + ) +endif() + +if (ENABLE_VULKAN) + target_sources(CemuCafe PRIVATE + HW/Latte/Renderer/Vulkan/CachedFBOVk.cpp + HW/Latte/Renderer/Vulkan/CachedFBOVk.h + HW/Latte/Renderer/Vulkan/CocoaSurface.h + HW/Latte/Renderer/Vulkan/LatteTextureViewVk.cpp + HW/Latte/Renderer/Vulkan/LatteTextureViewVk.h + HW/Latte/Renderer/Vulkan/LatteTextureVk.cpp + HW/Latte/Renderer/Vulkan/LatteTextureVk.h + HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp + HW/Latte/Renderer/Vulkan/RendererShaderVk.h + HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp + HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h + HW/Latte/Renderer/Vulkan/TextureReadbackVk.cpp + HW/Latte/Renderer/Vulkan/VKRBase.h + HW/Latte/Renderer/Vulkan/VKRMemoryManager.cpp + HW/Latte/Renderer/Vulkan/VKRMemoryManager.h + HW/Latte/Renderer/Vulkan/VKRPipelineInfo.cpp + HW/Latte/Renderer/Vulkan/VsyncDriver.cpp + HW/Latte/Renderer/Vulkan/VsyncDriver.h + HW/Latte/Renderer/Vulkan/VulkanAPI.cpp + HW/Latte/Renderer/Vulkan/VulkanAPI.h + HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp + HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.h + HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.cpp + HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.h + HW/Latte/Renderer/Vulkan/VulkanQuery.cpp + HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp + HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp + HW/Latte/Renderer/Vulkan/VulkanRenderer.h + HW/Latte/Renderer/Vulkan/VulkanSurfaceCopy.cpp + HW/Latte/Renderer/Vulkan/VulkanTextureReadback.h + ) +endif() + if(APPLE) target_sources(CemuCafe PRIVATE - HW/Latte/Renderer/Vulkan/CocoaSurface.mm HW/Latte/Renderer/MetalView.mm HW/Latte/Renderer/MetalView.h ) + if (ENABLE_VULKAN) + target_sources(CemuCafe PRIVATE + HW/Latte/Renderer/Vulkan/CocoaSurface.mm + ) + endif() endif() if(ENABLE_METAL) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index f016773c..fc0d1ae6 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -251,7 +251,7 @@ void InfoLog_PrintActiveSettings() if (!GetConfig().vk_accurate_barriers.GetValue()) cemuLog_log(LogType::Force, "Accurate barriers are disabled!"); } -#if ENABLE_METAL +#ifdef ENABLE_METAL else if (ActiveSettings::GetGraphicsAPI() == GraphicAPI::kMetal) { cemuLog_log(LogType::Force, "Async compile: {}", GetConfig().async_compile.GetValue() ? "true" : "false"); diff --git a/src/Cafe/GameProfile/GameProfile.cpp b/src/Cafe/GameProfile/GameProfile.cpp index 9ee0a696..5c15d7c3 100644 --- a/src/Cafe/GameProfile/GameProfile.cpp +++ b/src/Cafe/GameProfile/GameProfile.cpp @@ -226,7 +226,7 @@ bool GameProfile::Load(uint64_t title_id) m_graphics_api = (GraphicAPI)graphicsApi.value; gameProfile_loadEnumOption(iniParser, "accurateShaderMul", m_accurateShaderMul); -#if ENABLE_METAL +#ifdef ENABLE_METAL gameProfile_loadBooleanOption2(iniParser, "shaderFastMath", m_shaderFastMath); gameProfile_loadEnumOption(iniParser, "metalBufferCacheMode2", m_metalBufferCacheMode); gameProfile_loadEnumOption(iniParser, "positionInvariance2", m_positionInvariance); @@ -311,7 +311,7 @@ void GameProfile::Save(uint64_t title_id) fs->writeLine("[Graphics]"); WRITE_ENTRY(accurateShaderMul); -#if ENABLE_METAL +#ifdef ENABLE_METAL WRITE_ENTRY(shaderFastMath); WRITE_ENTRY_NUMBERED(metalBufferCacheMode, 2); WRITE_ENTRY_NUMBERED(positionInvariance, 2); @@ -346,7 +346,7 @@ void GameProfile::ResetOptional() // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; -#if ENABLE_METAL +#ifdef ENABLE_METAL m_shaderFastMath = true; m_metalBufferCacheMode = MetalBufferCacheMode::Auto; m_positionInvariance = PositionInvariance::Auto; @@ -371,7 +371,7 @@ void GameProfile::Reset() // graphic settings m_accurateShaderMul = AccurateShaderMulOption::True; -#if ENABLE_METAL +#ifdef ENABLE_METAL m_shaderFastMath = true; m_metalBufferCacheMode = MetalBufferCacheMode::Auto; m_positionInvariance = PositionInvariance::Auto; diff --git a/src/Cafe/GameProfile/GameProfile.h b/src/Cafe/GameProfile/GameProfile.h index 5155beac..06c2a13b 100644 --- a/src/Cafe/GameProfile/GameProfile.h +++ b/src/Cafe/GameProfile/GameProfile.h @@ -29,7 +29,7 @@ public: [[nodiscard]] const std::optional& GetGraphicsAPI() const { return m_graphics_api; } [[nodiscard]] const AccurateShaderMulOption& GetAccurateShaderMul() const { return m_accurateShaderMul; } -#if ENABLE_METAL +#ifdef ENABLE_METAL [[nodiscard]] bool GetShaderFastMath() const { return m_shaderFastMath; } [[nodiscard]] MetalBufferCacheMode GetBufferCacheMode() const { return m_metalBufferCacheMode; } [[nodiscard]] PositionInvariance GetPositionInvariance() const { return m_positionInvariance; } @@ -57,7 +57,7 @@ private: // graphic settings std::optional m_graphics_api{}; AccurateShaderMulOption m_accurateShaderMul = AccurateShaderMulOption::True; -#if ENABLE_METAL +#ifdef ENABLE_METAL bool m_shaderFastMath = true; MetalBufferCacheMode m_metalBufferCacheMode = MetalBufferCacheMode::Auto; PositionInvariance m_positionInvariance = PositionInvariance::Auto; diff --git a/src/Cafe/HW/Latte/Core/FetchShader.cpp b/src/Cafe/HW/Latte/Core/FetchShader.cpp index 7d724e13..4ea633ba 100644 --- a/src/Cafe/HW/Latte/Core/FetchShader.cpp +++ b/src/Cafe/HW/Latte/Core/FetchShader.cpp @@ -11,7 +11,7 @@ #include "HW/Latte/Renderer/Renderer.h" #include "util/containers/LookupTableL3.h" #include "util/helpers/fspinlock.h" -#if ENABLE_METAL +#ifdef ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" #endif #include /* SHA1_DIGEST_LENGTH */ @@ -108,21 +108,28 @@ void LatteShader_calculateFSKey(LatteFetchShader* fetchShader) key = std::rotl(key, 8); key += (uint64)attrib->semanticId; key = std::rotl(key, 8); - if (g_renderer->GetType() == RendererAPI::Metal) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_METAL + case RendererAPI::Metal: { key += (uint64)attrib->offset; key = std::rotl(key, 7); + break; } - else +#endif + default: { key += (uint64)(attrib->offset & 3); key = std::rotl(key, 2); + break; + } } } } // todo - also hash invalid buffer groups? -#if ENABLE_METAL +#ifdef ENABLE_METAL if (g_renderer->GetType() == RendererAPI::Metal) { for (sint32 g = 0; g < fetchShader->bufferGroups.size(); g++) @@ -171,7 +178,7 @@ void LatteFetchShader::CalculateFetchShaderVkHash() this->vkPipelineHashFragment = h; } -#if ENABLE_METAL +#ifdef ENABLE_METAL void LatteFetchShader::CheckIfVerticesNeedManualFetchMtl(uint32* contextRegister) { for (sint32 g = 0; g < bufferGroups.size(); g++) @@ -376,7 +383,7 @@ LatteFetchShader* LatteShaderRecompiler_createFetchShader(LatteFetchShader::Cach // these only make sense when vertex shader does not call FS? LatteShader_calculateFSKey(newFetchShader); newFetchShader->CalculateFetchShaderVkHash(); -#if ENABLE_METAL +#ifdef ENABLE_METAL newFetchShader->CheckIfVerticesNeedManualFetchMtl(contextRegister); #endif return newFetchShader; @@ -438,7 +445,7 @@ LatteFetchShader* LatteShaderRecompiler_createFetchShader(LatteFetchShader::Cach } LatteShader_calculateFSKey(newFetchShader); newFetchShader->CalculateFetchShaderVkHash(); -#if ENABLE_METAL +#ifdef ENABLE_METAL newFetchShader->CheckIfVerticesNeedManualFetchMtl(contextRegister); #endif diff --git a/src/Cafe/HW/Latte/Core/FetchShader.h b/src/Cafe/HW/Latte/Core/FetchShader.h index 54cf6ada..db72987b 100644 --- a/src/Cafe/HW/Latte/Core/FetchShader.h +++ b/src/Cafe/HW/Latte/Core/FetchShader.h @@ -55,7 +55,7 @@ struct LatteFetchShader void CalculateFetchShaderVkHash(); -#if ENABLE_METAL +#ifdef ENABLE_METAL void CheckIfVerticesNeedManualFetchMtl(uint32* contextRegister); #endif diff --git a/src/Cafe/HW/Latte/Core/LatteBufferData.cpp b/src/Cafe/HW/Latte/Core/LatteBufferData.cpp index 7620e6a7..33d148bb 100644 --- a/src/Cafe/HW/Latte/Core/LatteBufferData.cpp +++ b/src/Cafe/HW/Latte/Core/LatteBufferData.cpp @@ -9,7 +9,9 @@ #include "Cafe/GameProfile/GameProfile.h" #include "Cafe/HW/Latte/Core/LatteBufferCache.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" +#endif template void rectGenerate4thVertex(uint32be* output, uint32be* input0, uint32be* input1, uint32be* input2) @@ -196,7 +198,7 @@ bool LatteBufferCache_Sync(uint32 minIndex, uint32 maxIndex, uint32 baseInstance fixedBufferSize += 128; -#if BOOST_OS_MACOS +#if BOOST_OS_MACOS && defined(ENABLE_VULKAN) if(bufferStride % 4 != 0) { if (g_renderer->GetType() == RendererAPI::Vulkan) diff --git a/src/Cafe/HW/Latte/Core/LatteDefaultShaders.cpp b/src/Cafe/HW/Latte/Core/LatteDefaultShaders.cpp deleted file mode 100644 index 7c590dbb..00000000 --- a/src/Cafe/HW/Latte/Core/LatteDefaultShaders.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "Cafe/HW/Latte/Core/Latte.h" -#include "Cafe/HW/Latte/Core/LatteDraw.h" -#include "Cafe/HW/Latte/Core/LatteShader.h" -#include "Cafe/HW/Latte/Core/LatteDefaultShaders.h" -#include "util/helpers/StringBuf.h" - -LatteDefaultShader_t* _copyShader_depthToColor; -LatteDefaultShader_t* _copyShader_colorToDepth; - -void LatteDefaultShader_pixelCopyShader_generateVSBody(StringBuf* vs) -{ - vs->add("#version 420\r\n"); - vs->add("out vec2 passUV;\r\n"); - vs->add("uniform vec4 uf_vertexOffsets[4];\r\n"); - vs->add("\r\n"); - vs->add("void main(){\r\n"); - vs->add("int vID = gl_VertexID;\r\n"); - vs->add("passUV = uf_vertexOffsets[vID].zw;\r\n"); - vs->add("gl_Position = vec4(uf_vertexOffsets[vID].xy, 0.0, 1.0);\r\n"); - vs->add("}\r\n"); -} - -GLuint gxShaderDepr_compileRaw(StringBuf* strSourceVS, StringBuf* strSourceFS); -GLuint gxShaderDepr_compileRaw(const std::string& vertex_source, const std::string& fragment_source); - -LatteDefaultShader_t* LatteDefaultShader_getPixelCopyShader_depthToColor() -{ - if (_copyShader_depthToColor != 0) - return _copyShader_depthToColor; - catchOpenGLError(); - LatteDefaultShader_t* defaultShader = (LatteDefaultShader_t*)malloc(sizeof(LatteDefaultShader_t)); - memset(defaultShader, 0, sizeof(LatteDefaultShader_t)); - - StringBuf fCStr_vertexShader(1024 * 16); - LatteDefaultShader_pixelCopyShader_generateVSBody(&fCStr_vertexShader); - - StringBuf fCStr_defaultFragShader(1024 * 16); - fCStr_defaultFragShader.add("#version 420\r\n"); - fCStr_defaultFragShader.add("in vec2 passUV;\r\n"); - fCStr_defaultFragShader.add("uniform sampler2D textureSrc;\r\n"); - fCStr_defaultFragShader.add("layout(location = 0) out vec4 colorOut0;\r\n"); - fCStr_defaultFragShader.add("\r\n"); - fCStr_defaultFragShader.add("void main(){\r\n"); - fCStr_defaultFragShader.add("colorOut0 = vec4(texture(textureSrc, passUV).r,0.0,0.0,1.0);\r\n"); - fCStr_defaultFragShader.add("}\r\n"); - - defaultShader->glProgamId = gxShaderDepr_compileRaw(&fCStr_vertexShader, &fCStr_defaultFragShader); - catchOpenGLError(); - - defaultShader->copyShaderUniforms.uniformLoc_textureSrc = glGetUniformLocation(defaultShader->glProgamId, "textureSrc"); - defaultShader->copyShaderUniforms.uniformLoc_vertexOffsets = glGetUniformLocation(defaultShader->glProgamId, "uf_vertexOffsets"); - - _copyShader_depthToColor = defaultShader; - catchOpenGLError(); - return defaultShader; -} - -LatteDefaultShader_t* LatteDefaultShader_getPixelCopyShader_colorToDepth() -{ - if (_copyShader_colorToDepth != 0) - return _copyShader_colorToDepth; - catchOpenGLError(); - LatteDefaultShader_t* defaultShader = (LatteDefaultShader_t*)malloc(sizeof(LatteDefaultShader_t)); - memset(defaultShader, 0, sizeof(LatteDefaultShader_t)); - - StringBuf fCStr_vertexShader(1024 * 16); - LatteDefaultShader_pixelCopyShader_generateVSBody(&fCStr_vertexShader); - - StringBuf fCStr_defaultFragShader(1024 * 16); - fCStr_defaultFragShader.add("#version 420\r\n"); - fCStr_defaultFragShader.add("in vec2 passUV;\r\n"); - fCStr_defaultFragShader.add("uniform sampler2D textureSrc;\r\n"); - fCStr_defaultFragShader.add("layout(location = 0) out vec4 colorOut0;\r\n"); - fCStr_defaultFragShader.add("\r\n"); - fCStr_defaultFragShader.add("void main(){\r\n"); - fCStr_defaultFragShader.add("gl_FragDepth = texture(textureSrc, passUV).r;\r\n"); - fCStr_defaultFragShader.add("}\r\n"); - - - defaultShader->glProgamId = gxShaderDepr_compileRaw(&fCStr_vertexShader, &fCStr_defaultFragShader); - defaultShader->copyShaderUniforms.uniformLoc_textureSrc = glGetUniformLocation(defaultShader->glProgamId, "textureSrc"); - defaultShader->copyShaderUniforms.uniformLoc_vertexOffsets = glGetUniformLocation(defaultShader->glProgamId, "uf_vertexOffsets"); - - _copyShader_colorToDepth = defaultShader; - catchOpenGLError(); - return defaultShader; -} \ No newline at end of file diff --git a/src/Cafe/HW/Latte/Core/LatteDefaultShaders.h b/src/Cafe/HW/Latte/Core/LatteDefaultShaders.h deleted file mode 100644 index 3776a3d2..00000000 --- a/src/Cafe/HW/Latte/Core/LatteDefaultShaders.h +++ /dev/null @@ -1,13 +0,0 @@ - -typedef struct -{ - GLuint glProgamId; - struct - { - GLuint uniformLoc_textureSrc; - GLuint uniformLoc_vertexOffsets; - }copyShaderUniforms; -}LatteDefaultShader_t; - -LatteDefaultShader_t* LatteDefaultShader_getPixelCopyShader_depthToColor(); -LatteDefaultShader_t* LatteDefaultShader_getPixelCopyShader_colorToDepth(); \ No newline at end of file diff --git a/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp b/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp index 1bdbc4bb..2edcf4ea 100644 --- a/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp +++ b/src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp @@ -10,6 +10,7 @@ #include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h" #include "Cafe/GraphicPack/GraphicPack2.h" +#include "HW/Latte/Renderer/RendererCore.h" #include "config/ActiveSettings.h" #include "WindowSystem.h" #include "Cafe/OS/libs/erreula/erreula.h" @@ -694,7 +695,9 @@ void LatteRenderTarget_itHLESwapScanBuffer() performanceMonitor.gpuTime_frameTime.beginMeasuring(); LatteTC_CleanupUnusedTextures(); +#ifdef ENABLE_OPENGL LatteDraw_cleanupAfterFrame(); +#endif LatteQuery_CancelActiveGPU7Queries(); LatteBufferCache_notifySwapTVScanBuffer(); LattePerformanceMonitor_frameBegin(); diff --git a/src/Cafe/HW/Latte/Core/LatteRingBuffer.h b/src/Cafe/HW/Latte/Core/LatteRingBuffer.h index ce28c483..325836cc 100644 --- a/src/Cafe/HW/Latte/Core/LatteRingBuffer.h +++ b/src/Cafe/HW/Latte/Core/LatteRingBuffer.h @@ -1,3 +1,4 @@ +#pragma once typedef struct { diff --git a/src/Cafe/HW/Latte/Core/LatteShader.cpp b/src/Cafe/HW/Latte/Core/LatteShader.cpp index 91de6310..c2730821 100644 --- a/src/Cafe/HW/Latte/Core/LatteShader.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShader.cpp @@ -6,7 +6,9 @@ #include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h" #include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" +#endif #include "Cafe/OS/libs/gx2/GX2.h" // todo - remove dependency #include "Cafe/GraphicPack/GraphicPack2.h" #include "HW/Latte/Core/Latte.h" @@ -15,7 +17,7 @@ #include "config/ActiveSettings.h" #include "Cafe/GameProfile/GameProfile.h" #include "util/containers/flat_hash_map.hpp" -#if ENABLE_METAL +#ifdef ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" #endif #include @@ -376,7 +378,9 @@ void LatteShader_FinishCompilation(LatteDecompilerShader* shader) } shader->shader->WaitForCompiled(); +#ifdef ENABLE_OPENGL LatteShader_prepareSeparableUniforms(shader); +#endif LatteShader_CleanupAfterCompile(shader); } @@ -525,7 +529,7 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize, if (LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_DX_CLIP_SPACE_DEF()) vsHash += 0x1537; -#if ENABLE_METAL +#ifdef ENABLE_METAL if (g_renderer->GetType() == RendererAPI::Metal) { bool isRectVertexShader = (primitiveType == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS); @@ -550,7 +554,7 @@ void LatteSHRC_UpdateVSBaseHash(uint8* vertexShaderPtr, uint32 vertexShaderSize, vsHash += 51ULL; // Vertex fetch - if (_activeFetchShader->mtlFetchVertexManually) + if (_activeFetchShader->mtlFetchVertexManually) vsHash += 349ULL; } } @@ -650,7 +654,7 @@ uint64 LatteSHRC_CalcPSAuxHash(LatteDecompilerShader* pixelShader, uint32* conte auxHash += (uint64)dim; } -#if ENABLE_METAL +#ifdef ENABLE_METAL if (g_renderer->GetType() == RendererAPI::Metal) { // Textures as render targets @@ -683,20 +687,69 @@ uint64 LatteSHRC_CalcPSAuxHash(LatteDecompilerShader* pixelShader, uint32* conte return auxHash; } +void InitUniformLayoutFromDecompiler( + LatteDecompilerShader* shader, + const LatteDecompilerOutput_t& decompilerOutput +) +{ + const auto& offsets = decompilerOutput.uniformOffsetsVK; + + shader->uniform.loc_remapped = offsets.offset_remapped; + shader->uniform.loc_uniformRegister = offsets.offset_uniformRegister; + shader->uniform.count_uniformRegister = offsets.count_uniformRegister; + shader->uniform.loc_windowSpaceToClipSpaceTransform = offsets.offset_windowSpaceToClipSpaceTransform; + shader->uniform.loc_alphaTestRef = offsets.offset_alphaTestRef; + shader->uniform.loc_pointSize = offsets.offset_pointSize; + shader->uniform.loc_fragCoordScale = offsets.offset_fragCoordScale; + + // Texture scale uniforms + shader->uniform.list_ufTexRescale.clear(); + for (sint32 t = 0; t < LATTE_NUM_MAX_TEX_UNITS; t++) + { + if (offsets.offset_texScale[t] >= 0) + { + LatteUniformTextureScaleEntry_t entry{}; + entry.texUnit = t; + entry.uniformLocation = offsets.offset_texScale[t]; + shader->uniform.list_ufTexRescale.push_back(entry); + } + } + + shader->uniform.loc_verticesPerInstance = offsets.offset_verticesPerInstance; + + // Streamout buffers + for (sint32 t = 0; t < LATTE_NUM_STREAMOUT_BUFFER; t++) + { + shader->uniform.loc_streamoutBufferBase[t] = offsets.offset_streamoutBufferBase[t]; + } + + shader->uniform.uniformRangeSize = offsets.offset_endOfBlock; +} + LatteDecompilerShader* LatteShader_CreateShaderFromDecompilerOutput(LatteDecompilerOutput_t& decompilerOutput, uint64 baseHash, bool calculateAuxHash, uint64 optionalAuxHash, uint32* contextRegister) { LatteDecompilerShader* shader = decompilerOutput.shader; shader->baseHash = baseHash; // copy resource mapping // HACK - if (g_renderer->GetType() == RendererAPI::OpenGL) + switch (g_renderer->GetType()) + { +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: shader->resourceMapping = decompilerOutput.resourceMappingGL; - else if (g_renderer->GetType() == RendererAPI::Vulkan) - shader->resourceMapping = decompilerOutput.resourceMappingVK; -#if ENABLE_METAL - else - shader->resourceMapping = decompilerOutput.resourceMappingMTL; + break; #endif +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: + shader->resourceMapping = decompilerOutput.resourceMappingVK; + break; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + shader->resourceMapping = decompilerOutput.resourceMappingMTL; + break; +#endif + } // copy texture info shader->textureUnitMask2 = decompilerOutput.textureUnitMask; // copy streamout info @@ -705,33 +758,23 @@ LatteDecompilerShader* LatteShader_CreateShaderFromDecompilerOutput(LatteDecompi // copy uniform offsets // for OpenGL these are retrieved in _prepareSeparableUniforms() // HACK - if (g_renderer->GetType() == RendererAPI::Vulkan || g_renderer->GetType() == RendererAPI::Metal) - { - shader->uniform.loc_remapped = decompilerOutput.uniformOffsetsVK.offset_remapped; - shader->uniform.loc_uniformRegister = decompilerOutput.uniformOffsetsVK.offset_uniformRegister; - shader->uniform.count_uniformRegister = decompilerOutput.uniformOffsetsVK.count_uniformRegister; - shader->uniform.loc_windowSpaceToClipSpaceTransform = decompilerOutput.uniformOffsetsVK.offset_windowSpaceToClipSpaceTransform; - shader->uniform.loc_alphaTestRef = decompilerOutput.uniformOffsetsVK.offset_alphaTestRef; - shader->uniform.loc_pointSize = decompilerOutput.uniformOffsetsVK.offset_pointSize; - shader->uniform.loc_fragCoordScale = decompilerOutput.uniformOffsetsVK.offset_fragCoordScale; - for (sint32 t = 0; t < LATTE_NUM_MAX_TEX_UNITS; t++) - { - if (decompilerOutput.uniformOffsetsVK.offset_texScale[t] >= 0) - { - LatteUniformTextureScaleEntry_t entry = { 0 }; - entry.texUnit = t; - entry.uniformLocation = decompilerOutput.uniformOffsetsVK.offset_texScale[t]; - shader->uniform.list_ufTexRescale.push_back(entry); - } - } - shader->uniform.loc_verticesPerInstance = decompilerOutput.uniformOffsetsVK.offset_verticesPerInstance; - for (sint32 t = 0; t < LATTE_NUM_STREAMOUT_BUFFER; t++) - shader->uniform.loc_streamoutBufferBase[t] = decompilerOutput.uniformOffsetsVK.offset_streamoutBufferBase[t]; - shader->uniform.uniformRangeSize = decompilerOutput.uniformOffsetsVK.offset_endOfBlock; - } - else + switch (g_renderer->GetType()) { +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: shader->uniform.count_uniformRegister = decompilerOutput.uniformOffsetsGL.count_uniformRegister; + break; +#endif +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: + InitUniformLayoutFromDecompiler(shader, decompilerOutput); + break; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + InitUniformLayoutFromDecompiler(shader, decompilerOutput); + break; +#endif } // calculate aux hash if (calculateAuxHash) @@ -766,10 +809,12 @@ void LatteShader_GetDecompilerOptions(LatteDecompilerOptions& options, LatteCons options.usesGeometryShader = geometryShaderEnabled; options.spirvInstrinsics.hasRoundingModeRTEFloat32 = false; options.useTFViaSSBO = g_renderer->UseTFViaSSBO(); +#ifdef ENABLE_VULKAN if (g_renderer->GetType() == RendererAPI::Vulkan) { options.spirvInstrinsics.hasRoundingModeRTEFloat32 = VulkanRenderer::GetInstance()->HasSPRIVRoundingModeRTE32(); } +#endif options.strictMul = g_current_game_profile->GetAccurateShaderMul() != AccurateShaderMulOption::False; } @@ -845,12 +890,14 @@ LatteDecompilerShader* LatteShader_CompileSeparableVertexShader(uint64 baseHash, LatteShader_CreateRendererShader(vertexShader, false); performanceMonitor.numCompiledVS++; +#ifdef ENABLE_OPENGL if (g_renderer->GetType() == RendererAPI::OpenGL) { if (vertexShader->shader) vertexShader->shader->PreponeCompilation(true); LatteShader_FinishCompilation(vertexShader); } +#endif LatteSHRC_RegisterShader(vertexShader, vertexShader->baseHash, vertexShader->auxHash); return vertexShader; @@ -874,12 +921,14 @@ LatteDecompilerShader* LatteShader_CompileSeparableGeometryShader(uint64 baseHas LatteShader_CreateRendererShader(geometryShader, false); performanceMonitor.numCompiledGS++; +#ifdef ENABLE_OPENGL if (g_renderer->GetType() == RendererAPI::OpenGL) { if (geometryShader->shader) geometryShader->shader->PreponeCompilation(true); LatteShader_FinishCompilation(geometryShader); } +#endif LatteSHRC_RegisterShader(geometryShader, geometryShader->baseHash, geometryShader->auxHash); return geometryShader; @@ -903,12 +952,14 @@ LatteDecompilerShader* LatteShader_CompileSeparablePixelShader(uint64 baseHash, LatteShaderCache_writeSeparablePixelShader(_shaderBaseHash_ps, psAuxHash, pixelShaderPtr, pixelShaderSize, LatteGPUState.contextRegister, usesGeometryShader); } +#ifdef ENABLE_OPENGL if (g_renderer->GetType() == RendererAPI::OpenGL) { if (pixelShader->shader) pixelShader->shader->PreponeCompilation(true); LatteShader_FinishCompilation(pixelShader); } +#endif LatteSHRC_RegisterShader(pixelShader, _shaderBaseHash_ps, psAuxHash); return pixelShader; diff --git a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp index 14a1f9b0..a1b0e777 100644 --- a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp @@ -9,13 +9,17 @@ #include "WindowSystem.h" #include "Cafe/HW/Latte/Renderer/Renderer.h" +#ifdef ENABLE_OPENGL #include "Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h" +#endif +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.h" -#if ENABLE_METAL +#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.h" +#endif +#ifdef ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h" #include "Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h" #endif -#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineStableCache.h" #include #include "imgui/imgui_extension.h" @@ -273,14 +277,24 @@ static BootSoundPlayer g_bootSndPlayer; void LatteShaderCache_finish() { - if (g_renderer->GetType() == RendererAPI::Vulkan) + switch (g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: RendererShaderVk::ShaderCacheLoading_end(); - else if (g_renderer->GetType() == RendererAPI::OpenGL) - RendererShaderGL::ShaderCacheLoading_end(); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) - RendererShaderMtl::ShaderCacheLoading_end(); + return; #endif +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: + RendererShaderGL::ShaderCacheLoading_end(); + return; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + RendererShaderMtl::ShaderCacheLoading_end(); + return; +#endif + } } uint32 LatteShaderCache_getShaderCacheExtraVersion(uint64 titleId) @@ -359,21 +373,38 @@ void LatteShaderCache_Load() fs::create_directories(ActiveSettings::GetCachePath("shaderCache/transferable"), ec); fs::create_directories(ActiveSettings::GetCachePath("shaderCache/precompiled"), ec); // initialize renderer specific caches - if (g_renderer->GetType() == RendererAPI::Vulkan) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: RendererShaderVk::ShaderCacheLoading_begin(cacheTitleId); - else if (g_renderer->GetType() == RendererAPI::OpenGL) - RendererShaderGL::ShaderCacheLoading_begin(cacheTitleId); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) - RendererShaderMtl::ShaderCacheLoading_begin(cacheTitleId); + break; #endif +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: + RendererShaderGL::ShaderCacheLoading_begin(cacheTitleId); + break; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + RendererShaderMtl::ShaderCacheLoading_begin(cacheTitleId); + break; +#endif + } // get cache file name fs::path pathGeneric; - if (g_renderer->GetType() == RendererAPI::Metal) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_METAL + case RendererAPI::Metal: pathGeneric = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}_mtlshaders.bin", cacheTitleId); - else + break; +#endif + default: pathGeneric = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}_shaders.bin", cacheTitleId); + break; + } // calculate extraVersion for transferable and precompiled shader cache uint32 transferableExtraVersion = SHADER_CACHE_GENERIC_EXTRA_VERSION; @@ -471,8 +502,10 @@ void LatteShaderCache_Load() #endif LatteShaderCache_finish(); // if Vulkan or Metal then also load pipeline cache +#if defined(ENABLE_VULKAN) || defined(ENABLE_METAL) if (g_renderer->GetType() == RendererAPI::Vulkan || g_renderer->GetType() == RendererAPI::Metal) LatteShaderCache_LoadPipelineCache(cacheTitleId); +#endif g_renderer->BeginFrame(true); @@ -634,31 +667,52 @@ void LatteShaderCache_ShowProgress(const std::function & loadUpdateF void LatteShaderCache_LoadPipelineCache(uint64 cacheTitleId) { - if (g_renderer->GetType() == RendererAPI::Vulkan) + switch(g_renderer->GetType()) + { + #ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: g_shaderCacheLoaderState.pipelineFileCount = VulkanPipelineStableCache::GetInstance().BeginLoading(cacheTitleId); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) + break; + #endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: g_shaderCacheLoaderState.pipelineFileCount = MetalPipelineCache::GetInstance().BeginLoading(cacheTitleId); + break; #endif + } + g_shaderCacheLoaderState.loadedPipelines = 0; LatteShaderCache_ShowProgress(LatteShaderCache_updatePipelineLoadingProgress, true); - if (g_renderer->GetType() == RendererAPI::Vulkan) + + switch(g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: VulkanPipelineStableCache::GetInstance().EndLoading(); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) - MetalPipelineCache::GetInstance().EndLoading(); + break; #endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + MetalPipelineCache::GetInstance().EndLoading(); + break; +#endif + } } bool LatteShaderCache_updatePipelineLoadingProgress() { uint32 pipelinesMissingShaders = 0; - if (g_renderer->GetType() == RendererAPI::Vulkan) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: return VulkanPipelineStableCache::GetInstance().UpdateLoading(g_shaderCacheLoaderState.loadedPipelines, pipelinesMissingShaders); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: return MetalPipelineCache::GetInstance().UpdateLoading(g_shaderCacheLoaderState.loadedPipelines, pipelinesMissingShaders); #endif + } return false; } @@ -918,20 +972,37 @@ void LatteShaderCache_Close() delete s_shaderCacheGeneric; s_shaderCacheGeneric = nullptr; } - if (g_renderer->GetType() == RendererAPI::Vulkan) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: RendererShaderVk::ShaderCacheLoading_Close(); - else if (g_renderer->GetType() == RendererAPI::OpenGL) - RendererShaderGL::ShaderCacheLoading_Close(); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) - RendererShaderMtl::ShaderCacheLoading_Close(); + break; #endif +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: + RendererShaderGL::ShaderCacheLoading_Close(); + break; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + RendererShaderMtl::ShaderCacheLoading_Close(); + break; +#endif + } // if Vulkan or Metal then also close pipeline cache - if (g_renderer->GetType() == RendererAPI::Vulkan) - VulkanPipelineStableCache::GetInstance().Close(); -#if ENABLE_METAL - else if (g_renderer->GetType() == RendererAPI::Metal) - MetalPipelineCache::GetInstance().Close(); + switch(g_renderer->GetType()) + { +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: + VulkanPipelineStableCache::GetInstance().Close(); + break; #endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + MetalPipelineCache::GetInstance().Close(); + break; +#endif + } } diff --git a/src/Cafe/HW/Latte/Core/LatteSurfaceCopy.cpp b/src/Cafe/HW/Latte/Core/LatteSurfaceCopy.cpp index 45be6843..5e61e8df 100644 --- a/src/Cafe/HW/Latte/Core/LatteSurfaceCopy.cpp +++ b/src/Cafe/HW/Latte/Core/LatteSurfaceCopy.cpp @@ -1,7 +1,6 @@ #include "Cafe/HW/Latte/Core/Latte.h" #include "Cafe/HW/Latte/Core/LatteDraw.h" #include "Cafe/HW/Latte/Core/LatteShader.h" -#include "Cafe/HW/Latte/Core/LatteDefaultShaders.h" #include "Cafe/HW/Latte/Core/LatteTexture.h" #include "Cafe/HW/Latte/Renderer/Renderer.h" diff --git a/src/Cafe/HW/Latte/Core/LatteTexture.cpp b/src/Cafe/HW/Latte/Core/LatteTexture.cpp index 4445fb26..82dd1fbf 100644 --- a/src/Cafe/HW/Latte/Core/LatteTexture.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTexture.cpp @@ -567,6 +567,8 @@ bool __LatteTexture_IsBlockedFormatRelation(LatteTexture* texture1, LatteTexture if (texture1->format == Latte::E_GX2SURFFMT::D32_FLOAT && Latte::GetHWFormat(texture2->format) == Latte::E_HWSURFFMT::HWFMT_8_8_8_8) return true; } + +#ifdef ENABLE_VULKAN // Vulkan has stricter rules if (g_renderer->GetType() == RendererAPI::Vulkan) { @@ -574,6 +576,7 @@ bool __LatteTexture_IsBlockedFormatRelation(LatteTexture* texture1, LatteTexture if (texture1->format == Latte::E_GX2SURFFMT::D32_FLOAT && Latte::GetHWFormat(texture2->format) == Latte::E_HWSURFFMT::HWFMT_8_24) return true; } +#endif return false; } diff --git a/src/Cafe/HW/Latte/Core/LatteTextureLegacy.cpp b/src/Cafe/HW/Latte/Core/LatteTextureLegacy.cpp index 4c11e57c..7b8a0b7b 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureLegacy.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTextureLegacy.cpp @@ -4,9 +4,11 @@ #include "Cafe/HW/Latte/Renderer/Renderer.h" +#ifdef ENABLE_OPENGL #include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h" #include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureGL.h" #include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h" +#endif struct TexScaleXY { @@ -192,6 +194,7 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u LatteGPUState.repeatTextureInitialization = true; } +#ifdef ENABLE_OPENGL if (g_renderer->GetType() == RendererAPI::OpenGL) { // on OpenGL, texture views and sampler parameters are tied together (we are avoiding sampler objects due to driver bugs) @@ -214,6 +217,8 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u textureView->lastTextureBindIndex = LatteGPUState.textureBindCounter; rendererGL->renderstate_updateTextureSettingsGL(shaderContext, textureView, textureIndex + glBackendBaseTexUnit, word4, textureIndex, isDepthSampler); } +#endif + g_renderer->texture_setLatteTexture(textureView, textureIndex + glBackendBaseTexUnit); // update if data changed bool swizzleChanged = false; diff --git a/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp b/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp index 8df5dcea..b0a6bdf5 100644 --- a/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTextureReadback.cpp @@ -6,7 +6,9 @@ #include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Cafe/HW/Latte/Core/LatteTexture.h" +#ifdef ENABLE_OPENGL #include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h" +#endif #define LOG_READBACK_TIME diff --git a/src/Cafe/HW/Latte/Core/LatteTiming.cpp b/src/Cafe/HW/Latte/Core/LatteTiming.cpp index 115b60d9..60f4c52d 100644 --- a/src/Cafe/HW/Latte/Core/LatteTiming.cpp +++ b/src/Cafe/HW/Latte/Core/LatteTiming.cpp @@ -1,6 +1,8 @@ #include "Cafe/HW/Latte/Core/Latte.h" #include "Cafe/OS/libs/gx2/GX2_Event.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.h" +#endif #include "util/highresolutiontimer/HighResolutionTimer.h" #include "config/CemuConfig.h" #include "Cafe/CafeSystem.h" @@ -55,8 +57,10 @@ void LatteTiming_EnableHostDrivenVSync() { if (s_usingHostDrivenVSync) return; + #ifdef ENABLE_VULKAN VsyncDriver_startThread(LatteTiming_NotifyHostVSync); s_usingHostDrivenVSync = true; + #endif } bool LatteTiming_IsUsingHostDrivenVSync() diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.cpp index 13188743..6b358150 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.cpp @@ -10,7 +10,9 @@ #include "Cafe/HW/Latte/Core/FetchShader.h" #include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h" #include "Cafe/HW/Latte/Renderer/Renderer.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" +#endif #include "util/helpers/helpers.h" // parse instruction and if valid append it to instructionList @@ -1069,12 +1071,24 @@ void _LatteDecompiler_Process(LatteDecompilerShaderContext* shaderContext, uint8 // emit code if (shaderContext->shader->hasError == false) { - if (g_renderer->GetType() == RendererAPI::OpenGL || g_renderer->GetType() == RendererAPI::Vulkan) - LatteDecompiler_emitGLSLShader(shaderContext, shaderContext->shader); -#if ENABLE_METAL - else - LatteDecompiler_emitMSLShader(shaderContext, shaderContext->shader); + switch(g_renderer->GetType()) + { +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: + LatteDecompiler_emitGLSLShader(shaderContext, shaderContext->shader); + break; #endif +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: + LatteDecompiler_emitGLSLShader(shaderContext, shaderContext->shader); + break; +#endif +#ifdef ENABLE_METAL + case RendererAPI::Metal: + LatteDecompiler_emitMSLShader(shaderContext, shaderContext->shader); + break; +#endif + } } LatteDecompiler_cleanup(shaderContext); // fast access diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp index 18cba4b4..e8d5d490 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerAnalyzer.cpp @@ -10,7 +10,7 @@ #include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Common/MemPtr.h" #include "HW/Latte/ISA/LatteReg.h" -#if ENABLE_METAL +#ifdef ENABLE_METAL #include "HW/Latte/Renderer/Metal/MetalCommon.h" #endif @@ -403,11 +403,9 @@ void LatteDecompiler_analyzeExport(LatteDecompilerShaderContext* shaderContext, } else if (cfInstruction->exportType == 0 && cfInstruction->exportArrayBase == 61) { -#if ENABLE_METAL // Only check for depth buffer mask on Metal, as its not in the PS hash on other backends if (g_renderer->GetType() != RendererAPI::Metal || LatteMRT::GetActiveDepthBufferMask(*shaderContext->contextRegistersNew)) shader->depthMask = true; -#endif } else debugBreakpoint(); @@ -512,7 +510,7 @@ namespace LatteDecompiler } } -#if ENABLE_METAL +#ifdef ENABLE_METAL void _initTextureBindingPointsMTL(LatteDecompilerShaderContext* decompilerContext) { // for Vulkan we use consecutive indices @@ -563,7 +561,7 @@ namespace LatteDecompiler { decompilerContext->hasUniformVarBlock = true; // uf_verticesPerInstance and uf_streamoutBufferBase* } -#if ENABLE_METAL +#ifdef ENABLE_METAL if (g_renderer->GetType() == RendererAPI::Metal) { bool usesGeometryShader = UseGeometryShader(*decompilerContext->contextRegistersNew, decompilerContext->options->usesGeometryShader); @@ -1113,7 +1111,7 @@ void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteD shaderContext->output->resourceMappingVK.setIndex = 2; LatteDecompiler::_initTextureBindingPointsGL(shaderContext); LatteDecompiler::_initTextureBindingPointsVK(shaderContext); -#if ENABLE_METAL +#ifdef ENABLE_METAL LatteDecompiler::_initTextureBindingPointsMTL(shaderContext); #endif LatteDecompiler::_initUniformBindingPoints(shaderContext); diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h index 4c6b158a..0b19bcae 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerInternal.h @@ -266,7 +266,7 @@ struct LatteDecompilerShaderContext void LatteDecompiler_analyze(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); void LatteDecompiler_analyzeDataTypes(LatteDecompilerShaderContext* shaderContext); void LatteDecompiler_emitGLSLShader(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); -#if ENABLE_METAL +#ifdef ENABLE_METAL void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, LatteDecompilerShader* shader); #endif diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 7ceaf74d..8c2da361 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -33,7 +33,7 @@ extern bool hasValidFramebufferAttached; float supportBufferData[512 * 4]; -// Defined in the OpenGL renderer +// Defined in the Common renderer void LatteDraw_handleSpecialState8_clearAsDepth(); std::vector MetalRenderer::GetDevices() diff --git a/src/Cafe/HW/Latte/Core/LatteShaderGL.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/LatteShaderGL.cpp similarity index 100% rename from src/Cafe/HW/Latte/Core/LatteShaderGL.cpp rename to src/Cafe/HW/Latte/Renderer/OpenGL/LatteShaderGL.cpp diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp index 571961f4..c9437353 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRendererCore.cpp @@ -17,6 +17,7 @@ #include "Cafe/OS/libs/gx2/GX2.h" #include "Cafe/GameProfile/GameProfile.h" +#include "HW/Latte/Renderer/RendererCore.h" #include "config/ActiveSettings.h" @@ -52,7 +53,7 @@ struct uint32 maxIndex; uint32 minIndex; uint8* indexData; - // buffer + // buffer GLuint glIndexCacheBuffer; VirtualBufferHeap_t* indexBufferVirtualHeap; uint8* mappedIndexBuffer; @@ -371,6 +372,8 @@ void _decodeAndUploadIndexData(indexDataCacheEntry2_t* cacheEntry) void LatteDraw_cleanupAfterFrame() { + if (g_renderer->GetType() != RendererAPI::OpenGL) + return; // drop everything from cache that is older than 30 frames uint32 frameCounter = LatteGPUState.frameCounter; while (indexDataCacheFirst) @@ -524,70 +527,6 @@ void LatteDrawGL_prepareIndicesWithGPUCache(MPTR indexDataMPTR, _INDEX_TYPE inde indexState.indexData = (uint8*)(size_t)cacheEntry->heapEntry->startOffset; } -void LatteDraw_handleSpecialState8_clearAsDepth() -{ - if (LatteGPUState.contextNew.GetSpecialStateValues()[0] == 0) - cemuLog_logDebug(LogType::Force, "Special state 8 requires special state 0 but it is not set?"); - // get depth buffer information - uint32 regDepthBuffer = LatteGPUState.contextRegister[mmDB_HTILE_DATA_BASE]; - uint32 regDepthSize = LatteGPUState.contextRegister[mmDB_DEPTH_SIZE]; - uint32 regDepthBufferInfo = LatteGPUState.contextRegister[mmDB_DEPTH_INFO]; - // get format and tileMode from info reg - uint32 depthBufferTileMode = (regDepthBufferInfo >> 15) & 0xF; - - MPTR depthBufferPhysMem = regDepthBuffer << 8; - uint32 depthBufferPitch = (((regDepthSize >> 0) & 0x3FF) + 1); - uint32 depthBufferHeight = ((((regDepthSize >> 10) & 0xFFFFF) + 1) / depthBufferPitch); - depthBufferPitch <<= 3; - depthBufferHeight <<= 3; - uint32 depthBufferWidth = depthBufferPitch; - - sint32 sliceIndex = 0; // todo - sint32 mipIndex = 0; - - // clear all color buffers that match the format of the depth buffer - sint32 searchIndex = 0; - bool targetFound = false; - while (true) - { - LatteTextureView* view = LatteTC_LookupTextureByData(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, 1, sliceIndex, 1, &searchIndex); - if (!view) - { - // should we clear in RAM instead? - break; - } - sint32 effectiveClearWidth = view->baseTexture->width; - sint32 effectiveClearHeight = view->baseTexture->height; - LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0); - - // hacky way to get clear color - float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST - - uint8 clearColor[4] = { 0 }; - clearColor[0] = (uint8)(regClearColor[0] * 255.0f); - clearColor[1] = (uint8)(regClearColor[1] * 255.0f); - clearColor[2] = (uint8)(regClearColor[2] * 255.0f); - clearColor[3] = (uint8)(regClearColor[3] * 255.0f); - - // todo - use fragment shader software emulation (evoke for one pixel) to determine clear color - // todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight - - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - //cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer - if (glClearTexSubImage) - glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); - } - else - { - if (view->baseTexture->isDepth) - g_renderer->texture_clearDepthSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, true, view->baseTexture->hasStencil, 0.0f, 0); - else - g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]); - } - } -} - void LatteDrawGL_doDraw(_INDEX_TYPE indexType, uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count) { if (indexType == _INDEX_TYPE::U16_BE) @@ -755,10 +694,6 @@ void OpenGLRenderer::_setupVertexAttributes() } } -void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx); -void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, const char* variant); -void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister); - std::map g_mapGLRectEmulationGS; RendererShaderGL* rectsEmulationGS_generateShaderGL(LatteDecompilerShader* vertexShader) diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp index d578b842..de1e1222 100644 --- a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.cpp @@ -1,6 +1,7 @@ #include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h" #include "Cafe/HW/Latte/Renderer/OpenGL/RendererShaderGL.h" #include "Cafe/HW/Latte/Renderer/OpenGL/CachedFBOGL.h" +#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.h" #include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureGL.h" #include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h" @@ -8,7 +9,7 @@ #include "Cafe/HW/Latte/Core/LatteShader.h" #include "Cafe/HW/Latte/Core/LatteDraw.h" -#include "Cafe/HW/Latte/Core/LatteDefaultShaders.h" +#include "util/helpers/StringBuf.h" void LatteDraw_resetAttributePointerCache(); @@ -66,9 +67,9 @@ void OpenGLRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* s if (destinationTexture->isDepth) renderstate_setAlwaysWriteDepth(); // bind format specific copy shader - LatteDefaultShader_t* copyShader = LatteDefaultShader_getPixelCopyShader_depthToColor(); + LatteGLDefaultShader_t* copyShader = LatteGLDefaultShader_getPixelCopyShader_depthToColor(); if (destinationTexture->isDepth) - copyShader = LatteDefaultShader_getPixelCopyShader_colorToDepth(); + copyShader = LatteGLDefaultShader_getPixelCopyShader_colorToDepth(); glUseProgram(copyShader->glProgamId); catchOpenGLError(); // setup uniforms @@ -113,4 +114,86 @@ void OpenGLRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* s LatteGPUState.repeatTextureInitialization = true; glUseProgram(0); +} + +LatteGLDefaultShader_t* _copyShader_depthToColor; +LatteGLDefaultShader_t* _copyShader_colorToDepth; + +void LatteGLDefaultShader_pixelCopyShader_generateVSBody(StringBuf* vs) +{ + vs->add("#version 420\r\n"); + vs->add("out vec2 passUV;\r\n"); + vs->add("uniform vec4 uf_vertexOffsets[4];\r\n"); + vs->add("\r\n"); + vs->add("void main(){\r\n"); + vs->add("int vID = gl_VertexID;\r\n"); + vs->add("passUV = uf_vertexOffsets[vID].zw;\r\n"); + vs->add("gl_Position = vec4(uf_vertexOffsets[vID].xy, 0.0, 1.0);\r\n"); + vs->add("}\r\n"); +} + +GLuint gxShaderDepr_compileRaw(StringBuf* strSourceVS, StringBuf* strSourceFS); +GLuint gxShaderDepr_compileRaw(const std::string& vertex_source, const std::string& fragment_source); + +LatteGLDefaultShader_t* LatteGLDefaultShader_getPixelCopyShader_depthToColor() +{ + if (_copyShader_depthToColor != 0) + return _copyShader_depthToColor; + catchOpenGLError(); + LatteGLDefaultShader_t* defaultShader = (LatteGLDefaultShader_t*)malloc(sizeof(LatteGLDefaultShader_t)); + memset(defaultShader, 0, sizeof(LatteGLDefaultShader_t)); + + StringBuf fCStr_vertexShader(1024 * 16); + LatteGLDefaultShader_pixelCopyShader_generateVSBody(&fCStr_vertexShader); + + StringBuf fCStr_defaultFragShader(1024 * 16); + fCStr_defaultFragShader.add("#version 420\r\n"); + fCStr_defaultFragShader.add("in vec2 passUV;\r\n"); + fCStr_defaultFragShader.add("uniform sampler2D textureSrc;\r\n"); + fCStr_defaultFragShader.add("layout(location = 0) out vec4 colorOut0;\r\n"); + fCStr_defaultFragShader.add("\r\n"); + fCStr_defaultFragShader.add("void main(){\r\n"); + fCStr_defaultFragShader.add("colorOut0 = vec4(texture(textureSrc, passUV).r,0.0,0.0,1.0);\r\n"); + fCStr_defaultFragShader.add("}\r\n"); + + defaultShader->glProgamId = gxShaderDepr_compileRaw(&fCStr_vertexShader, &fCStr_defaultFragShader); + catchOpenGLError(); + + defaultShader->copyShaderUniforms.uniformLoc_textureSrc = glGetUniformLocation(defaultShader->glProgamId, "textureSrc"); + defaultShader->copyShaderUniforms.uniformLoc_vertexOffsets = glGetUniformLocation(defaultShader->glProgamId, "uf_vertexOffsets"); + + _copyShader_depthToColor = defaultShader; + catchOpenGLError(); + return defaultShader; +} + +LatteGLDefaultShader_t* LatteGLDefaultShader_getPixelCopyShader_colorToDepth() +{ + if (_copyShader_colorToDepth != 0) + return _copyShader_colorToDepth; + catchOpenGLError(); + LatteGLDefaultShader_t* defaultShader = (LatteGLDefaultShader_t*)malloc(sizeof(LatteGLDefaultShader_t)); + memset(defaultShader, 0, sizeof(LatteGLDefaultShader_t)); + + StringBuf fCStr_vertexShader(1024 * 16); + LatteGLDefaultShader_pixelCopyShader_generateVSBody(&fCStr_vertexShader); + + StringBuf fCStr_defaultFragShader(1024 * 16); + fCStr_defaultFragShader.add("#version 420\r\n"); + fCStr_defaultFragShader.add("in vec2 passUV;\r\n"); + fCStr_defaultFragShader.add("uniform sampler2D textureSrc;\r\n"); + fCStr_defaultFragShader.add("layout(location = 0) out vec4 colorOut0;\r\n"); + fCStr_defaultFragShader.add("\r\n"); + fCStr_defaultFragShader.add("void main(){\r\n"); + fCStr_defaultFragShader.add("gl_FragDepth = texture(textureSrc, passUV).r;\r\n"); + fCStr_defaultFragShader.add("}\r\n"); + + + defaultShader->glProgamId = gxShaderDepr_compileRaw(&fCStr_vertexShader, &fCStr_defaultFragShader); + defaultShader->copyShaderUniforms.uniformLoc_textureSrc = glGetUniformLocation(defaultShader->glProgamId, "textureSrc"); + defaultShader->copyShaderUniforms.uniformLoc_vertexOffsets = glGetUniformLocation(defaultShader->glProgamId, "uf_vertexOffsets"); + + _copyShader_colorToDepth = defaultShader; + catchOpenGLError(); + return defaultShader; } \ No newline at end of file diff --git a/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.h b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.h new file mode 100644 index 00000000..3c6e4c25 --- /dev/null +++ b/src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLSurfaceCopy.h @@ -0,0 +1,14 @@ +#pragma once + +typedef struct +{ + GLuint glProgamId; + struct + { + GLuint uniformLoc_textureSrc; + GLuint uniformLoc_vertexOffsets; + }copyShaderUniforms; +}LatteGLDefaultShader_t; + +LatteGLDefaultShader_t* LatteGLDefaultShader_getPixelCopyShader_depthToColor(); +LatteGLDefaultShader_t* LatteGLDefaultShader_getPixelCopyShader_colorToDepth(); \ No newline at end of file diff --git a/src/Cafe/HW/Latte/Renderer/RendererCore.cpp b/src/Cafe/HW/Latte/Renderer/RendererCore.cpp new file mode 100644 index 00000000..96d7b7c2 --- /dev/null +++ b/src/Cafe/HW/Latte/Renderer/RendererCore.cpp @@ -0,0 +1,132 @@ +#include "RendererCore.h" +#include "Cafe/HW/Latte/Renderer/Renderer.h" +#include "Cafe/HW/Latte/ISA/RegDefines.h" +#include "HW/Latte/Core/LatteShader.h" +#include "config/CemuConfig.h" + +#ifdef ENABLE_OPENGL +#include "Common/GLInclude/GLInclude.h" +#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h" +#endif + +void LatteDraw_handleSpecialState8_clearAsDepth() +{ + if (LatteGPUState.contextNew.GetSpecialStateValues()[0] == 0) + cemuLog_logDebug(LogType::Force, "Special state 8 requires special state 0 but it is not set?"); + // get depth buffer information + uint32 regDepthBuffer = LatteGPUState.contextRegister[mmDB_HTILE_DATA_BASE]; + uint32 regDepthSize = LatteGPUState.contextRegister[mmDB_DEPTH_SIZE]; + uint32 regDepthBufferInfo = LatteGPUState.contextRegister[mmDB_DEPTH_INFO]; + // get format and tileMode from info reg + uint32 depthBufferTileMode = (regDepthBufferInfo >> 15) & 0xF; + + MPTR depthBufferPhysMem = regDepthBuffer << 8; + uint32 depthBufferPitch = (((regDepthSize >> 0) & 0x3FF) + 1); + uint32 depthBufferHeight = ((((regDepthSize >> 10) & 0xFFFFF) + 1) / depthBufferPitch); + depthBufferPitch <<= 3; + depthBufferHeight <<= 3; + uint32 depthBufferWidth = depthBufferPitch; + + sint32 sliceIndex = 0; // todo + sint32 mipIndex = 0; + + // clear all color buffers that match the format of the depth buffer + sint32 searchIndex = 0; + bool targetFound = false; + while (true) + { + LatteTextureView* view = LatteTC_LookupTextureByData(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, 1, sliceIndex, 1, &searchIndex); + if (!view) + { + // should we clear in RAM instead? + break; + } + sint32 effectiveClearWidth = view->baseTexture->width; + sint32 effectiveClearHeight = view->baseTexture->height; + LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0); + + // hacky way to get clear color + float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST + + uint8 clearColor[4] = { 0 }; + clearColor[0] = (uint8)(regClearColor[0] * 255.0f); + clearColor[1] = (uint8)(regClearColor[1] * 255.0f); + clearColor[2] = (uint8)(regClearColor[2] * 255.0f); + clearColor[3] = (uint8)(regClearColor[3] * 255.0f); + + // todo - use fragment shader software emulation (evoke for one pixel) to determine clear color + // todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight + + switch (g_renderer->GetType()) + { +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: + { + //cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer + if (glClearTexSubImage) + glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor); + break; + } +#endif + default: + { + if (view->baseTexture->isDepth) + g_renderer->texture_clearDepthSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, true, view->baseTexture->hasStencil, 0.0f, 0); + else + g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + } + } +} + +/* rects emulation */ + +void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister) +{ + auto parameterMask = vertexShader->outputParameterMask; + for (uint32 i = 0; i < 32; i++) + { + if ((parameterMask & (1 << i)) == 0) + continue; + sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); + if (vsSemanticId < 0) + continue; + // make sure PS has matching input + if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) + continue; + gsSrc.append(fmt::format("passParameterSem{}Out = passParameterSem{}In[{}];\r\n", vsSemanticId, vsSemanticId, vIdx)); + } + gsSrc.append(fmt::format("gl_Position = gl_in[{}].gl_Position;\r\n", vIdx)); + gsSrc.append("EmitVertex();\r\n"); +} + +void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, const char* variant, const LatteContextRegister& latteRegister) +{ + auto parameterMask = vertexShader->outputParameterMask; + for (uint32 i = 0; i < 32; i++) + { + if ((parameterMask & (1 << i)) == 0) + continue; + sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); + if (vsSemanticId < 0) + continue; + // make sure PS has matching input + if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) + continue; + gsSrc.append(fmt::format("passParameterSem{}Out = gen4thVertex{}(passParameterSem{}In[0], passParameterSem{}In[1], passParameterSem{}In[2]);\r\n", vsSemanticId, variant, vsSemanticId, vsSemanticId, vsSemanticId)); + } + gsSrc.append(fmt::format("gl_Position = gen4thVertex{}(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_in[2].gl_Position);\r\n", variant)); + gsSrc.append("EmitVertex();\r\n"); +} + +void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister) +{ + sint32 pList[4] = { p0, p1, p2, p3 }; + for (sint32 i = 0; i < 4; i++) + { + if (pList[i] == 3) + rectsEmulationGS_outputGeneratedVertex(gsSrc, vertexShader, psInputTable, variant, latteRegister); + else + rectsEmulationGS_outputSingleVertex(gsSrc, vertexShader, psInputTable, pList[i], latteRegister); + } +} diff --git a/src/Cafe/HW/Latte/Renderer/RendererCore.h b/src/Cafe/HW/Latte/Renderer/RendererCore.h new file mode 100644 index 00000000..aaffec56 --- /dev/null +++ b/src/Cafe/HW/Latte/Renderer/RendererCore.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Cafe/HW/Latte/Core/LatteRingBuffer.h" +#include "Cafe/HW/Latte/Core/Latte.h" + +void LatteDraw_handleSpecialState8_clearAsDepth(); + +class LatteShaderPSInputTable; +void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx); +void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, const char* variant); +void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister); diff --git a/src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp b/src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp index a4f538a8..1acb4f47 100644 --- a/src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp +++ b/src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp @@ -1,5 +1,9 @@ #include "Cafe/HW/Latte/Renderer/RendererOuputShader.h" +#include "Cafe/HW/Latte/Renderer/Renderer.h" +#include "Cafe/HW/Latte/Core/Latte.h" +#ifdef ENABLE_OPENGL #include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h" +#endif #include "config/ActiveSettings.h" const std::string RendererOutputShader::s_copy_shader_source = @@ -246,10 +250,17 @@ fragment float4 main0(VertexOut in [[stage_in]], texture2d textureSrc [[t RendererOutputShader::RendererOutputShader(const std::string& vertex_source, const std::string& fragment_source) { std::string finalFragmentSrc; - if (g_renderer->GetType() == RendererAPI::Metal) - finalFragmentSrc = fragment_source; - else - finalFragmentSrc = PrependFragmentPreamble(fragment_source); + switch(g_renderer->GetType()) + { +#ifdef ENABLE_METAL + case RendererAPI::Metal: + finalFragmentSrc = fragment_source; + break; +#endif + default: + finalFragmentSrc = PrependFragmentPreamble(fragment_source); + break; + } m_vertex_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false)); m_fragment_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, finalFragmentSrc, false, false)); @@ -484,7 +495,10 @@ void main() } void RendererOutputShader::InitializeStatic() { - if (g_renderer->GetType() == RendererAPI::Metal) + switch(g_renderer->GetType()) + { +#ifdef ENABLE_METAL + case RendererAPI::Metal: { std::string vertex_source = GetMetalVertexSource(false); std::string vertex_source_ud = GetMetalVertexSource(true); @@ -497,21 +511,17 @@ void RendererOutputShader::InitializeStatic() s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source_mtl); s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source_mtl); + break; } - else +#endif +#ifdef ENABLE_OPENGL + case RendererAPI::OpenGL: { std::string vertex_source, vertex_source_ud; // vertex shader - if (g_renderer->GetType() == RendererAPI::OpenGL) - { - vertex_source = GetOpenGlVertexSource(false); - vertex_source_ud = GetOpenGlVertexSource(true); - } - else if (g_renderer->GetType() == RendererAPI::Vulkan) - { - vertex_source = GetVulkanVertexSource(false); - vertex_source_ud = GetVulkanVertexSource(true); - } + vertex_source = GetOpenGlVertexSource(false); + vertex_source_ud = GetOpenGlVertexSource(true); + s_copy_shader = new RendererOutputShader(vertex_source, s_copy_shader_source); s_copy_shader_ud = new RendererOutputShader(vertex_source_ud, s_copy_shader_source); @@ -520,7 +530,29 @@ void RendererOutputShader::InitializeStatic() s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source); s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source); + break; } +#endif +#ifdef ENABLE_VULKAN + case RendererAPI::Vulkan: + { + std::string vertex_source, vertex_source_ud; + // vertex shader + vertex_source = GetVulkanVertexSource(false); + vertex_source_ud = GetVulkanVertexSource(true); + + s_copy_shader = new RendererOutputShader(vertex_source, s_copy_shader_source); + s_copy_shader_ud = new RendererOutputShader(vertex_source_ud, s_copy_shader_source); + + s_bicubic_shader = new RendererOutputShader(vertex_source, s_bicubic_shader_source); + s_bicubic_shader_ud = new RendererOutputShader(vertex_source_ud, s_bicubic_shader_source); + + s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source); + s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source); + break; + } +#endif + } } void RendererOutputShader::ShutdownStatic() diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp index 55b2330e..ca166e69 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanPipelineCompiler.cpp @@ -9,58 +9,7 @@ #include "util/helpers/helpers.h" #include "util/helpers/Serializer.h" #include "Cafe/HW/Latte/Common/RegisterSerializer.h" - -/* rects emulation */ - -void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister) -{ - auto parameterMask = vertexShader->outputParameterMask; - for (uint32 i = 0; i < 32; i++) - { - if ((parameterMask & (1 << i)) == 0) - continue; - sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); - if (vsSemanticId < 0) - continue; - // make sure PS has matching input - if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) - continue; - gsSrc.append(fmt::format("passParameterSem{}Out = passParameterSem{}In[{}];\r\n", vsSemanticId, vsSemanticId, vIdx)); - } - gsSrc.append(fmt::format("gl_Position = gl_in[{}].gl_Position;\r\n", vIdx)); - gsSrc.append("EmitVertex();\r\n"); -} - -void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, const char* variant, const LatteContextRegister& latteRegister) -{ - auto parameterMask = vertexShader->outputParameterMask; - for (uint32 i = 0; i < 32; i++) - { - if ((parameterMask & (1 << i)) == 0) - continue; - sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); - if (vsSemanticId < 0) - continue; - // make sure PS has matching input - if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) - continue; - gsSrc.append(fmt::format("passParameterSem{}Out = gen4thVertex{}(passParameterSem{}In[0], passParameterSem{}In[1], passParameterSem{}In[2]);\r\n", vsSemanticId, variant, vsSemanticId, vsSemanticId, vsSemanticId)); - } - gsSrc.append(fmt::format("gl_Position = gen4thVertex{}(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_in[2].gl_Position);\r\n", variant)); - gsSrc.append("EmitVertex();\r\n"); -} - -void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister) -{ - sint32 pList[4] = { p0, p1, p2, p3 }; - for (sint32 i = 0; i < 4; i++) - { - if (pList[i] == 3) - rectsEmulationGS_outputGeneratedVertex(gsSrc, vertexShader, psInputTable, variant, latteRegister); - else - rectsEmulationGS_outputSingleVertex(gsSrc, vertexShader, psInputTable, pList[i], latteRegister); - } -} +#include "HW/Latte/Renderer/RendererCore.h" RendererShaderVk* rectsEmulationGS_generate(LatteDecompilerShader* vertexShader, const LatteContextRegister& latteRegister) { diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp index a6814186..d0933e35 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRendererCore.cpp @@ -1221,6 +1221,7 @@ void VulkanRenderer::draw_endRenderPass() m_state.activeRenderpassFBO = nullptr; } +// Defined in the Common renderer void LatteDraw_handleSpecialState8_clearAsDepth(); // transfer depth buffer data to color buffer diff --git a/src/config/ActiveSettings.cpp b/src/config/ActiveSettings.cpp index 862ac6c3..3352c143 100644 --- a/src/config/ActiveSettings.cpp +++ b/src/config/ActiveSettings.cpp @@ -1,7 +1,9 @@ #include "Cafe/GameProfile/GameProfile.h" #include "Cafe/IOSU/legacy/iosu_crypto.h" #include "Cafe/HW/Latte/Core/Latte.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" +#endif #include "Cafe/CafeSystem.h" #include "Cemu/Logging/CemuLogging.h" #include "config/ActiveSettings.h" @@ -107,9 +109,12 @@ bool ActiveSettings::WaitForGX2DrawDoneEnabled() GraphicAPI ActiveSettings::GetGraphicsAPI() { GraphicAPI api = g_current_game_profile->GetGraphicsAPI().value_or(GetConfig().graphic_api); + +#if defined(ENABLE_VULKAN) && defined(ENABLE_OPENGL) // check if vulkan even available if (api == kVulkan && !g_vulkan_available) api = kOpenGL; +#endif return api; } diff --git a/src/config/CemuConfig.cpp b/src/config/CemuConfig.cpp index 097587f8..17a67af0 100644 --- a/src/config/CemuConfig.cpp +++ b/src/config/CemuConfig.cpp @@ -144,7 +144,7 @@ XMLConfigParser CemuConfig::Load(XMLConfigParser& parser) fullscreen_scaling = graphic.get("FullscreenScaling", kKeepAspectRatio); async_compile = graphic.get("AsyncCompile", async_compile); vk_accurate_barriers = graphic.get("vkAccurateBarriers", true); // this used to be "VulkanAccurateBarriers" but because we changed the default to true in 1.27.1 the option name had to be changed -#if ENABLE_METAL +#ifdef ENABLE_METAL force_mesh_shaders = graphic.get("ForceMeshShaders", false); #endif @@ -273,7 +273,7 @@ XMLConfigParser CemuConfig::Load(XMLConfigParser& parser) crash_dump = debug.get("CrashDumpUnix", crash_dump); #endif gdb_port = debug.get("GDBPort", 1337); -#if ENABLE_METAL +#ifdef ENABLE_METAL gpu_capture_dir = debug.get("GPUCaptureDir", ""); framebuffer_fetch = debug.get("FramebufferFetch", true); #endif @@ -368,7 +368,7 @@ XMLConfigParser CemuConfig::Save(XMLConfigParser& parser) graphic.set("OverrideGammaValue", overrideGammaValue); graphic.set("UserDisplayGamma", userDisplayGamma); graphic.set("GX2DrawdoneSync", gx2drawdone_sync); -#if ENABLE_METAL +#ifdef ENABLE_METAL graphic.set("ForceMeshShaders", force_mesh_shaders); #endif //graphic.set("PrecompiledShaders", precompiled_shaders.GetValue()); @@ -437,7 +437,7 @@ XMLConfigParser CemuConfig::Save(XMLConfigParser& parser) debug.set("CrashDumpUnix", crash_dump.GetValue()); #endif debug.set("GDBPort", gdb_port); -#if ENABLE_METAL +#ifdef ENABLE_METAL debug.set("GPUCaptureDir", gpu_capture_dir); debug.set("FramebufferFetch", framebuffer_fetch); #endif diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index 6778ceb5..152c2c3f 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -65,6 +65,7 @@ struct GraphicPackEntry bool enabled = true; }; +#define GRAPHIC_API_COUNT 3 enum GraphicAPI { kOpenGL = 0, @@ -429,7 +430,13 @@ struct CemuConfig ConfigValueBounds console_language{ CafeConsoleLanguage::EN }; // graphics +#if defined(ENABLE_VULKAN) ConfigValue graphic_api{ kVulkan }; +#elif defined(ENABLE_METAL) + ConfigValue graphic_api{ kMetal }; +#elif defined(ENABLE_OPENGL) + ConfigValue graphic_api{ kOpenGL }; +#endif std::array legacy_graphic_device_uuid{}; // placeholder option for backwards compatibility with settings from 2.6 and before (renamed to "vkDevice") std::array vk_graphic_device_uuid; uint64 mtl_graphic_device_uuid{ 0 }; @@ -437,7 +444,7 @@ struct CemuConfig ConfigValue gx2drawdone_sync { true }; ConfigValue render_upside_down{ false }; ConfigValue async_compile{ true }; -#if ENABLE_METAL +#ifdef ENABLE_METAL ConfigValue force_mesh_shaders{ false }; #endif @@ -503,7 +510,7 @@ struct CemuConfig // debug ConfigValueBounds crash_dump{ CrashDump::Disabled }; ConfigValue gdb_port{ 1337 }; -#if ENABLE_METAL +#ifdef ENABLE_METAL ConfigValue gpu_capture_dir{ "" }; ConfigValue framebuffer_fetch{ true }; #endif diff --git a/src/gui/wxgui/CMakeLists.txt b/src/gui/wxgui/CMakeLists.txt index 9a2e880d..d57c9074 100644 --- a/src/gui/wxgui/CMakeLists.txt +++ b/src/gui/wxgui/CMakeLists.txt @@ -1,9 +1,5 @@ add_library(CemuWxGui STATIC canvas/IRenderCanvas.h - canvas/OpenGLCanvas.cpp - canvas/OpenGLCanvas.h - canvas/VulkanCanvas.cpp - canvas/VulkanCanvas.h CemuApp.cpp CemuApp.h CemuUpdateWindow.cpp @@ -118,6 +114,20 @@ add_library(CemuWxGui STATIC wxHelper.h ) +if (ENABLE_OPENGL) + target_sources(CemuWxGui PRIVATE + canvas/OpenGLCanvas.cpp + canvas/OpenGLCanvas.h + ) +endif() + +if (ENABLE_VULKAN) + target_sources(CemuWxGui PRIVATE + canvas/VulkanCanvas.cpp + canvas/VulkanCanvas.h + ) +endif() + if (ENABLE_METAL) target_sources(CemuWxGui PRIVATE canvas/MetalCanvas.cpp diff --git a/src/gui/wxgui/CemuApp.cpp b/src/gui/wxgui/CemuApp.cpp index a900f10b..4160acb6 100644 --- a/src/gui/wxgui/CemuApp.cpp +++ b/src/gui/wxgui/CemuApp.cpp @@ -3,7 +3,9 @@ #include "wxgui/MainWindow.h" #include "wxgui/wxgui.h" #include "config/CemuConfig.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" +#endif #include "Cafe/HW/Latte/Core/LatteOverlay.h" #include "config/ActiveSettings.h" #include "config/LaunchSettings.h" @@ -349,7 +351,9 @@ bool CemuApp::OnInit() __fastfail(0); } #endif + #ifdef ENABLE_VULKAN InitializeGlobalVulkan(); + #endif Bind(wxEVT_ACTIVATE_APP, &CemuApp::ActivateApp, this); diff --git a/src/gui/wxgui/GameProfileWindow.cpp b/src/gui/wxgui/GameProfileWindow.cpp index 37fac6bc..5962133e 100644 --- a/src/gui/wxgui/GameProfileWindow.cpp +++ b/src/gui/wxgui/GameProfileWindow.cpp @@ -113,7 +113,7 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id) first_row->Add(new wxStaticText(panel, wxID_ANY, _("Graphics API")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxString gapi_values[] = { "", "OpenGL", "Vulkan", -#if ENABLE_METAL +#ifdef ENABLE_METAL "Metal" #endif }; @@ -127,7 +127,7 @@ GameProfileWindow::GameProfileWindow(wxWindow* parent, uint64_t title_id) m_shader_mul_accuracy->SetToolTip(_("EXPERT OPTION\nControls the accuracy of floating point multiplication in shaders.\n\nRecommended: true")); first_row->Add(m_shader_mul_accuracy, 0, wxALL, 5); -#if ENABLE_METAL +#ifdef ENABLE_METAL first_row->Add(new wxStaticText(panel, wxID_ANY, _("Shader fast math")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxString math_values[] = { _("false"), _("true") }; @@ -296,7 +296,7 @@ void GameProfileWindow::ApplyProfile() else m_graphic_api->SetSelection(1 + m_game_profile.m_graphics_api.value()); // "", OpenGL, Vulkan, Metal m_shader_mul_accuracy->SetSelection((int)m_game_profile.m_accurateShaderMul); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_shader_fast_math->SetSelection((int)m_game_profile.m_shaderFastMath); m_metal_buffer_cache_mode->SetSelection((int)m_game_profile.m_metalBufferCacheMode); m_position_invariance->SetSelection((int)m_game_profile.m_positionInvariance); @@ -362,7 +362,7 @@ void GameProfileWindow::SaveProfile() m_game_profile.m_accurateShaderMul = (AccurateShaderMulOption)m_shader_mul_accuracy->GetSelection(); if (m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::False && m_game_profile.m_accurateShaderMul != AccurateShaderMulOption::True) m_game_profile.m_accurateShaderMul = AccurateShaderMulOption::True; // force a legal value -#if ENABLE_METAL +#ifdef ENABLE_METAL m_game_profile.m_shaderFastMath = (bool)m_shader_fast_math->GetSelection(); m_game_profile.m_metalBufferCacheMode = (MetalBufferCacheMode)m_metal_buffer_cache_mode->GetSelection(); m_game_profile.m_positionInvariance = (PositionInvariance)m_position_invariance->GetSelection(); diff --git a/src/gui/wxgui/GameProfileWindow.h b/src/gui/wxgui/GameProfileWindow.h index 3cb381d9..fe6150dc 100644 --- a/src/gui/wxgui/GameProfileWindow.h +++ b/src/gui/wxgui/GameProfileWindow.h @@ -40,7 +40,7 @@ private: wxChoice* m_graphic_api; wxChoice* m_shader_mul_accuracy; -#if ENABLE_METAL +#ifdef ENABLE_METAL wxChoice* m_shader_fast_math; wxChoice* m_metal_buffer_cache_mode; wxChoice* m_position_invariance; diff --git a/src/gui/wxgui/GeneralSettings2.cpp b/src/gui/wxgui/GeneralSettings2.cpp index 003bd130..f556809e 100644 --- a/src/gui/wxgui/GeneralSettings2.cpp +++ b/src/gui/wxgui/GeneralSettings2.cpp @@ -27,9 +27,11 @@ #include "audio/IAudioInputAPI.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" -#if ENABLE_METAL +#endif +#ifdef ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #endif #include "Cafe/Account/Account.h" @@ -87,6 +89,7 @@ private: IAudioInputAPI::DeviceDescriptionPtr m_description; }; +#ifdef ENABLE_VULKAN class wxVulkanUUID : public wxClientData { public: @@ -97,8 +100,9 @@ public: private: VulkanRenderer::DeviceInfo m_device_info; }; +#endif -#if ENABLE_METAL +#ifdef ENABLE_METAL class wxMetalUUID : public wxClientData { public: @@ -352,15 +356,25 @@ wxPanel* GeneralSettings2::AddGraphicsPage(wxNotebook* notebook) row->Add(new wxStaticText(box, wxID_ANY, _("Graphics API")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); - sint32 api_size = 1; - wxString choices[3] = { "OpenGL" }; + sint32 api_size = 0; + wxString choices[GRAPHIC_API_COUNT]; + +#ifdef ENABLE_OPENGL + choices[api_size++] = "OpenGL"; + m_api_map.push_back(GraphicAPI::kOpenGL); +#endif +#ifdef ENABLE_VULKAN if (g_vulkan_available) { choices[api_size++] = "Vulkan"; + m_api_map.push_back(GraphicAPI::kVulkan); } -#if ENABLE_METAL - choices[api_size++] = "Metal"; #endif +#ifdef ENABLE_METAL + choices[api_size++] = "Metal"; + m_api_map.push_back(GraphicAPI::kMetal); +#endif + wxASSERT(api_size > 0); m_graphic_api = new wxChoice(box, wxID_ANY, wxDefaultPosition, wxDefaultSize, api_size, choices); m_graphic_api->SetSelection(0); @@ -400,7 +414,7 @@ wxPanel* GeneralSettings2::AddGraphicsPage(wxNotebook* notebook) m_gx2drawdone_sync->SetToolTip(_("If synchronization is requested by the game, the emulated CPU will wait for the GPU to finish all operations.\nThis is more accurate behavior, but may cause lower performance")); graphic_misc_row->Add(m_gx2drawdone_sync, 0, wxALL, 5); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_force_mesh_shaders = new wxCheckBox(box, wxID_ANY, _("Force mesh shaders")); m_force_mesh_shaders->SetToolTip(_("Force mesh shaders on all GPUs that support them. Mesh shaders are disabled by default on Intel GPUs due to potential stability issues.\nMetal only")); graphic_misc_row->Add(m_force_mesh_shaders, 0, wxALL, 5); @@ -1028,7 +1042,7 @@ wxPanel* GeneralSettings2::AddDebugPage(wxNotebook* notebook) debug_panel_sizer->Add(debug_row, 0, wxALL | wxEXPAND, 5); } -#if ENABLE_METAL +#ifdef ENABLE_METAL { auto* debug_row = new wxFlexGridSizer(0, 2, 0, 0); debug_row->SetFlexibleDirection(wxBOTH); @@ -1216,9 +1230,10 @@ void GeneralSettings2::StoreConfig() } // graphics - config.graphic_api = (GraphicAPI)m_graphic_api->GetSelection(); + config.graphic_api = m_api_map[m_graphic_api->GetSelection()]; selection = m_graphic_device->GetSelection(); +#ifdef ENABLE_VULKAN if (config.graphic_api == GraphicAPI::kVulkan) { if (selection != wxNOT_FOUND) @@ -1232,25 +1247,26 @@ void GeneralSettings2::StoreConfig() else config.vk_graphic_device_uuid = {}; } -#if ENABLE_METAL - else if (config.graphic_api == GraphicAPI::kMetal) +#endif +#ifdef ENABLE_METAL + if (config.graphic_api == GraphicAPI::kMetal) { - if (selection != wxNOT_FOUND) - { - const auto* info = (wxMetalUUID*)m_graphic_device->GetClientObject(selection); - if (info) - config.mtl_graphic_device_uuid = info->GetDeviceInfo().uuid; - else - config.mtl_graphic_device_uuid = {}; - } - else - config.mtl_graphic_device_uuid = {}; + if (selection != wxNOT_FOUND) + { + const auto* info = (wxMetalUUID*)m_graphic_device->GetClientObject(selection); + if (info) + config.mtl_graphic_device_uuid = info->GetDeviceInfo().uuid; + else + config.mtl_graphic_device_uuid = {}; + } + else + config.mtl_graphic_device_uuid = {}; } #endif config.gx2drawdone_sync = m_gx2drawdone_sync->IsChecked(); -#if ENABLE_METAL +#ifdef ENABLE_METAL config.force_mesh_shaders = m_force_mesh_shaders->IsChecked(); #endif config.async_compile = m_async_compile->IsChecked(); @@ -1281,7 +1297,7 @@ void GeneralSettings2::StoreConfig() // debug config.crash_dump = (CrashDump)m_crash_dump->GetSelection(); config.gdb_port = m_gdb_port->GetValue(); -#if ENABLE_METAL +#ifdef ENABLE_METAL config.gpu_capture_dir = m_gpu_capture_dir->GetValue().utf8_string(); config.framebuffer_fetch = m_framebuffer_fetch->IsChecked(); #endif @@ -1721,7 +1737,12 @@ void GeneralSettings2::HandleGraphicsApiSelection() selection = GetConfig().vsync; m_vsync->Clear(); - if (m_graphic_api->GetSelection() == 0) + + auto api = m_api_map[m_graphic_api->GetSelection()]; + switch (api) + { +#ifdef ENABLE_OPENGL + case GraphicAPI::kOpenGL: { // OpenGL m_vsync->AppendString(_("Off")); @@ -1736,16 +1757,19 @@ void GeneralSettings2::HandleGraphicsApiSelection() m_gx2drawdone_sync->Enable(); m_async_compile->Disable(); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_force_mesh_shaders->Disable(); #endif + break; } - else if (m_graphic_api->GetSelection() == 1) +#endif +#ifdef ENABLE_VULKAN + case GraphicAPI::kVulkan: { // Vulkan m_gx2drawdone_sync->Disable(); m_async_compile->Enable(); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_force_mesh_shaders->Disable(); #endif @@ -1779,9 +1803,11 @@ void GeneralSettings2::HandleGraphicsApiSelection() } } } + break; } -#if ENABLE_METAL - else + #endif +#ifdef ENABLE_METAL + case GraphicAPI::kMetal: { // Metal m_gx2drawdone_sync->Disable(); @@ -1815,8 +1841,10 @@ void GeneralSettings2::HandleGraphicsApiSelection() } } } + break; } #endif + } } void GeneralSettings2::ApplyConfig() @@ -1870,7 +1898,14 @@ void GeneralSettings2::ApplyConfig() } // graphics - m_graphic_api->SetSelection(config.graphic_api); + for (int i = 0; i < (int)m_api_map.size(); ++i) + { + if (m_api_map[i] == config.graphic_api) + { + m_graphic_api->SetSelection(i); + break; + } + } m_vsync->SetSelection(config.vsync); m_overrideGamma->SetValue(config.overrideAppGammaPreference); m_overrideGammaValue->SetValue(config.overrideGammaValue); @@ -1883,7 +1918,7 @@ void GeneralSettings2::ApplyConfig() } m_async_compile->SetValue(config.async_compile); m_gx2drawdone_sync->SetValue(config.gx2drawdone_sync); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_force_mesh_shaders->SetValue(config.force_mesh_shaders); #endif m_upscale_filter->SetSelection(config.upscale_filter); @@ -2022,7 +2057,7 @@ void GeneralSettings2::ApplyConfig() // debug m_crash_dump->SetSelection((int)config.crash_dump.GetValue()); m_gdb_port->SetValue(config.gdb_port.GetValue()); -#if ENABLE_METAL +#ifdef ENABLE_METAL m_gpu_capture_dir->SetValue(wxString::FromUTF8(config.gpu_capture_dir.GetValue())); m_framebuffer_fetch->SetValue(config.framebuffer_fetch); #endif diff --git a/src/gui/wxgui/GeneralSettings2.h b/src/gui/wxgui/GeneralSettings2.h index 634f0cfa..2f7e3b68 100644 --- a/src/gui/wxgui/GeneralSettings2.h +++ b/src/gui/wxgui/GeneralSettings2.h @@ -1,4 +1,5 @@ #pragma once +#include "config/CemuConfig.h" #include #include #include @@ -36,6 +37,7 @@ private: bool m_game_launched; bool m_has_account_change = false; // keep track of dirty state of accounts + std::vector m_api_map; // map from dropdown index to GraphicsAPISetting, used in HandleGraphicsApiSelection wxPanel* AddGeneralPage(wxNotebook* notebook); @@ -71,7 +73,7 @@ private: wxCheckBox* m_userDisplayisSRGB; wxCheckBox *m_async_compile, *m_gx2drawdone_sync; -#if ENABLE_METAL +#ifdef ENABLE_METAL wxCheckBox *m_force_mesh_shaders; #endif wxRadioBox* m_upscale_filter, *m_downscale_filter, *m_fullscreen_scaling; @@ -99,7 +101,7 @@ private: // Debug wxChoice* m_crash_dump; wxSpinCtrl* m_gdb_port; -#if ENABLE_METAL +#ifdef ENABLE_METAL wxTextCtrl* m_gpu_capture_dir; wxCheckBox* m_framebuffer_fetch; #endif diff --git a/src/gui/wxgui/MainWindow.cpp b/src/gui/wxgui/MainWindow.cpp index 4ef4fe08..94bdb004 100644 --- a/src/gui/wxgui/MainWindow.cpp +++ b/src/gui/wxgui/MainWindow.cpp @@ -11,9 +11,13 @@ #include "wxgui/windows/TextureRelationViewer/TextureRelationWindow.h" #include "wxgui/windows/PPCThreadsViewer/DebugPPCThreadsWindow.h" #include "AudioDebuggerWindow.h" +#ifdef ENABLE_OPENGL #include "wxgui/canvas/OpenGLCanvas.h" +#endif +#ifdef ENABLE_VULKAN #include "wxgui/canvas/VulkanCanvas.h" -#if ENABLE_METAL +#endif +#ifdef ENABLE_METAL #include "wxgui/canvas/MetalCanvas.h" #endif #include "Cafe/OS/libs/nfc/nfc.h" @@ -42,7 +46,9 @@ #include "wxgui/DownloadGraphicPacksWindow.h" #include "wxgui/GettingStartedDialog.h" #include "wxgui/helpers/wxHelpers.h" +#ifdef ENABLE_VULKAN #include "Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.h" +#endif #include "wxgui/input/InputSettings2.h" #include "wxgui/input/HotkeySettings.h" #include "input/InputManager.h" @@ -66,7 +72,7 @@ #include "gamemode_client.h" #endif -#if ENABLE_METAL +#ifdef ENABLE_METAL #include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h" #endif @@ -1037,7 +1043,7 @@ void MainWindow::OnDebugSetting(wxCommandEvent& event) if(!GetConfig().vk_accurate_barriers) wxMessageBox(_("Warning: Disabling the accurate barriers option will lead to flickering graphics but may improve performance. It is highly recommended to leave it turned on."), _("Accurate barriers are off"), wxOK); } -#if ENABLE_METAL +#ifdef ENABLE_METAL else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE) { cemu_assert_debug(g_renderer->GetType() == RendererAPI::Metal); @@ -1601,14 +1607,29 @@ void MainWindow::CreateCanvas() this->GetSizer()->Add(m_game_panel, 1, wxEXPAND); // create canvas - if (ActiveSettings::GetGraphicsAPI() == kVulkan) - m_render_canvas = new VulkanCanvas(m_game_panel, wxSize(1280, 720), true); - else if (ActiveSettings::GetGraphicsAPI() == kOpenGL) + switch (ActiveSettings::GetGraphicsAPI()) + { + case kOpenGL: +#ifdef ENABLE_OPENGL m_render_canvas = GLCanvas_Create(m_game_panel, wxSize(1280, 720), true); -#if ENABLE_METAL - else - m_render_canvas = new MetalCanvas(m_game_panel, wxSize(1280, 720), true); + break; #endif + case kVulkan: +#ifdef ENABLE_VULKAN + m_render_canvas = new VulkanCanvas(m_game_panel, wxSize(1280, 720), true); + break; +#endif + case kMetal: +#ifdef ENABLE_METAL + m_render_canvas = new MetalCanvas(m_game_panel, wxSize(1280, 720), true); + break; +#endif + default: + cemu_assert(false && "Invalid graphics API selected"); + break; + } + + cemu_assert(m_render_canvas != nullptr); // mouse events m_render_canvas->Bind(wxEVT_MOTION, &MainWindow::OnMouseMove, this); @@ -1670,7 +1691,9 @@ void MainWindow::OnSizeEvent(wxSizeEvent& event) event.Skip(); + #ifdef ENABLE_VULKAN VsyncDriver_notifyWindowPosChanged(); + #endif } void MainWindow::OnDPIChangedEvent(wxDPIChangedEvent& event) @@ -1691,7 +1714,9 @@ void MainWindow::OnMove(wxMoveEvent& event) if (m_debugger_window && m_debugger_window->IsShown()) m_debugger_window->OnParentMove(GetPosition(), GetSize()); + #ifdef ENABLE_VULKAN VsyncDriver_notifyWindowPosChanged(); + #endif } void MainWindow::OnDebuggerClose(wxCloseEvent& event) @@ -2345,7 +2370,7 @@ void MainWindow::RecreateMenu() auto accurateBarriers = debugMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_VK_ACCURATE_BARRIERS, _("&Accurate barriers (Vulkan)")); accurateBarriers->Check(GetConfig().vk_accurate_barriers); -#if ENABLE_METAL +#ifdef ENABLE_METAL auto gpuCapture = debugMenu->Append(MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE, _("&GPU capture (Metal)")); gpuCapture->Enable(m_game_launched && g_renderer->GetType() == RendererAPI::Metal); #endif diff --git a/src/gui/wxgui/PadViewFrame.cpp b/src/gui/wxgui/PadViewFrame.cpp index 2079f1eb..b2e55a92 100644 --- a/src/gui/wxgui/PadViewFrame.cpp +++ b/src/gui/wxgui/PadViewFrame.cpp @@ -6,9 +6,13 @@ #include "config/ActiveSettings.h" #include "Cafe/OS/libs/swkbd/swkbd.h" +#ifdef ENABLE_OPENGL #include "wxgui/canvas/OpenGLCanvas.h" +#endif +#ifdef ENABLE_VULKAN #include "wxgui/canvas/VulkanCanvas.h" -#if ENABLE_METAL +#endif +#ifdef ENABLE_METAL #include "wxgui/canvas/MetalCanvas.h" #endif #include "config/CemuConfig.h" @@ -76,15 +80,24 @@ void PadViewFrame::InitializeRenderCanvas() auto sizer = new wxBoxSizer(wxVERTICAL); { if (ActiveSettings::GetGraphicsAPI() == kVulkan) + { + #ifdef ENABLE_VULKAN m_render_canvas = new VulkanCanvas(this, wxSize(854, 480), false); + #endif + } else if (ActiveSettings::GetGraphicsAPI() == kOpenGL) + { + #ifdef ENABLE_OPENGL m_render_canvas = GLCanvas_Create(this, wxSize(854, 480), false); -#if ENABLE_METAL + #endif + } +#ifdef ENABLE_METAL else m_render_canvas = new MetalCanvas(this, wxSize(854, 480), false); #endif sizer->Add(m_render_canvas, 1, wxEXPAND, 0, nullptr); } + cemu_assert(m_render_canvas != nullptr); SetSizer(sizer); Layout(); diff --git a/src/gui/wxgui/wxWindowSystem.cpp b/src/gui/wxgui/wxWindowSystem.cpp index 4b199741..b9e760ed 100644 --- a/src/gui/wxgui/wxWindowSystem.cpp +++ b/src/gui/wxgui/wxWindowSystem.cpp @@ -95,13 +95,17 @@ void WindowSystem::UpdateWindowTitles(bool isIdle, bool isLoading, double fps) { switch (g_renderer->GetType()) { +#ifdef ENABLE_OPENGL case RendererAPI::OpenGL: renderer = "[OpenGL]"; break; +#endif +#ifdef ENABLE_VULKAN case RendererAPI::Vulkan: renderer = "[Vulkan]"; break; -#if ENABLE_METAL +#endif +#ifdef ENABLE_METAL case RendererAPI::Metal: renderer = "[Metal]"; break; diff --git a/src/imgui/CMakeLists.txt b/src/imgui/CMakeLists.txt index e2d669c5..b5e91075 100644 --- a/src/imgui/CMakeLists.txt +++ b/src/imgui/CMakeLists.txt @@ -1,12 +1,22 @@ add_library(imguiImpl - imgui_impl_opengl3.cpp - imgui_impl_opengl3.h - imgui_impl_vulkan.cpp - imgui_impl_vulkan.h imgui_extension.cpp imgui_extension.h ) +if (ENABLE_OPENGL) + target_sources(imguiImpl PRIVATE + imgui_impl_opengl3.cpp + imgui_impl_opengl3.h + ) +endif() + +if (ENABLE_VULKAN) + target_sources(imguiImpl PRIVATE + imgui_impl_vulkan.cpp + imgui_impl_vulkan.h + ) +endif() + if (ENABLE_METAL) target_sources(imguiImpl PRIVATE imgui_impl_metal.mm diff --git a/src/imgui/imgui_extension.cpp b/src/imgui/imgui_extension.cpp index dadd2031..eb0e31ef 100644 --- a/src/imgui/imgui_extension.cpp +++ b/src/imgui/imgui_extension.cpp @@ -2,9 +2,13 @@ #include "WindowSystem.h" #include "Cafe/HW/Latte/Renderer/Renderer.h" #include "resource/IconsFontAwesome5.h" -#include "imgui_impl_opengl3.h" #include "resource/resource.h" +#ifdef ENABLE_OPENGL +#include "imgui_impl_opengl3.h" +#endif +#ifdef ENABLE_VULKAN #include "imgui_impl_vulkan.h" +#endif #include "input/InputManager.h" // diff --git a/src/main.cpp b/src/main.cpp index adce2680..fc632921 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,7 +19,6 @@ #include "util/helpers/helpers.h" #include "config/ActiveSettings.h" -#include "Cafe/HW/Latte/Renderer/Vulkan/VsyncDriver.h" #include "Cafe/IOSU/legacy/iosu_crypto.h" #include "Cafe/OS/libs/vpad/vpad.h" @@ -65,6 +64,7 @@ void _putenvSafe(const char* c) _putenv(s->c_str()); } +#ifdef ENABLE_OPENGL void reconfigureGLDrivers() { // reconfigure GL drivers to store @@ -85,12 +85,15 @@ void reconfigureGLDrivers() _putenvSafe("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1"); } +#endif +#ifdef ENABLE_VULKAN void reconfigureVkDrivers() { _putenvSafe("DISABLE_LAYER_AMD_SWITCHABLE_GRAPHICS_1=1"); _putenvSafe("DISABLE_VK_LAYER_VALVE_steam_fossilize_1=1"); } +#endif void WindowsInitCwd() { @@ -109,8 +112,12 @@ void WindowsInitCwd() void CemuCommonInit() { + #ifdef ENABLE_OPENGL reconfigureGLDrivers(); + #endif + #ifdef ENABLE_VULKAN reconfigureVkDrivers(); + #endif // crypto init AES128_init(); // init PPC timer @@ -258,7 +265,7 @@ int main(int argc, char* argv[]) int BreathOfTheWildChildProcessMain(); int main(int argc, char *argv[]) { -#if BOOST_OS_LINUX +#if BOOST_OS_LINUX && defined(ENABLE_VULKAN) if (getenv("CEMU_DETECT_RADV") != nullptr) return BreathOfTheWildChildProcessMain(); #endif