Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ if(Vulkan_FOUND)
message(STATUS "Couldn't find slang Shader Compiler executable, make sure it is present in Vulkan SDK or add it manually via Vulkan_slang_EXECUTABLE cmake variable. Slang shaders won't be compiled.")
endif()
# glsl compiler
if(NOT Vulkan_glslang_exe_FOUND)
if(NOT Vulkan_glslc_exe_FOUND)
find_program(Vulkan_glslc_EXECUTABLE
NAMES glslc
HINTS
Expand All @@ -85,7 +85,21 @@ if(Vulkan_FOUND)
else()
message(STATUS "Couldn't find glslc Shader Compiler executable, make sure it is present in Vulkan SDK or add it manually via Vulkan_glslc_EXECUTABLE cmake variable. GLSL shaders won't be compiled.")
endif()
# glsl compiler
# spvasm compiler
if(NOT Vulkan_spirvas_exe_FOUND)
find_program(Vulkan_spirvas_EXECUTABLE
NAMES spirv-as
HINTS
"$ENV{VULKAN_SDK}/Bin"
"$ENV{VULKAN_SDK}/bin"
)
endif()
if(Vulkan_spirvas_EXECUTABLE)
message(STATUS "Found spirv-as Shader Compiler under ${Vulkan_spirvas_EXECUTABLE}")
else()
message(STATUS "Couldn't find spirv-as Shader Compiler executable, make sure it is present in Vulkan SDK or add it manually via Vulkan_spirvas_EXECUTABLE cmake variable. SPIR-V assembly shaders won't be compiled.")
endif()

endif()

# globally add VKB_DEBUG for the debug build
Expand Down
2 changes: 2 additions & 0 deletions antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
////
- Copyright (c) 2023-2025, Holochip Inc
- Copyright (c) 2023-2025, Sascha Willems
- Copyright (c) 2025, Arm Limited and Contributors
-
- SPDX-License-Identifier: Apache-2.0
-
Expand Down Expand Up @@ -89,6 +90,7 @@
** xref:samples/extensions/shader_debugprintf/README.adoc[Shader Debug Printf]
** xref:samples/extensions/sparse_image/README.adoc[Sparse Image]
** xref:samples/extensions/synchronization_2/README.adoc[Synchronization 2]
** xref:samples/extensions/tensor_and_data_graph/README.adoc[Tensor and Data Graph]
** xref:samples/extensions/timeline_semaphore/README.adoc[Timeline semaphore]
** xref:samples/extensions/vertex_dynamic_state/README.adoc[Vertex dynamic state]
** xref:samples/extensions/dynamic_multisample_rasterization/README.adoc[Dynamic multisample rasterization]
Expand Down
93 changes: 73 additions & 20 deletions bldsys/cmake/sample_helper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
set(SCRIPT_DIR ${CMAKE_CURRENT_LIST_DIR})

function(add_sample)
set(options)
set(options)
set(oneValueArgs ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
set(multiValueArgs FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG)

Expand All @@ -35,7 +35,7 @@ function(add_sample)
AUTHOR ${TARGET_AUTHOR}
NAME ${TARGET_NAME}
DESCRIPTION ${TARGET_DESCRIPTION}
TAGS
TAGS
"any"
FILES
${TARGET_FILES}
Expand All @@ -54,7 +54,7 @@ endfunction()
function(add_sample_with_tags)
set(options)
set(oneValueArgs ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
set(multiValueArgs TAGS FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG)
set(multiValueArgs TAGS FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG SHADER_FILES_SPVASM)

cmake_parse_arguments(TARGET "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

Expand Down Expand Up @@ -83,7 +83,12 @@ function(add_sample_with_tags)
# Add slang shader files for this sample
foreach(SHADER_FILE_SLANG ${TARGET_SHADER_FILES_SLANG})
list(APPEND SHADERS_SLANG "${PROJECT_SOURCE_DIR}/shaders/${SHADER_FILE_SLANG}")
endforeach()
endforeach()

# Add spvasm shader files for this sample
foreach(SHADER_FILE_SPVASM ${TARGET_SHADER_FILES_SPVASM})
list(APPEND SHADERS_SPVASM "${PROJECT_SOURCE_DIR}/shaders/${SHADER_FILE_SPVASM}")
endforeach()

add_project(
TYPE "Sample"
Expand All @@ -92,7 +97,7 @@ function(add_sample_with_tags)
AUTHOR ${TARGET_AUTHOR}
NAME ${TARGET_NAME}
DESCRIPTION ${TARGET_DESCRIPTION}
TAGS
TAGS
${TARGET_TAGS}
FILES
${SRC_FILES}
Expand All @@ -103,15 +108,17 @@ function(add_sample_with_tags)
SHADERS_HLSL
${SHADERS_HLSL}
SHADERS_SLANG
${SHADERS_SLANG}
${SHADERS_SLANG}
SHADERS_SPVASM
${SHADERS_SPVASM}
DXC_ADDITIONAL_ARGUMENTS ${TARGET_DXC_ADDITIONAL_ARGUMENTS}
GLSLC_ADDITIONAL_ARGUMENTS ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
endfunction()

function(add_project)
set(options)
set(options)
set(oneValueArgs TYPE ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
set(multiValueArgs TAGS FILES LIBS SHADERS_GLSL SHADERS_HLSL SHADERS_SLANG)
set(multiValueArgs TAGS FILES LIBS SHADERS_GLSL SHADERS_HLSL SHADERS_SLANG SHADERS_SPVASM)

cmake_parse_arguments(TARGET "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

Expand All @@ -138,16 +145,19 @@ function(add_project)
if (TARGET_SHADERS_HLSL)
source_group("\\Shaders\\hlsl" FILES ${TARGET_SHADERS_HLSL})
# Disable automatic compilation of HLSL shaders for MSVC
set_source_files_properties(SOURCE ${SHADERS_HLSL} PROPERTIES VS_SETTINGS "ExcludedFromBuild=true")
set_source_files_properties(SOURCE ${SHADERS_HLSL} PROPERTIES VS_SETTINGS "ExcludedFromBuild=true")
endif()
if (TARGET_SHADERS_SLANG)
source_group("\\Shaders\\slang" FILES ${TARGET_SHADERS_SLANG})
endif()
endif()
if (TARGET_SHADERS_SPVASM)
source_group("\\Shaders\\spvasm" FILES ${TARGET_SHADERS_SPVASM})
endif()

if(${TARGET_TYPE} STREQUAL "Sample")
add_library(${PROJECT_NAME} OBJECT ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG})
add_library(${PROJECT_NAME} OBJECT ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG} ${SHADERS_SPVASM})
elseif(${TARGET_TYPE} STREQUAL "Test")
add_library(${PROJECT_NAME} STATIC ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG})
add_library(${PROJECT_NAME} STATIC ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG} ${SHADERS_SPVASM})
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)

Expand All @@ -160,15 +170,15 @@ endif()
target_link_libraries(${PROJECT_NAME} PUBLIC ${TARGET_LIBS})
endif()

# capitalise the first letter of the category (performance -> Performance)
# capitalise the first letter of the category (performance -> Performance)
string(SUBSTRING ${TARGET_CATEGORY} 0 1 FIRST_LETTER)
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
string(REGEX REPLACE "^.(.*)" "${FIRST_LETTER}\\1" CATEGORY "${TARGET_CATEGORY}")

if(${TARGET_TYPE} STREQUAL "Sample")
# set sample properties
set_target_properties(${PROJECT_NAME}
PROPERTIES
PROPERTIES
SAMPLE_CATEGORY ${TARGET_CATEGORY}
SAMPLE_AUTHOR ${TARGET_AUTHOR}
SAMPLE_NAME ${TARGET_NAME}
Expand All @@ -185,12 +195,12 @@ endif()
if(VKB_DO_CLANG_TIDY)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_CLANG_TIDY "${VKB_DO_CLANG_TIDY}")
endif()

# HLSL compilation via DXC
if(Vulkan_dxc_EXECUTABLE AND DEFINED SHADERS_HLSL)
set(OUTPUT_FILES "")
set(HLSL_TARGET_NAME ${PROJECT_NAME}-HLSL)
foreach(SHADER_FILE_HLSL ${TARGET_SHADERS_HLSL})
foreach(SHADER_FILE_HLSL ${TARGET_SHADERS_HLSL})
get_filename_component(HLSL_SPV_FILE ${SHADER_FILE_HLSL} NAME_WLE)
get_filename_component(bare_name ${HLSL_SPV_FILE} NAME_WLE)
get_filename_component(extension ${HLSL_SPV_FILE} LAST_EXT)
Expand Down Expand Up @@ -242,7 +252,7 @@ endif()
endforeach()
add_custom_target(${HLSL_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
set_property(TARGET ${HLSL_TARGET_NAME} PROPERTY FOLDER "Shaders-HLSL")
add_dependencies(${PROJECT_NAME} ${HLSL_TARGET_NAME})
add_dependencies(${PROJECT_NAME} ${HLSL_TARGET_NAME})
endif()

# Slang shader compilation
Expand Down Expand Up @@ -274,11 +284,11 @@ endif()
endforeach()
add_custom_target(${SLANG_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
set_property(TARGET ${SLANG_TARGET_NAME} PROPERTY FOLDER "Shaders-SLANG")
add_dependencies(${PROJECT_NAME} ${SLANG_TARGET_NAME})
add_dependencies(${PROJECT_NAME} ${SLANG_TARGET_NAME})
endif()

# GLSL shader compilation
if(Vulkan_glslc_EXECUTABLE AND DEFINED SHADERS_GLSL)
if(Vulkan_glslc_EXECUTABLE AND DEFINED SHADERS_GLSL)
set(GLSL_TARGET_NAME ${PROJECT_NAME}-GLSL)
set(OUTPUT_FILES "")
foreach(SHADER_FILE_GLSL ${TARGET_SHADERS_GLSL})
Expand All @@ -293,9 +303,22 @@ endif()
set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/shader-glsl-spv")
set(OUTPUT_FILE ${OUTPUT_DIR}/${bare_name}${extension}.spv)
file(MAKE_DIRECTORY ${OUTPUT_DIR})

# NOTE: Vulkan SDK has old glslc but new glslang. We must use glslang to compile shaders from `tensor_and_data_graph`.
# TODO: Remove workaround once glslc is updated.
if ("${CMAKE_CURRENT_BINARY_DIR}" MATCHES "tensor_and_data_graph" AND NOT ${SHADER_FILE_GLSL} MATCHES "base")
# glslang (NOT glslangValidator, as that also seems to be old)
string(REPLACE "glslangValidator" "glslang" GLSLANG_EXECUTABLE ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE})
SET(COMPILE_COMMAND ${GLSLANG_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -V -I"${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
else()
# glslc
SET(COMPILE_COMMAND ${Vulkan_glslc_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -I "${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
endif()


add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMAND ${Vulkan_glslc_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -I "${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS}
COMMAND ${COMPILE_COMMAND}
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_FILE} ${directory}
MAIN_DEPENDENCY ${SHADER_FILE_GLSL}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
Expand All @@ -310,4 +333,34 @@ endif()
add_dependencies(${PROJECT_NAME} ${GLSL_TARGET_NAME})
endif()

# spvasm shader compilation
if(Vulkan_spirvas_EXECUTABLE AND DEFINED SHADERS_SPVASM)
set(SPVASM_TARGET_NAME ${PROJECT_NAME}-SPVASM)
set(OUTPUT_FILES "")
foreach(SHADER_FILE_SPVASM ${TARGET_SHADERS_SPVASM})
get_filename_component(SPVASM_FILE ${SHADER_FILE_SPVASM} NAME_WLE)
get_filename_component(bare_name ${SPVASM_FILE} NAME_WLE)
get_filename_component(extension ${SHADER_FILE_SPVASM} LAST_EXT)
get_filename_component(directory ${SHADER_FILE_SPVASM} DIRECTORY)
set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/shader-spvasm-spv")
set(OUTPUT_FILE ${OUTPUT_DIR}/${bare_name}${extension}.spv)
file(MAKE_DIRECTORY ${OUTPUT_DIR})
add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMAND ${Vulkan_spirvas_EXECUTABLE} ${SHADER_FILE_SPVASM} -o ${OUTPUT_FILE} ${TARGET_SPVASM_ADDITIONAL_ARGUMENTS}
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_FILE} ${directory}
MAIN_DEPENDENCY ${SHADER_FILE_SPVASM}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
list(APPEND OUTPUT_FILES ${OUTPUT_FILE})
set_source_files_properties(${OUTPUT_FILE} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
endforeach()
add_custom_target(${SPVASM_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
set_property(TARGET ${SPVASM_TARGET_NAME} PROPERTY FOLDER "Shaders-SPVASM")
add_dependencies(${PROJECT_NAME} ${SPVASM_TARGET_NAME})

endif()

endfunction()
6 changes: 3 additions & 3 deletions docs/build.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,10 @@ Alternatively, for command line builds use the steps below:
cmake --build build/windows --config Release --target vulkan_samples
----

`Step 3.` Run the *Vulkan Samples* application
`Step 3.` Run the *Vulkan Samples* application by specifying the name of the sample

----
build\windows\app\bin\Release\AMD64\vulkan_samples.exe
build\windows\app\bin\Release\AMD64\vulkan_samples.exe sample <sample_name>
----

== Linux
Expand Down Expand Up @@ -388,7 +388,7 @@ ____
It is highly recommended to install https://d.android.com/studio[Android Studio] to build, run and trace the sample project. Building via Android Studio requires at least Ladybug 2024.2.1.

Android Studio uses the following plugins/tools to build samples:

* Android Gradle Plugin
* CMake Plugin, which installs and uses Ninja
* NDK
Expand Down
6 changes: 6 additions & 0 deletions framework/common/vk_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ int32_t get_bits_per_pixel(VkFormat format)
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage)
{
auto spirv = vkb::fs::read_shader_binary_u32(filename);
return load_shader_from_vector(spirv, device);
}

VkShaderModule load_shader_from_vector(const std::vector<uint32_t> &spirv, VkDevice device)
{
assert(spirv.size() != 0);

VkShaderModule shader_module;
VkShaderModuleCreateInfo module_create_info{};
Expand Down
8 changes: 8 additions & 0 deletions framework/common/vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ enum class ShadingLanguage
*/
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage);

/**
* @brief Helper function to create a VkShaderModule from a SPIR-V vector
* @param spirv The SPIR-V code in vector format
* @param device The logical device
* @return The shader module containing the loaded shader
*/
VkShaderModule load_shader_from_vector(const std::vector<uint32_t> &spirv, VkDevice device);

/**
* @brief Helper function to select a VkSurfaceFormatKHR
* @param gpu The VkPhysicalDevice to select a format for.
Expand Down
52 changes: 52 additions & 0 deletions framework/core/allocated.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2021-2025, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2024-2025, Bradley Austin Davis. All rights reserved.
* Copyright (c) 2025, Arm Limited and Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -181,6 +182,11 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
*/
DeviceMemoryType get_memory() const;

/**
* @brief Retrieves the offset into the raw Vulkan memory object (which can be retrieved from get_memory()).
*/
DeviceSizeType get_memory_offset() const;

/**
* @brief Maps Vulkan memory if it isn't already mapped to a host visible address. Does nothing if the
* allocation is already mapped (including persistently mapped allocations).
Expand Down Expand Up @@ -309,6 +315,25 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
* instead of `protected`, and because it (mostly) isolates interaction with the VMA to a single class
*/
[[nodiscard]] ImageType create_image(ImageCreateInfoType const &create_info);

/**
* @brief Internal method to retrieve the VMA allocation owned by this object.
*
* This is needed for derived classes to handle some of the VMA allocation code themselves,
* in particular for Tensor objects to be allocated, in tensor_and_data_graph_common.cpp.
* Once Tensor objects are integrated into VMA, this code can be refactored and this function removed.
*/
VmaAllocation get_allocation() const;

/**
* @brief Internal method to set the VMA allocation owned by this object.
*
* This is needed for derived classes to handle some of the VMA allocation code themselves,
* in particular for Tensor objects to be allocated, in tensor_and_data_graph_common.cpp.
* Once Tensor objects are integrated into VMA, this code can be refactored and this function removed.
*/
void set_allocation(VmaAllocation alloc);

/**
* @brief The post_create method is called after the creation of a buffer or image to store the allocation info internally. Derived classes
* could in theory override this to ensure any post-allocation operations are performed, but the base class should always be called to ensure
Expand Down Expand Up @@ -563,6 +588,21 @@ inline typename Allocated<bindingType, HandleType>::DeviceMemoryType Allocated<b
}
}

template <vkb::BindingType bindingType, typename HandleType>
inline typename Allocated<bindingType, HandleType>::DeviceSizeType Allocated<bindingType, HandleType>::get_memory_offset() const
{
VmaAllocationInfo alloc_info;
vmaGetAllocationInfo(get_memory_allocator(), allocation, &alloc_info);
if constexpr (bindingType == vkb::BindingType::Cpp)
{
return static_cast<vk::DeviceSize>(alloc_info.offset);
}
else
{
return alloc_info.offset;
}
}

template <vkb::BindingType bindingType, typename HandleType>
inline uint8_t *Allocated<bindingType, HandleType>::map()
{
Expand All @@ -580,6 +620,18 @@ inline bool Allocated<bindingType, HandleType>::mapped() const
return mapped_data != nullptr;
}

template <vkb::BindingType bindingType, typename HandleType>
inline VmaAllocation Allocated<bindingType, HandleType>::get_allocation() const
{
return allocation;
}

template <vkb::BindingType bindingType, typename HandleType>
inline void Allocated<bindingType, HandleType>::set_allocation(VmaAllocation alloc)
{
allocation = alloc;
}

template <vkb::BindingType bindingType, typename HandleType>
inline void Allocated<bindingType, HandleType>::post_create(VmaAllocationInfo const &allocation_info)
{
Expand Down
Loading
Loading