mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-04 05:04:33 +00:00
CMake: Simplify Metal shader build
Don't need multiple versions.
This commit is contained in:
@@ -1,47 +1,32 @@
|
||||
# Borrowed from PCSX2.
|
||||
|
||||
if(APPLE)
|
||||
function(add_metal_sources target sources)
|
||||
if(CMAKE_GENERATOR MATCHES "Xcode")
|
||||
# If we're generating an xcode project, you can just add the shaders to the main pcsx2 target and xcode will deal with them properly
|
||||
# This will make sure xcode supplies code completion, etc (if you use a custom command, it won't)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
XCODE_ATTRIBUTE_MTL_ENABLE_DEBUG_INFO INCLUDE_SOURCE
|
||||
function(add_metal_sources target sources library_name metal_std)
|
||||
set(air_files)
|
||||
set(compile_flags -std=${metal_std} -ffast-math)
|
||||
|
||||
foreach(source IN LISTS sources)
|
||||
get_filename_component(source_name ${source} NAME)
|
||||
set(air_file ${CMAKE_CURRENT_BINARY_DIR}/${library_name}/${source_name}.air)
|
||||
list(APPEND air_files ${air_file})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${air_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${library_name}
|
||||
COMMAND xcrun metal ${compile_flags} -o ${air_file} -c ${source}
|
||||
DEPENDS ${source}
|
||||
COMMENT "Compiling Metal shader ${source_name}"
|
||||
)
|
||||
foreach(shader IN LISTS sources)
|
||||
target_sources(${target} PRIVATE ${shader})
|
||||
set_source_files_properties(${shader} PROPERTIES LANGUAGE METAL)
|
||||
endforeach()
|
||||
else()
|
||||
function(generateMetallib std triple outputName)
|
||||
set(MetalShaderOut)
|
||||
set(flags
|
||||
-ffast-math
|
||||
$<$<NOT:$<CONFIG:Release,MinSizeRel>>:-gline-tables-only>
|
||||
$<$<NOT:$<CONFIG:Release,MinSizeRel>>:-MO>
|
||||
)
|
||||
foreach(shader IN LISTS sources)
|
||||
file(RELATIVE_PATH relativeShader "${CMAKE_SOURCE_DIR}" "${shader}")
|
||||
set(shaderOut ${CMAKE_CURRENT_BINARY_DIR}/${outputName}/${relativeShader}.air)
|
||||
list(APPEND MetalShaderOut ${shaderOut})
|
||||
get_filename_component(shaderDir ${shaderOut} DIRECTORY)
|
||||
add_custom_command(OUTPUT ${shaderOut}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${shaderDir}
|
||||
COMMAND xcrun metal ${flags} -std=${std} -target ${triple} -o ${shaderOut} -c ${shader}
|
||||
DEPENDS ${shader}
|
||||
)
|
||||
set(metallib ${CMAKE_CURRENT_BINARY_DIR}/${outputName}.metallib)
|
||||
endforeach()
|
||||
add_custom_command(OUTPUT ${metallib}
|
||||
COMMAND xcrun metallib -o ${metallib} ${MetalShaderOut}
|
||||
DEPENDS ${MetalShaderOut}
|
||||
)
|
||||
target_sources(${target} PRIVATE ${metallib})
|
||||
set_source_files_properties(${metallib} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
endfunction()
|
||||
generateMetallib(macos-metal2.0 air64-apple-macos10.13 default)
|
||||
generateMetallib(macos-metal2.2 air64-apple-macos10.15 Metal22)
|
||||
generateMetallib(macos-metal2.3 air64-apple-macos11.0 Metal23)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(metallib_file ${CMAKE_CURRENT_BINARY_DIR}/${library_name}.metallib)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${metallib_file}
|
||||
COMMAND xcrun metallib -o ${metallib_file} ${air_files}
|
||||
DEPENDS ${air_files}
|
||||
COMMENT "Linking Metal library ${library_name}.metallib"
|
||||
)
|
||||
|
||||
target_sources(${target} PRIVATE ${metallib_file})
|
||||
set_source_files_properties(${metallib_file} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
endfunction()
|
||||
endif()
|
||||
@@ -293,7 +293,7 @@ endif()
|
||||
function(add_util_resources target)
|
||||
if(APPLE)
|
||||
get_property(UTIL_METAL_SOURCES GLOBAL PROPERTY UTIL_METAL_SOURCES)
|
||||
add_metal_sources(${target} ${UTIL_METAL_SOURCES})
|
||||
add_metal_sources(${target} ${UTIL_METAL_SOURCES} metal_shaders macos-metal2.3)
|
||||
|
||||
# Copy MoltenVK into the bundle
|
||||
unset(MOLTENVK_PATH CACHE)
|
||||
|
||||
@@ -374,7 +374,7 @@ private:
|
||||
static_assert(sizeof(ClearPipelineConfig) == 8);
|
||||
|
||||
void SetFeatures(CreateFlags create_flags);
|
||||
bool LoadShaders();
|
||||
bool LoadShaders(Error* error);
|
||||
|
||||
std::unique_ptr<GPUShader> CreateShaderFromMSL(GPUShaderStage stage, std::string_view source,
|
||||
std::string_view entry_point, Error* error);
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
LOG_CHANNEL(GPUDevice);
|
||||
|
||||
// Can't include settings.h, nasty...
|
||||
namespace EmuFolders {
|
||||
extern std::string Resources;
|
||||
}
|
||||
|
||||
// TODO: Disable hazard tracking and issue barriers explicitly.
|
||||
|
||||
// Used for shader "binaries".
|
||||
@@ -356,11 +361,8 @@ bool MetalDevice::CreateDeviceAndMainSwapChain(std::string_view adapter, CreateF
|
||||
RenderBlankFrame(static_cast<MetalSwapChain*>(m_main_swap_chain.get()));
|
||||
}
|
||||
|
||||
if (!LoadShaders())
|
||||
{
|
||||
Error::SetStringView(error, "Failed to load shaders.");
|
||||
if (!LoadShaders(error))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateBuffers(error))
|
||||
return false;
|
||||
@@ -415,35 +417,29 @@ void MetalDevice::SetFeatures(CreateFlags create_flags)
|
||||
!HasCreateFlag(create_flags, CreateFlags::DisableCompressedTextures) && m_device.supportsBCTextureCompression;
|
||||
}
|
||||
|
||||
bool MetalDevice::LoadShaders()
|
||||
bool MetalDevice::LoadShaders(Error* error)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
auto try_lib = [this](NSString* name) -> id<MTLLibrary> {
|
||||
NSBundle* bundle = [NSBundle mainBundle];
|
||||
NSString* path = [bundle pathForResource:name ofType:@"metallib"];
|
||||
if (path == nil)
|
||||
{
|
||||
// Xcode places it alongside the binary.
|
||||
path = [NSString stringWithFormat:@"%@/%@.metallib", [bundle bundlePath], name];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path])
|
||||
return nil;
|
||||
}
|
||||
static constexpr const char* shader_lib_filename = "metal_shaders.metallib";
|
||||
|
||||
NSURL* url = [NSURL fileURLWithPath:path];
|
||||
id<MTLLibrary> lib = [m_device newLibraryWithURL:url error:nil];
|
||||
if (lib == nil)
|
||||
return nil;
|
||||
|
||||
return [lib retain];
|
||||
};
|
||||
|
||||
if (!(m_shaders = try_lib(@"Metal23")) && !(m_shaders = try_lib(@"Metal22")) &&
|
||||
!(m_shaders = try_lib(@"Metal21")) && !(m_shaders = try_lib(@"default")))
|
||||
std::string path = Path::Combine(EmuFolders::Resources, shader_lib_filename);
|
||||
if (!FileSystem::FileExists(path.c_str()))
|
||||
{
|
||||
Error::SetStringFmt(error, "{} was not found", shader_lib_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
NSError* nserror = nil;
|
||||
NSURL* url = [NSURL fileURLWithPath:CocoaTools::StringViewToNSString(path)];
|
||||
id<MTLLibrary> lib = [m_device newLibraryWithURL:url error:&nserror];
|
||||
if (lib == nil)
|
||||
{
|
||||
CocoaTools::NSErrorToErrorObject(error, "newLibraryWithURL failed: ", nserror);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_shaders = [lib retain];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user