WIP | Add slang + compile slang and optimize spirv

This commit is contained in:
2026-09-15 20:47:21 -04:00
parent c33b7e844d
commit 723f2c8b29
16 changed files with 639 additions and 114 deletions
+358
View File
@@ -0,0 +1,358 @@
---
Language: Cpp
AlignAfterOpenBracket: true
AccessModifierOffset: -1
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
AlignPPAndNotPP: true
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowBreakBeforeQtProperty: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: true
BinPackLongBracedList: true
BinPackParameters: BinPack
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterOpenBracketBracedList: false
BreakAfterOpenBracketFunction: false
BreakAfterOpenBracketIf: false
BreakAfterOpenBracketLoop: false
BreakAfterOpenBracketSwitch: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeCloseBracketBracedList: false
BreakBeforeCloseBracketFunction: false
BreakBeforeCloseBracketIf: false
BreakBeforeCloseBracketLoop: false
BreakBeforeCloseBracketSwitch: false
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 120
CommentPragmas: "^ IWYU pragma:"
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: AlignFirstComment
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: "^<.*"
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: ".*"
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: "([-_](test|unittest))?$"
IncludeIsMainSourceRegex: ""
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigitsInsert: 0
BinaryMaxDigitsRemove: 0
Decimal: 0
DecimalMinDigitsInsert: 0
DecimalMaxDigitsRemove: 0
Hex: 0
HexMinDigitsInsert: 0
HexMaxDigitsRemove: 0
BinaryMinDigits: 0
DecimalMinDigits: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ""
MacroBlockEnd: ""
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
NumericLiteralCase:
ExponentLetter: Leave
HexDigit: Leave
Prefix: Leave
Suffix: Leave
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ""
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- "c++"
- "C++"
CanonicalDelimiter: ""
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
IgnoreExtension: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBraces: Never
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...
+3
View File
@@ -0,0 +1,3 @@
CompileFlags:
Add: -Wno-unknown-warning-option
Remove: [-m*, -f*]
+3 -1
View File
@@ -1,2 +1,4 @@
build/ build/
.idea .idea/
bin/
/bin/
+32 -23
View File
@@ -1,42 +1,51 @@
cmake_minimum_required(VERSION 4.1) cmake_minimum_required(VERSION 4.1)
project(triangle) project(triangle)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}/")
set(ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets")
##### Project settings ###### set(BUILD_SHARED_LIBS OFF)
# Set the assets directory
set(ASSETS_DIR "assets")
set(SHADERS_DIR "assets/shaders")
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(BUILD_SHARED_LIBS ON)
else()
set(BUILD_SHARED_LIBS OFF)
endif()
##### Dependencies #####
set(CMAKE_POLICY_VERSION_MINIMUM 3.5) set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
option(ENABLE_CPP20_MODULE "Enable C++ 20 module support for Vulkan" OFF) option(ENABLE_CPP20_MODULE "Enable C++ 20 module support for Vulkan" OFF)
file(GLOB CMAKE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/*.cmake")
foreach(cmake_file ${CMAKE_FILES})
include(${cmake_file})
endforeach()
##### Project actions ##### set (CMAKE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/compileCommands.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/copy_files.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Vulkan.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/GLFW.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/spirv-headers.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/spirv-tools.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/slang-src.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/spirv-reflect.cmake"
)
foreach (cmake_file ${CMAKE_FILES})
include (${cmake_file})
endforeach ()
create_copy_folder_target(copy_assets_folder ${ASSETS_DIR} "${BINARY_DIR}/assets")
# Define out executable
file(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") file(GLOB SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h") file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEADER_FILES}) add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEADER_FILES})
# Add the shaders dependency set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${BINARY_DIR}")
add_dependencies(${PROJECT_NAME} slang_shaders) add_dependencies(${PROJECT_NAME} copy_assets_folder)
add_dependencies(${PROJECT_NAME} glsl_shaders)
target_include_directories(${PROJECT_NAME} PUBLIC "${glfw_SOURCE_DIR}/include") target_include_directories(${PROJECT_NAME} PUBLIC
"${glfw_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
# Link with libs
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}
slang
slang-rt
core # slang::core
SPIRV-Tools-opt
spirv-reflect-static
glfw glfw
Vulkan::cppm Vulkan::cppm
) )
+1 -1
View File
@@ -6,6 +6,6 @@ CPMAddPackage (
OPTIONS "GLFW_BUILD_DOCS OFF" OPTIONS "GLFW_BUILD_DOCS OFF"
OPTIONS "GLFW_BUILD_TEST OFF" OPTIONS "GLFW_BUILD_TEST OFF"
OPTIONS "GLFW_BUILD_EXAMPLES OFF" OPTIONS "GLFW_BUILD_EXAMPLES OFF"
OPTIONS "GLFW_BUILD_X11 OFF" OPTIONS "GLFW_BUILD_X11 ON"
OPTIONS "GLFW_BUILD_WAYLAND ON" OPTIONS "GLFW_BUILD_WAYLAND ON"
) )
+11
View File
@@ -0,0 +1,11 @@
function(create_copy_folder_target target_name src dst)
add_custom_target(${target_name}
COMMAND
${CMAKE_COMMAND}
-E copy_directory
${src}
${dst}
COMMENT "Copying ${src} to ${dst}"
)
endfunction()
-37
View File
@@ -1,37 +0,0 @@
option(SHADERS_DIR "Directory to look for GLSL shaders" "assets/shaders")
find_program(GLSLC_EXECUTABLE NAMES glslc)
if(NOT GLSLC_EXECUTABLE)
message(FATAL_ERROR "glslc executable not found.")
else()
message(STATUS "Found glslc executable: ${GLSLC_EXECUTABLE}")
endif()
function(create_glslc_shader_target TARGET SOURCE_DIR OUTPUT_DIR)
file(MAKE_DIRECTORY ${OUTPUT_DIR})
message(STATUS "GLSL Shader output directory: ${OUTPUT_DIR}")
file (GLOB SHADER_FILES "${SOURCE_DIR}/*.vert")
file(GLOB FRAG_FILES "${SOURCE_DIR}/*.frag")
list(APPEND SHADER_FILES ${FRAG_FILES})
message(STATUS "Found glsl shaders: ${SHADER_FILES}")
set(OUTPUT_FILES "")
foreach(SHADER_FILE ${SHADER_FILES})
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME)
set(OUTPUT_FILE "${OUTPUT_DIR}/${SHADER_NAME}.spv")
list(APPEND OUTPUT_FILES ${OUTPUT_FILE})
message(STATUS "Compiling ${SHADER_FILE} to ${OUTPUT_FILE}")
add_custom_command (
OUTPUT ${OUTPUT_FILE}
COMMAND ${GLSLC_EXECUTABLE} ${SHADER_FILE} -o ${OUTPUT_FILE}
DEPENDS ${SHADER_FILE}
COMMENT "Compiling ${SHADER_FILE} -> ${OUTPUT_FILE}"
VERBATIM
)
endforeach()
add_custom_target(${TARGET} ALL DEPENDS ${OUTPUT_FILES})
endfunction()
create_glslc_shader_target(glsl_shaders
"${SHADERS_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${SHADERS_DIR}"
)
+49
View File
@@ -0,0 +1,49 @@
set(SLANG_ENABLE_CUDA OFF CACHE BOOL "")
set(SLANG_ENABLE_OPTIX OFF CACHE BOOL "")
set(SLANG_ENABLE_NVAPI OFF CACHE BOOL "")
set(SLANG_ENABLE_XLIB OFF CACHE BOOL "")
set(SLANG_ENABLE_AFTERMATH OFF CACHE BOOL "")
set(SLANG_ENABLE_DX_ON_VK OFF CACHE BOOL "")
set(SLANG_ENABLE_GFX OFF CACHE BOOL "")
set(SLANG_ENABLE_SLANG_RHI OFF CACHE BOOL "")
set(SLANG_ENABLE_SLANGC ON CACHE BOOL "")
set(SLANG_ENABLE_SLANGRT ON CACHE BOOL "")
set(SLANG_ENABLE_SLANG_GLSLANG OFF CACHE BOOL "")
set(SLANG_ENABLE_TESTS OFF CACHE BOOL "")
set(SLANG_ENABLE_EXAMPLES OFF CACHE BOOL "")
set(SLANG_ENABLE_REPLAYER OFF CACHE BOOL "")
set(SLANG_ENABLE_PREBUILT_BINARIES OFF CACHE BOOL "")
set(SLANG_EMBED_CORE_MODULE_SOURCE OFF CACHE BOOL "")
set(SLANG_ENABLE_DXIL OFF CACHE BOOL "")
set(SLANG_LIB_TYPE STATIC CACHE STRING "")
set(SLANG_RHI_ENABLE_D3D11 OFF CACHE BOOL "")
set(SLANG_RHI_ENABLE_D3D12 OFF CACHE BOOL "")
set(SLANG_RHI_ENABLE_METAL OFF CACHE BOOL "")
set(SLANG_RHI_ENABLE_CUDA OFF CACHE BOOL "")
set(SLANG_RHI_ENABLE_WGPU OFF CACHE BOOL "")
CPMAddPackage(
URI "gh:shader-slang/slang@2026.14"
OPTIONS "SLANG_ENABLE_CUDA OFF"
OPTIONS "SLANG_ENABLE_OPTIX OFF"
OPTIONS "SLANG_ENABLE_NVAPI OFF"
OPTIONS "SLANG_ENABLE_XLIB OFF"
OPTIONS "SLANG_ENABLE_AFTERMATH OFF"
OPTIONS "SLANG_ENABLE_DX_ON_VK OFF"
OPTIONS "SLANG_ENABLE_GFX OFF"
OPTIONS "SLANG_ENABLE_SLANG_RHI OFF"
OPTIONS "SLANG_ENABLE_SLANGC ON"
OPTIONS "SLANG_ENABLE_SLANGRT ON"
OPTIONS "SLANG_ENABLE_SLANG_GLSLANG OFF"
OPTIONS "SLANG_ENABLE_TESTS OFF"
OPTIONS "SLANG_ENABLE_REPLAYER OFF"
OPTIONS "SLANG_ENABLE_PREBUILT_BINARIES OFF"
OPTIONS "SLANG_EMBED_CORE_MODULE_SOURCE OFF"
OPTIONS "SLANG_ENABLE_DXIL OFF"
OPTIONS "SLANG_LIB_TYPE STATIC"
OPTIONS "SLANG_RHI_ENABLE_D3D11 OFF"
OPTIONS "SLANG_RHI_ENABLE_D3D12 OFF"
OPTIONS "SLANG_RHI_ENABLE_METAL OFF"
OPTIONS "SLANG_RHI_ENABLE_CUDA OFF"
OPTIONS "SLANG_RHI_ENABLE_WGPU OFF"
)
-36
View File
@@ -1,36 +0,0 @@
option(SHADERS_DIR "Directory to look for SLANG shaders" "assets/shaders")
find_program(SLANGC_EXECUTABLE NAMES slangc)
if(NOT SLANGC_EXECUTABLE)
message(FATAL_ERROR "slangc executable not found.")
else()
message(STATUS "Found slangc executable: ${SLANGC_EXECUTABLE}")
endif()
function(create_slang_shader_target TARGET SOURCE_DIR OUTPUT_DIR)
file(MAKE_DIRECTORY ${OUTPUT_DIR})
message(STATUS "Shader output directory: ${OUTPUT_DIR}")
file(GLOB SHADER_FILES "${SOURCE_DIR}/*.slang")
message(STATUS "Found shaders: ${SHADER_FILES}")
set(ENTRY_POINTS -entry vertMain -entry fragMain)
set(OUTPUT_FILES "")
foreach(SHADER_FILE ${SHADER_FILES})
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE)
set(OUTPUT_FILE "${OUTPUT_DIR}/${SHADER_NAME}.spv")
list(APPEND OUTPUT_FILES ${OUTPUT_FILE})
message(STATUS "Compiling ${SHADER_FILE} to ${OUTPUT_FILE}")
add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMAND ${SLANGC_EXECUTABLE} ${SHADER_FILE} -target spirv -profile spirv_1_4 -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o ${OUTPUT_FILE}
DEPENDS ${SHADER_FILE}
COMMENT "Compiling ${SHADER_FILE} -> ${OUTPUT_FILE}"
VERBATIM
)
endforeach()
add_custom_target(${TARGET} ALL DEPENDS ${OUTPUT_FILES})
endfunction()
create_slang_shader_target(slang_shaders
"${SHADERS_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/${SHADERS_DIR}"
)
+7
View File
@@ -0,0 +1,7 @@
CPMAddPackage(
URL "https://github.com/KhronosGroup/SPIRV-Headers/archive/refs/tags/vulkan-sdk-1.4.357.0.zip"
NAME SPIRV-Headers
OPTIONS "SPIRV_SKIP_TESTS TRUE"
OPTIONS "SPIRV_SKIP_EXECUTABLES TRUE"
OPTIONS "SPIRV_WERROR FALSE"
)
+9
View File
@@ -0,0 +1,9 @@
CPMAddPackage(
URI "https://github.com/KhronosGroup/SPIRV-Reflect/archive/refs/tags/vulkan-sdk-1.4.357.0.zip"
NAME SPIRV-Reflect
OPTIONS "SPIRV_SKIP_TESTS ON"
OPTIONS "SPIRV_SKIP_EXECUTABLES ON"
OPTIONS "SPIRV_WERROR OFF"
OPTIONS "SPIRV_REFLECT_EXECUTABLE OFF"
OPTIONS "SPIRV_REFLECT_STATIC_LIB ON"
)
+11
View File
@@ -0,0 +1,11 @@
CPMAddPackage(
NAME SPIRV-Tools
GIT_REPOSITORY "https://github.com/KhronosGroup/SPIRV-Tools"
GIT_TAG "vulkan-sdk-1.4.357"
OPTIONS "SPIRV_SKIP_TESTS ON"
OPTIONS "SPIRV_SKIP_EXECUTABLES ON"
OPTIONS "SPIRV_WERROR OFF"
)
if (TARGET spirv-tools-check-python-tests)
set_target_properties(spirv-tools-check-python-tests PROPERTIES EXCLUDE_FROM_ALL ON)
endif ()
+5 -1
View File
@@ -2,6 +2,8 @@
// INCLUDES // // INCLUDES //
// Include vulkan // Include vulkan
#include "slang.h"
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@@ -106,7 +108,9 @@ private:
// Shader // // Shader //
static std::vector<char> readFile(const std::string &filename); static std::vector<char> readFile(const std::string &filename);
[[nodiscard]] vk::raii::ShaderModule createShaderModule(const std::vector<char> &code) const; [[nodiscard]] vk::raii::ShaderModule createShaderModule(const std::vector<uint8_t> &code) const;
static void compileShaderSlang(slang::IGlobalSession *&slangGlobalSession, const char* code, const char* entryPointName, std::vector<uint8_t> *outSPIRV);
static void optimizeSPIRV(std::vector<uint8_t> *inoutSPIRV);
// Pipeline // // Pipeline //
void createGraphicsPipeline(); void createGraphicsPipeline();
+2
View File
@@ -5,6 +5,8 @@ int main() {
// Create the application // Create the application
Application app; Application app;
// TODO: Add slang global session destroy
try { try {
// Run le app // Run le app
app.run(); app.run();
+16 -7
View File
@@ -1,21 +1,30 @@
#include "app.h"
#include "slang-com-ptr.h"
#include "vulkan/vulkan.hpp"
#include <cstdint> #include <cstdint>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_raii.hpp> #include <vulkan/vulkan_raii.hpp>
#include "app.h"
#include "vulkan/vulkan.hpp"
void Application::createGraphicsPipeline() { void Application::createGraphicsPipeline() {
// Load in the shader // Load in the shader
auto shaderCode = readFile("assets/shaders/shader.spv"); auto shaderCode = readFile("assets/shaders/shader.slang");
// Create the shader module std::vector<uint8_t> vertCode;
vk::raii::ShaderModule shaderModule = createShaderModule(shaderCode); std::vector<uint8_t> fragCode;
Slang::ComPtr<slang::IGlobalSession> slangGlobalSession;
compileShaderSlang(*slangGlobalSession.writeRef(), shaderCode.data(), "vertMain", &vertCode);
compileShaderSlang(*slangGlobalSession.writeRef(), shaderCode.data(), "fragMain", &fragCode);
// Create the vertex shader module
vk::raii::ShaderModule vertModule = createShaderModule(vertCode);
// Create the fragment shader module
vk::raii::ShaderModule fragModule = createShaderModule(fragCode);
// Define the fragment and vertex shader stages, making sure to specify "vertMain" and "fragMain" are the entry // Define the fragment and vertex shader stages, making sure to specify "vertMain" and "fragMain" are the entry
// points // points
vk::PipelineShaderStageCreateInfo vertShaderStageInfo{ vk::PipelineShaderStageCreateInfo vertShaderStageInfo{
.stage = vk::ShaderStageFlagBits::eVertex, .module = shaderModule, .pName = "vertMain"}; .stage = vk::ShaderStageFlagBits::eVertex, .module = vertModule, .pName = "vertMain"};
vk::PipelineShaderStageCreateInfo fragShaderStageInfo{ vk::PipelineShaderStageCreateInfo fragShaderStageInfo{
.stage = vk::ShaderStageFlagBits::eFragment, .module = shaderModule, .pName = "fragMain"}; .stage = vk::ShaderStageFlagBits::eFragment, .module = fragModule, .pName = "fragMain"};
// Make sure the stages are in an array so its easier to pass on later on // Make sure the stages are in an array so its easier to pass on later on
vk::PipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo}; vk::PipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
+128 -4
View File
@@ -1,7 +1,13 @@
#include <fstream>
#include <vulkan/vulkan_raii.hpp>
#include "app.h" #include "app.h"
#include "vulkan/vulkan.hpp" #include "vulkan/vulkan.hpp"
#include <bits/regex_constants.h>
#include <core/slang-basic.h>
#include <fstream>
#include <slang-com-helper.h>
#include <slang-com-ptr.h>
#include <slang.h>
#include <spirv-tools/optimizer.hpp>
#include <vulkan/vulkan_raii.hpp>
std::vector<char> Application::readFile(const std::string &filename) { std::vector<char> Application::readFile(const std::string &filename) {
// Load the file in, checking to make sure it openned without errors // Load the file in, checking to make sure it openned without errors
@@ -21,8 +27,8 @@ std::vector<char> Application::readFile(const std::string &filename) {
return buffer; return buffer;
} }
vk::raii::ShaderModule Application::createShaderModule(const std::vector<char> &code) const { vk::raii::ShaderModule Application::createShaderModule(const std::vector<uint8_t> &code) const {
// Create the shader module (feel like this is self explainatory enough to not need a comment at all...) // Create the shader module (feel like this is self explanatory enough to not need a comment at all...)
vk::ShaderModuleCreateInfo createInfo{.codeSize = code.size() * sizeof(char), vk::ShaderModuleCreateInfo createInfo{.codeSize = code.size() * sizeof(char),
.pCode = reinterpret_cast<const uint32_t *>(code.data())}; .pCode = reinterpret_cast<const uint32_t *>(code.data())};
@@ -30,3 +36,121 @@ vk::raii::ShaderModule Application::createShaderModule(const std::vector<char> &
return shaderModule; return shaderModule;
} }
void Application::compileShaderSlang(slang::IGlobalSession *&slangGlobalSession,
const char *code,
const char *entryPointName,
std::vector<uint8_t> *outSPIRV) {
if (!slangGlobalSession) {
Slang::ComPtr<slang::IGlobalSession> globalSession;
if (SLANG_FAILED(slang::createGlobalSession(globalSession.writeRef()))) {
throw std::runtime_error("Failed to create slang global session");
}
slangGlobalSession = globalSession.detach();
}
// clang-format off
const slang::CompilerOptionEntry compilerOptions[] = {
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "SPV_GOOGLE_user_type"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvDerivativeControl"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvImageQuery"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvImageGatherExtended"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvSparseResidency"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvMinLog"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvFragmentFullyCoveredEXT"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvRayTracingPositionFetchKHR"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvRayQueryKHR"}},
{.name = slang::CompilerOptionName::Capability, .value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvInt64Atomics"}},
};
// clang-format on
const slang::TargetDesc targetDesc = {
.format = SLANG_SPIRV,
.profile = slangGlobalSession->findProfile("spirv_1_6"),
.flags = SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY,
.forceGLSLScalarBufferLayout = true,
.compilerOptionEntries = &compilerOptions[0],
// You really should have a function that figures out the size of an
// array, but honestly even this function is beyond the scope of this
// project so im just hardcoding it for now.
.compilerOptionEntryCount = 10,
};
const slang::CompilerOptionEntry sessionOptions[] = {
{
.name = slang::CompilerOptionName::DisableWarning,
.value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "39001"},
},
};
const slang::SessionDesc sessionDesc = {
.targets = &targetDesc,
.targetCount = 1,
.compilerOptionEntries = sessionOptions,
// The same goes here as above, this *should* be automated.
.compilerOptionEntryCount = 1,
};
Slang::ComPtr<slang::ISession> session;
if (SLANG_FAILED(slangGlobalSession->createSession(sessionDesc, session.writeRef()))) {
throw std::runtime_error("Failed to create slang session.");
}
slang::IModule *slangModule = nullptr;
{
Slang::ComPtr<slang::IBlob> diagnosticBlob;
slangModule = session->loadModuleFromSourceString("", "", code, diagnosticBlob.writeRef());
if (diagnosticBlob)
printf("%s", static_cast<const char *>(diagnosticBlob->getBufferPointer()));
if (!slangModule)
throw std::runtime_error("Failed to load slang module from source string.");
}
Slang::ComPtr<slang::IEntryPoint> entryPoint;
if (SLANG_FAILED(slangModule->findEntryPointByName(entryPointName, entryPoint.writeRef())))
throw std::runtime_error("Failed to find slang shader entry point.");
Slang::List<slang::IComponentType*> componentTypes;
componentTypes.add(slangModule);
componentTypes.add(entryPoint);
Slang::ComPtr<slang::IComponentType> composedProgram;
{
Slang::ComPtr<slang::IBlob> diagnosticBlob;
SlangResult result = session->createCompositeComponentType(componentTypes.getBuffer(), componentTypes.getCount(), composedProgram.writeRef(), diagnosticBlob.writeRef());
if (diagnosticBlob)
printf("%s\n", static_cast<const char*>(diagnosticBlob->getBufferPointer()));
if (SLANG_FAILED(result))
throw std::runtime_error("Failed to create slang composite component type.");
}
Slang::ComPtr<slang::IBlob> spirvCode;
{
Slang::ComPtr<slang::IBlob> diagnosticBlob;
constexpr int entryPointIndex = 0;
const SlangResult result = composedProgram->getEntryPointCode(entryPointIndex, 0, spirvCode.writeRef(), diagnosticBlob.writeRef());
if (diagnosticBlob)
printf("%s\n", static_cast<const char*>(diagnosticBlob->getBufferPointer()));
if (SLANG_FAILED(result))
throw std::runtime_error("Failed to get code entry point.");
}
const auto *ptr = reinterpret_cast<const uint8_t*>(spirvCode->getBufferPointer());
*outSPIRV = std::vector<uint8_t>(ptr, ptr + spirvCode->getBufferSize());
}
void Application::optimizeSPIRV(std::vector<uint8_t> *inoutSPIRV) {
spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_4);
optimizer.RegisterPerformancePasses();
optimizer.SetMessageConsumer([](spv_message_level_t level, const char*, const spv_position_t &, const char* msg) {
if (level <= SPV_MSG_WARNING)
printf("SPIRV-Opt: %s\n", msg);
});
std::vector<uint32_t> optimized;
if (!optimizer.Run(reinterpret_cast<const uint32_t *>(inoutSPIRV->data()), inoutSPIRV->size() / sizeof(uint32_t), &optimized))
throw std::runtime_error("Failed to run spirv-opt");
const auto *p = reinterpret_cast<const uint8_t*>(optimized.data());
inoutSPIRV->assign(p, p + optimized.size() * sizeof(uint32_t));
}