Skip to content

Commit 98e67ff

Browse files
committed
Add simple_tensor_and_data_graph sample
* Added initial tensor and data graph sample, common framework and documentation. Signed-off-by: Aron Virginas-Tar <aron.virginas-tar@arm.com>
1 parent f731014 commit 98e67ff

39 files changed

+17367
-2879
lines changed

CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ if(Vulkan_FOUND)
7272
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.")
7373
endif()
7474
# glsl compiler
75-
if(NOT Vulkan_glslang_exe_FOUND)
75+
if(NOT Vulkan_glslc_exe_FOUND)
7676
find_program(Vulkan_glslc_EXECUTABLE
7777
NAMES glslc
7878
HINTS
@@ -85,7 +85,21 @@ if(Vulkan_FOUND)
8585
else()
8686
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.")
8787
endif()
88-
# glsl compiler
88+
# spvasm compiler
89+
if(NOT Vulkan_spirvas_exe_FOUND)
90+
find_program(Vulkan_spirvas_EXECUTABLE
91+
NAMES spirv-as
92+
HINTS
93+
"$ENV{VULKAN_SDK}/Bin"
94+
"$ENV{VULKAN_SDK}/bin"
95+
)
96+
endif()
97+
if(Vulkan_spirvas_EXECUTABLE)
98+
message(STATUS "Found spirv-as Shader Compiler under ${Vulkan_spirvas_EXECUTABLE}")
99+
else()
100+
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.")
101+
endif()
102+
89103
endif()
90104

91105
# globally add VKB_DEBUG for the debug build

antora/modules/ROOT/nav.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
////
22
- Copyright (c) 2023-2025, Holochip Inc
33
- Copyright (c) 2023-2025, Sascha Willems
4+
- Copyright (c) 2025, Arm Limited and Contributors
45
-
56
- SPDX-License-Identifier: Apache-2.0
67
-
@@ -89,6 +90,7 @@
8990
** xref:samples/extensions/shader_debugprintf/README.adoc[Shader Debug Printf]
9091
** xref:samples/extensions/sparse_image/README.adoc[Sparse Image]
9192
** xref:samples/extensions/synchronization_2/README.adoc[Synchronization 2]
93+
** xref:samples/extensions/tensor_and_data_graph/README.adoc[Tensor and Data Graph]
9294
** xref:samples/extensions/timeline_semaphore/README.adoc[Timeline semaphore]
9395
** xref:samples/extensions/vertex_dynamic_state/README.adoc[Vertex dynamic state]
9496
** xref:samples/extensions/dynamic_multisample_rasterization/README.adoc[Dynamic multisample rasterization]

bldsys/cmake/sample_helper.cmake

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
set(SCRIPT_DIR ${CMAKE_CURRENT_LIST_DIR})
2323

2424
function(add_sample)
25-
set(options)
25+
set(options)
2626
set(oneValueArgs ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
2727
set(multiValueArgs FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG)
2828

@@ -35,7 +35,7 @@ function(add_sample)
3535
AUTHOR ${TARGET_AUTHOR}
3636
NAME ${TARGET_NAME}
3737
DESCRIPTION ${TARGET_DESCRIPTION}
38-
TAGS
38+
TAGS
3939
"any"
4040
FILES
4141
${TARGET_FILES}
@@ -54,7 +54,7 @@ endfunction()
5454
function(add_sample_with_tags)
5555
set(options)
5656
set(oneValueArgs ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
57-
set(multiValueArgs TAGS FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG)
57+
set(multiValueArgs TAGS FILES LIBS SHADER_FILES_GLSL SHADER_FILES_HLSL SHADER_FILES_SLANG SHADER_FILES_SPVASM)
5858

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

@@ -83,7 +83,12 @@ function(add_sample_with_tags)
8383
# Add slang shader files for this sample
8484
foreach(SHADER_FILE_SLANG ${TARGET_SHADER_FILES_SLANG})
8585
list(APPEND SHADERS_SLANG "${PROJECT_SOURCE_DIR}/shaders/${SHADER_FILE_SLANG}")
86-
endforeach()
86+
endforeach()
87+
88+
# Add spvasm shader files for this sample
89+
foreach(SHADER_FILE_SPVASM ${TARGET_SHADER_FILES_SPVASM})
90+
list(APPEND SHADERS_SPVASM "${PROJECT_SOURCE_DIR}/shaders/${SHADER_FILE_SPVASM}")
91+
endforeach()
8792

8893
add_project(
8994
TYPE "Sample"
@@ -92,7 +97,7 @@ function(add_sample_with_tags)
9297
AUTHOR ${TARGET_AUTHOR}
9398
NAME ${TARGET_NAME}
9499
DESCRIPTION ${TARGET_DESCRIPTION}
95-
TAGS
100+
TAGS
96101
${TARGET_TAGS}
97102
FILES
98103
${SRC_FILES}
@@ -103,15 +108,17 @@ function(add_sample_with_tags)
103108
SHADERS_HLSL
104109
${SHADERS_HLSL}
105110
SHADERS_SLANG
106-
${SHADERS_SLANG}
111+
${SHADERS_SLANG}
112+
SHADERS_SPVASM
113+
${SHADERS_SPVASM}
107114
DXC_ADDITIONAL_ARGUMENTS ${TARGET_DXC_ADDITIONAL_ARGUMENTS}
108115
GLSLC_ADDITIONAL_ARGUMENTS ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
109116
endfunction()
110117

111118
function(add_project)
112-
set(options)
119+
set(options)
113120
set(oneValueArgs TYPE ID CATEGORY AUTHOR NAME DESCRIPTION DXC_ADDITIONAL_ARGUMENTS GLSLC_ADDITIONAL_ARGUMENTS)
114-
set(multiValueArgs TAGS FILES LIBS SHADERS_GLSL SHADERS_HLSL SHADERS_SLANG)
121+
set(multiValueArgs TAGS FILES LIBS SHADERS_GLSL SHADERS_HLSL SHADERS_SLANG SHADERS_SPVASM)
115122

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

@@ -138,16 +145,19 @@ function(add_project)
138145
if (TARGET_SHADERS_HLSL)
139146
source_group("\\Shaders\\hlsl" FILES ${TARGET_SHADERS_HLSL})
140147
# Disable automatic compilation of HLSL shaders for MSVC
141-
set_source_files_properties(SOURCE ${SHADERS_HLSL} PROPERTIES VS_SETTINGS "ExcludedFromBuild=true")
148+
set_source_files_properties(SOURCE ${SHADERS_HLSL} PROPERTIES VS_SETTINGS "ExcludedFromBuild=true")
142149
endif()
143150
if (TARGET_SHADERS_SLANG)
144151
source_group("\\Shaders\\slang" FILES ${TARGET_SHADERS_SLANG})
145-
endif()
152+
endif()
153+
if (TARGET_SHADERS_SPVASM)
154+
source_group("\\Shaders\\spvasm" FILES ${TARGET_SHADERS_SPVASM})
155+
endif()
146156

147157
if(${TARGET_TYPE} STREQUAL "Sample")
148-
add_library(${PROJECT_NAME} OBJECT ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG})
158+
add_library(${PROJECT_NAME} OBJECT ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG} ${SHADERS_SPVASM})
149159
elseif(${TARGET_TYPE} STREQUAL "Test")
150-
add_library(${PROJECT_NAME} STATIC ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG})
160+
add_library(${PROJECT_NAME} STATIC ${TARGET_FILES} ${SHADERS_GLSL} ${SHADERS_HLSL} ${SHADERS_SLANG} ${SHADERS_SPVASM})
151161
endif()
152162
set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
153163

@@ -160,15 +170,15 @@ endif()
160170
target_link_libraries(${PROJECT_NAME} PUBLIC ${TARGET_LIBS})
161171
endif()
162172

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

168178
if(${TARGET_TYPE} STREQUAL "Sample")
169179
# set sample properties
170180
set_target_properties(${PROJECT_NAME}
171-
PROPERTIES
181+
PROPERTIES
172182
SAMPLE_CATEGORY ${TARGET_CATEGORY}
173183
SAMPLE_AUTHOR ${TARGET_AUTHOR}
174184
SAMPLE_NAME ${TARGET_NAME}
@@ -185,12 +195,12 @@ endif()
185195
if(VKB_DO_CLANG_TIDY)
186196
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_CLANG_TIDY "${VKB_DO_CLANG_TIDY}")
187197
endif()
188-
198+
189199
# HLSL compilation via DXC
190200
if(Vulkan_dxc_EXECUTABLE AND DEFINED SHADERS_HLSL)
191201
set(OUTPUT_FILES "")
192202
set(HLSL_TARGET_NAME ${PROJECT_NAME}-HLSL)
193-
foreach(SHADER_FILE_HLSL ${TARGET_SHADERS_HLSL})
203+
foreach(SHADER_FILE_HLSL ${TARGET_SHADERS_HLSL})
194204
get_filename_component(HLSL_SPV_FILE ${SHADER_FILE_HLSL} NAME_WLE)
195205
get_filename_component(bare_name ${HLSL_SPV_FILE} NAME_WLE)
196206
get_filename_component(extension ${HLSL_SPV_FILE} LAST_EXT)
@@ -242,7 +252,7 @@ endif()
242252
endforeach()
243253
add_custom_target(${HLSL_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
244254
set_property(TARGET ${HLSL_TARGET_NAME} PROPERTY FOLDER "Shaders-HLSL")
245-
add_dependencies(${PROJECT_NAME} ${HLSL_TARGET_NAME})
255+
add_dependencies(${PROJECT_NAME} ${HLSL_TARGET_NAME})
246256
endif()
247257

248258
# Slang shader compilation
@@ -274,11 +284,11 @@ endif()
274284
endforeach()
275285
add_custom_target(${SLANG_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
276286
set_property(TARGET ${SLANG_TARGET_NAME} PROPERTY FOLDER "Shaders-SLANG")
277-
add_dependencies(${PROJECT_NAME} ${SLANG_TARGET_NAME})
287+
add_dependencies(${PROJECT_NAME} ${SLANG_TARGET_NAME})
278288
endif()
279289

280290
# GLSL shader compilation
281-
if(Vulkan_glslc_EXECUTABLE AND DEFINED SHADERS_GLSL)
291+
if(Vulkan_glslc_EXECUTABLE AND DEFINED SHADERS_GLSL)
282292
set(GLSL_TARGET_NAME ${PROJECT_NAME}-GLSL)
283293
set(OUTPUT_FILES "")
284294
foreach(SHADER_FILE_GLSL ${TARGET_SHADERS_GLSL})
@@ -293,9 +303,22 @@ endif()
293303
set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/shader-glsl-spv")
294304
set(OUTPUT_FILE ${OUTPUT_DIR}/${bare_name}${extension}.spv)
295305
file(MAKE_DIRECTORY ${OUTPUT_DIR})
306+
307+
# NOTE: Vulkan SDK has old glslc but new glslang. We must use glslang to compile shaders from `tensor_and_data_graph`.
308+
# TODO: Remove workaround once glslc is updated.
309+
if ("${CMAKE_CURRENT_BINARY_DIR}" MATCHES "tensor_and_data_graph" AND NOT ${SHADER_FILE_GLSL} MATCHES "base")
310+
# glslang (NOT glslangValidator, as that also seems to be old)
311+
string(REPLACE "glslangValidator" "glslang" GLSLANG_EXECUTABLE ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE})
312+
SET(COMPILE_COMMAND ${GLSLANG_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -V -I"${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
313+
else()
314+
# glslc
315+
SET(COMPILE_COMMAND ${Vulkan_glslc_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -I "${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS})
316+
endif()
317+
318+
296319
add_custom_command(
297320
OUTPUT ${OUTPUT_FILE}
298-
COMMAND ${Vulkan_glslc_EXECUTABLE} ${SHADER_FILE_GLSL} -o ${OUTPUT_FILE} -I "${CMAKE_SOURCE_DIR}/shaders/includes/glsl" ${TARGET_GLSLC_ADDITIONAL_ARGUMENTS}
321+
COMMAND ${COMPILE_COMMAND}
299322
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_FILE} ${directory}
300323
MAIN_DEPENDENCY ${SHADER_FILE_GLSL}
301324
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@@ -310,4 +333,34 @@ endif()
310333
add_dependencies(${PROJECT_NAME} ${GLSL_TARGET_NAME})
311334
endif()
312335

336+
# spvasm shader compilation
337+
if(Vulkan_spirvas_EXECUTABLE AND DEFINED SHADERS_SPVASM)
338+
set(SPVASM_TARGET_NAME ${PROJECT_NAME}-SPVASM)
339+
set(OUTPUT_FILES "")
340+
foreach(SHADER_FILE_SPVASM ${TARGET_SHADERS_SPVASM})
341+
get_filename_component(SPVASM_FILE ${SHADER_FILE_SPVASM} NAME_WLE)
342+
get_filename_component(bare_name ${SPVASM_FILE} NAME_WLE)
343+
get_filename_component(extension ${SHADER_FILE_SPVASM} LAST_EXT)
344+
get_filename_component(directory ${SHADER_FILE_SPVASM} DIRECTORY)
345+
set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/shader-spvasm-spv")
346+
set(OUTPUT_FILE ${OUTPUT_DIR}/${bare_name}${extension}.spv)
347+
file(MAKE_DIRECTORY ${OUTPUT_DIR})
348+
add_custom_command(
349+
OUTPUT ${OUTPUT_FILE}
350+
COMMAND ${Vulkan_spirvas_EXECUTABLE} ${SHADER_FILE_SPVASM} -o ${OUTPUT_FILE} ${TARGET_SPVASM_ADDITIONAL_ARGUMENTS}
351+
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT_FILE} ${directory}
352+
MAIN_DEPENDENCY ${SHADER_FILE_SPVASM}
353+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
354+
)
355+
list(APPEND OUTPUT_FILES ${OUTPUT_FILE})
356+
set_source_files_properties(${OUTPUT_FILE} PROPERTIES
357+
MACOSX_PACKAGE_LOCATION Resources
358+
)
359+
endforeach()
360+
add_custom_target(${SPVASM_TARGET_NAME} DEPENDS ${OUTPUT_FILES})
361+
set_property(TARGET ${SPVASM_TARGET_NAME} PROPERTY FOLDER "Shaders-SPVASM")
362+
add_dependencies(${PROJECT_NAME} ${SPVASM_TARGET_NAME})
363+
364+
endif()
365+
313366
endfunction()

docs/build.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ Alternatively, for command line builds use the steps below:
210210
cmake --build build/windows --config Release --target vulkan_samples
211211
----
212212

213-
`Step 3.` Run the *Vulkan Samples* application
213+
`Step 3.` Run the *Vulkan Samples* application by specifying the name of the sample
214214

215215
----
216-
build\windows\app\bin\Release\AMD64\vulkan_samples.exe
216+
build\windows\app\bin\Release\AMD64\vulkan_samples.exe sample <sample_name>
217217
----
218218

219219
== Linux
@@ -368,7 +368,7 @@ ____
368368
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.
369369

370370
Android Studio uses the following plugins/tools to build samples:
371-
371+
372372
* Android Gradle Plugin
373373
* CMake Plugin, which installs and uses Ninja
374374
* NDK

framework/common/vk_common.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,12 @@ int32_t get_bits_per_pixel(VkFormat format)
334334
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage)
335335
{
336336
auto spirv = vkb::fs::read_shader_binary_u32(filename);
337+
return load_shader_from_vector(spirv, device);
338+
}
339+
340+
VkShaderModule load_shader_from_vector(const std::vector<uint32_t> &spirv, VkDevice device)
341+
{
342+
assert(spirv.size() != 0);
337343

338344
VkShaderModule shader_module;
339345
VkShaderModuleCreateInfo module_create_info{};

framework/common/vk_common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ enum class ShadingLanguage
145145
*/
146146
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage);
147147

148+
/**
149+
* @brief Helper function to create a VkShaderModule from a SPIR-V vector
150+
* @param spirv The SPIR-V code in vector format
151+
* @param device The logical device
152+
* @return The shader module containing the loaded shader
153+
*/
154+
VkShaderModule load_shader_from_vector(const std::vector<uint32_t> &spirv, VkDevice device);
155+
148156
/**
149157
* @brief Helper function to select a VkSurfaceFormatKHR
150158
* @param gpu The VkPhysicalDevice to select a format for.

framework/core/allocated.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* Copyright (c) 2021-2025, NVIDIA CORPORATION. All rights reserved.
22
* Copyright (c) 2024-2025, Bradley Austin Davis. All rights reserved.
3+
* Copyright (c) 2025, Arm Limited and Contributors
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*
@@ -181,6 +182,11 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
181182
*/
182183
DeviceMemoryType get_memory() const;
183184

185+
/**
186+
* @brief Retrieves the offset into the raw Vulkan memory object (which can be retrieved from get_memory()).
187+
*/
188+
DeviceSizeType get_memory_offset() const;
189+
184190
/**
185191
* @brief Maps Vulkan memory if it isn't already mapped to a host visible address. Does nothing if the
186192
* allocation is already mapped (including persistently mapped allocations).
@@ -309,6 +315,25 @@ class Allocated : public vkb::core::VulkanResource<bindingType, HandleType>
309315
* instead of `protected`, and because it (mostly) isolates interaction with the VMA to a single class
310316
*/
311317
[[nodiscard]] ImageType create_image(ImageCreateInfoType const &create_info);
318+
319+
/**
320+
* @brief Internal method to retrieve the VMA allocation owned by this object.
321+
*
322+
* This is needed for derived classes to handle some of the VMA allocation code themselves,
323+
* in particular for Tensor objects to be allocated, in tensor_and_data_graph_common.cpp.
324+
* Once Tensor objects are integrated into VMA, this code can be refactored and this function removed.
325+
*/
326+
VmaAllocation get_allocation() const;
327+
328+
/**
329+
* @brief Internal method to set the VMA allocation owned by this object.
330+
*
331+
* This is needed for derived classes to handle some of the VMA allocation code themselves,
332+
* in particular for Tensor objects to be allocated, in tensor_and_data_graph_common.cpp.
333+
* Once Tensor objects are integrated into VMA, this code can be refactored and this function removed.
334+
*/
335+
void set_allocation(VmaAllocation alloc);
336+
312337
/**
313338
* @brief The post_create method is called after the creation of a buffer or image to store the allocation info internally. Derived classes
314339
* could in theory override this to ensure any post-allocation operations are performed, but the base class should always be called to ensure
@@ -563,6 +588,21 @@ inline typename Allocated<bindingType, HandleType>::DeviceMemoryType Allocated<b
563588
}
564589
}
565590

591+
template <vkb::BindingType bindingType, typename HandleType>
592+
inline typename Allocated<bindingType, HandleType>::DeviceSizeType Allocated<bindingType, HandleType>::get_memory_offset() const
593+
{
594+
VmaAllocationInfo alloc_info;
595+
vmaGetAllocationInfo(get_memory_allocator(), allocation, &alloc_info);
596+
if constexpr (bindingType == vkb::BindingType::Cpp)
597+
{
598+
return static_cast<vk::DeviceSize>(alloc_info.offset);
599+
}
600+
else
601+
{
602+
return alloc_info.offset;
603+
}
604+
}
605+
566606
template <vkb::BindingType bindingType, typename HandleType>
567607
inline uint8_t *Allocated<bindingType, HandleType>::map()
568608
{
@@ -580,6 +620,18 @@ inline bool Allocated<bindingType, HandleType>::mapped() const
580620
return mapped_data != nullptr;
581621
}
582622

623+
template <vkb::BindingType bindingType, typename HandleType>
624+
inline VmaAllocation Allocated<bindingType, HandleType>::get_allocation() const
625+
{
626+
return allocation;
627+
}
628+
629+
template <vkb::BindingType bindingType, typename HandleType>
630+
inline void Allocated<bindingType, HandleType>::set_allocation(VmaAllocation alloc)
631+
{
632+
allocation = alloc;
633+
}
634+
583635
template <vkb::BindingType bindingType, typename HandleType>
584636
inline void Allocated<bindingType, HandleType>::post_create(VmaAllocationInfo const &allocation_info)
585637
{

0 commit comments

Comments
 (0)