-
Notifications
You must be signed in to change notification settings - Fork 11
feat(metal): precompiled internal shaders #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3fe8ecc
fcafc75
9da75d6
7a57c94
2a1f96e
6d68916
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| # PlumeInternalShaders.cmake | ||
| # Internal shader compilation for Plume's built-in shaders (clear, resolve) | ||
|
|
||
| # Build the file_to_c tool for the host system | ||
| function(plume_build_file_to_c) | ||
| if(TARGET plume_file_to_c) | ||
| return() | ||
| endif() | ||
|
|
||
| set(FILE_TO_C_SOURCE "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/tools/file_to_c.cpp") | ||
|
|
||
| add_executable(plume_file_to_c ${FILE_TO_C_SOURCE}) | ||
| set_target_properties(plume_file_to_c PROPERTIES | ||
| RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plume_tools" | ||
| ) | ||
|
|
||
| if(APPLE) | ||
| set_target_properties(plume_file_to_c PROPERTIES | ||
| XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-" | ||
| ) | ||
| endif() | ||
| endfunction() | ||
|
|
||
| # Compile Metal shaders to embedded C headers | ||
| function(plume_compile_metal_shaders TARGET_NAME) | ||
| if(NOT APPLE) | ||
| return() | ||
| endif() | ||
|
|
||
| # Build the file_to_c tool | ||
| plume_build_file_to_c() | ||
|
|
||
| # Get the shader source directory | ||
| set(SHADER_DIR "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../shaders") | ||
| set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/plume_shaders") | ||
|
|
||
| # Create output directory | ||
| file(MAKE_DIRECTORY "${OUTPUT_DIR}") | ||
|
|
||
| # List of shaders to compile | ||
| set(PLUME_METAL_SHADERS | ||
| plume_clear | ||
| plume_resolve | ||
| ) | ||
|
|
||
| set(GENERATED_SOURCES "") | ||
| set(GENERATED_HEADERS "") | ||
|
|
||
| foreach(SHADER_NAME ${PLUME_METAL_SHADERS}) | ||
| set(SHADER_SOURCE "${SHADER_DIR}/${SHADER_NAME}.metal") | ||
| set(IR_OUTPUT "${OUTPUT_DIR}/${SHADER_NAME}.ir") | ||
| set(METALLIB_OUTPUT "${OUTPUT_DIR}/${SHADER_NAME}.metallib") | ||
| set(C_OUTPUT "${OUTPUT_DIR}/${SHADER_NAME}.metallib.c") | ||
| set(H_OUTPUT "${OUTPUT_DIR}/${SHADER_NAME}.metallib.h") | ||
|
|
||
| # Compile Metal to IR | ||
| add_custom_command( | ||
| OUTPUT ${IR_OUTPUT} | ||
| COMMAND xcrun -sdk macosx metal -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} -o ${IR_OUTPUT} -c ${SHADER_SOURCE} | ||
| DEPENDS ${SHADER_SOURCE} | ||
| COMMENT "Compiling ${SHADER_NAME}.metal to IR" | ||
| VERBATIM | ||
| ) | ||
|
|
||
| # Link IR to metallib | ||
| add_custom_command( | ||
| OUTPUT ${METALLIB_OUTPUT} | ||
| COMMAND xcrun -sdk macosx metallib ${IR_OUTPUT} -o ${METALLIB_OUTPUT} | ||
| DEPENDS ${IR_OUTPUT} | ||
| COMMENT "Linking ${SHADER_NAME} to metallib" | ||
| VERBATIM | ||
| ) | ||
|
|
||
| # Generate C header with embedded data | ||
| add_custom_command( | ||
| OUTPUT ${C_OUTPUT} ${H_OUTPUT} | ||
| COMMAND plume_file_to_c ${METALLIB_OUTPUT} "${SHADER_NAME}_metallib" ${C_OUTPUT} ${H_OUTPUT} | ||
| DEPENDS ${METALLIB_OUTPUT} plume_file_to_c | ||
| COMMENT "Generating embedded header for ${SHADER_NAME}" | ||
| VERBATIM | ||
| ) | ||
|
|
||
| list(APPEND GENERATED_SOURCES ${C_OUTPUT}) | ||
| list(APPEND GENERATED_HEADERS ${H_OUTPUT}) | ||
| endforeach() | ||
|
|
||
| # Add generated sources to the target | ||
| target_sources(${TARGET_NAME} PRIVATE ${GENERATED_SOURCES}) | ||
|
|
||
| # Add include directory for generated headers | ||
| target_include_directories(${TARGET_NAME} PRIVATE "${OUTPUT_DIR}") | ||
| endfunction() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| # Shader compilation functions for Plume | ||
| # Using DXC for HLSL to SPIR-V compilation and Metal for macOS | ||
|
|
||
| # Build file_to_c tool (shared with plume core) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason not to just unify this whole shader compilation utility with the new one? May be useful for consumers.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't want to make this PR too big, this one just aims to precompile and embed the shaders Metal uses -- but yes, I think I'll right after make a follow up PR that provides some primitives for shader compilation
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, sounds good. |
||
| include(${CMAKE_SOURCE_DIR}/cmake/PlumeInternalShaders.cmake) | ||
| plume_build_file_to_c() | ||
|
|
||
| # Fetch DXC for shader compilation | ||
| include(FetchContent) | ||
| FetchContent_Declare( | ||
|
|
@@ -13,7 +17,7 @@ FetchContent_MakeAvailable(dxc) | |
| # Set up DXC paths based on platform | ||
| if(WIN32) | ||
| set(DXC "${dxc_SOURCE_DIR}/bin/x64/dxc.exe") | ||
|
|
||
| # Dependencies that must be next to the DLL if on Windows | ||
| if(EXISTS "${dxc_SOURCE_DIR}/bin/x64/dxcompiler.dll") | ||
| configure_file("${dxc_SOURCE_DIR}/bin/x64/dxcompiler.dll" "${CMAKE_BINARY_DIR}/bin/dxcompiler.dll" COPYONLY) | ||
|
|
@@ -30,12 +34,12 @@ elseif(APPLE) | |
| set(DXC_EXECUTABLE "${dxc_SOURCE_DIR}/bin/arm64/dxc-macos") | ||
| set(DXC_LIB_DIR "${dxc_SOURCE_DIR}/lib/arm64") | ||
| endif() | ||
|
|
||
| # Make sure the executable is accessible and has execute permissions | ||
| if(EXISTS "${DXC_EXECUTABLE}") | ||
| # Set executable permission if needed | ||
| execute_process(COMMAND chmod +x "${DXC_EXECUTABLE}") | ||
|
|
||
| # Set DXC command with DYLD_LIBRARY_PATH | ||
| set(DXC "DYLD_LIBRARY_PATH=${DXC_LIB_DIR}" "${DXC_EXECUTABLE}") | ||
| else() | ||
|
|
@@ -50,7 +54,7 @@ else() | |
| set(DXC_EXECUTABLE "${dxc_SOURCE_DIR}/bin/arm64/dxc-linux") | ||
| set(DXC_LIB_DIR "${dxc_SOURCE_DIR}/lib/arm64") | ||
| endif() | ||
|
|
||
| # Make sure the executable is accessible and has execute permissions | ||
| if(EXISTS "${DXC_EXECUTABLE}") | ||
| # Set executable permission if needed | ||
|
|
@@ -85,10 +89,10 @@ function(build_shader_dxc_impl TARGET_NAME SHADER_SOURCE SHADER_TYPE OUTPUT_NAME | |
| set(SHADER_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.hlsl.${OUTPUT_EXT}") | ||
| set(C_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.hlsl.${OUTPUT_FORMAT}.c") | ||
| set(H_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.hlsl.${OUTPUT_FORMAT}.h") | ||
|
|
||
| # Create output directory | ||
| file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/shaders") | ||
|
|
||
| # Determine the shader options based on type | ||
| if(SHADER_TYPE STREQUAL "vertex") | ||
| set(SHADER_PROFILE "vs_6_0") | ||
|
|
@@ -107,7 +111,7 @@ function(build_shader_dxc_impl TARGET_NAME SHADER_SOURCE SHADER_TYPE OUTPUT_NAME | |
| endif() | ||
|
|
||
| set(BLOB_NAME "${OUTPUT_NAME}Blob${BLOB_SUFFIX}") | ||
|
|
||
| # Compile using DXC | ||
| add_custom_command( | ||
| OUTPUT ${SHADER_OUTPUT} | ||
|
|
@@ -116,18 +120,18 @@ function(build_shader_dxc_impl TARGET_NAME SHADER_SOURCE SHADER_TYPE OUTPUT_NAME | |
| DEPENDS ${SHADER_SOURCE} | ||
| COMMENT "Compiling ${SHADER_TYPE} shader ${SHADER_SOURCE} to ${OUTPUT_FORMAT} using DXC" | ||
| ) | ||
|
|
||
| # Generate C header | ||
| add_custom_command( | ||
| OUTPUT "${C_OUTPUT}" "${H_OUTPUT}" | ||
| COMMAND file_to_c ${SHADER_OUTPUT} "${BLOB_NAME}" "${C_OUTPUT}" "${H_OUTPUT}" | ||
| DEPENDS ${SHADER_OUTPUT} file_to_c | ||
| COMMAND plume_file_to_c ${SHADER_OUTPUT} "${BLOB_NAME}" "${C_OUTPUT}" "${H_OUTPUT}" | ||
| DEPENDS ${SHADER_OUTPUT} plume_file_to_c | ||
| COMMENT "Generating C header for ${OUTPUT_FORMAT} shader ${OUTPUT_NAME}" | ||
| ) | ||
|
|
||
| # Add the generated source file to the target | ||
| target_sources(${TARGET_NAME} PRIVATE "${C_OUTPUT}") | ||
|
|
||
| # Make sure the target can find the generated header | ||
| target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}") | ||
| endfunction() | ||
|
|
@@ -149,37 +153,37 @@ function(build_shader_metal_impl TARGET_NAME SHADER_SOURCE OUTPUT_NAME) | |
| set(IR_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.ir") | ||
| set(METAL_C_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.metal.c") | ||
| set(METAL_H_OUTPUT "${CMAKE_BINARY_DIR}/shaders/${OUTPUT_NAME}.metal.h") | ||
|
|
||
| # Create output directory | ||
| file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/shaders") | ||
|
|
||
| # Compile Metal to IR | ||
| add_custom_command( | ||
| OUTPUT ${IR_OUTPUT} | ||
| COMMAND xcrun -sdk macosx metal -o ${IR_OUTPUT} -c ${SHADER_SOURCE} | ||
| DEPENDS ${SHADER_SOURCE} | ||
| COMMENT "Compiling Metal shader to IR" | ||
| ) | ||
|
|
||
| # Compile IR to metallib | ||
| add_custom_command( | ||
| OUTPUT ${METALLIB_OUTPUT} | ||
| COMMAND xcrun -sdk macosx metallib ${IR_OUTPUT} -o ${METALLIB_OUTPUT} | ||
| DEPENDS ${IR_OUTPUT} | ||
| COMMENT "Compiling Metal IR to metallib" | ||
| ) | ||
|
|
||
| # Generate C header | ||
| add_custom_command( | ||
| OUTPUT "${METAL_C_OUTPUT}" "${METAL_H_OUTPUT}" | ||
| COMMAND file_to_c ${METALLIB_OUTPUT} "${OUTPUT_NAME}BlobMSL" "${METAL_C_OUTPUT}" "${METAL_H_OUTPUT}" | ||
| DEPENDS ${METALLIB_OUTPUT} file_to_c | ||
| COMMAND plume_file_to_c ${METALLIB_OUTPUT} "${OUTPUT_NAME}BlobMSL" "${METAL_C_OUTPUT}" "${METAL_H_OUTPUT}" | ||
| DEPENDS ${METALLIB_OUTPUT} plume_file_to_c | ||
| COMMENT "Generating C header for Metal shader ${OUTPUT_NAME}" | ||
| ) | ||
|
|
||
| # Add the generated source file to the target | ||
| target_sources(${TARGET_NAME} PRIVATE "${METAL_C_OUTPUT}") | ||
|
|
||
| # Make sure the target can find the generated header | ||
| target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}") | ||
| endfunction() | ||
|
|
@@ -188,7 +192,7 @@ endfunction() | |
| function(compile_shader TARGET_NAME SHADER_SOURCE SHADER_TYPE OUTPUT_NAME ENTRY_POINT) | ||
| # Get the file extension to determine the shader language | ||
| get_filename_component(SHADER_EXT ${SHADER_SOURCE} EXT) | ||
|
|
||
| # Compile based on extension | ||
| if(SHADER_EXT MATCHES ".*\\.metal$") | ||
| # Compile Metal shader | ||
|
|
@@ -198,7 +202,7 @@ function(compile_shader TARGET_NAME SHADER_SOURCE SHADER_TYPE OUTPUT_NAME ENTRY_ | |
| elseif(SHADER_SOURCE MATCHES ".*\\.hlsl$") | ||
| # Compile HLSL shader to SPIR-V using DXC | ||
| build_shader_spirv_impl(${TARGET_NAME} ${SHADER_SOURCE} ${SHADER_TYPE} ${OUTPUT_NAME} ${ENTRY_POINT}) | ||
|
|
||
| # Also compile to DXIL on Windows | ||
| if(WIN32) | ||
| build_shader_dxil_impl(${TARGET_NAME} ${SHADER_SOURCE} ${SHADER_TYPE} ${OUTPUT_NAME} ${ENTRY_POINT}) | ||
|
|
@@ -212,8 +216,8 @@ function(file_to_c_header INPUT_FILE OUTPUT_FILE VARIABLE_NAME) | |
| add_custom_command( | ||
| OUTPUT ${OUTPUT_FILE} | ||
| COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/shaders | ||
| COMMAND ${CMAKE_BINARY_DIR}/bin/file_to_c ${INPUT_FILE} ${OUTPUT_FILE} ${VARIABLE_NAME} ${VARIABLE_NAME}Size | ||
| DEPENDS ${INPUT_FILE} file_to_c | ||
| COMMAND plume_file_to_c ${INPUT_FILE} ${VARIABLE_NAME} ${OUTPUT_FILE} ${OUTPUT_FILE} | ||
| DEPENDS ${INPUT_FILE} plume_file_to_c | ||
| COMMENT "Converting ${INPUT_FILE} to C header" | ||
| ) | ||
| endfunction() | ||
| endfunction() | ||
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
realized we'd never set one, best to set one