From bcb2dc41fc8ef166f94728945975dc4ce0bbc4dc Mon Sep 17 00:00:00 2001 From: Colin Cornaby Date: Mon, 8 Apr 2024 00:07:03 -0700 Subject: [PATCH] Move shaders into shader library target --- Sources/Plasma/Apps/plClient/CMakeLists.txt | 22 +++++-- .../FeatureLib/pfMetalPipeline/CMakeLists.txt | 35 +++++++++-- .../pfMetalPipeline/plMetalDevice.cpp | 16 ++--- .../pfMetalPipeline/plMetalDevice.h | 6 ++ .../plMetalDeviceLibraryLoader.mm | 60 +++++++++++++++++++ .../pfMetalPipeline/plMetalPipeline.cpp | 2 +- 6 files changed, 120 insertions(+), 21 deletions(-) create mode 100644 Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDeviceLibraryLoader.mm diff --git a/Sources/Plasma/Apps/plClient/CMakeLists.txt b/Sources/Plasma/Apps/plClient/CMakeLists.txt index 21be8e81cf..5a912d7ccc 100644 --- a/Sources/Plasma/Apps/plClient/CMakeLists.txt +++ b/Sources/Plasma/Apps/plClient/CMakeLists.txt @@ -116,6 +116,10 @@ elseif(APPLE) Mac-Cocoa/PLSLoginWindowController.xib Mac-Cocoa/PLSPatcherWindowController.xib ) + list(APPEND plClient_SHADERTARGETS + pfMetalPipelineShadersMSL21 + pfMetalPipelineShadersMSL23 + ) else() list(APPEND plClient_SOURCES main.cpp @@ -146,18 +150,15 @@ if(APPLE) MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1" RESOURCE "${plClient_XCODE_RESOURCES}" XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon - XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" - XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES" XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=RelWithDebInfo] "YES" - XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${Plasma_SOURCE_DIR}/Sources/Plasma/NucleusLib/inc/" XCODE_ATTRIBUTE_INSTALL_PATH "/Applications" XCODE_ATTRIBUTE_SKIP_INSTALL "NO" XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/Mac-Cocoa/plClient.entitlements" XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES" XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER org.Huru.UruExplorer + XCODE_EMBED_RESOURCES "${plClient_SHADERTARGETS}" ) target_compile_options(plClient PRIVATE -fobjc-arc) target_sources(plClient PRIVATE Mac-Cocoa/Assets.xcassets) @@ -238,13 +239,24 @@ target_link_libraries( $<$:pfDXPipeline> $<$:pfGLPipeline> $<$:pfMetalPipeline> - $<$:pfMetalPipelineShaders> CURL::libcurl "$<$:-framework Cocoa>" "$<$:-framework QuartzCore>" ) target_include_directories(plClient PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") +if(APPLE) + add_dependencies( + plClient + pfMetalPipelineShadersMSL21 + pfMetalPipelineShadersMSL23 + ) + list(APPEND plClient_RESOURCES + $ + $ + ) +endif() + if(PLASMA_EXTERNAL_RELEASE) set_target_properties(plClient PROPERTIES OUTPUT_NAME "UruExplorer") endif(PLASMA_EXTERNAL_RELEASE) diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt b/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt index 86fdca3090..f37be27cb3 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt @@ -25,6 +25,7 @@ set(pfMetalPipeline_SOURCES plMetalVertexShader.cpp plMetalTextFont.cpp plMetalDevicePerformanceShaders.mm + plMetalDeviceLibraryLoader.mm ) set(pfMetalPipeline_HEADERS @@ -63,7 +64,11 @@ target_include_directories(pfMetalPipeline PUBLIC "ShaderSrc") source_group("Source Files" FILES ${pfMetalPipeline_SOURCES}) source_group("Header Files" FILES ${pfMetalPipeline_HEADERS}) -add_library(pfMetalPipelineShaders INTERFACE) +# All supported Macs for Plasma/Metal support MSL 2.1 +add_library(pfMetalPipelineShadersMSL21 MODULE) +# Build a 2.3 varient for macOS 11 and/or Apple Silicon specific features +add_library(pfMetalPipelineShadersMSL23 MODULE) + set(pfMetalPipeline_SHADERS ShaderSrc/FixedPipelineShaders.metal ShaderSrc/PlateShaders.metal @@ -79,8 +84,28 @@ set(pfMetalPipeline_SHADERS ShaderSrc/GammaCorrection.metal ShaderSrc/TextFontShader.metal ) -set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY plClient PROPERTIES LANGUAGE METAL) -# source group does not work with an interface library in Xcode, but maybe someday... -source_group("Metal Shaders" FILES ${pfMetalPipeline_SHADERS}) +set_target_properties(pfMetalPipelineShadersMSL21 PROPERTIES + XCODE_PRODUCT_TYPE com.apple.product-type.metal-library + XCODE_ATTRIBUTE_MTL_LANGUAGE_REVISION Metal21 + XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${Plasma_SOURCE_DIR}/Sources/Plasma/NucleusLib/inc/" + SUFFIX ".metallib" + XCODE_ATTRIBUTE_EXECUTABLE_PREFIX "" + XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" +) +set_target_properties(pfMetalPipelineShadersMSL23 PROPERTIES + XCODE_PRODUCT_TYPE com.apple.product-type.metal-library + XCODE_ATTRIBUTE_MTL_LANGUAGE_REVISION Metal23 + XCODE_ATTRIBUTE_MTL_HEADER_SEARCH_PATHS "${Plasma_SOURCE_DIR}/Sources/Plasma/NucleusLib/inc/" + SUFFIX ".metallib" + XCODE_ATTRIBUTE_EXECUTABLE_PREFIX "" + XCODE_ATTRIBUTE_MTL_FAST_MATH "YES" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=Debug] "INCLUDE_SOURCE" + XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO[variant=RelWithDebInfo] "INCLUDE_SOURCE" +) +set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY pfMetalPipelineShadersMSL21 PROPERTIES LANGUAGE METAL) +set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY pfMetalPipelineShadersMSL23 PROPERTIES LANGUAGE METAL) -target_sources(pfMetalPipelineShaders INTERFACE ${pfMetalPipeline_SHADERS}) +target_sources(pfMetalPipelineShadersMSL21 PRIVATE ${pfMetalPipeline_SHADERS}) +target_sources(pfMetalPipelineShadersMSL23 PRIVATE ${pfMetalPipeline_SHADERS}) diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.cpp b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.cpp index d188e067ee..fad22cb8ab 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.cpp @@ -480,6 +480,8 @@ plMetalDevice::plMetalDevice() fReverseZStencilState = fMetalDevice->newDepthStencilState(depthDescriptor); depthDescriptor->release(); + + LoadLibrary(); } void plMetalDevice::SetViewport() @@ -1065,15 +1067,13 @@ void plMetalDevice::StartPipelineBuild(plMetalPipelineRecord& record, std::condi return; } - MTL::Library* library = fMetalDevice->newDefaultLibrary(); - std::shared_ptr pipelineState = record.state; MTL::RenderPipelineDescriptor* descriptor = MTL::RenderPipelineDescriptor::alloc()->init(); descriptor->setLabel(pipelineState->GetDescription()); - const MTL::Function* vertexFunction = pipelineState->GetVertexFunction(library); - const MTL::Function* fragmentFunction = pipelineState->GetFragmentFunction(library); + const MTL::Function* vertexFunction = pipelineState->GetVertexFunction(fShaderLibrary); + const MTL::Function* fragmentFunction = pipelineState->GetFragmentFunction(fShaderLibrary); descriptor->setVertexFunction(vertexFunction); descriptor->setFragmentFunction(fragmentFunction); @@ -1108,7 +1108,6 @@ void plMetalDevice::StartPipelineBuild(plMetalPipelineRecord& record, std::condi }); descriptor->release(); - library->release(); } plMetalDevice::plMetalLinkedPipeline* plMetalDevice::PipelineState(plMetalPipelineState* pipelineState) @@ -1241,12 +1240,9 @@ MTL::SamplerState* plMetalDevice::SampleStateForClampFlags(hsGMatState::hsGMatCl void plMetalDevice::CreateGammaAdjustState() { MTL::RenderPipelineDescriptor* gammaDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); - MTL::Library* library = fMetalDevice->newDefaultLibrary(); - - gammaDescriptor->setVertexFunction(library->newFunction(MTLSTR("gammaCorrectVertex"))->autorelease()); - gammaDescriptor->setFragmentFunction(library->newFunction(MTLSTR("gammaCorrectFragment"))->autorelease()); - library->release(); + gammaDescriptor->setVertexFunction(fShaderLibrary->newFunction(MTLSTR("gammaCorrectVertex"))->autorelease()); + gammaDescriptor->setFragmentFunction(fShaderLibrary->newFunction(MTLSTR("gammaCorrectFragment"))->autorelease()); gammaDescriptor->colorAttachments()->object(0)->setPixelFormat(fFramebufferFormat); diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.h b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.h index 9fbff73299..d94f13e56d 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.h +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDevice.h @@ -188,6 +188,8 @@ class plMetalDevice void EncodeBlur(MTL::CommandBuffer* commandBuffer, MTL::Texture* texture, float sigma); MTL::PixelFormat GetFramebufferFormat() const { return fFramebufferFormat; }; + + MTL::Library* GetShaderLibrary() { return fShaderLibrary; } private: struct plMetalPipelineRecord @@ -252,6 +254,10 @@ class plMetalDevice MTL::CommandBuffer* fBlitCommandBuffer; MTL::BlitCommandEncoder* fBlitCommandEncoder; + + MTL::Library* fShaderLibrary; + + void LoadLibrary(); bool NeedsPostprocessing() const { diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDeviceLibraryLoader.mm b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDeviceLibraryLoader.mm new file mode 100644 index 0000000000..2c57847119 --- /dev/null +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalDeviceLibraryLoader.mm @@ -0,0 +1,60 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +#include +#include +#include "plMetalDevice.h" + +void plMetalDevice::LoadLibrary() +{ + NS::Error* error; + if (@available(macOS 11, *)) + { + NSURL* shaderURL = [NSBundle.mainBundle URLForResource:@"pfMetalPipelineShadersMSL23" withExtension:@"metallib"]; + fShaderLibrary = fMetalDevice->newLibrary(static_cast(shaderURL), &error); + } + else + { + NSURL* shaderURL = [NSBundle.mainBundle URLForResource:@"pfMetalPipelineShadersMSL21" withExtension:@"metallib"]; + fShaderLibrary = fMetalDevice->newLibrary(static_cast(shaderURL), &error); + } +} diff --git a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp index 85f527ede2..951fd2590a 100644 --- a/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp +++ b/Sources/Plasma/FeatureLib/pfMetalPipeline/plMetalPipeline.cpp @@ -2744,7 +2744,7 @@ void plMetalPipeline::IPreprocessAvatarTextures() // But that hash map assumes that it follows the vertex arrangement of the models. // After a refactor, this function creation should go there. MTL::RenderPipelineDescriptor* descriptor = MTL::RenderPipelineDescriptor::alloc()->init()->autorelease(); - MTL::Library* library = fDevice.fMetalDevice->newDefaultLibrary()->autorelease(); + MTL::Library* library = fDevice.GetShaderLibrary(); MTL::Function* vertFunction = library->newFunction(MTLSTR("PreprocessAvatarVertexShader"))->autorelease(); MTL::Function* fragFunction = library->newFunction(MTLSTR("PreprocessAvatarFragmentShader"))->autorelease();