Skip to content

Commit

Permalink
Embed shader in executable.
Browse files Browse the repository at this point in the history
  • Loading branch information
stripe2933 committed Dec 22, 2024
1 parent 174f25e commit 1b660a2
Show file tree
Hide file tree
Showing 24 changed files with 210 additions and 109 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ target_link_shaders(vk-gltf-viewer
shaders/unlit_primitive.vert
shaders/weighted_blended_composition.frag
)

target_link_shaders_variant(vk-gltf-viewer
AMD_SHADER_IMAGE_LOAD_STORE_LOD "0;1"
shaders/prefilteredmap.comp
Expand Down
125 changes: 79 additions & 46 deletions cmake/CompileShader.cmake
Original file line number Diff line number Diff line change
@@ -1,101 +1,134 @@
if (${Vulkan_glslc_FOUND})
message(STATUS "Using Vulkan glslc for shader compilation.")
elseif (${Vulkan_glslangValidator_FOUND})
message(WARNING "Vulkan glslc not found, using glslangValidator for shader compilation instead. Modifying indirectly included files will NOT trigger recompilation.")
else()
message(FATAL_ERROR "No shader compiler found.")
endif ()

function(target_link_shaders TARGET)
if (${Vulkan_glslc_FOUND})
message(STATUS "Using Vulkan glslc for shader compilation.")
elseif (${Vulkan_glslangValidator_FOUND})
message(WARNING "Vulkan glslc not found, using glslangValidator for shader compilation instead. Modifying indirectly included files will NOT trigger recompilation.")
else()
message(FATAL_ERROR "No shader compiler found.")
endif ()
# Make target identifier.
string(MAKE_C_IDENTIFIER ${TARGET} target_identifier)

set(outputs "")
foreach (source IN LISTS ARGN)
# Get filename from source.
cmake_path(GET source FILENAME filename)

# Make source path absolute.
cmake_path(ABSOLUTE_PATH source OUTPUT_VARIABLE source)

set(output "shader/${filename}.spv")
# Make shader identifier.
string(MAKE_C_IDENTIFIER ${filename} shader_identifier)

if (${Vulkan_glslc_FOUND})
set(depfile "shader_depfile/${filename}.d")
add_custom_command(
OUTPUT "${output}"
COMMAND ${Vulkan_GLSLC_EXECUTABLE} -MD -MF "${depfile}" $<$<CONFIG:Release>:-O> --target-env=vulkan1.2 "${source}" -o "${output}"
DEPENDS "${source}"
BYPRODUCTS "${depfile}"
COMMENT "Compiling SPIRV: ${source} -> ${output}"
DEPFILE "${depfile}"
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${Vulkan_GLSLC_EXECUTABLE} -MD -MF shader_depfile/${filename}.d $<$<CONFIG:Release>:-O> --target-env=vulkan1.2 -mfmt=num ${source} -o "shader/${filename}.h"
&& ${CMAKE_COMMAND} -E echo "export module ${target_identifier}:shader.${shader_identifier}\;" > shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E echo "namespace ${target_identifier}::shader { export constexpr unsigned int ${shader_identifier}[] = {" >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E cat shader/${filename}.h >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E rm shader/${filename}.h
&& ${CMAKE_COMMAND} -E echo "}\;}" >> shader/${filename}.cppm
DEPENDS ${source}
BYPRODUCTS shader_depfile/${filename}.d
COMMENT "Compiling SPIR-V: ${source} -> ${filename}.cppm"
DEPFILE shader_depfile/${filename}.d
VERBATIM
COMMAND_EXPAND_LISTS
)
elseif (${Vulkan_glslangValidator_FOUND})
add_custom_command(
OUTPUT "${output}"
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} -V $<$<CONFIG:Debug>:-Od> --target-env vulkan1.2 "${source}" -o "${output}"
DEPENDS "${source}"
COMMENT "Compiling SPIRV: ${source} -> ${output}"
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} -V $<$<CONFIG:Debug>:-Od> --target-env vulkan1.2 -x ${source} -o "shader/${filename}.h"
&& ${CMAKE_COMMAND} -E echo "export module ${target_identifier}:shader.${shader_identifier}\;" > shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E echo "namespace ${target_identifier}::shader { export constexpr unsigned int ${shader_identifier}[] = {" >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E cat shader/${filename}.h >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E rm shader/${filename}.h
&& ${CMAKE_COMMAND} -E echo "}\;}" >> shader/${filename}.cppm
DEPENDS ${source}
COMMENT "Compiling SPIR-V: ${source}"
VERBATIM
COMMAND_EXPAND_LISTS
)
endif ()

# Make target depends on output shader file.
string(CONFIGURE "${TARGET}_${filename}" shader_target)
add_custom_target("${shader_target}" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${output}")
add_dependencies("${TARGET}" "${shader_target}")
list(APPEND outputs ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm)
endforeach ()

target_compile_definitions(${TARGET} PRIVATE COMPILED_SHADER_DIR="shader")
target_sources(${TARGET} PRIVATE FILE_SET CXX_MODULES FILES ${outputs})
endfunction()

function(target_link_shaders_variant TARGET MACRO_NAME MACRO_VALUES)
if (${Vulkan_glslc_FOUND})
message(STATUS "Using Vulkan glslc for shader compilation.")
elseif (${Vulkan_glslangValidator_FOUND})
message(WARNING "Vulkan glslc not found, using glslangValidator for shader compilation instead. Modifying indirectly included files will NOT trigger recompilation.")
else()
message(FATAL_ERROR "No shader compiler found.")
endif ()
# Make target identifier.
string(MAKE_C_IDENTIFIER ${TARGET} target_identifier)

set(outputs "")
foreach (source IN LISTS ARGN)
# Get filename from source.
cmake_path(GET source FILENAME filename)

# Make shader identifier.
string(MAKE_C_IDENTIFIER ${filename} shader_identifier)

# Make source path absolute.
cmake_path(ABSOLUTE_PATH source OUTPUT_VARIABLE source)

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${CMAKE_COMMAND} -E echo "export module ${target_identifier}:shader.${shader_identifier}\;" > shader/${filename}.cppm
COMMAND ${CMAKE_COMMAND} -E echo "namespace ${target_identifier}::shader {" >> shader/${filename}.cppm
COMMENT "Compiling SPIR-V: ${source} (${MACRO_NAME}=${MACRO_VALUES})"
VERBATIM
COMMAND_EXPAND_LISTS
)

foreach (macro_value IN LISTS MACRO_VALUES)
set(output "shader/${filename}_${MACRO_NAME}_${macro_value}.spv")
# Make variant identifier.
string(MAKE_C_IDENTIFIER "${MACRO_NAME}_${macro_value}" variant_identifier)

if (${Vulkan_glslc_FOUND})
set(depfile "shader_depfile/${filename}_${MACRO_NAME}_${macro_value}.d")
add_custom_command(
OUTPUT "${output}"
COMMAND ${Vulkan_GLSLC_EXECUTABLE} -MD -MF "${depfile}" $<$<CONFIG:Release>:-O> --target-env=vulkan1.2 -D${MACRO_NAME}=${macro_value} "${source}" -o "${output}"
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${Vulkan_GLSLC_EXECUTABLE} -MD -MF shader_depfile/${filename}_${variant_identifier}.d $<$<CONFIG:Release>:-O> --target-env=vulkan1.2 -mfmt=num -D${MACRO_NAME}=${macro_value} "${source}" -o shader/${filename}_${variant_identifier}_body.h
&& ${CMAKE_COMMAND} -E echo "export constexpr unsigned int ${shader_identifier}_${variant_identifier}[] = {" >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E cat shader/${filename}_${variant_identifier}_body.h >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E rm shader/${filename}_${variant_identifier}_body.h
&& ${CMAKE_COMMAND} -E echo "}\;" >> shader/${filename}.cppm
DEPENDS "${source}"
BYPRODUCTS "${depfile}"
COMMENT "Compiling SPIRV: ${source} -> ${output}"
DEPFILE "${depfile}"
BYPRODUCTS shader_depfile/${filename}_${variant_identifier}.d
DEPFILE shader_depfile/${filename}_${variant_identifier}.d
VERBATIM
COMMAND_EXPAND_LISTS
APPEND
)
elseif (${Vulkan_glslangValidator_FOUND})
add_custom_command(
OUTPUT "${output}"
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} -V $<$<CONFIG:Debug>:-Od> --target-env vulkan1.2 "${source}" -D${MACRO_NAME}=${macro_value} -o "${output}"
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} -V $<$<CONFIG:Debug>:-Od> --target-env vulkan1.2 -x ${source} -D${MACRO_NAME}=${macro_value} -o shader/${filename}_${variant_identifier}_body.h
&& ${CMAKE_COMMAND} -E echo "export constexpr unsigned int ${shader_identifier}_${variant_identifier}[] = {" >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E cat shader/${filename}_${variant_identifier}_body.h >> shader/${filename}.cppm
&& ${CMAKE_COMMAND} -E rm shader/${filename}_${variant_identifier}_body.h
&& ${CMAKE_COMMAND} -E echo "}\;" >> shader/${filename}.cppm
DEPENDS "${source}"
COMMENT "Compiling SPIRV: ${source} -> ${output}"
VERBATIM
COMMAND_EXPAND_LISTS
APPEND
)
endif ()

# Make target depends on output shader file.
string(CONFIGURE "${TARGET}_${filename}_${MACRO_NAME}_${macro_value}" shader_target)
add_custom_target("${shader_target}" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${output}")
add_dependencies("${TARGET}" "${shader_target}")
endforeach ()

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm
COMMAND ${CMAKE_COMMAND} -E echo "}" >> shader/${filename}.cppm
APPEND
VERBATIM
COMMAND_EXPAND_LISTS
)

list(APPEND outputs ${CMAKE_CURRENT_BINARY_DIR}/shader/${filename}.cppm)
endforeach ()

target_compile_definitions(${TARGET} PRIVATE COMPILED_SHADER_DIR="shader")
target_sources(${TARGET} PRIVATE FILE_SET CXX_MODULES FILES ${outputs})
endfunction()
8 changes: 5 additions & 3 deletions impl/vulkan/pipeline/BrdfmapComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module vk_gltf_viewer;
import :vulkan.pipeline.BrdfmapComputer;

import std;
import :shader.brdfmap_comp;

vk_gltf_viewer::vulkan::pipeline::BrdfmapComputer::DescriptorSetLayout::DescriptorSetLayout(
const vk::raii::Device &device
Expand All @@ -29,13 +30,14 @@ vk_gltf_viewer::vulkan::pipeline::BrdfmapComputer::BrdfmapComputer(
{},
createPipelineStages(
device,
vku::Shader::fromSpirvFile(
COMPILED_SHADER_DIR "/brdfmap.comp.spv",
vku::Shader {
shader::brdfmap_comp,
vk::ShaderStageFlagBits::eCompute,
vku::unsafeAddress(vk::SpecializationInfo {
vku::unsafeProxy(vk::SpecializationMapEntry { 0, 0, sizeof(SpecializationConstants::numSamples) }),
vk::ArrayProxyNoTemporaries<const SpecializationConstants>(specializationConstants),
}))).get()[0],
}),
}).get()[0],
*pipelineLayout,
} } { }

Expand Down
3 changes: 2 additions & 1 deletion impl/vulkan/pipeline/JumpFloodComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import :vulkan.pipeline.JumpFloodComputer;

import std;
import :math.extended_arithmetic;
import :shader.jump_flood_comp;

struct vk_gltf_viewer::vulkan::pipeline::JumpFloodComputer::PushConstant {
vk::Bool32 forward;
Expand Down Expand Up @@ -38,7 +39,7 @@ vk_gltf_viewer::vulkan::pipeline::JumpFloodComputer::JumpFloodComputer(
{},
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/jump_flood.comp.spv", vk::ShaderStageFlagBits::eCompute)).get()[0],
vku::Shader { shader::jump_flood_comp, vk::ShaderStageFlagBits::eCompute }).get()[0],
*pipelineLayout,
} } { }

Expand Down
23 changes: 15 additions & 8 deletions interface/vulkan/pipeline/BlendPrimitiveRenderer.cppm
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export module vk_gltf_viewer:vulkan.pipeline.BlendPrimitiveRenderer;

import std;
import vku;
import :shader.faceted_primitive_vert;
import :shader.primitive_vert;
import :shader.blend_faceted_primitive_frag;
import :shader.blend_primitive_frag;
export import :vulkan.pl.Primitive;
export import :vulkan.rp.Scene;

Expand All @@ -14,16 +19,18 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
) : Pipeline { device, nullptr, vku::getDefaultGraphicsPipelineCreateInfo(
createPipelineStages(
device,
vku::Shader::fromSpirvFile(
vku::Shader {
fragmentShaderTBN
? COMPILED_SHADER_DIR "/faceted_primitive.vert.spv"
: COMPILED_SHADER_DIR "/primitive.vert.spv",
vk::ShaderStageFlagBits::eVertex),
vku::Shader::fromSpirvFile(
? std::span<const std::uint32_t> { shader::faceted_primitive_vert }
: std::span<const std::uint32_t> { shader::primitive_vert },
vk::ShaderStageFlagBits::eVertex,
},
vku::Shader {
fragmentShaderTBN
? COMPILED_SHADER_DIR "/blend_faceted_primitive.frag.spv"
: COMPILED_SHADER_DIR "/blend_primitive.frag.spv",
vk::ShaderStageFlagBits::eFragment)).get(),
? std::span<const std::uint32_t> { shader::blend_faceted_primitive_frag }
: std::span<const std::uint32_t> { shader::blend_primitive_frag },
vk::ShaderStageFlagBits::eFragment,
}).get(),
*layout, 1, true, vk::SampleCountFlagBits::e4)
.setPRasterizationState(vku::unsafeAddress(vk::PipelineRasterizationStateCreateInfo {
{},
Expand Down
6 changes: 4 additions & 2 deletions interface/vulkan/pipeline/BlendUnlitPrimitiveRenderer.cppm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export module vk_gltf_viewer:vulkan.pipeline.BlendUnlitPrimitiveRenderer;

import vku;
import :shader.unlit_primitive_vert;
import :shader.blend_unlit_primitive_frag;
export import :vulkan.pl.Primitive;
export import :vulkan.rp.Scene;

Expand All @@ -13,8 +15,8 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
) : Pipeline { device, nullptr, vku::getDefaultGraphicsPipelineCreateInfo(
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/unlit_primitive.vert.spv", vk::ShaderStageFlagBits::eVertex),
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/blend_unlit_primitive.frag.spv", vk::ShaderStageFlagBits::eFragment)).get(),
vku::Shader { shader::unlit_primitive_vert, vk::ShaderStageFlagBits::eVertex },
vku::Shader { shader::blend_unlit_primitive_frag, vk::ShaderStageFlagBits::eFragment }).get(),
*layout, 1, true, vk::SampleCountFlagBits::e4)
.setPRasterizationState(vku::unsafeAddress(vk::PipelineRasterizationStateCreateInfo {
{},
Expand Down
3 changes: 2 additions & 1 deletion interface/vulkan/pipeline/CubemapComputer.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export module vk_gltf_viewer:vulkan.pipeline.CubemapComputer;
import std;
import vku;
export import vulkan_hpp;
import :shader.cubemap_comp;

namespace vk_gltf_viewer::vulkan::inline pipeline {
export struct CubemapComputer {
Expand Down Expand Up @@ -51,7 +52,7 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
{},
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/cubemap.comp.spv", vk::ShaderStageFlagBits::eCompute)).get()[0],
vku::Shader { shader::cubemap_comp, vk::ShaderStageFlagBits::eCompute }).get()[0],
*pipelineLayout,
} } { }

Expand Down
6 changes: 4 additions & 2 deletions interface/vulkan/pipeline/CubemapToneMappingRenderer.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export module vk_gltf_viewer:vulkan.pipeline.CubemapToneMappingRenderer;
import std;
export import glm;
export import vku;
import :shader.screen_quad_vert;
import :shader.cubemap_tone_mapping_frag;
export import :vulkan.rp.CubemapToneMapping;

namespace vk_gltf_viewer::vulkan::inline pipeline {
Expand Down Expand Up @@ -33,8 +35,8 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
pipeline { device, nullptr, vku::getDefaultGraphicsPipelineCreateInfo(
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/screen_quad.vert.spv", vk::ShaderStageFlagBits::eVertex),
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/cubemap_tone_mapping.frag.spv", vk::ShaderStageFlagBits::eFragment)).get(),
vku::Shader { shader::screen_quad_vert, vk::ShaderStageFlagBits::eVertex },
vku::Shader { shader::cubemap_tone_mapping_frag, vk::ShaderStageFlagBits::eFragment }).get(),
*pipelineLayout, 1)
.setPRasterizationState(vku::unsafeAddress(vk::PipelineRasterizationStateCreateInfo {
{},
Expand Down
6 changes: 4 additions & 2 deletions interface/vulkan/pipeline/DepthRenderer.cppm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export module vk_gltf_viewer:vulkan.pipeline.DepthRenderer;

import vku;
import :shader.depth_vert;
import :shader.depth_frag;
export import :vulkan.pl.PrimitiveNoShading;

namespace vk_gltf_viewer::vulkan::inline pipeline {
Expand All @@ -12,8 +14,8 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
vku::getDefaultGraphicsPipelineCreateInfo(
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/depth.vert.spv", vk::ShaderStageFlagBits::eVertex),
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/depth.frag.spv", vk::ShaderStageFlagBits::eFragment)).get(),
vku::Shader { shader::depth_vert, vk::ShaderStageFlagBits::eVertex },
vku::Shader { shader::depth_frag, vk::ShaderStageFlagBits::eFragment }).get(),
*layout, 1, true)
.setPDepthStencilState(vku::unsafeAddress(vk::PipelineDepthStencilStateCreateInfo {
{},
Expand Down
6 changes: 4 additions & 2 deletions interface/vulkan/pipeline/JumpFloodSeedRenderer.cppm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export module vk_gltf_viewer:vulkan.pipeline.JumpFloodSeedRenderer;

import vku;
import :shader.jump_flood_seed_vert;
import :shader.jump_flood_seed_frag;
export import :vulkan.pl.PrimitiveNoShading;

namespace vk_gltf_viewer::vulkan::inline pipeline {
Expand All @@ -12,8 +14,8 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
vku::getDefaultGraphicsPipelineCreateInfo(
createPipelineStages(
device,
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/jump_flood_seed.vert.spv", vk::ShaderStageFlagBits::eVertex),
vku::Shader::fromSpirvFile(COMPILED_SHADER_DIR "/jump_flood_seed.frag.spv", vk::ShaderStageFlagBits::eFragment)).get(),
vku::Shader { shader::jump_flood_seed_vert, vk::ShaderStageFlagBits::eVertex },
vku::Shader { shader::jump_flood_seed_frag, vk::ShaderStageFlagBits::eFragment }).get(),
*layout, 1, true)
.setPDepthStencilState(vku::unsafeAddress(vk::PipelineDepthStencilStateCreateInfo {
{},
Expand Down
Loading

0 comments on commit 1b660a2

Please sign in to comment.