From d62c2c47d8044857593b1dbc1a0ee0aff78a0e6f Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:09:49 +0200 Subject: [PATCH 01/19] cmake: rename DaemonBuildInfo as DaemonSourceGenerator --- CMakeLists.txt | 2 +- cmake/DaemonGame.cmake | 2 +- cmake/{DaemonBuildInfo.cmake => DaemonSourceGenerator.cmake} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename cmake/{DaemonBuildInfo.cmake => DaemonSourceGenerator.cmake} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24b09edacf..3c7254cf51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ if (Daemon_OUT) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Daemon_OUT}) endif() -include(DaemonBuildInfo) +include(DaemonSourceGenerator) include(DaemonPlatform) ################################################################################ diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 8462617b62..e93369cce1 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -39,7 +39,7 @@ option(BUILD_GAME_NATIVE_DLL "Build the shared library files, mostly useful for option(BUILD_GAME_NATIVE_EXE "Build native executable, which might be used for better performances by server owners" OFF) include(ExternalProject) -include(DaemonBuildInfo) +include(DaemonSourceGenerator) include(DaemonPlatform) # Do not report unused native compiler if native vms are not built. diff --git a/cmake/DaemonBuildInfo.cmake b/cmake/DaemonSourceGenerator.cmake similarity index 100% rename from cmake/DaemonBuildInfo.cmake rename to cmake/DaemonSourceGenerator.cmake From 7c106ed20979082982a4085c6d5cae7761cfa9b1 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:13:14 +0200 Subject: [PATCH 02/19] DaemonSourceGenerator: rework it a bit --- cmake/DaemonSourceGenerator.cmake | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 95f08084e5..ebd5fe3ba7 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,23 +1,27 @@ -set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/GeneratedSource") +set(DAEMON_GENERATED_SUBDIR "GeneratedSource") +set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") -set(DAEMON_BUILDINFO_DIR "DaemonBuildInfo") -set(DAEMON_BUILDINFO_HEADER "// Automatically generated, do not modify!\n") -set(DAEMON_BUILDINFO_CPP_EXT ".cpp") -set(DAEMON_BUILDINFO_H_EXT ".h") -set(BUILDINFOLIST) +set(DAEMON_BUILDINFO_SUBDIR "DaemonBuildInfo") +set(DAEMON_BUILDINFO_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_SUBDIR}") file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}") include_directories("${DAEMON_GENERATED_DIR}") -file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_DIR}") +file(MAKE_DIRECTORY "${DAEMON_BUILDINFO_DIR}") + +set(DAEMON_GENERATED_HEADER "// Automatically generated, do not modify!\n") +set(DAEMON_GENERATED_CPP_EXT ".cpp") +set(DAEMON_GENERATED_H_EXT ".h") + +set(BUILDINFOLIST) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind} "${DAEMON_BUILDINFO_HEADER}") + set(DAEMON_BUILDINFO_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() macro(daemon_add_buildinfo TYPE NAME VALUE) - set(DAEMON_BUILDINFO_CPP "${DAEMON_BUILDINFO_CPP}const ${TYPE} ${NAME}=${VALUE};\n") - set(DAEMON_BUILDINFO_H "${DAEMON_BUILDINFO_H}extern const ${TYPE} ${NAME};\n") + string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${TYPE} ${NAME}=${VALUE};\n") + string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${TYPE} ${NAME};\n") endmacro() macro(daemon_write_generated GENERATED_PATH GENERATED_CONTENT) @@ -35,10 +39,10 @@ endmacro() macro(daemon_write_buildinfo NAME) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_BUILDINFO_${kind}_EXT}") - set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_DIR}/${DAEMON_BUILDINFO_${kind}_NAME}") + set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_GENERATED_${kind}_EXT}") + set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_SUBDIR}/${DAEMON_BUILDINFO_${kind}_NAME}") - daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}}") + daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}_TEXT}") list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() From 10f15240f6237c197bf63b51da4df8894dd8b535 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 4 Oct 2025 01:07:17 +0200 Subject: [PATCH 03/19] DaemonSourceGenerator: make the embedded file generator reusable --- CMakeLists.txt | 35 +--------- cmake/DaemonSourceGenerator.cmake | 68 +++++++++++++++++++ src.cmake | 104 +++++++++++++++--------------- src/engine/renderer/gl_shader.cpp | 6 +- src/engine/renderer/src.cmake | 3 +- 5 files changed, 127 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c7254cf51..7fad63177c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -927,39 +927,8 @@ if (BUILD_CLIENT) Tests ${CLIENTTESTLIST} ) - # generate glsl include files - set(GLSL_SOURCE_DIR ${ENGINE_DIR}/renderer/glsl_source) - set(EMBED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed_data) - file(MAKE_DIRECTORY ${EMBED_INCLUDE_DIR}) - - set(SHADERS_CPP_TEXT "// This file is auto-generated by CMakeLists.txt.\n") - string(APPEND SHADERS_CPP_TEXT "#include \"common/Common.h\"\n\n") - set(SHADERMAP_TEXT "") - - foreach(res ${GLSLSOURCELIST}) - get_filename_component(filename_no_ext ${res} NAME_WE) - set(outpath ${EMBED_INCLUDE_DIR}/${filename_no_ext}.glsl.h) - - add_custom_command( - OUTPUT ${outpath} - COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}" - "-DVARIABLE_NAME=${filename_no_ext}_glsl" -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake - MAIN_DEPENDENCY ${res} - ) - - set_property(TARGET client-objects APPEND PROPERTY SOURCES ${outpath}) - - string(APPEND SHADERS_CPP_TEXT "#include \"../embed_data/${filename_no_ext}.glsl.h\"\n") - string(APPEND SHADERMAP_TEXT "\t{ \"${filename_no_ext}.glsl\", ") - string(APPEND SHADERMAP_TEXT "std::string(reinterpret_cast( ${filename_no_ext}_glsl ), ") - string(APPEND SHADERMAP_TEXT "sizeof( ${filename_no_ext}_glsl )) },\n") - endforeach() - - string(APPEND SHADERS_CPP_TEXT "\nextern const std::unordered_map shadermap\n{\n") - string(APPEND SHADERS_CPP_TEXT "${SHADERMAP_TEXT}") - string(APPEND SHADERS_CPP_TEXT "};\n") - - daemon_write_generated("shaders.cpp" "${SHADERS_CPP_TEXT}") + # Generate GLSL include files. + daemon_embed_files("EngineShaders" "GLSL" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index ebd5fe3ba7..fc2cdbb58c 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -2,12 +2,16 @@ set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") set(DAEMON_BUILDINFO_SUBDIR "DaemonBuildInfo") +set(DAEMON_EMBEDDED_SUBDIR "DaemonEmbeddedFiles") + set(DAEMON_BUILDINFO_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_SUBDIR}") +set(DAEMON_EMBEDDED_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_EMBEDDED_SUBDIR}") file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}") include_directories("${DAEMON_GENERATED_DIR}") file(MAKE_DIRECTORY "${DAEMON_BUILDINFO_DIR}") +file(MAKE_DIRECTORY "${DAEMON_EMBEDDED_DIR}") set(DAEMON_GENERATED_HEADER "// Automatically generated, do not modify!\n") set(DAEMON_GENERATED_CPP_EXT ".cpp") @@ -46,3 +50,67 @@ macro(daemon_write_buildinfo NAME) list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() + +macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) + set(EMBED_SOURCE_DIR "${SLUG}_EMBED_DIR") + set(EMBED_SOURCE_LIST "${SLUG}_EMBED_LIST") + + set(EMBED_SUBDIR "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}") + set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") + + foreach(kind CPP H) + set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") + endforeach() + + string(APPEND EMBED_CPP_TEXT "#include \"${EMBED_H_FILE}\"\n\n") + + set(EMBED_MAP_TEXT "") + + foreach(filename ${${EMBED_SOURCE_LIST}}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") + + set(inpath "${${EMBED_SOURCE_DIR}}/${filename}") + set(outpath "${EMBED_DIR}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") + + add_custom_command( + OUTPUT "${outpath}" + COMMAND ${CMAKE_COMMAND} + "-DINPUT_FILE=${inpath}" + "-DOUTPUT_FILE=${outpath}" + "-DVARIABLE_NAME=${filename_symbol}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" + MAIN_DEPENDENCY ${inpath} + ) + + set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") + + string(APPEND EMBED_CPP_TEXT + "#include \"${BASENAME}/${filename_symbol}.h\"\n") + string(APPEND EMBED_MAP_TEXT + "\t{ \"${filename}\", " + "std::string(reinterpret_cast( ${filename_symbol} ), " + "sizeof( ${filename_symbol} )) },\n") + endforeach() + + string(APPEND EMBED_CPP_TEXT + "\n" + "namespace ${BASENAME} {\n" + "const std::unordered_map FileMap\n{\n" + "${EMBED_MAP_TEXT}" + "};\n" + "}" + ) + + string(APPEND EMBED_H_TEXT + "#include \"common/Common.h\"\n" + "\n" + "namespace ${BASENAME} {\n" + "extern const std::unordered_map FileMap;\n" + "};\n" + ) + + foreach(kind CPP H) + daemon_write_generated("${EMBED_${kind}_FILE}" "${EMBED_${kind}_TEXT}") + endforeach() +endmacro() diff --git a/src.cmake b/src.cmake index 20305a0ebb..7430a577b9 100644 --- a/src.cmake +++ b/src.cmake @@ -86,68 +86,68 @@ else() include (${ENGINE_DIR}/renderer/src.cmake) endif() -set(GLSLSOURCELIST +set(GLSL_EMBED_DIR "${ENGINE_DIR}/renderer/glsl_source") +set(GLSL_EMBED_LIST # Common shader libraries - ${ENGINE_DIR}/renderer/glsl_source/common.glsl - ${ENGINE_DIR}/renderer/glsl_source/common_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogEquation_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/shaderProfiler_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/shaderProfiler_fp.glsl - + common.glsl + common_cp.glsl + fogEquation_fp.glsl + shaderProfiler_vp.glsl + shaderProfiler_fp.glsl # Material system shaders - ${ENGINE_DIR}/renderer/glsl_source/material_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/material_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/material_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/clearSurfaces_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/cull_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthReduction_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/processSurfaces_cp.glsl + material_cp.glsl + material_vp.glsl + material_fp.glsl + clearSurfaces_cp.glsl + cull_cp.glsl + depthReduction_cp.glsl + processSurfaces_cp.glsl # Screen-space shaders - ${ENGINE_DIR}/renderer/glsl_source/screenSpace_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/blur_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/cameraEffects_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/contrast_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogGlobal_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fxaa_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fxaa3_11_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/motionblur_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/ssao_fp.glsl + screenSpace_vp.glsl + blur_fp.glsl + cameraEffects_fp.glsl + contrast_fp.glsl + fogGlobal_fp.glsl + fxaa_fp.glsl + fxaa3_11_fp.glsl + motionblur_fp.glsl + ssao_fp.glsl # Lighting shaders - ${ENGINE_DIR}/renderer/glsl_source/depthtile1_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthtile1_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthtile2_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lighttile_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lighttile_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/computeLight_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reliefMapping_fp.glsl + depthtile1_vp.glsl + depthtile1_fp.glsl + depthtile2_fp.glsl + lighttile_vp.glsl + lighttile_fp.glsl + computeLight_fp.glsl + reliefMapping_fp.glsl # Common vertex shader libraries - ${ENGINE_DIR}/renderer/glsl_source/deformVertexes_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexAnimation_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexSimple_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexSkinning_vp.glsl + deformVertexes_vp.glsl + vertexAnimation_vp.glsl + vertexSimple_vp.glsl + vertexSkinning_vp.glsl # Regular shaders - ${ENGINE_DIR}/renderer/glsl_source/fogQuake3_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogQuake3_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/generic_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/generic_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/heatHaze_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/heatHaze_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lightMapping_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lightMapping_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/liquid_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/liquid_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/portal_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/portal_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reflection_CB_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reflection_CB_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/screen_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/screen_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/skybox_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/skybox_fp.glsl + fogQuake3_vp.glsl + fogQuake3_fp.glsl + generic_vp.glsl + generic_fp.glsl + heatHaze_vp.glsl + heatHaze_fp.glsl + lightMapping_vp.glsl + lightMapping_fp.glsl + liquid_vp.glsl + liquid_fp.glsl + portal_vp.glsl + portal_fp.glsl + reflection_CB_vp.glsl + reflection_CB_fp.glsl + screen_vp.glsl + screen_fp.glsl + skybox_vp.glsl + skybox_fp.glsl ) set(SERVERLIST diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index cc6bc46432..4552a34131 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include "gl_shader.h" #include "Material.h" +#include "DaemonEmbeddedFiles/EngineShaders.h" // We currently write GLBinaryHeader to a file and memcpy all over it. // Make sure it's a pod, so we don't put a std::string in it or something @@ -41,7 +42,6 @@ static Cvar::Cvar r_logUnmarkedGLSLBuilds( "r_logUnmarkedGLSLBuilds", "Log building information for GLSL shaders that are built after the map is loaded", Cvar::NONE, true ); -extern const std::unordered_map shadermap; // shaderKind's value will be determined later based on command line setting or absence of. ShaderKind shaderKind = ShaderKind::Unknown; @@ -92,8 +92,8 @@ namespace // Implementation details const char* GetInternalShader(Str::StringRef filename) { - auto it = shadermap.find(filename); - if (it != shadermap.end()) + auto it = EngineShaders::FileMap.find(filename); + if (it != EngineShaders::FileMap.end()) return it->second.c_str(); return nullptr; } diff --git a/src/engine/renderer/src.cmake b/src/engine/renderer/src.cmake index ff85e9872a..59c7156011 100644 --- a/src/engine/renderer/src.cmake +++ b/src/engine/renderer/src.cmake @@ -1,6 +1,7 @@ set(RENDERERLIST - ${DAEMON_GENERATED_DIR}/shaders.cpp + ${DAEMON_EMBEDDED_DIR}/EngineShaders.cpp + ${DAEMON_EMBEDDED_DIR}/EngineShaders.h ${ENGINE_DIR}/renderer/BufferBind.h ${ENGINE_DIR}/renderer/DetectGLVendors.cpp ${ENGINE_DIR}/renderer/DetectGLVendors.h From fb9e39f063f9dcb191eea135ab202e8f2b035e72 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:17:12 +0200 Subject: [PATCH 04/19] EmbedText make possible to chose between TEXT and BINARY formats when embedding files --- CMakeLists.txt | 2 +- cmake/DaemonSourceGenerator.cmake | 1 + cmake/EmbedText.cmake | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fad63177c..17d2739a87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -928,7 +928,7 @@ if (BUILD_CLIENT) ) # Generate GLSL include files. - daemon_embed_files("EngineShaders" "GLSL" "client-objects") + daemon_embed_files("EngineShaders" "GLSL" "TEXT" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index fc2cdbb58c..1c6da48be5 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -78,6 +78,7 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${inpath}" "-DOUTPUT_FILE=${outpath}" + "-DFILE_FORMAT=${FORMAT}" "-DVARIABLE_NAME=${filename_symbol}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" MAIN_DEPENDENCY ${inpath} diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index 43b9ffab4b..dc88b23f2d 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -1,8 +1,20 @@ # Converts a text file into a C-language char array definition. # For use in CMake script mode (cmake -P). -# Required definitions on command line: INPUT_FILE, OUTPUT_FILE, VARIABLE_NAME +# Required definitions on command line: +# INPUT_FILE, OUTPUT_FILE, FILE_FORMAT, VARIABLE_NAME + +# Inspired by: +# https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982 -# Inspired by https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982 file(READ ${INPUT_FILE} contents HEX) -string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents ${contents}) # Strip \r for consistency + +if ("${FILE_FORMAT}" STREQUAL "TEXT") + # Strip \r for consistency. + string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") +elseif("${FILE_FORMAT}" STREQUAL "BINARY") + string(REGEX REPLACE "(..)" "0x\\1," contents "${contents}") +else() + message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") +endif() + file(WRITE ${OUTPUT_FILE} "const unsigned char ${VARIABLE_NAME}[] = {${contents}};\n") From 9af0becba5066553a3e9301741d33fb4eb6eac07 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:33:45 +0200 Subject: [PATCH 05/19] DaemonSourceGenerator: provide embedded files as part as the namespace --- cmake/DaemonSourceGenerator.cmake | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 1c6da48be5..47d74b7b49 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -63,7 +63,17 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() - string(APPEND EMBED_CPP_TEXT "#include \"${EMBED_H_FILE}\"\n\n") + string(APPEND EMBED_CPP_TEXT + "#include \"${EMBED_H_FILE}\"\n" + "\n" + "namespace ${BASENAME} {\n" + ) + + string(APPEND EMBED_H_TEXT + "#include \"common/Common.h\"\n" + "\n" + "namespace ${BASENAME} {\n" + ) set(EMBED_MAP_TEXT "") @@ -87,16 +97,22 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") string(APPEND EMBED_CPP_TEXT - "#include \"${BASENAME}/${filename_symbol}.h\"\n") + "#include \"${BASENAME}/${filename_symbol}.h\"\n" + ) + + string(APPEND EMBED_H_TEXT + "extern const unsigned char ${filename_symbol}[];\n" + ) + string(APPEND EMBED_MAP_TEXT "\t{ \"${filename}\", " "std::string(reinterpret_cast( ${filename_symbol} ), " - "sizeof( ${filename_symbol} )) },\n") + "sizeof( ${filename_symbol} )) },\n" + ) endforeach() string(APPEND EMBED_CPP_TEXT "\n" - "namespace ${BASENAME} {\n" "const std::unordered_map FileMap\n{\n" "${EMBED_MAP_TEXT}" "};\n" @@ -104,9 +120,6 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) ) string(APPEND EMBED_H_TEXT - "#include \"common/Common.h\"\n" - "\n" - "namespace ${BASENAME} {\n" "extern const std::unordered_map FileMap;\n" "};\n" ) From 59386eb73f585be3ecf69ce76540602398fd0aa0 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 03:08:19 +0200 Subject: [PATCH 06/19] EmbedText: split embedded source lines just in case if an editor or debugger opens it --- cmake/EmbedText.cmake | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index dc88b23f2d..447f30f069 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -8,6 +8,7 @@ file(READ ${INPUT_FILE} contents HEX) +# Translate the file content. if ("${FILE_FORMAT}" STREQUAL "TEXT") # Strip \r for consistency. string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") @@ -17,4 +18,18 @@ else() message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") endif() -file(WRITE ${OUTPUT_FILE} "const unsigned char ${VARIABLE_NAME}[] = {${contents}};\n") +# Split long lines. +string(REGEX REPLACE + "(0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,)" "\\1\n" + contents "${contents}" +) + +# A bit more of beautification. +string(REGEX REPLACE ",$" ",\n" contents "${contents}") + +file(WRITE ${OUTPUT_FILE} + "const unsigned char ${VARIABLE_NAME}[] =\n" + "{\n" + "${contents}" + "};\n" +) From 14a748e2bb25b7274a12672206c2a2afbf142b96 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 03:56:30 +0200 Subject: [PATCH 07/19] DaemonSourceGenerator: also add the generated source entry-point to the target --- cmake/DaemonSourceGenerator.cmake | 5 ++++- src/engine/renderer/src.cmake | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 47d74b7b49..2bf09fcc06 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -59,8 +59,11 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") foreach(kind CPP H) - set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_BASENAME "${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_SRC_FILE "${DAEMON_EMBEDDED_DIR}/${EMBED_${kind}_BASENAME}") + set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${EMBED_${kind}_BASENAME}") set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") + set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${EMBED_${kind}_SRC_FILE}") endforeach() string(APPEND EMBED_CPP_TEXT diff --git a/src/engine/renderer/src.cmake b/src/engine/renderer/src.cmake index 59c7156011..98ef800b31 100644 --- a/src/engine/renderer/src.cmake +++ b/src/engine/renderer/src.cmake @@ -1,7 +1,5 @@ set(RENDERERLIST - ${DAEMON_EMBEDDED_DIR}/EngineShaders.cpp - ${DAEMON_EMBEDDED_DIR}/EngineShaders.h ${ENGINE_DIR}/renderer/BufferBind.h ${ENGINE_DIR}/renderer/DetectGLVendors.cpp ${ENGINE_DIR}/renderer/DetectGLVendors.h From b96492ca590ada5abd825ae2b37f876f36a4b7df Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 04:16:25 +0200 Subject: [PATCH 08/19] DaemonSourceGenerator: lowercase local variables (even if the leak outside) --- cmake/DaemonSourceGenerator.cmake | 84 +++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 2bf09fcc06..c3e542263c 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -23,111 +23,111 @@ foreach(kind CPP H) set(DAEMON_BUILDINFO_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() -macro(daemon_add_buildinfo TYPE NAME VALUE) - string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${TYPE} ${NAME}=${VALUE};\n") - string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${TYPE} ${NAME};\n") +macro(daemon_add_buildinfo type name value) + string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${type} ${name}=${value};\n") + string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${type} ${name};\n") endmacro() -macro(daemon_write_generated GENERATED_PATH GENERATED_CONTENT) - set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${GENERATED_PATH}) +macro(daemon_write_generated generated_path generated_content) + set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${generated_path}) if (EXISTS "${DAEMON_GENERATED_FILE}") - file(READ "${DAEMON_GENERATED_FILE}" GENERATED_CONTENT_READ) + file(READ "${DAEMON_GENERATED_FILE}" generated_content_read) endif() - if (NOT "${GENERATED_CONTENT}" STREQUAL "${GENERATED_CONTENT_READ}") - message(STATUS "Generating ${GENERATED_PATH}") - file(WRITE "${DAEMON_GENERATED_FILE}" "${GENERATED_CONTENT}") + if (NOT "${generated_content}" STREQUAL "${generated_content_read}") + message(STATUS "Generating ${generated_path}") + file(WRITE "${DAEMON_GENERATED_FILE}" "${generated_content}") endif() endmacro() -macro(daemon_write_buildinfo NAME) +macro(daemon_write_buildinfo name) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_GENERATED_${kind}_EXT}") - set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_SUBDIR}/${DAEMON_BUILDINFO_${kind}_NAME}") + set(daemon_buildinfo_${kind}_name "${name}${DAEMON_GENERATED_${kind}_EXT}") + set(daemon_buildinfo_${kind}_path "${DAEMON_BUILDINFO_SUBDIR}/${daemon_buildinfo_${kind}_name}") - daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}_TEXT}") + daemon_write_generated("${daemon_buildinfo_${kind}_path}" "${DAEMON_BUILDINFO_${kind}_TEXT}") list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() -macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) - set(EMBED_SOURCE_DIR "${SLUG}_EMBED_DIR") - set(EMBED_SOURCE_LIST "${SLUG}_EMBED_LIST") +macro(daemon_embed_files basename slug format targetname) + set(embed_source_dir "${slug}_EMBED_DIR") + set(embed_source_list "${slug}_EMBED_LIST") - set(EMBED_SUBDIR "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}") - set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") + set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") + set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") foreach(kind CPP H) - set(EMBED_${kind}_BASENAME "${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") - set(EMBED_${kind}_SRC_FILE "${DAEMON_EMBEDDED_DIR}/${EMBED_${kind}_BASENAME}") - set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${EMBED_${kind}_BASENAME}") - set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") - set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${EMBED_${kind}_SRC_FILE}") + set(embed_${kind}_basename "${basename}${DAEMON_GENERATED_${kind}_EXT}") + set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") + set(embed_${kind}_file "${DAEMON_EMBEDDED_SUBDIR}/${embed_${kind}_basename}") + set(embed_${kind}_text "${DAEMON_GENERATED_HEADER}") + set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${embed_${kind}_src_file}") endforeach() - string(APPEND EMBED_CPP_TEXT - "#include \"${EMBED_H_FILE}\"\n" + string(APPEND embed_CPP_text + "#include \"${embed_H_file}\"\n" "\n" - "namespace ${BASENAME} {\n" + "namespace ${basename} {\n" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "#include \"common/Common.h\"\n" "\n" - "namespace ${BASENAME} {\n" + "namespace ${basename} {\n" ) - set(EMBED_MAP_TEXT "") + set(embed_map_text "") - foreach(filename ${${EMBED_SOURCE_LIST}}) + foreach(filename ${${embed_source_list}}) string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") - set(inpath "${${EMBED_SOURCE_DIR}}/${filename}") - set(outpath "${EMBED_DIR}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") + set(inpath "${${embed_source_dir}}/${filename}") + set(outpath "${embed_dir}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") add_custom_command( OUTPUT "${outpath}" COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${inpath}" "-DOUTPUT_FILE=${outpath}" - "-DFILE_FORMAT=${FORMAT}" + "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" MAIN_DEPENDENCY ${inpath} ) - set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") + set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${outpath}") - string(APPEND EMBED_CPP_TEXT - "#include \"${BASENAME}/${filename_symbol}.h\"\n" + string(APPEND embed_CPP_text + "#include \"${basename}/${filename_symbol}.h\"\n" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "extern const unsigned char ${filename_symbol}[];\n" ) - string(APPEND EMBED_MAP_TEXT + string(APPEND embed_map_text "\t{ \"${filename}\", " "std::string(reinterpret_cast( ${filename_symbol} ), " "sizeof( ${filename_symbol} )) },\n" ) endforeach() - string(APPEND EMBED_CPP_TEXT + string(APPEND embed_CPP_text "\n" "const std::unordered_map FileMap\n{\n" - "${EMBED_MAP_TEXT}" + "${embed_map_text}" "};\n" "}" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "extern const std::unordered_map FileMap;\n" "};\n" ) foreach(kind CPP H) - daemon_write_generated("${EMBED_${kind}_FILE}" "${EMBED_${kind}_TEXT}") + daemon_write_generated("${embed_${kind}_file}" "${embed_${kind}_text}") endforeach() endmacro() From f87d0340fa5900894bab910422bf8a98133e5a9f Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 02:18:45 +0200 Subject: [PATCH 09/19] DaemonSourceGenerator: explicit mkdir --- cmake/DaemonSourceGenerator.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index c3e542263c..4aab0699bb 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -58,6 +58,8 @@ macro(daemon_embed_files basename slug format targetname) set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") + file(MAKE_DIRECTORY "${embed_dir}") + foreach(kind CPP H) set(embed_${kind}_basename "${basename}${DAEMON_GENERATED_${kind}_EXT}") set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") From ac27caa9003f523df0a491a52f69c8066452f541 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 01:24:56 +0200 Subject: [PATCH 10/19] DaemonSourceGenerator: do not copy the embedded files in the map --- cmake/DaemonSourceGenerator.cmake | 8 +++----- cmake/EmbedText.cmake | 7 +++++-- src/common/Common.h | 1 + src/common/EmbeddedFile.h | 7 +++++++ src/engine/renderer/gl_shader.cpp | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 src/common/EmbeddedFile.h diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 4aab0699bb..f0f68ab208 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -110,22 +110,20 @@ macro(daemon_embed_files basename slug format targetname) ) string(APPEND embed_map_text - "\t{ \"${filename}\", " - "std::string(reinterpret_cast( ${filename_symbol} ), " - "sizeof( ${filename_symbol} )) },\n" + "\t{ \"${filename}\", { ${filename_symbol}, sizeof( ${filename_symbol}) - 1 } },\n" ) endforeach() string(APPEND embed_CPP_text "\n" - "const std::unordered_map FileMap\n{\n" + "const embeddedFileMap_t FileMap\n{\n" "${embed_map_text}" "};\n" "}" ) string(APPEND embed_H_text - "extern const std::unordered_map FileMap;\n" + "extern const embeddedFileMap_t FileMap;\n" "};\n" ) diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index 447f30f069..43512dbf54 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -11,13 +11,16 @@ file(READ ${INPUT_FILE} contents HEX) # Translate the file content. if ("${FILE_FORMAT}" STREQUAL "TEXT") # Strip \r for consistency. - string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") + string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") elseif("${FILE_FORMAT}" STREQUAL "BINARY") string(REGEX REPLACE "(..)" "0x\\1," contents "${contents}") else() message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") endif() +# Add null terminator. +set(contents "${contents}0x00,") + # Split long lines. string(REGEX REPLACE "(0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,)" "\\1\n" @@ -28,7 +31,7 @@ string(REGEX REPLACE string(REGEX REPLACE ",$" ",\n" contents "${contents}") file(WRITE ${OUTPUT_FILE} - "const unsigned char ${VARIABLE_NAME}[] =\n" + "constexpr unsigned char ${VARIABLE_NAME}[] =\n" "{\n" "${contents}" "};\n" diff --git a/src/common/Common.h b/src/common/Common.h index 4fedbd6844..bc7d7de12a 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -48,6 +48,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Color.h" #include "Serialize.h" #include "DisjointSets.h" +#include "EmbeddedFile.h" using Math::Vec2; using Math::Vec3; diff --git a/src/common/EmbeddedFile.h b/src/common/EmbeddedFile.h new file mode 100644 index 0000000000..142995c941 --- /dev/null +++ b/src/common/EmbeddedFile.h @@ -0,0 +1,7 @@ +struct embeddedFileMapEntry_t +{ + const unsigned char* data; + size_t size; +}; + +using embeddedFileMap_t = std::unordered_map; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 4552a34131..ef4d07b448 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -94,7 +94,7 @@ namespace // Implementation details { auto it = EngineShaders::FileMap.find(filename); if (it != EngineShaders::FileMap.end()) - return it->second.c_str(); + return (const char*) it->second.data; return nullptr; } From f174fb6202330bce36557f9216cdf9f5f6dd6bed Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 01:44:22 +0200 Subject: [PATCH 11/19] DaemonSourceGenerator: also make generated source depend on generators to regenerate the target --- cmake/DaemonSourceGenerator.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index f0f68ab208..4f092e9e3e 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,3 +1,7 @@ +set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") +get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) +set(DAEMON_TEXT_EMBEDDER "${current_list_dir}/cmake/EmbedText.cmake") + set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") @@ -65,6 +69,7 @@ macro(daemon_embed_files basename slug format targetname) set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") set(embed_${kind}_file "${DAEMON_EMBEDDED_SUBDIR}/${embed_${kind}_basename}") set(embed_${kind}_text "${DAEMON_GENERATED_HEADER}") + set_property(SOURCE "${embed_${kind}_src_file}" APPEND PROPERTY OBJECT_DEPENDS "${DAEMON_SOURCE_GENERATOR}") set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${embed_${kind}_src_file}") endforeach() @@ -95,8 +100,11 @@ macro(daemon_embed_files basename slug format targetname) "-DOUTPUT_FILE=${outpath}" "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" - -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" + -P "${DAEMON_TEXT_EMBEDDER}" MAIN_DEPENDENCY ${inpath} + DEPENDS + "${DAEMON_FILE_EMBEDDER}" + "${DAEMON_SOURCE_GENERATOR}" ) set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${outpath}") From 2acdc5cad7564c9a17a5ee97887d951b29506b2e Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 9 Oct 2025 01:26:31 +0200 Subject: [PATCH 12/19] cmake: rename EmbedText as DaemonFileEmbedder --- cmake/{EmbedText.cmake => DaemonFileEmbedder.cmake} | 0 cmake/DaemonSourceGenerator.cmake | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename cmake/{EmbedText.cmake => DaemonFileEmbedder.cmake} (100%) diff --git a/cmake/EmbedText.cmake b/cmake/DaemonFileEmbedder.cmake similarity index 100% rename from cmake/EmbedText.cmake rename to cmake/DaemonFileEmbedder.cmake diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 4f092e9e3e..5dc59ccc0f 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,6 +1,6 @@ set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -set(DAEMON_TEXT_EMBEDDER "${current_list_dir}/cmake/EmbedText.cmake") +set(DAEMON_FILE_EMBEDDER "${current_list_dir}/DaemonFileEmbedder.cmake") set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") @@ -100,7 +100,7 @@ macro(daemon_embed_files basename slug format targetname) "-DOUTPUT_FILE=${outpath}" "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" - -P "${DAEMON_TEXT_EMBEDDER}" + -P "${DAEMON_FILE_EMBEDDER}" MAIN_DEPENDENCY ${inpath} DEPENDS "${DAEMON_FILE_EMBEDDER}" From f41f5dbdb80046ebcd6e22399011001afa0758fe Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 9 Oct 2025 04:16:39 +0200 Subject: [PATCH 13/19] DaemonSourceGenerator: add license --- cmake/DaemonSourceGenerator.cmake | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 5dc59ccc0f..d3d3fcc546 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,3 +1,29 @@ +# Daemon BSD Source Code +# Copyright (c) 2025, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) set(DAEMON_FILE_EMBEDDER "${current_list_dir}/DaemonFileEmbedder.cmake") From 6ca22b6e8d7dc3f4b35f57978ff2c032feeb1008 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 16 Oct 2025 17:11:09 +0200 Subject: [PATCH 14/19] =?UTF-8?q?DaemonSourceGenerator:=20use=20file(GENER?= =?UTF-8?q?ATE=20=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmake/DaemonSourceGenerator.cmake | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index d3d3fcc546..a0c5b8b2ef 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -58,26 +58,12 @@ macro(daemon_add_buildinfo type name value) string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${type} ${name};\n") endmacro() -macro(daemon_write_generated generated_path generated_content) - set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${generated_path}) - - if (EXISTS "${DAEMON_GENERATED_FILE}") - file(READ "${DAEMON_GENERATED_FILE}" generated_content_read) - endif() - - if (NOT "${generated_content}" STREQUAL "${generated_content_read}") - message(STATUS "Generating ${generated_path}") - file(WRITE "${DAEMON_GENERATED_FILE}" "${generated_content}") - endif() -endmacro() - macro(daemon_write_buildinfo name) foreach(kind CPP H) - set(daemon_buildinfo_${kind}_name "${name}${DAEMON_GENERATED_${kind}_EXT}") - set(daemon_buildinfo_${kind}_path "${DAEMON_BUILDINFO_SUBDIR}/${daemon_buildinfo_${kind}_name}") + set(buildinfo_file_path "${DAEMON_BUILDINFO_DIR}/${name}${DAEMON_GENERATED_${kind}_EXT}") - daemon_write_generated("${daemon_buildinfo_${kind}_path}" "${DAEMON_BUILDINFO_${kind}_TEXT}") - list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") + file(GENERATE OUTPUT "${buildinfo_file_path}" CONTENT "${DAEMON_BUILDINFO_${kind}_TEXT}") + list(APPEND BUILDINFOLIST "${buildinfo_file_path}") endforeach() endmacro() @@ -162,6 +148,7 @@ macro(daemon_embed_files basename slug format targetname) ) foreach(kind CPP H) - daemon_write_generated("${embed_${kind}_file}" "${embed_${kind}_text}") + set(embed_file "${DAEMON_GENERATED_DIR}/${embed_${kind}_file}") + file(GENERATE OUTPUT "${embed_file}" CONTENT "${embed_${kind}_text}") endforeach() endmacro() From 2bdccd1ad44f6324146067a35b72dd65a9b7c0dd Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 16 Oct 2025 17:29:11 +0200 Subject: [PATCH 15/19] DaemonSourceGenerator: use explicit variable names --- CMakeLists.txt | 2 +- cmake/DaemonSourceGenerator.cmake | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d2739a87..028bbd3188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -928,7 +928,7 @@ if (BUILD_CLIENT) ) # Generate GLSL include files. - daemon_embed_files("EngineShaders" "GLSL" "TEXT" "client-objects") + daemon_embed_files("EngineShaders" "${GLSL_EMBED_DIR}" "${GLSL_EMBED_LIST}" "TEXT" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index a0c5b8b2ef..cd1559838e 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -67,10 +67,7 @@ macro(daemon_write_buildinfo name) endforeach() endmacro() -macro(daemon_embed_files basename slug format targetname) - set(embed_source_dir "${slug}_EMBED_DIR") - set(embed_source_list "${slug}_EMBED_LIST") - +macro(daemon_embed_files basename dir list format targetname) set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") @@ -99,10 +96,10 @@ macro(daemon_embed_files basename slug format targetname) set(embed_map_text "") - foreach(filename ${${embed_source_list}}) + foreach(filename ${list}) string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") - set(inpath "${${embed_source_dir}}/${filename}") + set(inpath "${dir}/${filename}") set(outpath "${embed_dir}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") add_custom_command( From 2f82ad36bd132a93caefff2e315da7e1831697eb Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 5 Oct 2025 02:24:12 +0300 Subject: [PATCH 16/19] Daemon-vulkan infrastructure 2 --- .gitignore | 3 + CMakeLists.txt | 9 +- cmake/DaemonFileEmbedder.cmake | 4 +- cmake/DaemonSourceGenerator.cmake | 34 ++- cmake/DaemonVulkan.cmake | 147 +++++++++++++ cmake/DaemonVulkan/VulkanShaderParser.cpp | 242 ++++++++++++++++++++++ 6 files changed, 434 insertions(+), 5 deletions(-) create mode 100644 cmake/DaemonVulkan.cmake create mode 100644 cmake/DaemonVulkan/VulkanShaderParser.cpp diff --git a/.gitignore b/.gitignore index 00e20db8da..f1665ee1f8 100644 --- a/.gitignore +++ b/.gitignore @@ -57,5 +57,8 @@ external_deps/* .vs .vscode +#ignore python cache +*.pyc + #ignore removed recastnavigation submodule libs/recastnavigation diff --git a/CMakeLists.txt b/CMakeLists.txt index 028bbd3188..c33f718767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -530,6 +530,7 @@ endif() if (USE_VULKAN) add_definitions("-DDAEMON_RENDERER_VULKAN=1") add_definitions("-DVK_NO_PROTOTYPES=1") + include(DaemonVulkan) else() add_definitions("-DDAEMON_RENDERER_OPENGL=1") @@ -927,8 +928,12 @@ if (BUILD_CLIENT) Tests ${CLIENTTESTLIST} ) - # Generate GLSL include files. - daemon_embed_files("EngineShaders" "${GLSL_EMBED_DIR}" "${GLSL_EMBED_LIST}" "TEXT" "client-objects") + if (USE_VULKAN) + GenerateVulkanShaders( client-objects ) + else() + # Generate GLSL include files. + daemon_embed_files("EngineShaders" "${GLSL_EMBED_DIR}" "${GLSL_EMBED_LIST}" "TEXT" "client-objects") + endif() endif() if (BUILD_SERVER) diff --git a/cmake/DaemonFileEmbedder.cmake b/cmake/DaemonFileEmbedder.cmake index 43512dbf54..c7848ed5a6 100644 --- a/cmake/DaemonFileEmbedder.cmake +++ b/cmake/DaemonFileEmbedder.cmake @@ -1,7 +1,7 @@ # Converts a text file into a C-language char array definition. # For use in CMake script mode (cmake -P). # Required definitions on command line: -# INPUT_FILE, OUTPUT_FILE, FILE_FORMAT, VARIABLE_NAME +# INPUT_FILE, OUTPUT_FILE, VARIABLE_NAME, FILE_FORMAT, EMBED_MODE # Inspired by: # https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982 @@ -30,7 +30,7 @@ string(REGEX REPLACE # A bit more of beautification. string(REGEX REPLACE ",$" ",\n" contents "${contents}") -file(WRITE ${OUTPUT_FILE} +file(${EMBED_MODE} ${OUTPUT_FILE} "constexpr unsigned char ${VARIABLE_NAME}[] =\n" "{\n" "${contents}" diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index cd1559838e..9e3499c932 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -67,6 +67,37 @@ macro(daemon_write_buildinfo name) endforeach() endmacro() +function(GenerateEmbedFilesConstexpr srcPaths dstPath format target) + set(first TRUE) + foreach(srcPath IN LISTS srcPaths) + get_filename_component(filename "${srcPath}" NAME_WE) + + if(first) + set(mode WRITE) + set(first FALSE) + else() + set(mode APPEND) + endif() + + set(cmd ${CMAKE_COMMAND} + "-DINPUT_FILE=${srcPath}" + "-DOUTPUT_FILE=${dstPath}" + "-DFILE_FORMAT=${format}" + "-DVARIABLE_NAME=${filename}" + "-DEMBED_MODE=${mode}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" ) + list(APPEND cmdList ${cmd}) + endforeach() + + add_custom_command( + OUTPUT ${dstPath} + COMMAND ${cmdList} + DEPENDS ${srcPath} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DaemonEmbed.cmake + ) + + target_sources(${target} PRIVATE ${dstPath}) +endfunction() + macro(daemon_embed_files basename dir list format targetname) set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") @@ -109,7 +140,8 @@ macro(daemon_embed_files basename dir list format targetname) "-DOUTPUT_FILE=${outpath}" "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" - -P "${DAEMON_FILE_EMBEDDER}" + "-DEMBED_MODE=WRITE" + -P "${DAEMON_TEXT_EMBEDDER}" MAIN_DEPENDENCY ${inpath} DEPENDS "${DAEMON_FILE_EMBEDDER}" diff --git a/cmake/DaemonVulkan.cmake b/cmake/DaemonVulkan.cmake new file mode 100644 index 0000000000..9a6be3bda8 --- /dev/null +++ b/cmake/DaemonVulkan.cmake @@ -0,0 +1,147 @@ +# =========================================================================== +# +# Daemon BSD Source Code +# Copyright (c) 2025 Daemon Developers +# All rights reserved. +# +# This file is part of the Daemon BSD Source Code (Daemon Source Code). +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# =========================================================================== + +option( VULKAN_SPIRV_OUT "Output text SPIR-V files alongside the binary format." ON ) +option( VULKAN_SPIRV_OPTIMISE "Enable SPIR-V optimisations." ON ) +option( VULKAN_SPIRV_LTO "Enable link-time SPIR-V optimisations." ON ) + +set( VULKAN_SPIRV_DEBUG "default" CACHE STRING "glslangValidator debug options (remove: g0, non-semantic: gV)") +set_property( CACHE VULKAN_SPIRV_DEBUG PROPERTY STRINGS default remove non-semantic ) + +if( USE_VULKAN ) + add_executable( VulkanShaderParser "${DAEMON_DIR}/cmake/DaemonVulkan/VulkanShaderParser.cpp" ) + + set( GRAPHICS_ENGINE_PATH ${DAEMON_DIR}/src/engine/renderer-vulkan/GraphicsEngine/ ) + set( GRAPHICS_ENGINE_PROCESSED_PATH ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/ ) + target_compile_definitions( VulkanShaderParser PRIVATE "-DDAEMON_VULKAN_GRAPHICS_ENGINE_PATH=\"${GRAPHICS_ENGINE_PATH}\"" ) + target_compile_definitions( VulkanShaderParser PRIVATE "-DDAEMON_VULKAN_GRAPHICS_ENGINE_PROCESSED_PATH=\"${GRAPHICS_ENGINE_PROCESSED_PATH}\"" ) + + file( MAKE_DIRECTORY ${GRAPHICS_ENGINE_PROCESSED_PATH} ) + + file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/processed/ ) + file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/ ) + file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/ ) +endif() + +include( DaemonEmbed ) + +macro( GenerateVulkanShaders target ) + # Pre-processing for #insert/#include + foreach( src IN LISTS graphicsEngineList ) + set( graphicsEngineProcessedList ${graphicsEngineProcessedList} ${src} ) + list( APPEND graphicsEngineOutputList ${GRAPHICS_ENGINE_PROCESSED_PATH}processed/${src} ) + + get_filename_component( name "${src}" NAME_WE ) + + if( VULKAN_SPIRV_OUT ) + set( spirvAsmPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/${name}.spirv ) + endif() + + set( spirvBinPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/${name}.spirvBin ) + + list( APPEND graphicsEngineOutputList ${spirvAsmPath} ) + list( APPEND graphicsEngineOutputList ${spirvBinPath} ) + endforeach() + + list( APPEND graphicsEngineOutputList ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/spirv.h ) + + # glslangValidator + find_program( glslangV glslangValidator HINTS /usr/bin /usr/local/bin $ENV{VULKAN_SDK}/Bin/ $ENV{VULKAN_SDK}/Bin32/ ) + + if( glslangV STREQUAL "glslangValidator-NOTFOUND" ) + message( FATAL_ERROR "glslangValidator not found; make sure you have the Vulkan SDK installed" ) + endif() + + set( spirvOptions --target-env vulkan1.3 --glsl-version 460 -e main -l -t ) + + if( VULKAN_SPIRV_OUT ) + set( spirvOut "ON" ) + else() + set( spirvOut "OFF" ) + endif() + + if( NOT VULKAN_SPIRV_OPTIMISE ) + set( spirvOptions ${spirvOptions} -Od ) + endif() + + if( VULKAN_SPIRV_LTO ) + set( spirvOptions ${spirvOptions} --lto ) + endif() + + if( VULKAN_SPIRV_DEBUG STREQUAL "remove" ) + set( spirvOptions ${spirvOptions} -g0 ) + elseif( VULKAN_SPIRV_DEBUG STREQUAL "non-semantic" ) + set( spirvOptions ${spirvOptions} -gV ) + endif() + + add_custom_command( + COMMAND VulkanShaderParser \"${glslangV} ${spirvOptions}\" ${spirvOut} ${graphicsEngineProcessedList} + DEPENDS ${graphicsEngineIDEList} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DaemonVulkan.cmake + OUTPUT ${graphicsEngineOutputList} + COMMENT "Generating Vulkan Graphics Engine: ${graphicsEngineProcessedList}" + ) + + add_custom_target( VulkanShaderParserTarget ALL + DEPENDS ${graphicsEngineOutputList} + ) + + # file( STRINGS ${GRAPHICS_ENGINE_PROCESSED_PATH}ShaderStages stagesList ) + + foreach( src IN LISTS graphicsEngineList ) + set( srcPath ${GRAPHICS_ENGINE_PROCESSED_PATH}processed/${src} ) + + get_filename_component( name "${src}" NAME_WE ) + + set( spirvAsmPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/${name}.spirv ) + + set( spirvBinPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/${name}.spirvBin ) + + list( POP_FRONT stagesList stage ) + + #add_custom_command( + # OUTPUT ${spirvBinPath} + # COMMAND ${glslangV} ${spirvOptions} -S ${stage} -V ${srcPath} -o ${spirvBinPath} -H > ${spirvAsmPath} + # DEPENDS ${srcPath} + # COMMENT "Generating Vulkan graphics engine binaries: ${src}" + #) + + list( APPEND spirvBinList ${spirvBinPath} ) + endforeach() + + GenerateEmbedFilesConstexpr( "${spirvBinList}" ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/spirv.h BINARY client-objects ) + + add_custom_target( VulkanShaderBin ALL + DEPENDS ${spirvBinList} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DaemonVulkan.cmake + ) + + target_sources( ${target} PRIVATE ${graphicsEngineOutputList} ) +endmacro() \ No newline at end of file diff --git a/cmake/DaemonVulkan/VulkanShaderParser.cpp b/cmake/DaemonVulkan/VulkanShaderParser.cpp new file mode 100644 index 0000000000..7108f39cb4 --- /dev/null +++ b/cmake/DaemonVulkan/VulkanShaderParser.cpp @@ -0,0 +1,242 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2025, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +#include +#include + +#include +#include +#include +#include + +#include + +std::string graphicsEnginePath = DAEMON_VULKAN_GRAPHICS_ENGINE_PATH; +std::string graphicsEngineProcessedPath = DAEMON_VULKAN_GRAPHICS_ENGINE_PROCESSED_PATH; + +std::string srcPath = graphicsEngineProcessedPath + "processed/"; +std::string spirvPath = graphicsEngineProcessedPath + "spirv/"; +std::string spirvBinPath = graphicsEngineProcessedPath + "bin/"; + +std::string StripLicense( const std::string& shaderText ) { + const size_t start = shaderText.find( "/*" ); + + if ( start == std::string::npos ) { + return shaderText; + } + + const size_t end = shaderText.find( "*/" ); + + const char* src = &shaderText.c_str()[end + 2]; + + uint32_t pos = end + 2; + while ( src && ( *src == ' ' || *src == '\t' || *src == '\n' ) ) { + src++; + pos++; + } + + return shaderText.substr( pos ); +} + +enum Stage { + FRAGMENT, + VERTEX, + COMPUTE +}; + +const std::unordered_map stageKeywords = { + { "local_size_x", COMPUTE }, + { "local_size_y", COMPUTE }, + { "local_size_z", COMPUTE }, + { "gl_Position", VERTEX }, +}; + +std::string ProcessInserts( const std::string& shaderText, Stage* stage, int insertCount = 0, int lineCount = 0 ) { + std::string out; + std::istringstream shaderTextStream( StripLicense( shaderText ) ); + + std::string line; + + int insertStartCount = insertCount; + + while ( std::getline( shaderTextStream, line, '\n' ) ) { + ++lineCount; + const std::string::size_type posInsert = line.find( "#insert" ); + const std::string::size_type position = posInsert == std::string::npos ? line.find( "#include" ) : posInsert; + + if ( !*stage ) { + for ( const std::pair& pair : stageKeywords ) { + if ( line.find( pair.first ) != std::string::npos ) { + *stage = pair.second; + break; + } + } + } + + if ( position == std::string::npos || line.find_first_not_of( " \t" ) != position ) { + out += line + "\n"; + continue; + } + + const bool useInsert = posInsert != std::string::npos; + + std::string shaderInsertPath = line.substr( + position + ( useInsert ? 8 : 10 ), + ( useInsert ? std::string::npos : line.size() - position - 11 ) ); + + if ( useInsert ) { + shaderInsertPath += ".glsl"; + } + + // Inserted shader lines will start at 10000, 20000 etc. to easily tell them apart from the main shader code + ++insertCount; + out += "#line " + std::to_string( insertCount * 10000 ) + "\n"; + out += "/**************************************************/\n"; + + FILE* glslSource = fopen( ( graphicsEnginePath + shaderInsertPath ).c_str(), "r" ); + + if ( !glslSource ) { + char* err = strerror( errno ); + exit( 3 ); + } + + fseek( glslSource, 0, SEEK_END ); + int size = ftell( glslSource ) + 1; + + fseek( glslSource, 0, 0 ); + + std::string glslSrc; + glslSrc.resize( size ); + fread( glslSrc.data(), sizeof( char ), size, glslSource ); + glslSrc.resize( strlen( glslSrc.c_str() ) ); + glslSrc.shrink_to_fit(); + + fclose( glslSource ); + + out += ProcessInserts( glslSrc, stage, insertCount, 0 ); + + out += "/**************************************************/\n"; + out += "#line " + std::to_string( insertStartCount * 10000 + lineCount ) + "\n"; + } + + return out; +} + +int main( int argc, char** argv ) { + #ifdef _MSC_VER + std::replace( graphicsEnginePath.begin(), graphicsEnginePath.end(), '/', '\\' ); + std::replace( graphicsEngineProcessedPath.begin(), graphicsEngineProcessedPath.end(), '/', '\\' ); + std::replace( srcPath.begin(), srcPath.end(), '/', '\\' ); + std::replace( spirvPath.begin(), spirvPath.end(), '/', '\\' ); + std::replace( spirvBinPath.begin(), spirvBinPath.end(), '/', '\\' ); + #endif + + /* FILE* shaderStages = fopen( ( graphicsEngineProcessedPath + "ShaderStages" ).c_str(), "w" ); + + if ( !shaderStages ) { + char* err = strerror( errno ); + return 1; + } + + fseek( shaderStages, 0, 0 ); */ + + const std::string baseSpirvOptions = argv[1]; + + const bool spirvAsm = !stricmp( argv[2], "ON" ); + + for( int i = 3; i < argc; i++ ) { + std::string path = argv[i]; + + FILE* glslSource = fopen( ( graphicsEnginePath + path ).c_str(), "r" ); + + if( !glslSource ) { + char* err = strerror( errno ); + return 1; + } + + size_t nameOffset = path.rfind( "/" ); + std::string name = nameOffset == std::string::npos ? path : path.substr( nameOffset ); + std::string nameNoExt = name.substr( 0, name.rfind( "." ) ); + + FILE* processedGLSL = fopen( ( srcPath + name ).c_str(), "w" ); + + if( !processedGLSL ) { + return 2; + } + + fseek( glslSource, 0, SEEK_END ); + int size = ftell( glslSource ); + + fseek( glslSource, 0, 0 ); + fseek( processedGLSL, 0, 0 ); + + std::string glslSrc; + glslSrc.resize( size ); + fread( glslSrc.data(), sizeof( char ), size, glslSource ); + glslSrc.resize( strlen( glslSrc.c_str() ) ); + glslSrc.shrink_to_fit(); + + Stage stage = FRAGMENT; + const std::string processedSrc = ProcessInserts( glslSrc, &stage, 0, 0 ); + fwrite( processedSrc.c_str(), sizeof( char ), processedSrc.size(), processedGLSL ); + + std::string spirvOptions = baseSpirvOptions; + switch ( stage ) { + case VERTEX: + spirvOptions += " -S vert"; + // fwrite( "vert", sizeof( char ), 4, shaderStages ); + break; + case FRAGMENT: + spirvOptions += " -S frag"; + // fwrite( "frag", sizeof( char ), 4, shaderStages ); + break; + case COMPUTE: + spirvOptions += " -S comp"; + // fwrite( "comp", sizeof( char ), 4, shaderStages ); + break; + } + + fclose( glslSource ); + fclose( processedGLSL ); + + spirvOptions += " -V " + srcPath + name + " -o " + spirvBinPath + nameNoExt + ".spirvBin"; + if ( spirvAsm ) { + spirvOptions += " -H > " + spirvPath + nameNoExt + ".spirv"; + } + + int r = system( spirvOptions.c_str() ); + + if ( i < argc - 1 ) { + // fwrite( "\n", sizeof( char ), 1, shaderStages ); + } + } + + // fclose( shaderStages ); +} From 22b69eb453b4558409b8b7f6f26ac4d9a5b711fd Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 5 Oct 2025 15:04:47 +0300 Subject: [PATCH 17/19] Add VulkanHeaders Vulkan header generator and xml spec from https://github.com/KhronosGroup/Vulkan-Docs commit: 7fe2b623f13dabb885e35b953dd690f01093d4bb --- libs/VulkanHeaders/apiconventions.py | 21 + libs/VulkanHeaders/cgenerator.py | 549 + libs/VulkanHeaders/generator.py | 1424 + libs/VulkanHeaders/genvk.py | 1160 + libs/VulkanHeaders/reflib.py | 686 + libs/VulkanHeaders/reg.py | 1885 + libs/VulkanHeaders/spec_tools/__init__.py | 7 + libs/VulkanHeaders/spec_tools/algo.py | 145 + libs/VulkanHeaders/spec_tools/attributes.py | 142 + libs/VulkanHeaders/spec_tools/base_printer.py | 213 + .../spec_tools/consistency_tools.py | 864 + .../spec_tools/console_printer.py | 273 + libs/VulkanHeaders/spec_tools/conventions.py | 562 + .../spec_tools/data_structures.py | 58 + libs/VulkanHeaders/spec_tools/entity_db.py | 666 + libs/VulkanHeaders/spec_tools/file_process.py | 119 + libs/VulkanHeaders/spec_tools/html_printer.py | 434 + .../VulkanHeaders/spec_tools/macro_checker.py | 228 + .../spec_tools/macro_checker_file.py | 1673 + libs/VulkanHeaders/spec_tools/main.py | 244 + libs/VulkanHeaders/spec_tools/shared.py | 256 + libs/VulkanHeaders/spec_tools/util.py | 58 + libs/VulkanHeaders/spec_tools/validity.py | 224 + libs/VulkanHeaders/vk.xml | 31806 ++++++++++++++++ libs/VulkanHeaders/vkconventions.py | 314 + 25 files changed, 44011 insertions(+) create mode 100644 libs/VulkanHeaders/apiconventions.py create mode 100644 libs/VulkanHeaders/cgenerator.py create mode 100644 libs/VulkanHeaders/generator.py create mode 100644 libs/VulkanHeaders/genvk.py create mode 100644 libs/VulkanHeaders/reflib.py create mode 100644 libs/VulkanHeaders/reg.py create mode 100644 libs/VulkanHeaders/spec_tools/__init__.py create mode 100644 libs/VulkanHeaders/spec_tools/algo.py create mode 100644 libs/VulkanHeaders/spec_tools/attributes.py create mode 100644 libs/VulkanHeaders/spec_tools/base_printer.py create mode 100644 libs/VulkanHeaders/spec_tools/consistency_tools.py create mode 100644 libs/VulkanHeaders/spec_tools/console_printer.py create mode 100644 libs/VulkanHeaders/spec_tools/conventions.py create mode 100644 libs/VulkanHeaders/spec_tools/data_structures.py create mode 100644 libs/VulkanHeaders/spec_tools/entity_db.py create mode 100644 libs/VulkanHeaders/spec_tools/file_process.py create mode 100644 libs/VulkanHeaders/spec_tools/html_printer.py create mode 100644 libs/VulkanHeaders/spec_tools/macro_checker.py create mode 100644 libs/VulkanHeaders/spec_tools/macro_checker_file.py create mode 100644 libs/VulkanHeaders/spec_tools/main.py create mode 100644 libs/VulkanHeaders/spec_tools/shared.py create mode 100644 libs/VulkanHeaders/spec_tools/util.py create mode 100644 libs/VulkanHeaders/spec_tools/validity.py create mode 100644 libs/VulkanHeaders/vk.xml create mode 100644 libs/VulkanHeaders/vkconventions.py diff --git a/libs/VulkanHeaders/apiconventions.py b/libs/VulkanHeaders/apiconventions.py new file mode 100644 index 0000000000..da734fa308 --- /dev/null +++ b/libs/VulkanHeaders/apiconventions.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2021-2025 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Generic alias for working group-specific API conventions interface. + +# This import should be changed at the repository / working group level to +# specify the correct API's conventions. + + +import os + +defaultAPI = 'vulkan' + +VulkanAPI = os.getenv('VULKAN_API', default=defaultAPI) + +if VulkanAPI == 'vulkansc': + from vkconventions import VulkanSCConventions as APIConventions +else: + from vkconventions import VulkanConventions as APIConventions diff --git a/libs/VulkanHeaders/cgenerator.py b/libs/VulkanHeaders/cgenerator.py new file mode 100644 index 0000000000..1660f4dd82 --- /dev/null +++ b/libs/VulkanHeaders/cgenerator.py @@ -0,0 +1,549 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +import os +import re + +from generator import (GeneratorOptions, + MissingGeneratorOptionsConventionsError, + MissingGeneratorOptionsError, MissingRegistryError, + OutputGenerator, noneStr, regSortFeatures, write) + +class CGeneratorOptions(GeneratorOptions): + """CGeneratorOptions - subclass of GeneratorOptions. + + Adds options used by COutputGenerator objects during C language header + generation.""" + + def __init__(self, + prefixText='', + genFuncPointers=True, + protectFile=True, + protectFeature=True, + protectProto=None, + protectProtoStr=None, + protectExtensionProto=None, + protectExtensionProtoStr=None, + protectExportName=None, + protectExportProtoStr=None, + apicall='', + apientry='', + apientryp='', + indentFuncProto=True, + indentFuncPointer=False, + alignFuncParam=0, + genEnumBeginEndRange=False, + genAliasMacro=False, + genStructExtendsComment=False, + aliasMacro='', + misracstyle=False, + misracppstyle=False, + **kwargs + ): + """Constructor. + Additional parameters beyond parent class: + + - prefixText - list of strings to prefix generated header with + (usually a copyright statement + calling convention macros) + - protectFile - True if multiple inclusion protection should be + generated (based on the filename) around the entire header + - protectFeature - True if #ifndef..#endif protection should be + generated around a feature interface in the header file + - genFuncPointers - True if function pointer typedefs should be + generated + - protectProto - If conditional protection should be generated + around prototype declarations, set to either '#ifdef' + to require opt-in (#ifdef protectProtoStr) or '#ifndef' + to require opt-out (#ifndef protectProtoStr). Otherwise + set to None. + - protectProtoStr - #ifdef/#ifndef symbol to use around prototype + declarations, if protectProto is set + - protectExtensionProto - If conditional protection should be generated + around extension prototype declarations, set to either '#ifdef' + to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' + to require opt-out (#ifndef protectExtensionProtoStr). Otherwise + set to None + - protectExtensionProtoStr - #ifdef/#ifndef symbol to use around + extension prototype declarations, if protectExtensionProto is set + - protectExportName - name used to determine if a command is + exported matching an entry in the XML 'export' attribute. + Set to None if no matching should be done. + - protectExportProtoStr - #ifndef symbol to use around prototypes + for commands that are not exported. + Set to None if no protection is wanted. + - apicall - string to use for the function declaration prefix, + such as APICALL on Windows + - apientry - string to use for the calling convention macro, + in typedefs, such as APIENTRY + - apientryp - string to use for the calling convention macro + in function pointer typedefs, such as APIENTRYP + - indentFuncProto - True if prototype declarations should put each + parameter on a separate line + - indentFuncPointer - True if typedefed function pointers should put each + parameter on a separate line + - alignFuncParam - if nonzero and parameters are being put on a + separate line, align parameter names at the specified column + - genEnumBeginEndRange - True if BEGIN_RANGE / END_RANGE macros should + be generated for enumerated types + - genAliasMacro - True if the OpenXR alias macro should be generated + for aliased types (unclear what other circumstances this is useful) + - genStructExtendsComment - True if comments showing the structures + whose pNext chain a structure extends are included before its + definition + - aliasMacro - alias macro to inject when genAliasMacro is True + - misracstyle - generate MISRA C-friendly headers + - misracppstyle - generate MISRA C++-friendly headers""" + + GeneratorOptions.__init__(self, **kwargs) + + self.prefixText = prefixText + """list of strings to prefix generated header with (usually a copyright statement + calling convention macros).""" + + self.genFuncPointers = genFuncPointers + """True if function pointer typedefs should be generated""" + + self.protectFile = protectFile + """True if multiple inclusion protection should be generated (based on the filename) around the entire header.""" + + self.protectFeature = protectFeature + """True if #ifndef..#endif protection should be generated around a feature interface in the header file.""" + + self.protectProto = protectProto + """If conditional protection should be generated around prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectProtoStr) or '#ifndef' to require opt-out (#ifndef protectProtoStr). Otherwise set to None.""" + + self.protectProtoStr = protectProtoStr + """#ifdef/#ifndef symbol to use around prototype declarations, if protectProto is set""" + + self.protectExtensionProto = protectExtensionProto + """If conditional protection should be generated around extension prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' to require opt-out (#ifndef protectExtensionProtoStr). Otherwise set to None.""" + + self.protectExtensionProtoStr = protectExtensionProtoStr + """#ifdef/#ifndef symbol to use around extension prototype declarations, if protectExtensionProto is set""" + + self.protectExportName = protectExportName + """Export name for commands which are exported""" + + self.protectExportProtoStr = protectExportProtoStr + """#ifndef symbol to use around prototypes for commands which are not exported""" + + self.apicall = apicall + """string to use for the function declaration prefix, such as APICALL on Windows.""" + + self.apientry = apientry + """string to use for the calling convention macro, in typedefs, such as APIENTRY.""" + + self.apientryp = apientryp + """string to use for the calling convention macro in function pointer typedefs, such as APIENTRYP.""" + + self.indentFuncProto = indentFuncProto + """True if prototype declarations should put each parameter on a separate line""" + + self.indentFuncPointer = indentFuncPointer + """True if typedefed function pointers should put each parameter on a separate line""" + + self.alignFuncParam = alignFuncParam + """if nonzero and parameters are being put on a separate line, align parameter names at the specified column""" + + self.genEnumBeginEndRange = genEnumBeginEndRange + """True if BEGIN_RANGE / END_RANGE macros should be generated for enumerated types""" + + self.genAliasMacro = genAliasMacro + """True if the OpenXR alias macro should be generated for aliased types (unclear what other circumstances this is useful)""" + + self.genStructExtendsComment = genStructExtendsComment + """True if comments showing the structures whose pNext chain a structure extends are included before its definition""" + + self.aliasMacro = aliasMacro + """alias macro to inject when genAliasMacro is True""" + + self.misracstyle = misracstyle + """generate MISRA C-friendly headers""" + + self.misracppstyle = misracppstyle + """generate MISRA C++-friendly headers""" + + self.codeGenerator = True + """True if this generator makes compilable code""" + + +class COutputGenerator(OutputGenerator): + """Generates C-language API interfaces.""" + + # This is an ordered list of sections in the header file. + TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum', + 'group', 'bitmask', 'funcpointer', 'struct'] + ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # Internal state - accumulators for different inner block text + self.sections = {section: [] for section in self.ALL_SECTIONS} + self.feature_not_empty = False + self.may_alias = None + + def beginFile(self, genOpts): + OutputGenerator.beginFile(self, genOpts) + if self.genOpts is None: + raise MissingGeneratorOptionsError() + # C-specific + # + # Multiple inclusion protection & C++ wrappers. + if self.genOpts.protectFile and self.genOpts.filename: + headerSym = re.sub(r'\.h', '_h_', + os.path.basename(self.genOpts.filename)).upper() + write('#ifndef', headerSym, file=self.outFile) + write('#define', headerSym, '1', file=self.outFile) + self.newline() + + # User-supplied prefix text, if any (list of strings) + if genOpts.prefixText: + for s in genOpts.prefixText: + write(s, file=self.outFile) + + # C++ extern wrapper - after prefix lines so they can add includes. + self.newline() + write('#ifdef __cplusplus', file=self.outFile) + write('extern "C" {', file=self.outFile) + write('#endif', file=self.outFile) + self.newline() + + def endFile(self): + # C-specific + # Finish C++ wrapper and multiple inclusion protection + if self.genOpts is None: + raise MissingGeneratorOptionsError() + self.newline() + write('#ifdef __cplusplus', file=self.outFile) + write('}', file=self.outFile) + write('#endif', file=self.outFile) + if self.genOpts.protectFile and self.genOpts.filename: + self.newline() + write('#endif', file=self.outFile) + # Finish processing in superclass + OutputGenerator.endFile(self) + + def beginFeature(self, interface, emit): + # Start processing in superclass + OutputGenerator.beginFeature(self, interface, emit) + # C-specific + # Accumulate includes, defines, types, enums, function pointer typedefs, + # end function prototypes separately for this feature. They are only + # printed in endFeature(). + self.sections = {section: [] for section in self.ALL_SECTIONS} + self.feature_not_empty = False + + def _endProtectComment(self, protect_str, protect_directive='#ifdef'): + if protect_directive is None or protect_str is None: + raise RuntimeError('Should not call in here without something to protect') + + # Do not put comments after #endif closing blocks if this is not set + if not self.genOpts.conventions.protectProtoComment: + return '' + elif 'ifdef' in protect_directive: + return f' /* {protect_str} */' + else: + return f' /* !{protect_str} */' + + def endFeature(self): + "Actually write the interface to the output file." + # C-specific + if self.emit: + if self.feature_not_empty: + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + is_core = self.featureName and self.featureName.startswith(f"{self.conventions.api_prefix}VERSION_") + if self.genOpts.conventions.writeFeature(self.featureName, self.featureExtraProtect, self.genOpts.filename): + self.newline() + if self.genOpts.protectFeature: + write('#ifndef', self.featureName, file=self.outFile) + + # If type declarations are needed by other features based on + # this one, it may be necessary to suppress the ExtraProtect, + # or move it below the 'for section...' loop. + if self.featureExtraProtect is not None: + write('#ifdef', self.featureExtraProtect, file=self.outFile) + self.newline() + + # Generate warning of possible use in IDEs + write(f'// {self.featureName} is a preprocessor guard. Do not pass it to API calls.', file=self.outFile) + write('#define', self.featureName, '1', file=self.outFile) + for section in self.TYPE_SECTIONS: + contents = self.sections[section] + if contents: + write('\n'.join(contents), file=self.outFile) + + if self.genOpts.genFuncPointers and self.sections['commandPointer']: + write('\n'.join(self.sections['commandPointer']), file=self.outFile) + self.newline() + + if self.sections['command']: + if self.genOpts.protectProto: + write(self.genOpts.protectProto, + self.genOpts.protectProtoStr, file=self.outFile) + if self.genOpts.protectExtensionProto and not is_core: + write(self.genOpts.protectExtensionProto, + self.genOpts.protectExtensionProtoStr, file=self.outFile) + write('\n'.join(self.sections['command']), end='', file=self.outFile) + if self.genOpts.protectExtensionProto and not is_core: + write('#endif' + + self._endProtectComment(protect_directive=self.genOpts.protectExtensionProto, + protect_str=self.genOpts.protectExtensionProtoStr), + file=self.outFile) + if self.genOpts.protectProto: + write('#endif' + + self._endProtectComment(protect_directive=self.genOpts.protectProto, + protect_str=self.genOpts.protectProtoStr), + file=self.outFile) + else: + self.newline() + + if self.featureExtraProtect is not None: + write('#endif' + + self._endProtectComment(protect_str=self.featureExtraProtect), + file=self.outFile) + + if self.genOpts.protectFeature: + write('#endif' + + self._endProtectComment(protect_str=self.featureName), + file=self.outFile) + # Finish processing in superclass + OutputGenerator.endFeature(self) + + def appendSection(self, section, text): + "Append a definition to the specified section" + + if section is None: + self.logMsg('error', 'Missing section in appendSection (probably a element missing its \'category\' attribute. Text:', text) + exit(1) + + self.sections[section].append(text) + self.feature_not_empty = True + + def genType(self, typeinfo, name, alias): + "Generate type." + OutputGenerator.genType(self, typeinfo, name, alias) + typeElem = typeinfo.elem + + # Vulkan: + # Determine the category of the type, and the type section to add + # its definition to. + # 'funcpointer' is added to the 'struct' section as a workaround for + # internal issue #877, since structures and function pointer types + # can have cross-dependencies. + category = typeElem.get('category') + if category == 'funcpointer': + section = 'struct' + else: + section = category + + if category in ('struct', 'union'): + # If the type is a struct type, generate it using the + # special-purpose generator. + self.genStruct(typeinfo, name, alias) + else: + if self.genOpts is None: + raise MissingGeneratorOptionsError() + + body = self.deprecationComment(typeElem) + + # OpenXR: this section was not under 'else:' previously, just fell through + if alias: + # If the type is an alias, just emit a typedef declaration + body += f"typedef {alias} {name};\n" + else: + # Replace tags with an APIENTRY-style string + # (from self.genOpts). Copy other text through unchanged. + # If the resulting text is an empty string, do not emit it. + body += noneStr(typeElem.text) + for elem in typeElem: + if elem.tag == 'apientry': + body += self.genOpts.apientry + noneStr(elem.tail) + else: + body += noneStr(elem.text) + noneStr(elem.tail) + if category == 'define' and self.misracppstyle(): + body = body.replace("(uint32_t)", "static_cast") + if body: + # Add extra newline after multi-line entries. + if '\n' in body[0:-1]: + body += '\n' + self.appendSection(section, body) + + def genProtectString(self, protect_str): + """Generate protection string. + + Protection strings are the strings defining the OS/Platform/Graphics + requirements for a given API command. When generating the + language header files, we need to make sure the items specific to a + graphics API or OS platform are properly wrapped in #ifs.""" + protect_if_str = '' + protect_end_str = '' + if not protect_str: + return (protect_if_str, protect_end_str) + + if ',' in protect_str: + protect_list = protect_str.split(',') + protect_defs = (f'defined({d})' for d in protect_list) + protect_def_str = ' && '.join(protect_defs) + protect_if_str = f'#if {protect_def_str}\n' + protect_end_str = f'#endif // {protect_def_str}\n' + else: + protect_if_str = f'#ifdef {protect_str}\n' + protect_end_str = f'#endif // {protect_str}\n' + + return (protect_if_str, protect_end_str) + + def typeMayAlias(self, typeName): + if not self.may_alias: + if self.registry is None: + raise MissingRegistryError() + # First time we have asked if a type may alias. + # So, populate the set of all names of types that may. + + # Everyone with an explicit mayalias="true" + self.may_alias = set(typeName + for typeName, data in self.registry.typedict.items() + if data.elem.get('mayalias') == 'true') + + # Every type mentioned in some other type's parentstruct attribute. + polymorphic_bases = (otherType.elem.get('parentstruct') + for otherType in self.registry.typedict.values()) + self.may_alias.update(set(x for x in polymorphic_bases + if x is not None)) + return typeName in self.may_alias + + def genStruct(self, typeinfo, typeName, alias): + """Generate struct (e.g. C "struct" type). + + This is a special case of the tag where the contents are + interpreted as a set of tags instead of freeform C + C type declarations. The tags are just like + tags - they are a declaration of a struct or union member. + Only simple member declarations are supported (no nested + structs etc.) + + If alias is not None, then this struct aliases another; just + generate a typedef of that alias.""" + OutputGenerator.genStruct(self, typeinfo, typeName, alias) + + if self.genOpts is None: + raise MissingGeneratorOptionsError() + + typeElem = typeinfo.elem + body = self.deprecationComment(typeElem) + + if alias: + body += f"typedef {alias} {typeName};\n" + else: + (protect_begin, protect_end) = self.genProtectString(typeElem.get('protect')) + if protect_begin: + body += protect_begin + + if self.genOpts.genStructExtendsComment: + structextends = typeElem.get('structextends') + body += f"// {typeName} extends {structextends}\n" if structextends else '' + + body += f"typedef {typeElem.get('category')}" + + # This is an OpenXR-specific alternative where aliasing refers + # to an inheritance hierarchy of types rather than C-level type + # aliases. + if self.genOpts.genAliasMacro and self.typeMayAlias(typeName): + body += f" {self.genOpts.aliasMacro}" + + body += f" {typeName} {{\n" + + targetLen = self.getMaxCParamTypeLength(typeinfo) + for member in typeElem.findall('.//member'): + body += self.deprecationComment(member, indent = 4) + body += self.makeCParamDecl(member, targetLen + 4) + body += ';\n' + body += f"}} {typeName};\n" + if protect_end: + body += protect_end + + self.appendSection('struct', body) + + def genGroup(self, groupinfo, groupName, alias=None): + """Generate groups (e.g. C "enum" type). + + These are concatenated together with other types. + + If alias is not None, it is the name of another group type + which aliases this type; just generate that alias.""" + OutputGenerator.genGroup(self, groupinfo, groupName, alias) + groupElem = groupinfo.elem + + # After either enumerated type or alias paths, add the declaration + # to the appropriate section for the group being defined. + if groupElem.get('type') == 'bitmask': + section = 'bitmask' + else: + section = 'group' + + if alias: + # If the group name is aliased, just emit a typedef declaration + # for the alias. + body = f"typedef {alias} {groupName};\n" + self.appendSection(section, body) + else: + if self.genOpts is None: + raise MissingGeneratorOptionsError() + (section, body) = self.buildEnumCDecl(self.genOpts.genEnumBeginEndRange, groupinfo, groupName) + self.appendSection(section, f"\n{body}") + + def genEnum(self, enuminfo, name, alias): + """Generate the C declaration for a constant (a single value). + + tags may specify their values in several ways, but are usually + just integers.""" + + OutputGenerator.genEnum(self, enuminfo, name, alias) + + body = self.deprecationComment(enuminfo.elem) + body += self.buildConstantCDecl(enuminfo, name, alias) + self.appendSection('enum', body) + + def genCmd(self, cmdinfo, name, alias): + "Command generation" + OutputGenerator.genCmd(self, cmdinfo, name, alias) + + # if alias: + # prefix = '// ' + name + ' is an alias of command ' + alias + '\n' + # else: + # prefix = '' + if self.genOpts is None: + raise MissingGeneratorOptionsError() + + prefix = '' + decls = self.makeCDecls(cmdinfo.elem) + + # If the 'export' attribute is not set for this command, or does not + # match the export name selected during generation, wrap the command + # prototype in a C conditional which can be enabled to make the + # prototype not appear at compile time. + + export = cmdinfo.elem.get('export','') + protect_prefix = protect_suffix = '' + if export is None or self.genOpts.protectExportName not in export.split(','): + if self.genOpts.protectExportProtoStr is not None: + # Command is not exported, so should not be visible if + # suppressed by this symbol + protect_prefix = f'#ifndef {self.genOpts.protectExportProtoStr}\n' + protect_suffix = '\n#endif' + + decls[0] = protect_prefix + decls[0] + protect_suffix + + self.appendSection('command', f"{prefix + decls[0]}\n") + if self.genOpts.genFuncPointers: + self.appendSection('commandPointer', decls[1]) + + def misracstyle(self): + return self.genOpts.misracstyle + + def misracppstyle(self): + return self.genOpts.misracppstyle diff --git a/libs/VulkanHeaders/generator.py b/libs/VulkanHeaders/generator.py new file mode 100644 index 0000000000..5d369a3614 --- /dev/null +++ b/libs/VulkanHeaders/generator.py @@ -0,0 +1,1424 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 +"""Base class for source/header/doc generators, as well as some utility functions.""" + +from __future__ import unicode_literals + +import io +import os +import pdb +import re +import shutil +import sys +import tempfile +try: + from pathlib import Path +except ImportError: + from pathlib2 import Path # type: ignore + +from spec_tools.util import getElemName, getElemType + + +def write(*args, **kwargs): + file = kwargs.pop('file', sys.stdout) + end = kwargs.pop('end', '\n') + file.write(' '.join(str(arg) for arg in args)) + file.write(end) + + +def noneStr(s): + """Return string argument, or "" if argument is None. + + Used in converting etree Elements into text. + s - string to convert""" + if s: + return s + return "" + + +def enquote(s): + """Return string argument with surrounding quotes, + for serialization into Python code.""" + if s: + if isinstance(s, str): + return f"'{s}'" + else: + return s + return None + + +def regSortCategoryKey(feature): + """Sort key for regSortFeatures. + Sorts by category of the feature name string: + + - Core API features (those defined with a `` tag) + - (sort VKSC after VK - this is Vulkan-specific) + - ARB/KHR/OES (Khronos extensions) + - other (EXT/vendor extensions)""" + + if feature.elem.tag == 'feature': + if feature.name.startswith('VKSC'): + return 0.5 + else: + return 0 + + if feature.category.upper() in ('ARB', 'KHR', 'OES'): + return 1 + + return 2 + + +def regSortOrderKey(feature): + """Sort key for regSortFeatures - key is the sortorder attribute.""" + + return feature.sortorder + + +def regSortNameKey(feature): + """Sort key for regSortFeatures - key is the extension name.""" + + return feature.name + + +def regSortFeatureVersionKey(feature): + """Sort key for regSortFeatures - key is the feature version. + `` elements all have version number 0.""" + + return float(feature.versionNumber) + + +def regSortExtensionNumberKey(feature): + """Sort key for regSortFeatures - key is the extension number. + `` elements all have extension number 0.""" + + return int(feature.number) + + +def regSortFeatures(featureList): + """Default sort procedure for features. + + - Sorts by explicit sort order (default 0) relative to other features + - then by feature category ('feature' or 'extension'), + - then by version number (for features) + - then by extension number (for extensions)""" + featureList.sort(key=regSortExtensionNumberKey) + featureList.sort(key=regSortFeatureVersionKey) + featureList.sort(key=regSortCategoryKey) + featureList.sort(key=regSortOrderKey) + + +class MissingGeneratorOptionsError(RuntimeError): + """Error raised when a Generator tries to do something that requires GeneratorOptions but it is None.""" + + def __init__(self, msg=None): + full_msg = 'Missing generator options object self.genOpts' + if msg: + full_msg += f": {msg}" + super().__init__(full_msg) + + +class MissingRegistryError(RuntimeError): + """Error raised when a Generator tries to do something that requires a Registry object but it is None.""" + + def __init__(self, msg=None): + full_msg = 'Missing Registry object self.registry' + if msg: + full_msg += f": {msg}" + super().__init__(full_msg) + + +class MissingGeneratorOptionsConventionsError(RuntimeError): + """Error raised when a Generator tries to do something that requires a Conventions object but it is None.""" + + def __init__(self, msg=None): + full_msg = 'Missing Conventions object self.genOpts.conventions' + if msg: + full_msg += f": {msg}" + super().__init__(full_msg) + + +class GeneratorOptions: + """Base class for options used during header/documentation production. + + These options are target language independent, and used by + Registry.apiGen() and by base OutputGenerator objects.""" + + def __init__(self, + conventions=None, + filename=None, + directory='.', + genpath=None, + apiname=None, + mergeApiNames=None, + profile=None, + versions='.*', + emitversions='.*', + defaultExtensions=None, + addExtensions=None, + removeExtensions=None, + emitExtensions=None, + emitSpirv=None, + emitFormats=None, + reparentEnums=True, + sortProcedure=regSortFeatures, + requireCommandAliases=False, + requireDepends=True, + ): + """Constructor. + + Arguments: + + - conventions - may be mandatory for some generators: + an object that implements ConventionsBase + - filename - basename of file to generate, or None to write to stdout. + - directory - directory in which to generate filename + - genpath - path to previously generated files, such as apimap.py + - apiname - string matching `` 'apiname' attribute, e.g. 'gl'. + - mergeApiNames - If not None, a comma separated list of API names + to merge into the API specified by 'apiname' + - profile - string specifying API profile , e.g. 'core', or None. + - versions - regex matching API versions to process interfaces for. + Normally `'.*'` or `'[0-9][.][0-9]'` to match all defined versions. + - emitversions - regex matching API versions to actually emit + interfaces for (though all requested versions are considered + when deciding which interfaces to generate). For GL 4.3 glext.h, + this might be `'1[.][2-5]|[2-4][.][0-9]'`. + - defaultExtensions - If not None, a string which must in its + entirety match the pattern in the "supported" attribute of + the ``. Defaults to None. Usually the same as apiname. + - addExtensions - regex matching names of additional extensions + to include. Defaults to None. + - removeExtensions - regex matching names of extensions to + remove (after defaultExtensions and addExtensions). Defaults + to None. + - emitExtensions - regex matching names of extensions to actually emit + interfaces for (though all requested versions are considered when + deciding which interfaces to generate). Defaults to None. + - emitSpirv - regex matching names of extensions and capabilities + to actually emit interfaces for. + - emitFormats - regex matching names of formats to actually emit + interfaces for. + - reparentEnums - move elements which extend an enumerated + type from or elements to the target + element. This is required for almost all purposes, but the + InterfaceGenerator relies on the list of interfaces in the + or being complete. Defaults to True. + - sortProcedure - takes a list of FeatureInfo objects and sorts + them in place to a preferred order in the generated output. + - requireCommandAliases - if True, treat command aliases + as required dependencies. + - requireDepends - whether to follow API dependencies when emitting + APIs. + + Default is + - core API versions + - Khronos (ARB/KHR/OES) extensions + - All other extensions + - By core API version number or extension number in each group. + + The regex patterns can be None or empty, in which case they match + nothing.""" + self.conventions = conventions + """may be mandatory for some generators: + an object that implements ConventionsBase""" + + self.filename = filename + "basename of file to generate, or None to write to stdout." + + self.genpath = genpath + """path to previously generated files, such as apimap.py""" + + self.directory = directory + "directory in which to generate filename" + + self.apiname = apiname + "string matching `` 'apiname' attribute, e.g. 'gl'." + + self.mergeApiNames = mergeApiNames + "comma separated list of API names to merge into the API specified by 'apiname'" + + self.profile = profile + "string specifying API profile , e.g. 'core', or None." + + self.versions = self.emptyRegex(versions) + """regex matching API versions to process interfaces for. + Normally `'.*'` or `'[0-9][.][0-9]'` to match all defined versions.""" + + self.emitversions = self.emptyRegex(emitversions) + """regex matching API versions to actually emit + interfaces for (though all requested versions are considered + when deciding which interfaces to generate). For GL 4.3 glext.h, + this might be `'1[.][2-5]|[2-4][.][0-9]'`.""" + + self.defaultExtensions = defaultExtensions + """If not None, a string which must in its + entirety match the pattern in the "supported" attribute of + the ``. Defaults to None. Usually the same as apiname.""" + + self.addExtensions = self.emptyRegex(addExtensions) + """regex matching names of additional extensions + to include. Defaults to None.""" + + self.removeExtensions = self.emptyRegex(removeExtensions) + """regex matching names of extensions to + remove (after defaultExtensions and addExtensions). Defaults + to None.""" + + self.emitExtensions = self.emptyRegex(emitExtensions) + """regex matching names of extensions to actually emit + interfaces for (though all requested versions are considered when + deciding which interfaces to generate).""" + + self.emitSpirv = self.emptyRegex(emitSpirv) + """regex matching names of extensions and capabilities + to actually emit interfaces for.""" + + self.emitFormats = self.emptyRegex(emitFormats) + """regex matching names of formats + to actually emit interfaces for.""" + + self.reparentEnums = reparentEnums + """boolean specifying whether to remove elements from + or when extending an type.""" + + self.sortProcedure = sortProcedure + """takes a list of FeatureInfo objects and sorts + them in place to a preferred order in the generated output. + Default is core API versions, ARB/KHR/OES extensions, all + other extensions, alphabetically within each group.""" + + self.codeGenerator = False + """True if this generator makes compilable code""" + + self.registry = None + """Populated later with the registry object.""" + + self.requireCommandAliases = requireCommandAliases + """True if alias= attributes of tags are transitively + required.""" + + self.requireDepends = requireDepends + """True if dependencies of API tags are transitively required.""" + + def emptyRegex(self, pat): + """Substitute a regular expression which matches no version + or extension names for None or the empty string.""" + if not pat: + return '_nomatch_^' + + return pat + + +class OutputGenerator: + """Generate specified API interfaces in a specific style, such as a C header. + + Base class for generating API interfaces. + Manages basic logic, logging, and output file control. + Derived classes actually generate formatted output. + """ + + # categoryToPath - map XML 'category' to include file directory name + categoryToPath = { + 'bitmask': 'flags', + 'enum': 'enums', + 'funcpointer': 'funcpointers', + 'handle': 'handles', + 'define': 'defines', + 'basetype': 'basetypes', + } + + def breakName(self, name, msg): + """Break into debugger if this is a special name""" + + # List of string names to break on + bad = ( + ) + + if name in bad and True: + print(f'breakName {name}: {msg}') + pdb.set_trace() + + def __init__(self, errFile=sys.stderr, warnFile=sys.stderr, diagFile=sys.stdout): + """Constructor + + - errFile, warnFile, diagFile - file handles to write errors, + warnings, diagnostics to. May be None to not write.""" + self.outFile = None + self.errFile = errFile + self.warnFile = warnFile + self.diagFile = diagFile + # Internal state + self.featureName = None + """The current feature name being generated.""" + + self.genOpts = None + """The GeneratorOptions subclass instance.""" + + self.registry = None + """The specification registry object.""" + + self.featureDictionary = {} + """The dictionary of dictionaries of API features.""" + + # Used for extension enum value generation + self.extBase = 1000000000 + self.extBlockSize = 1000 + self.madeDirs = {} + + # API dictionary, which may be loaded by the beginFile method of + # derived generators. + self.apidict = None + + # File suffix for generated files, set in beginFile below. + self.file_suffix = '' + + def logMsg(self, level, *args): + """Write a message of different categories to different + destinations. + + - `level` + - 'diag' (diagnostic, voluminous) + - 'warn' (warning) + - 'error' (fatal error - raises exception after logging) + + - `*args` - print()-style arguments to direct to corresponding log""" + if level == 'error': + strfile = io.StringIO() + write('ERROR:', *args, file=strfile) + if self.errFile is not None: + write(strfile.getvalue(), file=self.errFile) + raise UserWarning(strfile.getvalue()) + elif level == 'warn': + if self.warnFile is not None: + write('WARNING:', *args, file=self.warnFile) + elif level == 'diag': + if self.diagFile is not None: + write('DIAG:', *args, file=self.diagFile) + else: + raise UserWarning( + f"*** FATAL ERROR in Generator.logMsg: unknown level:{level}") + + def enumToValue(self, elem, needsNum, bitwidth = 32, + forceSuffix = False, parent_for_alias_dereference=None): + """Parse and convert an `` tag into a value. + + - elem - Element + - needsNum - generate a numeric representation of the element value + - bitwidth - size of the numeric representation in bits (32 or 64) + - forceSuffix - if True, always use a 'U' / 'ULL' suffix on integers + - parent_for_alias_dereference - if not None, an Element containing + the parent of elem, used to look for elements this is an alias of + + Returns a list: + + - first element - integer representation of the value, or None + if needsNum is False. The value must be a legal number + if needsNum is True. + - second element - string representation of the value + + There are several possible representations of values. + + - A 'value' attribute simply contains the value. + - A 'bitpos' attribute defines a value by specifying the bit + position which is set in that value. + - An 'offset','extbase','extends' triplet specifies a value + as an offset to a base value defined by the specified + 'extbase' extension name, which is then cast to the + typename specified by 'extends'. This requires probing + the registry database, and imbeds knowledge of the + API extension enum scheme in this function. + - An 'alias' attribute contains the name of another enum + which this is an alias of. The other enum must be + declared first when emitting this enum.""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + + name = elem.get('name') + numVal = None + if 'value' in elem.keys(): + value = elem.get('value') + # print('About to translate value =', value, 'type =', type(value)) + if needsNum: + numVal = int(value, 0) + # If there is a non-integer, numeric 'type' attribute (e.g. 'u' or + # 'ull'), append it to the string value. + # t = enuminfo.elem.get('type') + # if t is not None and t != '' and t != 'i' and t != 's': + # value += enuminfo.type + if forceSuffix: + if bitwidth == 64: + value = f"{value}ULL" + else: + value = f"{value}U" + self.logMsg('diag', 'Enum', name, '-> value [', numVal, ',', value, ']') + return [numVal, value] + if 'bitpos' in elem.keys(): + value = elem.get('bitpos') + bitpos = int(value, 0) + numVal = 1 << bitpos + value = f'0x{numVal:08x}' + if bitwidth == 64 or bitpos >= 32: + value = f"{value}ULL" + elif forceSuffix: + value = f"{value}U" + self.logMsg('diag', 'Enum', name, '-> bitpos [', numVal, ',', value, ']') + return [numVal, value] + if 'offset' in elem.keys(): + # Obtain values in the mapping from the attributes + enumNegative = False + offset = int(elem.get('offset'), 0) + extnumber = int(elem.get('extnumber'), 0) + extends = elem.get('extends') + if 'dir' in elem.keys(): + enumNegative = True + self.logMsg('diag', 'Enum', name, 'offset =', offset, + 'extnumber =', extnumber, 'extends =', extends, + 'enumNegative =', enumNegative) + # Now determine the actual enumerant value, as defined + # in the "Layers and Extensions" appendix of the spec. + numVal = self.extBase + (extnumber - 1) * self.extBlockSize + offset + if enumNegative: + numVal *= -1 + value = '%d' % numVal + # More logic needed! + self.logMsg('diag', 'Enum', name, '-> offset [', numVal, ',', value, ']') + return [numVal, value] + if 'alias' in elem.keys(): + alias_of = elem.get('alias') + if parent_for_alias_dereference is None: + return (None, alias_of) + siblings = parent_for_alias_dereference.findall('enum') + for sib in siblings: + sib_name = sib.get('name') + if sib_name == alias_of: + return self.enumToValue(sib, needsNum) + raise RuntimeError("Could not find the aliased enum value") + return [None, None] + + def checkDuplicateEnums(self, enums): + """Check enumerated values for duplicates. + + - enums - list of `` Elements + + returns the list with duplicates stripped""" + # Dictionaries indexed by name and numeric value. + # Entries are [ Element, numVal, strVal ] matching name or value + + nameMap = {} + valueMap = {} + + stripped = [] + for elem in enums: + name = elem.get('name') + (numVal, strVal) = self.enumToValue(elem, True) + + if name in nameMap: + # Duplicate name found; check values + (name2, numVal2, strVal2) = nameMap[name] + + # Duplicate enum values for the same name are benign. This + # happens when defining the same enum conditionally in + # several extension blocks. + if (strVal2 == strVal or (numVal is not None + and numVal == numVal2)): + True + # self.logMsg('info', 'checkDuplicateEnums: Duplicate enum (' + name + + # ') found with the same value:' + strVal) + else: + self.logMsg('warn', 'checkDuplicateEnums: Duplicate enum (' + name + + ') found with different values:' + strVal + + ' and ' + strVal2) + + # Do not add the duplicate to the returned list + continue + elif numVal in valueMap: + # Duplicate value found (such as an alias); report it, but + # still add this enum to the list. + (name2, numVal2, strVal2) = valueMap[numVal] + + msg = 'Two enums found with the same value: {} = {} = {}'.format( + name, name2.get('name'), strVal) + self.logMsg('error', msg) + + # Track this enum to detect followon duplicates + nameMap[name] = [elem, numVal, strVal] + if numVal is not None: + valueMap[numVal] = [elem, numVal, strVal] + + # Add this enum to the list + stripped.append(elem) + + # Return the list + return stripped + + def misracstyle(self): + return False; + + def misracppstyle(self): + return False; + + def deprecationComment(self, elem, indent = 0): + """If an API element is marked deprecated, return a brief comment + describing why. + Otherwise, return an empty string. + + - elem - Element of the API. + API name is determined depending on the element tag. + - indent - number of spaces to indent the comment""" + + reason = elem.get('deprecated') + + # This is almost always the path taken. + if reason == None: + return '' + + # There is actually a deprecated attribute. + padding = indent * ' ' + + # Determine the API name. + if elem.tag == 'member' or elem.tag == 'param': + name = elem.find('.//name').text + else: + name = elem.get('name') + + if reason == 'aliased': + return f'{padding}// {name} is a deprecated alias\n' + elif reason == 'ignored': + return f'{padding}// {name} is deprecated and should not be used\n' + elif reason == 'true': + return f'{padding}// {name} is deprecated, but no reason was given in the API XML\n' + else: + # This can be caught by schema validation + self.logMsg('error', f"{name} has an unknown deprecation attribute value '{reason}'") + exit(1) + + def buildEnumCDecl(self, expand, groupinfo, groupName): + """Generate the C declaration for an enum""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + + groupElem = groupinfo.elem + + # Determine the required bit width for the enum group. + # 32 is the default, which generates C enum types for the values. + bitwidth = 32 + + # If the constFlagBits preference is set, 64 is the default for bitmasks + if self.genOpts.conventions.constFlagBits and groupElem.get('type') == 'bitmask': + bitwidth = 64 + + # Check for an explicitly defined bitwidth, which will override any defaults. + if groupElem.get('bitwidth'): + try: + bitwidth = int(groupElem.get('bitwidth')) + except ValueError as ve: + self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for ', groupName, ' - must be an integer value\n') + exit(1) + + usebitmask = False + usedefine = False + + # Bitmask flags can be generated as either "static const uint{32,64}_t" values, + # or as 32-bit C enums. 64-bit types must use uint64_t values. + if groupElem.get('type') == 'bitmask': + if bitwidth > 32 or self.misracppstyle(): + usebitmask = True + if self.misracstyle(): + usedefine = True + + if usedefine or usebitmask: + # Validate the bitwidth and generate values appropriately + if bitwidth > 64: + self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for bitmask type ', groupName, ' - must be less than or equal to 64\n') + exit(1) + else: + return self.buildEnumCDecl_BitmaskOrDefine(groupinfo, groupName, bitwidth, usedefine) + else: + # Validate the bitwidth and generate values appropriately + if bitwidth > 32: + self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for enum type ', groupName, ' - must be less than or equal to 32\n') + exit(1) + else: + return self.buildEnumCDecl_Enum(expand, groupinfo, groupName) + + def buildEnumCDecl_BitmaskOrDefine(self, groupinfo, groupName, bitwidth, usedefine): + """Generate the C declaration for an "enum" that is actually a + set of flag bits""" + groupElem = groupinfo.elem + flagTypeName = groupElem.get('name') + + # Prefix + body = f"// Flag bits for {flagTypeName}\n" + + if bitwidth == 64: + body += f"typedef VkFlags64 {flagTypeName};\n"; + else: + body += f"typedef VkFlags {flagTypeName};\n"; + + # Maximum allowable value for a flag (unsigned 64-bit integer) + maxValidValue = 2**(64) - 1 + minValidValue = 0 + + # Get a list of nested 'enum' tags. + enums = groupElem.findall('enum') + + # Check for and report duplicates, and return a list with them + # removed. + enums = self.checkDuplicateEnums(enums) + + # Accumulate non-numeric enumerant values separately and append + # them following the numeric values, to allow for aliases. + # NOTE: this does not do a topological sort yet, so aliases of + # aliases can still get in the wrong order. + aliasText = '' + + # Loop over the nested 'enum' tags. + for elem in enums: + # Convert the value to an integer and use that to track min/max. + # Values of form -(number) are accepted but nothing more complex. + # Should catch exceptions here for more complex constructs. Not yet. + (numVal, strVal) = self.enumToValue(elem, True, bitwidth, True) + name = elem.get('name') + + # Range check for the enum value + if numVal is not None and (numVal > maxValidValue or numVal < minValidValue): + self.logMsg('error', 'Allowable range for flag types in C is [', minValidValue, ',', maxValidValue, '], but', name, 'flag has a value outside of this (', strVal, ')\n') + exit(1) + + decl = self.genRequirements(name, mustBeFound = False) + + if self.isEnumRequired(elem): + protect = elem.get('protect') + if protect is not None: + body += f'#ifdef {protect}\n' + + body += self.deprecationComment(elem, indent = 0) + + if usedefine: + decl += f"#define {name} {strVal}\n" + elif self.misracppstyle(): + decl += f"static constexpr {flagTypeName} {name} {{{strVal}}};\n" + else: + # Some C compilers only allow initializing a 'static const' variable with a literal value. + # So initializing an alias from another 'static const' value would fail to compile. + # Work around this by chasing the aliases to get the actual value. + while numVal is None: + alias = self.registry.tree.find(f"enums/enum[@name='{strVal}']") + if alias is not None: + (numVal, strVal) = self.enumToValue(alias, True, bitwidth, True) + else: + self.logMsg('error', f'No such alias {strVal} for enum {name}') + decl += f"static const {flagTypeName} {name} = {strVal};\n" + + if numVal is not None: + body += decl + else: + aliasText += decl + + if protect is not None: + body += '#endif\n' + + # Now append the non-numeric enumerant values + body += aliasText + + # Postfix + + return ("bitmask", body) + + def buildEnumCDecl_Enum(self, expand, groupinfo, groupName): + """Generate the C declaration for an enumerated type""" + groupElem = groupinfo.elem + + # Break the group name into prefix and suffix portions for range + # enum generation + expandName = re.sub(r'([0-9]+|[a-z_])([A-Z0-9])', r'\1_\2', groupName).upper() + expandPrefix = expandName + expandSuffix = '' + expandSuffixMatch = re.search(r'[A-Z][A-Z]+$', groupName) + if expandSuffixMatch: + expandSuffix = f"_{expandSuffixMatch.group()}" + # Strip off the suffix from the prefix + expandPrefix = expandName.rsplit(expandSuffix, 1)[0] + + # Prefix + body = ["typedef enum %s {" % groupName] + + # @@ Should use the type="bitmask" attribute instead + isEnum = ('FLAG_BITS' not in expandPrefix) + + # Allowable range for a C enum - which is that of a signed 32-bit integer + maxValidValue = 2**(32 - 1) - 1 + minValidValue = (maxValidValue * -1) - 1 + + # Get a list of nested 'enum' tags. + enums = groupElem.findall('enum') + + # Check for and report duplicates, and return a list with them + # removed. + enums = self.checkDuplicateEnums(enums) + + # Loop over the nested 'enum' tags. Keep track of the minimum and + # maximum numeric values, if they can be determined; but only for + # core API enumerants, not extension enumerants. This is inferred + # by looking for 'extends' attributes. + minName = None + + # Accumulate non-numeric enumerant values separately and append + # them following the numeric values, to allow for aliases. + # NOTE: this does not do a topological sort yet, so aliases of + # aliases can still get in the wrong order. + aliasText = [] + + maxName = None + minValue = None + maxValue = None + for elem in enums: + # Convert the value to an integer and use that to track min/max. + # Values of form -(number) are accepted but nothing more complex. + # Should catch exceptions here for more complex constructs. Not yet. + (numVal, strVal) = self.enumToValue(elem, True) + name = elem.get('name') + + # Extension enumerants are only included if they are required + if self.isEnumRequired(elem): + decl = '' + + protect = elem.get('protect') + if protect is not None: + decl += f'#ifdef {protect}\n' + + + decl += self.genRequirements(name, mustBeFound = False, indent = 2) + decl += self.deprecationComment(elem, indent = 2) + decl += f' {name} = {strVal},' + + if protect is not None: + decl += '\n#endif' + + if numVal is not None: + body.append(decl) + else: + aliasText.append(decl) + + # Range check for the enum value + if numVal is not None and (numVal > maxValidValue or numVal < minValidValue): + self.logMsg('error', 'Allowable range for C enum types is [', minValidValue, ',', maxValidValue, '], but', name, 'has a value outside of this (', strVal, ')\n') + exit(1) + + # Do not track min/max for non-numbers (numVal is None) + if isEnum and numVal is not None and elem.get('extends') is None: + if minName is None: + minName = maxName = name + minValue = maxValue = numVal + elif minValue is None or numVal < minValue: + minName = name + minValue = numVal + elif maxValue is None or numVal > maxValue: + maxName = name + maxValue = numVal + + # Now append the non-numeric enumerant values + body.extend(aliasText) + + # Generate min/max value tokens - legacy use case. + if isEnum and expand: + body.extend((f' {expandPrefix}_BEGIN_RANGE{expandSuffix} = {minName},', + f' {expandPrefix}_END_RANGE{expandSuffix} = {maxName},', + f' {expandPrefix}_RANGE_SIZE{expandSuffix} = ({maxName} - {minName} + 1),')) + + # Generate a range-padding value to ensure the enum is 32 bits, but + # only in code generators, so it does not appear in documentation + if (self.genOpts.codeGenerator or + self.conventions.generate_max_enum_in_docs): + body.append(f' {expandPrefix}_MAX_ENUM{expandSuffix} = 0x7FFFFFFF') + + # Postfix + body.append("} %s;" % groupName) + + # Determine appropriate section for this declaration + if groupElem.get('type') == 'bitmask': + section = 'bitmask' + else: + section = 'group' + + return (section, '\n'.join(body)) + + def buildConstantCDecl(self, enuminfo, name, alias): + """Generate the C declaration for a constant (a single + value). + + tags may specify their values in several ways, but are + usually just integers or floating-point numbers.""" + + (_, strVal) = self.enumToValue(enuminfo.elem, False) + + if self.misracppstyle() and enuminfo.elem.get('type') and not alias: + # Generate e.g.: static constexpr uint32_t x = ~static_cast(1U); + # This appeases MISRA "underlying type" rules. + typeStr = enuminfo.elem.get('type'); + invert = '~' in strVal + number = strVal.strip("()~UL") + if typeStr != "float": + number += 'U' + strVal = "~" if invert else "" + strVal += f"static_cast<{typeStr}>({number})" + body = f"static constexpr {typeStr.ljust(9)}{name.ljust(33)} {{{strVal}}};" + elif enuminfo.elem.get('type') and not alias: + # Generate e.g.: #define x (~0ULL) + typeStr = enuminfo.elem.get('type'); + invert = '~' in strVal + paren = '(' in strVal + number = strVal.strip("()~UL") + if typeStr != "float": + if typeStr == "uint64_t": + number += 'ULL' + else: + number += 'U' + strVal = "~" if invert else "" + strVal += number + if paren: + strVal = f"({strVal})"; + body = f"#define {name.ljust(33)} {strVal}"; + else: + body = f"#define {name.ljust(33)} {strVal}" + + return body + + def makeDir(self, path): + """Create a directory, if not already done. + + Generally called from derived generators creating hierarchies.""" + self.logMsg('diag', 'OutputGenerator::makeDir(', path, ')') + if path not in self.madeDirs: + # This can get race conditions with multiple writers, see + # https://stackoverflow.com/questions/273192/ + if not os.path.exists(path): + os.makedirs(path) + self.madeDirs[path] = None + + def beginFile(self, genOpts): + """Start a new interface file + + - genOpts - GeneratorOptions controlling what is generated and how""" + + self.genOpts = genOpts + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + self.should_insert_may_alias_macro = \ + self.genOpts.conventions.should_insert_may_alias_macro(self.genOpts) + self.file_suffix = self.genOpts.conventions.file_suffix + + # Try to import the API dictionary, apimap.py, if it exists. Nothing + # in apimap.py cannot be extracted directly from the XML, and in the + # future we should do that. + if self.genOpts.genpath is not None: + try: + sys.path.insert(0, self.genOpts.genpath) + import apimap + self.apidict = apimap + except ImportError: + self.apidict = None + + self.conventions = genOpts.conventions + + # Open a temporary file for accumulating output. + if self.genOpts.filename is not None: + self.outFile = tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', newline='\n', delete=False) + else: + self.outFile = sys.stdout + + def endFile(self): + if self.errFile: + self.errFile.flush() + if self.warnFile: + self.warnFile.flush() + if self.diagFile: + self.diagFile.flush() + if self.outFile: + self.outFile.flush() + if self.outFile != sys.stdout and self.outFile != sys.stderr: + self.outFile.close() + + if self.genOpts is None: + raise MissingGeneratorOptionsError() + + # On successfully generating output, move the temporary file to the + # target file. + if self.genOpts.filename is not None: + directory = Path(self.genOpts.directory) + if sys.platform == 'win32': + if not Path.exists(directory): + os.makedirs(directory) + shutil.copy(self.outFile.name, directory / self.genOpts.filename) + os.remove(self.outFile.name) + self.genOpts = None + + def beginFeature(self, interface, emit): + """Write interface for a feature and tag generated features as having been done. + + - interface - element for the `` / `` to generate + - emit - actually write to the header only when True""" + self.emit = emit + self.featureName = interface.get('name') + # If there is an additional 'protect' attribute in the feature, save it + self.featureExtraProtect = interface.get('protect') + + def endFeature(self): + """Finish an interface file, closing it when done. + + Derived classes responsible for emitting feature""" + self.featureName = None + self.featureExtraProtect = None + + def genRequirements(self, name, mustBeFound = True, indent = 0): + """Generate text showing what core versions and extensions introduce + an API. This exists in the base Generator class because it is used by + the shared enumerant-generating interfaces (buildEnumCDecl, etc.). + Here it returns an empty string for most generators, but can be + overridden by e.g. DocGenerator. + + - name - name of the API + - mustBeFound - If True, when requirements for 'name' cannot be + determined, a warning comment is generated. + """ + + return '' + + def validateFeature(self, featureType, featureName): + """Validate we are generating something only inside a `` tag""" + if self.featureName is None: + raise UserWarning('Attempt to generate', featureType, + featureName, 'when not in feature') + + def genType(self, typeinfo, name, alias): + """Generate interface for a type + + - typeinfo - TypeInfo for a type + + Extend to generate as desired in your derived class.""" + self.validateFeature('type', name) + + def genStruct(self, typeinfo, typeName, alias): + """Generate interface for a C "struct" type. + + - typeinfo - TypeInfo for a type interpreted as a struct + + Extend to generate as desired in your derived class.""" + self.validateFeature('struct', typeName) + + # The mixed-mode tags may contain no-op tags. + # It is convenient to remove them here where all output generators + # will benefit. + for member in typeinfo.elem.findall('.//member'): + for comment in member.findall('comment'): + member.remove(comment) + + def genGroup(self, groupinfo, groupName, alias): + """Generate interface for a group of enums (C "enum") + + - groupinfo - GroupInfo for a group. + + Extend to generate as desired in your derived class.""" + + self.validateFeature('group', groupName) + + def genEnum(self, enuminfo, typeName, alias): + """Generate interface for an enum (constant). + + - enuminfo - EnumInfo for an enum + - name - enum name + + Extend to generate as desired in your derived class.""" + self.validateFeature('enum', typeName) + + def genCmd(self, cmd, cmdinfo, alias): + """Generate interface for a command. + + - cmdinfo - CmdInfo for a command + + Extend to generate as desired in your derived class.""" + self.validateFeature('command', cmdinfo) + + def genSpirv(self, spirv, spirvinfo, alias): + """Generate interface for a spirv element. + + - spirvinfo - SpirvInfo for a command + + Extend to generate as desired in your derived class.""" + return + + def genFormat(self, format, formatinfo, alias): + """Generate interface for a format element. + + - formatinfo - FormatInfo + + Extend to generate as desired in your derived class.""" + return + + def genSyncStage(self, stageinfo): + """Generate interface for a sync stage element. + + - stageinfo - SyncStageInfo + + Extend to generate as desired in your derived class.""" + return + + def genSyncAccess(self, accessinfo): + """Generate interface for a sync stage element. + + - accessinfo - AccessInfo + + Extend to generate as desired in your derived class.""" + return + + def genSyncPipeline(self, pipelineinfo): + """Generate interface for a sync stage element. + + - pipelineinfo - SyncPipelineInfo + + Extend to generate as desired in your derived class.""" + return + + def makeProtoName(self, name, tail): + """Turn a `` `` into C-language prototype + and typedef declarations for that name. + + - name - contents of `` tag + - tail - whatever text follows that tag in the Element""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + return self.genOpts.apientry + name + tail + + def makeTypedefName(self, name, tail): + """Make the function-pointer typedef name for a command.""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + return f"({self.genOpts.apientryp}PFN_{name}{tail})" + + def makeCParamDecl(self, param, aligncol): + """Return a string which is an indented, formatted + declaration for a `` or `` block (e.g. function parameter + or structure/union member). + + - param - Element (`` or ``) to format + - aligncol - if non-zero, attempt to align the nested `` element + at this column""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + indent = ' ' + paramdecl = indent + prefix = noneStr(param.text) + + for elem in param: + text = noneStr(elem.text) + tail = noneStr(elem.tail) + + if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail): + # OpenXR-specific macro insertion - but not in apiinc for the spec + tail = self.genOpts.conventions.make_voidpointer_alias(tail) + if elem.tag == 'name' and aligncol > 0: + self.logMsg('diag', 'Aligning parameter', elem.text, 'to column', self.genOpts.alignFuncParam) + # Align at specified column, if possible + paramdecl = paramdecl.rstrip() + oldLen = len(paramdecl) + # This works around a problem where very long type names - + # longer than the alignment column - would run into the tail + # text. + paramdecl = f"{paramdecl.ljust(aligncol - 1)} " + newLen = len(paramdecl) + self.logMsg('diag', 'Adjust length of parameter decl from', oldLen, 'to', newLen, ':', paramdecl) + + if (self.misracppstyle() and prefix.find('const ') != -1): + # Change pointer type order from e.g. "const void *" to "void const *". + # If the string starts with 'const', reorder it to be after the first type. + paramdecl += f"{prefix.replace('const ', '') + text} const{tail}" + else: + paramdecl += prefix + text + tail + + # Clear prefix for subsequent iterations + prefix = '' + + paramdecl = paramdecl + prefix + + if aligncol == 0: + # Squeeze out multiple spaces other than the indentation + paramdecl = indent + ' '.join(paramdecl.split()) + return paramdecl + + def getCParamTypeLength(self, param): + """Return the length of the type field is an indented, formatted + declaration for a `` or `` block (e.g. function parameter + or structure/union member). + + - param - Element (`` or ``) to identify""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + if self.genOpts.conventions is None: + raise MissingGeneratorOptionsConventionsError() + + # Allow for missing tag + newLen = 0 + paramdecl = f" {noneStr(param.text)}" + for elem in param: + text = noneStr(elem.text) + tail = noneStr(elem.tail) + + if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail): + # OpenXR-specific macro insertion + tail = self.genOpts.conventions.make_voidpointer_alias(tail) + if elem.tag == 'name': + # Align at specified column, if possible + newLen = len(paramdecl.rstrip()) + self.logMsg('diag', 'Identifying length of', elem.text, 'as', newLen) + paramdecl += text + tail + + return newLen + + def getMaxCParamTypeLength(self, info): + """Return the length of the longest type field for a member/parameter. + + - info - TypeInfo or CommandInfo. + """ + lengths = (self.getCParamTypeLength(member) + for member in info.getMembers()) + return max(lengths) + + def getHandleParent(self, typename): + """Get the parent of a handle object.""" + if self.registry is None: + raise MissingRegistryError() + + info = self.registry.typedict.get(typename) + if info is None: + return None + + elem = info.elem + if elem is not None: + return elem.get('parent') + + return None + + def iterateHandleAncestors(self, typename): + """Iterate through the ancestors of a handle type.""" + current = self.getHandleParent(typename) + while current is not None: + yield current + current = self.getHandleParent(current) + + def getHandleAncestors(self, typename): + """Get the ancestors of a handle object.""" + return list(self.iterateHandleAncestors(typename)) + + def getTypeCategory(self, typename): + """Get the category of a type.""" + if self.registry is None: + raise MissingRegistryError() + + info = self.registry.typedict.get(typename) + if info is None: + return None + + elem = info.elem + if elem is not None: + return elem.get('category') + return None + + def isStructAlwaysValid(self, structname): + """Try to do check if a structure is always considered valid (i.e. there is no rules to its acceptance).""" + # A conventions object is required for this call. + if not self.conventions: + raise RuntimeError("To use isStructAlwaysValid, be sure your options include a Conventions object.") + if self.registry is None: + raise MissingRegistryError() + + if self.conventions.type_always_valid(structname): + return True + + category = self.getTypeCategory(structname) + if self.conventions.category_requires_validation(category): + return False + + info = self.registry.typedict.get(structname) + if info is None: + self.logMsg('error', f'isStructAlwaysValid({structname}) - structure not found in typedict') + + members = info.getMembers() + + for member in members: + member_name = getElemName(member) + if member_name in (self.conventions.structtype_member_name, + self.conventions.nextpointer_member_name): + return False + + if member.get('noautovalidity'): + return False + + member_type = getElemType(member) + + if member_type in ('void', 'char') or self.paramIsArray(member) or self.paramIsPointer(member): + return False + + if self.conventions.type_always_valid(member_type): + continue + + member_category = self.getTypeCategory(member_type) + + if self.conventions.category_requires_validation(member_category): + return False + + if member_category in ('struct', 'union'): + if self.isStructAlwaysValid(member_type) is False: + return False + + return True + + def paramIsArray(self, param): + """Check if the parameter passed in is a pointer to an array. + + param the XML information for the param + """ + return param.get('len') is not None + + def paramIsPointer(self, param): + """Check if the parameter passed in is a pointer. + + param the XML information for the param + """ + tail = param.find('type').tail + return tail is not None and '*' in tail + + def isEnumRequired(self, elem): + """Return True if this `` element is + required, False otherwise + + - elem - `` element to test""" + required = elem.get('required') is not None + self.logMsg('diag', 'isEnumRequired:', elem.get('name'), + '->', required) + return required + + # @@@ This code is overridden by equivalent code now run in + # @@@ Registry.generateFeature + + required = False + + extname = elem.get('extname') + if extname is not None: + # 'supported' attribute was injected when the element was + # moved into the group in Registry.parseTree() + if self.genOpts.defaultExtensions == elem.get('supported'): + required = True + elif re.match(self.genOpts.addExtensions, extname) is not None: + required = True + elif elem.get('version') is not None: + required = re.match(self.genOpts.emitversions, elem.get('version')) is not None + else: + required = True + + return required + + def makeCDecls(self, cmd): + """Return C prototype and function pointer typedef for a + `` Element, as a two-element list of strings. + + - cmd - Element containing a `` tag""" + if self.genOpts is None: + raise MissingGeneratorOptionsError() + proto = cmd.find('proto') + params = cmd.findall('param') + # Begin accumulating prototype and typedef strings + pdecl = self.genOpts.apicall + tdecl = 'typedef ' + + # Insert the function return type/name. + # For prototypes, add APIENTRY macro before the name + # For typedefs, add (APIENTRY *) around the name and + # use the PFN_cmdnameproc naming convention. + # Done by walking the tree for element by element. + # etree has elem.text followed by (elem[i], elem[i].tail) + # for each child element and any following text + # Leading text + pdecl += noneStr(proto.text) + tdecl += noneStr(proto.text) + # For each child element, if it is a wrap in appropriate + # declaration. Otherwise append its contents and tail contents. + for elem in proto: + text = noneStr(elem.text) + tail = noneStr(elem.tail) + if elem.tag == 'name': + pdecl += self.makeProtoName(text, tail) + tdecl += self.makeTypedefName(text, tail) + else: + pdecl += text + tail + tdecl += text + tail + + if self.genOpts.alignFuncParam == 0: + # Squeeze out multiple spaces - there is no indentation + pdecl = ' '.join(pdecl.split()) + tdecl = ' '.join(tdecl.split()) + + # Now add the parameter declaration list, which is identical + # for prototypes and typedefs. Concatenate all the text from + # a node without the tags. No tree walking required + # since all tags are ignored. + # Uses: self.indentFuncProto + # self.indentFuncPointer + # self.alignFuncParam + n = len(params) + # Indented parameters + if n > 0: + indentdecl = '(\n' + indentdecl += ',\n'.join(self.makeCParamDecl(p, self.genOpts.alignFuncParam) + for p in params) + indentdecl += ');' + else: + indentdecl = '(void);' + # Non-indented parameters + paramdecl = '(' + if n > 0: + paramnames = [] + if self.misracppstyle(): + for p in params: + param = '' + firstIter = True; + for t in p.itertext(): + if (firstIter): + prefix = t + firstIter = False + else: + # Change pointer type order from e.g. "const void *" to "void const *". + # If the string starts with 'const', reorder it to be after the first type. + if (prefix.find('const ') != -1): + param += f"{prefix.replace('const ', '') + t} const " + else: + param += prefix + t + # Clear prefix for subsequent iterations + prefix = '' + paramnames.append(param); + else: + paramnames = (''.join(t for t in p.itertext()) + for p in params) + paramdecl += ', '.join(paramnames) + else: + paramdecl += 'void' + paramdecl += ");" + + return [pdecl + indentdecl, tdecl + paramdecl] + + def newline(self): + """Print a newline to the output file (utility function)""" + write('', file=self.outFile) + + def setRegistry(self, registry): + self.registry = registry diff --git a/libs/VulkanHeaders/genvk.py b/libs/VulkanHeaders/genvk.py new file mode 100644 index 0000000000..6e242d8819 --- /dev/null +++ b/libs/VulkanHeaders/genvk.py @@ -0,0 +1,1160 @@ +#!/usr/bin/env python3 +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os +import pdb +import re +import sys +import copy +import time +import xml.etree.ElementTree as etree + +sys.path.append(os.path.abspath(os.path.dirname(__file__))) + +from cgenerator import CGeneratorOptions, COutputGenerator +from reflib import logDiag, logWarn, logErr, setLogFile +from reg import Registry +from apiconventions import APIConventions + +# Simple timer functions +startTime = None + + +def startTimer(timeit): + global startTime + if timeit: + startTime = time.process_time() + + +def endTimer(timeit, msg): + global startTime + if timeit and startTime is not None: + endTime = time.process_time() + logDiag(msg, endTime - startTime) + startTime = None + + +def makeREstring(strings, default=None, strings_are_regex=False): + """Turn a list of strings into a regexp string matching exactly those strings.""" + if strings or default is None: + if not strings_are_regex: + strings = (re.escape(s) for s in strings) + return f"^({'|'.join(strings)})$" + return default + + +def makeGenOpts(args): + """Returns a directory of [ generator function, generator options ] indexed + by specified short names. The generator options incorporate the following + parameters: + + args is a parsed argument object; see below for the fields that are used.""" + global genOpts + genOpts = {} + + # Default class of extensions to include, or None + defaultExtensions = args.defaultExtensions + + # Additional extensions to include (list of extensions) + extensions = args.extension + + # Extensions to remove (list of extensions) + removeExtensions = args.removeExtensions + + # Extensions to emit (list of extensions) + emitExtensions = args.emitExtensions + + # SPIR-V capabilities / features to emit (list of extensions & capabilities) + emitSpirv = args.emitSpirv + + # Vulkan Formats to emit + emitFormats = args.emitFormats + + # Features to include (list of features) + features = args.feature + + # Whether to disable inclusion protect in headers + protect = args.protect + + # Output target directory + directory = args.directory + + # Path to generated files, particularly apimap.py + genpath = args.genpath + + # Generate MISRA C-friendly headers + misracstyle = args.misracstyle + + # Generate MISRA C++-friendly headers + misracppstyle = args.misracppstyle + + # Descriptive names for various regexp patterns used to select + # versions and extensions + allFormats = allSpirv = allFeatures = allExtensions = r'.*' + + # Turn lists of names/patterns into matching regular expressions + addExtensionsPat = makeREstring(extensions, None) + removeExtensionsPat = makeREstring(removeExtensions, None) + emitExtensionsPat = makeREstring(emitExtensions, allExtensions) + emitSpirvPat = makeREstring(emitSpirv, allSpirv) + emitFormatsPat = makeREstring(emitFormats, allFormats) + featuresPat = makeREstring(features, allFeatures) + + # Copyright text prefixing all headers (list of strings). + # The SPDX formatting below works around constraints of the 'reuse' tool + prefixStrings = [ + '/*', + '** Copyright 2015-2025 The Khronos Group Inc.', + '**', + '** SPDX-License-Identifier' + ': Apache-2.0', + '*/', + '' + ] + + # Text specific to Vulkan headers + vkPrefixStrings = [ + '/*', + '** This header is generated from the Khronos Vulkan XML API Registry.', + '**', + '*/', + '' + ] + + vulkanLayer = args.vulkanLayer + + # Defaults for generating re-inclusion protection wrappers (or not) + protectFile = protect + + # An API style conventions object + conventions = APIConventions() + + if args.apiname is not None: + defaultAPIName = args.apiname + else: + defaultAPIName = conventions.xml_api_name + + # APIs to merge + mergeApiNames = args.mergeApiNames + + isCTS = args.isCTS + + # Try to set up specification generators if the needed modules are available + try: + from docgenerator import DocGeneratorOptions, DocOutputGenerator + from jsgenerator import JSOutputGenerator + from pygenerator import PyOutputGenerator + from rubygenerator import RubyOutputGenerator + from validitygenerator import ValidityOutputGenerator + from hostsyncgenerator import HostSynchronizationOutputGenerator + from extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions, + ExtensionMetaDocOutputGenerator) + from interfacedocgenerator import InterfaceDocGenerator + from featurerequirementsgenerator import FeatureRequirementsDocGenerator + from spirvcapgenerator import SpirvCapabilityOutputGenerator + from formatsgenerator import FormatsOutputGenerator + from syncgenerator import SyncOutputGenerator + + # API include files for spec and ref pages + # Overwrites include subdirectories in spec source tree + # The generated include files do not include the calling convention + # macros (apientry etc.), unlike the header files. + # Because the 1.0 core branch includes ref pages for extensions, + # all the extension interfaces need to be generated, even though + # none are used by the core spec itself. + genOpts['apiinc'] = [ + DocOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = genpath, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + apicall = '', + apientry = '', + apientryp = '*', + alignFuncParam = 48, + expandEnumerants = False) + ] + + # JavaScript, Python, and Ruby representations of API information, used + # by scripts that do not need to load the full XML. + genOpts['apimap.cjs'] = [ + JSOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'apimap.cjs', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + genOpts['apimap.py'] = [ + PyOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'apimap.py', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + genOpts['apimap.rb'] = [ + RubyOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'apimap.rb', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + # API validity files for spec + # + # requireCommandAliases is set to True because we need validity files + # for the command something is promoted to even when the promoted-to + # feature is not included. This avoids wordy includes of validity files. + genOpts['validinc'] = [ + ValidityOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + requireCommandAliases = True, + ) + ] + + # API host sync table files for spec + genOpts['hostsyncinc'] = [ + HostSynchronizationOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + # Extension metainformation for spec extension appendices + # Includes all extensions by default, but only so that the generated + # 'promoted_extensions_*' files refer to all extensions that were + # promoted to a core version. + genOpts['extinc'] = [ + ExtensionMetaDocOutputGenerator, + ExtensionMetaDocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = None, + defaultExtensions = defaultExtensions, + addExtensions = addExtensionsPat, + removeExtensions = None, + emitExtensions = emitExtensionsPat) + ] + + # Version and extension interface docs for version/extension appendices + # Includes all extensions by default. + genOpts['interfaceinc'] = [ + InterfaceDocGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + # Feature requirements for versions/extensions + # Includes all extensions by default. + genOpts['requirementsinc'] = [ + FeatureRequirementsDocGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'featurerequirements.adoc', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = addExtensionsPat, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat) + ] + + genOpts['spirvcapinc'] = [ + SpirvCapabilityOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + emitSpirv = emitSpirvPat, + reparentEnums = False) + ] + + # Used to generate various format chapter tables + genOpts['formatsinc'] = [ + FormatsOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + emitFormats = emitFormatsPat, + reparentEnums = False) + ] + + # Used to generate various synchronization chapter tables + genOpts['syncinc'] = [ + SyncOutputGenerator, + DocGeneratorOptions( + conventions = conventions, + filename = 'timeMarker', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + reparentEnums = False) + ] + + except ImportError: + # Module dependencies are not available for spec generation + pass + + # Platform extensions, in their own header files + # Each element of the platforms[] array defines information for + # generating a single platform: + # [0] is the generated header file name + # [1] is the set of platform extensions to generate + # [2] is additional extensions whose interfaces should be considered, + # but suppressed in the output, to avoid duplicate definitions of + # dependent types like VkDisplayKHR and VkSurfaceKHR which come from + # non-platform extensions. + + # Track all platform extensions, for exclusion from vulkan_core.h + allPlatformExtensions = [] + + # Extensions suppressed for all WSI platforms (WSI extensions required + # by all platforms) + commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ] + + # Extensions required and suppressed for beta "platform". This can + # probably eventually be derived from the requires= attributes of + # the extension blocks. + betaRequireExtensions = [ + 'VK_KHR_portability_subset', + 'VK_NV_displacement_micromap', + 'VK_AMDX_dense_geometry_format', + 'VK_AMDX_shader_enqueue', + 'VK_NV_cuda_kernel_launch', + ] + + betaSuppressExtensions = [ + 'VK_EXT_opacity_micromap', + 'VK_KHR_pipeline_library', + ] + + platforms = [ + [ 'vulkan_android.h', [ 'VK_KHR_android_surface', + 'VK_ANDROID_external_memory_android_hardware_buffer', + 'VK_ANDROID_external_format_resolve' + ], commonSuppressExtensions + + [ 'VK_KHR_format_feature_flags2', + ] ], + [ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface', + 'VK_FUCHSIA_external_memory', + 'VK_FUCHSIA_external_semaphore', + 'VK_FUCHSIA_buffer_collection' ], commonSuppressExtensions ], + [ 'vulkan_ggp.h', [ 'VK_GGP_stream_descriptor_surface', + 'VK_GGP_frame_token' ], commonSuppressExtensions ], + [ 'vulkan_ios.h', [ 'VK_MVK_ios_surface' ], commonSuppressExtensions ], + [ 'vulkan_macos.h', [ 'VK_MVK_macos_surface' ], commonSuppressExtensions ], + [ 'vulkan_vi.h', [ 'VK_NN_vi_surface' ], commonSuppressExtensions ], + [ 'vulkan_wayland.h', [ 'VK_KHR_wayland_surface' ], commonSuppressExtensions ], + [ 'vulkan_win32.h', [ 'VK_.*_win32(|_.*)', 'VK_.*_winrt(|_.*)', 'VK_EXT_full_screen_exclusive' ], + commonSuppressExtensions + + [ 'VK_KHR_external_semaphore', + 'VK_KHR_external_memory_capabilities', + 'VK_KHR_external_fence', + 'VK_KHR_external_fence_capabilities', + 'VK_KHR_get_surface_capabilities2', + 'VK_NV_external_memory_capabilities', + ] ], + [ 'vulkan_xcb.h', [ 'VK_KHR_xcb_surface' ], commonSuppressExtensions ], + [ 'vulkan_xlib.h', [ 'VK_KHR_xlib_surface' ], commonSuppressExtensions ], + [ 'vulkan_directfb.h', [ 'VK_EXT_directfb_surface' ], commonSuppressExtensions ], + [ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ], + [ 'vulkan_metal.h', [ 'VK_EXT_metal_surface', + 'VK_EXT_metal_objects', + 'VK_EXT_external_memory_metal' ], commonSuppressExtensions ], + [ 'vulkan_ohos.h', ['VK_OHOS_surface' ], commonSuppressExtensions ], + [ 'vulkan_screen.h', [ 'VK_QNX_screen_surface', + 'VK_QNX_external_memory_screen_buffer' ], commonSuppressExtensions ], + [ 'vulkan_sci.h', [ 'VK_NV_external_sci_sync', + 'VK_NV_external_sci_sync2', + 'VK_NV_external_memory_sci_buf'], commonSuppressExtensions ], + [ 'vulkan_beta.h', betaRequireExtensions, betaSuppressExtensions ], + ] + + for platform in platforms: + headername = platform[0] + + allPlatformExtensions += platform[1] + + addPlatformExtensionsRE = makeREstring( + platform[1] + platform[2], strings_are_regex=True) + emitPlatformExtensionsRE = makeREstring( + platform[1], strings_are_regex=True) + + opts = CGeneratorOptions( + conventions = conventions, + filename = headername, + directory = directory, + genpath = None, + apiname = defaultAPIName, + mergeApiNames = mergeApiNames, + profile = None, + versions = featuresPat, + emitversions = None, + defaultExtensions = None, + addExtensions = addPlatformExtensionsRE, + removeExtensions = None, + emitExtensions = emitPlatformExtensionsRE, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + protectExportName = defaultAPIName, + protectExportProtoStr = 'VK_ONLY_EXPORTED_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + + genOpts[headername] = [ COutputGenerator, opts ] + + # Header for core API + extensions. + # To generate just the core API, + # change to 'defaultExtensions = None' below. + # + # By default this adds all enabled, non-platform extensions. + # It removes all platform extensions (from the platform headers options + # constructed above) as well as any explicitly specified removals. + + removeExtensionsPat = makeREstring( + allPlatformExtensions + removeExtensions, None, strings_are_regex=True) + + genOpts['vulkan_core.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vulkan_core.h', + directory = directory, + genpath = None, + apiname = defaultAPIName, + mergeApiNames = mergeApiNames, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = defaultExtensions, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + protectExportName = 'vulkan', + protectExportProtoStr = 'VK_ONLY_EXPORTED_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + # Vulkan versions to include for SC header - SC *removes* features from 1.0/1.1/1.2 + scVersions = makeREstring(['VK_VERSION_1_0', 'VK_VERSION_1_1', 'VK_VERSION_1_2', 'VKSC_VERSION_1_0']) + + genOpts['vulkan_sc_core.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vulkan_sc_core.h', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + protectExportName = defaultAPIName, + protectExportProtoStr = 'VK_ONLY_EXPORTED_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + genOpts['vulkan_sc_core.hpp'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vulkan_sc_core.hpp', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + protectExportName = defaultAPIName, + protectExportProtoStr = 'VK_ONLY_EXPORTED_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + # Try to set up Vulkan SC JSON generators if the needed modules are available + try: + from json_parser import JSONParserGenerator, JSONParserOptions + from schema_generator import SchemaGeneratorOptions, SchemaOutputGenerator + from json_generator import JSONGeneratorOptions, JSONOutputGenerator + from json_h_generator import JSONHeaderOutputGenerator, JSONHeaderGeneratorOptions + from json_c_generator import JSONCOutputGenerator, JSONCGeneratorOptions + + genOpts['vk.json'] = [ + SchemaOutputGenerator, + SchemaGeneratorOptions( + conventions = conventions, + filename = 'vk.json', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48) + ] + + if vulkanLayer: + genOpts['vulkan_json_data.hpp'] = [ + JSONOutputGenerator, + JSONGeneratorOptions( + conventions = conventions, + filename = 'vulkan_json_data.hpp', + directory = directory, + apiname = 'vulkan', + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = None, + addExtensions = addExtensionsPat, + removeExtensions = None, + emitExtensions = None, + vulkanLayer = vulkanLayer, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48) + ] + else: + genOpts['vulkan_json_data.hpp'] = [ + JSONOutputGenerator, + JSONGeneratorOptions( + conventions = conventions, + filename = 'vulkan_json_data.hpp', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + vulkanLayer = vulkanLayer, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + isCTS = isCTS, + alignFuncParam = 48) + ] + + # keep any relevant platform extensions for the following generators + # (needed for e.g. the vulkan_sci extensions) + explicitRemoveExtensionsPat = makeREstring( + removeExtensions, None, strings_are_regex=True) + + # Raw C header file generator. + genOpts['vulkan_json_gen.h'] = [ + JSONHeaderOutputGenerator, + JSONHeaderGeneratorOptions( + conventions = conventions, + filename = 'vulkan_json_gen.h', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = explicitRemoveExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48) + ] + + # Raw C source file generator. + genOpts['vulkan_json_gen.c'] = [ + JSONCOutputGenerator, + JSONCGeneratorOptions( + conventions = conventions, + filename = 'vulkan_json_gen.c', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = explicitRemoveExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48) + ] + + genOpts['vulkan_json_parser.hpp'] = [ + JSONParserGenerator, + JSONParserOptions( + conventions = conventions, + filename = 'vulkan_json_parser.hpp', + directory = directory, + apiname = 'vulkansc', + profile = None, + versions = scVersions, + emitversions = scVersions, + defaultExtensions = 'vulkansc', + addExtensions = addExtensionsPat, + removeExtensions = explicitRemoveExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + isCTS = isCTS, + alignFuncParam = 48) + ] + except ImportError: + # Module dependencies are not available for Vulkan SC JSON generation + pass + + # Unused - vulkan10.h target. + # It is possible to generate a header with just the Vulkan 1.0 + + # extension interfaces defined, but since the promoted KHR extensions + # are now defined in terms of the 1.1 interfaces, such a header is very + # similar to vulkan_core.h. + genOpts['vulkan10.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vulkan10.h', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = 'VK_VERSION_1_0', + emitversions = 'VK_VERSION_1_0', + defaultExtensions = None, + addExtensions = None, + removeExtensions = None, + emitExtensions = None, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + # Video header target - combines all video extension dependencies into a + # single header, at present. + genOpts['vk_video.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vk_video.h', + directory = directory, + genpath = None, + apiname = 'vulkan', + profile = None, + versions = None, + emitversions = None, + defaultExtensions = defaultExtensions, + addExtensions = addExtensionsPat, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = '', + apientry = '', + apientryp = '', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + # Video extension 'Std' interfaces, each in its own header files + # These are not Vulkan extensions, or a part of the Vulkan API at all. + # They are treated in a similar fashion for generation purposes, but + # all required APIs for each interface must be explicitly required. + # + # Each element of the videoStd[] array is an extension name defining an + # interface, and is also the basis for the generated header file name. + + videoStd = [ + 'vulkan_video_codecs_common', + 'vulkan_video_codec_h264std', + 'vulkan_video_codec_h264std_decode', + 'vulkan_video_codec_h264std_encode', + 'vulkan_video_codec_h265std', + 'vulkan_video_codec_h265std_decode', + 'vulkan_video_codec_h265std_encode', + 'vulkan_video_codec_vp9std', + 'vulkan_video_codec_vp9std_decode', + 'vulkan_video_codec_av1std', + 'vulkan_video_codec_av1std_decode', + 'vulkan_video_codec_av1std_encode', + ] + + # Unused at present + # addExtensionRE = makeREstring(videoStd) + for codec in videoStd: + headername = f'{codec}.h' + + # Consider all of the codecs 'extensions', but only emit this one + emitExtensionRE = makeREstring([codec]) + + opts = CGeneratorOptions( + conventions = conventions, + filename = headername, + directory = directory, + genpath = None, + apiname = defaultAPIName, + mergeApiNames = mergeApiNames, + profile = None, + versions = None, + emitversions = None, + defaultExtensions = None, + addExtensions = emitExtensionRE, + removeExtensions = None, + emitExtensions = emitExtensionRE, + requireDepends = False, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = False, + protectFile = protectFile, + protectFeature = False, + alignFuncParam = 48, + ) + + genOpts[headername] = [ COutputGenerator, opts ] + + # Unused - vulkan11.h target. + # It is possible to generate a header with just the Vulkan 1.0 + + # extension interfaces defined, but since the promoted KHR extensions + # are now defined in terms of the 1.1 interfaces, such a header is very + # similar to vulkan_core.h. + genOpts['vulkan11.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'vulkan11.h', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = '^VK_VERSION_1_[01]$', + emitversions = '^VK_VERSION_1_[01]$', + defaultExtensions = None, + addExtensions = None, + removeExtensions = None, + emitExtensions = None, + prefixText = prefixStrings + vkPrefixStrings, + genFuncPointers = True, + protectFile = protectFile, + protectFeature = False, + protectProto = '#ifndef', + protectProtoStr = 'VK_NO_PROTOTYPES', + apicall = 'VKAPI_ATTR ', + apientry = 'VKAPI_CALL ', + apientryp = 'VKAPI_PTR *', + alignFuncParam = 48, + misracstyle = misracstyle, + misracppstyle = misracppstyle) + ] + + genOpts['alias.h'] = [ + COutputGenerator, + CGeneratorOptions( + conventions = conventions, + filename = 'alias.h', + directory = directory, + genpath = None, + apiname = defaultAPIName, + profile = None, + versions = featuresPat, + emitversions = featuresPat, + defaultExtensions = defaultExtensions, + addExtensions = None, + removeExtensions = removeExtensionsPat, + emitExtensions = emitExtensionsPat, + prefixText = None, + genFuncPointers = False, + protectFile = False, + protectFeature = False, + protectProto = '', + protectProtoStr = '', + apicall = '', + apientry = '', + apientryp = '', + alignFuncParam = 36) + ] + + +def genTarget(args): + """Create an API generator and corresponding generator options based on + the requested target and command line options. + + This is encapsulated in a function so it can be profiled and/or timed. + The args parameter is a parsed argument object containing the following + fields that are used: + + - target - target to generate + - directory - directory to generate it in + - protect - True if re-inclusion wrappers should be created + - extensions - list of additional extensions to include in generated interfaces""" + + # Create generator options with parameters specified on command line + makeGenOpts(args) + + # Select a generator matching the requested target + if args.target in genOpts: + createGenerator = genOpts[args.target][0] + options = genOpts[args.target][1] + + logDiag('* Building', options.filename) + logDiag('* options.apiname =', options.apiname) + logDiag('* options.versions =', options.versions) + logDiag('* options.emitversions =', options.emitversions) + logDiag('* options.defaultExtensions =', options.defaultExtensions) + logDiag('* options.addExtensions =', options.addExtensions) + logDiag('* options.removeExtensions =', options.removeExtensions) + logDiag('* options.emitExtensions =', options.emitExtensions) + logDiag('* options.emitSpirv =', options.emitSpirv) + logDiag('* options.emitFormats =', options.emitFormats) + + gen = createGenerator(errFile=errWarn, + warnFile=errWarn, + diagFile=diag) + return (gen, options) + else: + logErr('No generator options for unknown target:', args.target) + return None + + +# -feature name +# -extension name +# For both, "name" may be a single name, or a space-separated list +# of names, or a regular expression. +if __name__ == '__main__': + parser = argparse.ArgumentParser() + + parser.add_argument('-apiname', action='store', + default=None, + help='Specify API to generate (defaults to repository-specific conventions object value)') + parser.add_argument('-mergeApiNames', action='store', + default=None, + help='Specify a comma separated list of APIs to merge into the target API') + parser.add_argument('-defaultExtensions', action='store', + default=APIConventions().xml_api_name, + help='Specify a single class of extensions to add to targets') + parser.add_argument('-extension', action='append', + default=[], + help='Specify an extension or extensions to add to targets') + parser.add_argument('-removeExtensions', action='append', + default=[], + help='Specify an extension or extensions to remove from targets') + parser.add_argument('-emitExtensions', action='append', + default=[], + help='Specify an extension or extensions to emit in targets') + parser.add_argument('-emitSpirv', action='append', + default=[], + help='Specify a SPIR-V extension or capability to emit in targets') + parser.add_argument('-emitFormats', action='append', + default=[], + help='Specify Vulkan Formats to emit in targets') + parser.add_argument('-feature', action='append', + default=[], + help='Specify a core API feature name or names to add to targets') + parser.add_argument('-debug', action='store_true', + help='Enable debugging') + parser.add_argument('-dump', action='store_true', + help='Enable dump to stderr') + parser.add_argument('-diagfile', action='store', + default=None, + help='Write diagnostics to specified file') + parser.add_argument('-errfile', action='store', + default=None, + help='Write errors and warnings to specified file instead of stderr') + parser.add_argument('-noprotect', dest='protect', action='store_false', + help='Disable inclusion protection in output headers') + parser.add_argument('-profile', action='store_true', + help='Enable profiling') + parser.add_argument('-registry', action='store', + default='vk.xml', + help='Use specified registry file instead of vk.xml') + parser.add_argument('-time', action='store_true', + help='Enable timing') + parser.add_argument('-genpath', action='store', default='gen', + help='Path to generated files') + parser.add_argument('-o', action='store', dest='directory', + default='.', + help='Create target and related files in specified directory') + parser.add_argument('target', metavar='target', nargs='?', + help='Specify target') + parser.add_argument('-quiet', action='store_true', default=True, + help='Suppress script output during normal execution.') + parser.add_argument('-verbose', action='store_false', dest='quiet', default=True, + help='Enable script output during normal execution.') + parser.add_argument('--vulkanLayer', action='store_true', dest='vulkanLayer', + help='Enable scripts to generate VK specific vulkan_json_data.hpp for json_gen_layer.') + parser.add_argument('-misracstyle', dest='misracstyle', action='store_true', + help='generate MISRA C-friendly headers') + parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true', + help='generate MISRA C++-friendly headers') + parser.add_argument('--iscts', action='store_true', dest='isCTS', + help='Specify if this should generate CTS compatible code') + + args = parser.parse_args() + + # This splits arguments which are space-separated lists + args.feature = [name for arg in args.feature for name in arg.split()] + args.extension = [name for arg in args.extension for name in arg.split()] + + # create error/warning & diagnostic files + if args.errfile: + errWarn = open(args.errfile, 'w', encoding='utf-8') + else: + errWarn = sys.stderr + + if args.diagfile: + diag = open(args.diagfile, 'w', encoding='utf-8') + else: + diag = None + + if args.time: + # Log diagnostics and warnings + setLogFile(setDiag = True, setWarn = True, filename = '-') + + # Create the API generator & generator options + (gen, options) = genTarget(args) + + # Create the registry object with the specified generator and generator + # options. The options are set before XML loading as they may affect it. + reg = Registry(gen, options) + + # Parse the specified registry XML into an ElementTree object + startTimer(args.time) + tree = etree.parse(args.registry) + endTimer(args.time, '* Time to make ElementTree =') + + # Load the XML tree into the registry object + startTimer(args.time) + reg.loadElementTree(tree) + endTimer(args.time, '* Time to parse ElementTree =') + + if args.dump: + logDiag('* Dumping registry to regdump.txt') + reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8')) + + # Finally, use the output generator to create the requested target + if args.debug: + pdb.run('reg.apiGen()') + else: + startTimer(args.time) + reg.apiGen() + endTimer(args.time, f"* Time to generate {options.filename} =") + + if not args.quiet: + logDiag('* Generated', options.filename) diff --git a/libs/VulkanHeaders/reflib.py b/libs/VulkanHeaders/reflib.py new file mode 100644 index 0000000000..248b02895c --- /dev/null +++ b/libs/VulkanHeaders/reflib.py @@ -0,0 +1,686 @@ +#!/usr/bin/env python3 +# Copyright 2016-2025 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Utility functions for automatic ref page generation and other script stuff + +import importlib +import io +import os +import re +import sys +import subprocess + +# global errFile, warnFile, diagFile + +errFile = sys.stderr +warnFile = sys.stdout +diagFile = None +logSourcefile = None +logProcname = None +logLine = None + +def unescapeQuotes(s): + """Remove \' escape sequences in a string (refpage description)""" + return s.replace('\\\'', '\'') + +def write(*args, **kwargs ): + file = kwargs.pop('file',sys.stdout) + end = kwargs.pop('end','\n') + file.write(' '.join(str(arg) for arg in args)) + file.write(end) + +def setLogSourcefile(filename): + """Metadata which may be printed (if not None) for diagnostic messages""" + global logSourcefile + logSourcefile = filename + +def setLogProcname(procname): + global logProcname + logProcname = procname + +def setLogLine(line): + global logLine + logLine = line + +def logHeader(severity): + """Generate prefix for a diagnostic line using metadata and severity""" + global logSourcefile, logProcname, logLine + + msg = f'{severity}: ' + if logProcname: + msg = f'{msg} in {logProcname}' + if logSourcefile: + msg = f'{msg} for {logSourcefile}' + if logLine: + msg = f'{msg} line {str(logLine)}' + return f'{msg} ' + +def setLogFile(setDiag, setWarn, filename): + """Set the file handle to log either or both warnings and diagnostics to. + + - setDiag and setWarn are True if the corresponding handle is to be set. + - filename is None for no logging, '-' for stdout, or a pathname.""" + global diagFile, warnFile + + if filename is None: + return + + if filename == '-': + fp = sys.stdout + else: + fp = open(filename, 'w', encoding='utf-8') + + if setDiag: + diagFile = fp + if setWarn: + warnFile = fp + +def logDiag(*args, **kwargs): + file = kwargs.pop('file', diagFile) + end = kwargs.pop('end','\n') + if file is not None: + file.write(logHeader('DIAG') + ' '.join(str(arg) for arg in args)) + file.write(end) + +def logWarn(*args, **kwargs): + file = kwargs.pop('file', warnFile) + end = kwargs.pop('end','\n') + if file is not None: + file.write(logHeader('WARN') + ' '.join(str(arg) for arg in args)) + file.write(end) + +def logErr(*args, **kwargs): + file = kwargs.pop('file', errFile) + end = kwargs.pop('end','\n') + + strfile = io.StringIO() + strfile.write(logHeader('ERROR') + ' '.join(str(arg) for arg in args)) + strfile.write(end) + + if file is not None: + file.write(strfile.getvalue()) + raise UserWarning(strfile.getvalue()) + +def isempty(s): + """Return True if s is nothing but white space, False otherwise""" + return len(''.join(s.split())) == 0 + +class pageInfo: + """Information about a ref page relative to the file it is extracted from.""" + def __init__(self): + self.extractPage = True + """True if page should be extracted""" + + self.Warning = None + """string warning if page is suboptimal or cannot be generated""" + + self.embed = False + """False or the name of the ref page this include is embedded within""" + + self.type = None + """refpage type attribute - 'structs', 'protos', 'freeform', etc.""" + + self.name = None + """struct/proto/enumerant/etc. name""" + + self.desc = None + """short description of ref page""" + + self.begin = None + """index of first line of the page (heuristic or // refBegin)""" + + self.include = None + """index of include:: line defining the page""" + + self.param = None + """index of first line of parameter/member definitions""" + + self.body = None + """index of first line of body text""" + + self.validity = None + """index of validity include""" + + self.end = None + """index of last line of the page (heuristic validity include, or // refEnd)""" + + self.alias = '' + """aliases of this name, if supplied, or ''""" + + self.refs = '' + """cross-references on // refEnd line, if supplied""" + + self.spec = None + """'spec' attribute in refpage open block, if supplied, or None for the default ('api') type""" + + self.anchor = None + """'anchor' attribute in refpage open block, if supplied, or inferred to be the same as the 'name'""" + +def printPageInfoField(desc, line, file): + """Print a single field of a pageInfo struct, possibly None. + + - desc - string description of field + - line - field value or None + - file - indexed by line""" + if line is not None: + logDiag(f'{desc}: {line+1}\t-> file[line]', end='') + else: + logDiag(f'{desc}: {line}') + +def printPageInfo(pi, file): + """Print out fields of a pageInfo struct + + - pi - pageInfo + - file - indexed by pageInfo""" + logDiag(f'TYPE: {pi.type}') + logDiag(f'NAME: {pi.name}') + logDiag(f'WARNING: {pi.Warning}') + logDiag(f'EXTRACT: {pi.extractPage}') + logDiag(f'EMBED: {pi.embed}') + logDiag(f'DESC: {pi.desc}') + printPageInfoField('BEGIN ', pi.begin, file) + printPageInfoField('INCLUDE ', pi.include, file) + printPageInfoField('PARAM ', pi.param, file) + printPageInfoField('BODY ', pi.body, file) + printPageInfoField('VALIDITY', pi.validity, file) + printPageInfoField('END ', pi.end, file) + logDiag(f'REFS: "{pi.refs}"') + +def prevPara(file, line): + """Go back one paragraph from the specified line and return the line number + of the first line of that paragraph. + + Paragraphs are delimited by blank lines. It is assumed that the + current line is the first line of a paragraph. + + - file is an array of strings + - line is the starting point (zero-based)""" + # Skip over current paragraph + while (line >= 0 and not isempty(file[line])): + line = line - 1 + # Skip over white space + while (line >= 0 and isempty(file[line])): + line = line - 1 + # Skip to first line of previous paragraph + while (line >= 1 and not isempty(file[line-1])): + line = line - 1 + return line + +def nextPara(file, line): + """Go forward one paragraph from the specified line and return the line + number of the first line of that paragraph. + + Paragraphs are delimited by blank lines. It is assumed that the + current line is standalone (which is bogus). + + - file is an array of strings + - line is the starting point (zero-based)""" + maxLine = len(file) - 1 + # Skip over current paragraph + while (line != maxLine and not isempty(file[line])): + line = line + 1 + # Skip over white space + while (line != maxLine and isempty(file[line])): + line = line + 1 + return line + +def lookupPage(refpageMap, name): + """Return (creating if needed) the pageInfo entry in refpageMap for name""" + if name not in refpageMap: + pi = pageInfo() + pi.name = name + refpageMap[name] = pi + else: + pi = refpageMap[name] + return pi + +def loadFile(filename): + """Load a file into a list of strings. Return the (list, newline_string) or (None, None) on failure""" + newline_string = "\n" + try: + with open(filename, 'rb') as fp: + contents = fp.read() + if contents.count(b"\r\n") > 1: + newline_string = "\r\n" + + with open(filename, 'r', encoding='utf-8') as fp: + lines = fp.readlines() + except: + logWarn(f'Cannot open file {filename} : {sys.exc_info()[0]}') + return None, None + + return lines, newline_string + +def clampToBlock(line, minline, maxline): + """Clamp a line number to be in the range [minline,maxline]. + + If the line number is None, just return it. + If minline is None, do not clamp to that value.""" + if line is None: + return line + if minline and line < minline: + return minline + if line > maxline: + return maxline + + return line + +def fixupRefs(refpageMap, specFile, file): + """Fill in missing fields in pageInfo structures, to the extent they can be + inferred. + + - refpageMap - dictionary of pageInfo structures + - specFile - filename + - file - list of strings making up the file, indexed by pageInfo""" + # All potential ref pages are now in refpageMap. Process them to + # identify actual page start/end/description boundaries, if + # not already determined from the text. + for name in sorted(refpageMap.keys()): + pi = refpageMap[name] + + # # If nothing is found but an include line with no begin, validity, + # # or end, this is not intended as a ref page (yet). Set the begin + # # line to the include line, so autogeneration can at least + # # pull the include out, but mark it not to be extracted. + # # Examples include the host sync table includes in + # # chapters/fundamentals.adoc and the table of Vk*Flag types in + # # appendices/boilerplate.adoc. + # if pi.begin is None and pi.validity is None and pi.end is None: + # pi.begin = pi.include + # pi.extractPage = False + # pi.Warning = 'No begin, validity, or end lines identified' + # continue + + # Using open block delimiters, ref pages must *always* have a + # defined begin and end. If either is undefined, that is fatal. + if pi.begin is None: + pi.extractPage = False + pi.Warning = 'Cannot identify start of ref page open block' + continue + + if pi.end is None: + pi.extractPage = False + pi.Warning = 'Cannot identify end of ref page open block' + continue + + # If there is no description of the page, infer one from the type + if pi.desc is None: + if pi.type is not None: + # pi.desc = pi.type[0:len(pi.type)-1] + ' (no short description available)' + pi.Warning = 'No short description available; could infer from the type and name' + else: + pi.extractPage = False + pi.Warning = 'No short description available, cannot infer from the type' + continue + + # Try to determine where the parameter and body sections of the page + # begin. funcpointer, proto, and struct pages infer the location of + # the parameter and body sections. Other pages infer the location of + # the body, but have no parameter sections. + # + # Probably some other types infer this as well - refer to list of + # all page types in genRef.py:emitPage() + if pi.include is not None: + if pi.type in ['funcpointers', 'protos', 'structs']: + pi.param = nextPara(file, pi.include) + if pi.body is None: + pi.body = nextPara(file, pi.param) + + # Vulkan Feature struct refpages may have interstitial + # text between the include block and the actual + # parameter descriptions. + # If so, advance the body one more paragraph. + if 'This structure describes the following feature' in file[pi.param]: + pi.body = nextPara(file, pi.body) + else: + if pi.body is None: + pi.body = nextPara(file, pi.include) + else: + pi.Warning = 'Page does not have an API definition include::' + + # It is possible for the inferred param and body lines to run past + # the end of block, if, for example, there is no parameter section. + pi.param = clampToBlock(pi.param, pi.include, pi.end) + pi.body = clampToBlock(pi.body, pi.param, pi.end) + + if pi.type in ['funcpointers', 'protos']: + # It is possible for the inferred parameter section to be invalid, + # such as for the type PFN_vkVoidFunction, which has no parameters. + # Since the parameter section is always a bullet-point list, we know + # the section is invalid if its text does not start with a list item. + # Note: This also deletes parameter sections that are simply empty. + if pi.param is not None and not file[pi.param].startswith(' * '): + pi.body = pi.param + pi.param = None + + # We can get to this point with .include, .param, and .validity + # all being None, indicating those sections were not found. + + logDiag(f'fixupRefs: after processing, {pi.name} looks like:') + printPageInfo(pi, file) + + # Now that all the valid pages have been found, try to make some + # inferences about invalid pages. + # + # If a reference without a .end is entirely inside a valid reference, + # then it is intentionally embedded - may want to create an indirect + # page that links into the embedding page. This is done by a very + # inefficient double loop, but the loop depth is small. + for name in sorted(refpageMap.keys()): + pi = refpageMap[name] + + if pi.end is None: + for embedName in sorted(refpageMap.keys()): + logDiag(f'fixupRefs: comparing {pi.name} to {embedName}') + embed = refpageMap[embedName] + # Do not check embeddings which are themselves invalid + if not embed.extractPage: + logDiag(f'Skipping check for embedding in: {embed.name}') + continue + if embed.begin is None or embed.end is None: + logDiag(f'fixupRefs: {name}:', + f'cannot compare to unanchored ref {embed.name}', + f'in {specFile} at line {pi.include}') + printPageInfo(pi, file) + printPageInfo(embed, file) + # If an embed is found, change the error to a warning + elif (pi.include is not None and pi.include >= embed.begin and + pi.include <= embed.end): + logDiag(f'fixupRefs: Found embed for: {name} inside: {embedName}', + f'in {specFile} at line {pi.include}') + pi.embed = embed.name + pi.Warning = f'Embedded in definition for {embed.name}' + break + else: + logDiag(f'fixupRefs: No embed match for: {name} inside {embedName}', + f'in {specFile} at line {pi.include}') + + +def compatiblePageTypes(refpage_type, pagemap_type): + """Returns whether two refpage 'types' (categories) are compatible - + this is only true for 'consts' and 'enums' types.""" + + constsEnums = [ 'consts', 'enums' ] + + if refpage_type == pagemap_type: + return True + if refpage_type in constsEnums and pagemap_type in constsEnums: + return True + return False + +# Patterns used to recognize interesting lines in an asciidoc source file. +# These patterns are only compiled once. +endifPat = re.compile(r'^endif::(?P[\w_+,]+)\[\]') +beginPat = re.compile(r'^\[open,(?Prefpage=.*)\]') +# attribute key/value pairs of an open block +attribStr = r"([a-z]+)='([^'\\]*(?:\\.[^'\\]*)*)'" +attribPat = re.compile(attribStr) +bodyPat = re.compile(r'^// *refBody') +errorPat = re.compile(r'^// *refError') + +# This regex transplanted from check_spec_links +# It looks for various generated file conventions, and for the api/validity +# include (generated_type), protos/struct/etc path (category), and API name +# (entity_name). +# It could be put into the API conventions object, instead of being +# generalized for all the different specs. +INCLUDE = re.compile( + r'include::(?P((../){1,4}|\{generated\}/)(generated/)?)(?P[\w]+)/(?P\w+)/(?P[^./]+)\.(adoc|txt)[\[][\]]') + +def findRefs(file, filename): + """Identify reference pages in a list of strings, returning a dictionary of + pageInfo entries for each one found, or None on failure.""" + setLogSourcefile(filename) + setLogProcname('findRefs') + + # To reliably detect the open blocks around reference pages, we must + # first detect the '[open,refpage=...]' markup delimiting the block; + # skip past the '--' block delimiter on the next line; and identify the + # '--' block delimiter closing the page. + # This cannot be done solely with pattern matching, and requires state to + # track 'inside/outside block'. + # When looking for open blocks, possible states are: + # 'outside' - outside a block + # 'start' - have found the '[open...]' line + # 'inside' - have found the following '--' line + openBlockState = 'outside' + + # Dictionary of interesting line numbers and strings related to an API + # name + refpageMap = {} + + numLines = len(file) + line = 0 + + # Track the pageInfo object corresponding to the current open block + pi = None + + while (line < numLines): + setLogLine(line) + + # Only one of the patterns can possibly match. Add it to + # the dictionary for that name. + + # [open,refpage=...] starting a refpage block + matches = beginPat.search(file[line]) + if matches is not None: + logDiag('Matched open block pattern') + attribs = matches.group('attribs') + + # If the previous open block was not closed, raise an error + if openBlockState != 'outside': + logErr(f'Nested open block starting at line {line} of {filename}') + + openBlockState = 'start' + + # Parse the block attributes + matches = attribPat.findall(attribs) + + # Extract each attribute + name = None + desc = None + refpage_type = None + spec_type = None + anchor = None + alias = None + xrefs = None + + for (key,value) in matches: + logDiag(f'got attribute {key} = {value}') + if key == 'refpage': + name = value + elif key == 'desc': + desc = unescapeQuotes(value) + elif key == 'type': + refpage_type = value + elif key == 'spec': + spec_type = value + elif key == 'anchor': + anchor = value + elif key == 'alias': + alias = value + elif key == 'xrefs': + xrefs = value + else: + logWarn(f'unknown open block attribute: {key}') + + if name is None or desc is None or refpage_type is None: + logWarn('missing one or more required open block attributes:' + 'refpage, desc, or type') + # Leave pi is None so open block delimiters are ignored + else: + pi = lookupPage(refpageMap, name) + pi.desc = desc + # Must match later type definitions in interface/validity includes + pi.type = refpage_type + pi.spec = spec_type + pi.anchor = anchor + if alias: + pi.alias = alias + if xrefs: + pi.refs = xrefs + logDiag(f'open block for {name} added', + f'DESC = {desc} TYPE = {refpage_type} ALIAS = {alias}', + f'XREFS = {xrefs} SPEC = {spec_type} ANCHOR = {anchor}') + + line = line + 1 + continue + + # '--' starting or ending and open block + if file[line].rstrip() == '--': + if openBlockState == 'outside': + # Only refpage open blocks should use -- delimiters + logWarn('Unexpected double-dash block delimiters') + elif openBlockState == 'start': + # -- delimiter following [open,refpage=...] + openBlockState = 'inside' + + if pi is None: + logWarn('no pageInfo available for opening -- delimiter') + else: + pi.begin = line + 1 + logDiag(f'opening -- delimiter: added BEGIN = {pi.begin}') + elif openBlockState == 'inside': + # -- delimiter ending an open block + if pi is None: + logWarn('no pageInfo available for closing -- delimiter') + else: + pi.end = line - 1 + logDiag(f'closing -- delimiter: added END = {pi.end}') + + openBlockState = 'outside' + pi = None + else: + logWarn('unknown openBlockState:', openBlockState) + + line = line + 1 + continue + + matches = INCLUDE.search(file[line]) + if matches is not None: + # Something got included, not sure what yet. + gen_type = matches.group('generated_type') + refpage_type = matches.group('category') + name = matches.group('entity_name') + + # This will never match in OpenCL + if gen_type == 'validity': + logDiag('Matched validity pattern') + if pi is not None: + if pi.type and not compatiblePageTypes(refpage_type, pi.type): + logWarn(f'ERROR: refpageMap[{name}] type:', + pi.type, 'does not match type:', refpage_type) + pi.validity = line + logDiag(f'added TYPE = {pi.type} VALIDITY = {pi.validity}') + else: + logWarn('validity include:: line NOT inside block') + + line = line + 1 + continue + + if gen_type == 'api': + logDiag('Matched include pattern') + if pi is not None: + if pi.include is not None: + logDiag('found multiple includes for this block') + if pi.type and not compatiblePageTypes(refpage_type, pi.type): + logWarn(f'ERROR: refpageMap[{name}] type:', + pi.type, 'does not match type:', refpage_type) + pi.include = line + logDiag(f'added TYPE = {pi.type} INCLUDE = {pi.include}') + else: + logWarn('interface include:: line NOT inside block') + + line = line + 1 + continue + + logDiag(f'ignoring unrecognized include line {matches.group()}') + + # Vulkan 1.1 markup allows the last API include construct to be + # followed by an asciidoctor endif:: construct (and also preceded, + # at some distance). + # This looks for endif:: immediately following an include:: line + # and, if found, moves the include boundary to this line. + matches = endifPat.search(file[line]) + if matches is not None and pi is not None: + if pi.include == line - 1: + logDiag('Matched endif pattern following include; moving include') + pi.include = line + else: + logDiag('Matched endif pattern (not following include)') + + line = line + 1 + continue + + matches = bodyPat.search(file[line]) + if matches is not None: + logDiag('Matched // refBody pattern') + if pi is not None: + pi.body = line + logDiag(f'added BODY = {pi.body}') + else: + logWarn('// refBody line NOT inside block') + + line = line + 1 + continue + + # OpenCL spec uses // refError to tag "validity" (Errors) language, + # instead of /validity/ includes. + matches = errorPat.search(file[line]) + if matches is not None: + logDiag('Matched // refError pattern') + if pi is not None: + pi.validity = line + logDiag(f'added VALIDITY (refError) = {pi.validity}') + else: + logWarn('// refError line NOT inside block') + + line = line + 1 + continue + + line = line + 1 + continue + + if pi is not None: + logErr('Unclosed open block at EOF!') + + setLogSourcefile(None) + setLogProcname(None) + setLogLine(None) + + return refpageMap + + +def getBranch(): + """Determine current git branch + + Returns (branch name, ''), or (None, stderr output) if the branch name + cannot be determined""" + + command = [ 'git', 'symbolic-ref', '--short', 'HEAD' ] + results = subprocess.run(command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + # git command failed + if len(results.stderr) > 0: + return (None, results.stderr) + + # Remove newline from output and convert to a string + branch = results.stdout.rstrip().decode() + if len(branch) > 0: + # Strip trailing newline + branch = results.stdout.decode()[0:-1] + + return (branch, '') + +def importFileModule(file): + """importFileModule - import file as a module and return that module""" + + (path, file) = os.path.split(file) + (module, extension) = os.path.splitext(file) + sys.path.append(path) + + return importlib.import_module(module) + diff --git a/libs/VulkanHeaders/reg.py b/libs/VulkanHeaders/reg.py new file mode 100644 index 0000000000..14183af15f --- /dev/null +++ b/libs/VulkanHeaders/reg.py @@ -0,0 +1,1885 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +"""Types and classes for manipulating an API registry.""" + +import copy +import re +import sys +import xml.etree.ElementTree as etree +from collections import defaultdict, deque, namedtuple + +from generator import GeneratorOptions, OutputGenerator, noneStr, write +from apiconventions import APIConventions + +def apiNameMatch(str, supported): + """Return whether a required api name matches a pattern specified for an + XML 'api' attribute or 'supported' attribute. + + - str - API name such as 'vulkan' or 'openxr'. May be None, in which + case it never matches (this should not happen). + - supported - comma-separated list of XML API names. May be None, in + which case str always matches (this is the usual case).""" + + if str is not None: + return supported is None or str in supported.split(',') + + # Fallthrough case - either str is None or the test failed + return False + +def matchAPIProfile(api, profile, elem): + """Return whether an API and profile + being generated matches an element's profile + + - api - string naming the API to match + - profile - string naming the profile to match + - elem - Element which (may) have 'api' and 'profile' + attributes to match to. + + If a tag is not present in the Element, the corresponding API + or profile always matches. + + Otherwise, the tag must exactly match the API or profile. + + Thus, if 'profile' = core: + + - `` with no attribute will match + - `` will match + - `` will not match + + Possible match conditions: + + ``` + Requested Element + Profile Profile + --------- -------- + None None Always matches + 'string' None Always matches + None 'string' Does not match. Cannot generate multiple APIs + or profiles, so if an API/profile constraint + is present, it must be asked for explicitly. + 'string' 'string' Strings must match + ``` + + ** In the future, we will allow regexes for the attributes, + not just strings, so that `api="^(gl|gles2)"` will match. Even + this is not really quite enough, we might prefer something + like `"gl(core)|gles1(common-lite)"`.""" + # Match 'api', if present + elem_api = elem.get('api') + if elem_api: + if api is None: + raise UserWarning("No API requested, but 'api' attribute is present with value '" + + elem_api + "'") + elif api != elem_api: + # Requested API does not match attribute + return False + elem_profile = elem.get('profile') + if elem_profile: + if profile is None: + raise UserWarning("No profile requested, but 'profile' attribute is present with value '" + + elem_profile + "'") + elif profile != elem_profile: + # Requested profile does not match attribute + return False + return True + + +def mergeAPIs(tree, fromApiNames, toApiName): + """Merge multiple APIs using the precedence order specified in apiNames. + Also deletes elements. + + tree - Element at the root of the hierarchy to merge. + apiNames - list of strings of API names.""" + + stack = deque() + stack.append(tree) + + while len(stack) > 0: + parent = stack.pop() + + for child in parent.findall('*'): + if child.tag == 'remove': + # Remove elements + parent.remove(child) + else: + stack.append(child) + + supportedList = child.get('supported') + if supportedList: + supportedList = supportedList.split(',') + for apiName in [toApiName] + fromApiNames: + if apiName in supportedList: + child.set('supported', toApiName) + + if child.get('api'): + definitionName = None + definitionVariants = [] + + # Keep only one definition with the same name if there are multiple definitions + if child.tag in ['type']: + if child.get('name') is not None: + definitionName = child.get('name') + definitionVariants = parent.findall(f"{child.tag}[@name='{definitionName}']") + else: + definitionName = child.find('name').text + definitionVariants = parent.findall(f"{child.tag}/name[.='{definitionName}']/..") + elif child.tag in ['member', 'param']: + definitionName = child.find('name').text + definitionVariants = parent.findall(f"{child.tag}/name[.='{definitionName}']/..") + elif child.tag in ['enum', 'feature']: + definitionName = child.get('name') + definitionVariants = parent.findall(f"{child.tag}[@name='{definitionName}']") + elif child.tag in ['require']: + # No way to correlate require tags because they do not have a definite identifier in the way they + # are used in the latest forms of the XML so the best we can do is simply enable all of them + if child.get('api') in fromApiNames: + child.set('api', toApiName) + elif child.tag in ['command']: + definitionName = child.find('proto/name').text + definitionVariants = parent.findall(f"{child.tag}/proto/name[.='{definitionName}']/../..") + + if definitionName: + bestMatchApi = None + requires = None + for apiName in [toApiName] + fromApiNames: + for variant in definitionVariants: + # Keep any requires attributes from the target API + if variant.get('requires') and variant.get('api') == apiName: + requires = variant.get('requires') + # Find the best matching definition + if apiName in variant.get('api').split(',') and bestMatchApi is None: + bestMatchApi = variant.get('api') + + if bestMatchApi: + for variant in definitionVariants: + if variant.get('api') != bestMatchApi: + # Only keep best matching definition + parent.remove(variant) + else: + # Add requires attribute from the target API if it is not overridden + if requires is not None and variant.get('requires') is None: + variant.set('requires', requires) + variant.set('api', toApiName) + + +def stripNonmatchingAPIs(tree, apiName, actuallyDelete = True): + """Remove tree Elements with 'api' attributes matching apiName. + + tree - Element at the root of the hierarchy to strip. Only its + children can actually be removed, not the tree itself. + apiName - string which much match a command-separated component of + the 'api' attribute. + actuallyDelete - only delete matching elements if True.""" + + stack = deque() + stack.append(tree) + + while len(stack) > 0: + parent = stack.pop() + + for child in parent.findall('*'): + api = child.get('api') + + if apiNameMatch(apiName, api): + # Add child to the queue + stack.append(child) + elif not apiNameMatch(apiName, api): + # Child does not match requested api. Remove it. + if actuallyDelete: + parent.remove(child) + + +class BaseInfo: + """Base class for information about a registry feature + (type/group/enum/command/API/extension). + + Represents the state of a registry feature, used during API generation. + """ + + def __init__(self, elem): + self.required = False + """should this feature be defined during header generation + (has it been removed by a profile or version)?""" + + self.declared = False + "has this feature been defined already?" + + self.elem = elem + "etree Element for this feature" + + self.deprecatedbyversion = None + self.deprecatedbyextensions = [] + self.deprecatedlink = None + + def resetState(self): + """Reset required/declared to initial values. Used + prior to generating a new API interface.""" + self.required = False + self.declared = False + + def compareKeys(self, info, key, required = False): + """Return True if self.elem and info.elem have the same attribute + value for key. + If 'required' is not True, also returns True if neither element + has an attribute value for key.""" + + if required and key not in self.elem.keys(): + return False + return self.elem.get(key) == info.elem.get(key) + + def compareElem(self, info, infoName): + """Return True if self.elem and info.elem have the same definition. + info - the other object + infoName - 'type' / 'group' / 'enum' / 'command' / 'feature' / + 'extension'""" + + if infoName == 'enum': + if self.compareKeys(info, 'extends'): + # Either both extend the same type, or no type + if (self.compareKeys(info, 'value', required = True) or + self.compareKeys(info, 'bitpos', required = True)): + # If both specify the same value or bit position, + # they are equal + return True + elif (self.compareKeys(info, 'extnumber') and + self.compareKeys(info, 'offset') and + self.compareKeys(info, 'dir')): + # If both specify the same relative offset, they are equal + return True + elif (self.compareKeys(info, 'alias')): + # If both are aliases of the same value + return True + else: + return False + else: + # The same enum cannot extend two different types + return False + else: + # Non-s should never be redefined + return False + + +class TypeInfo(BaseInfo): + """Registry information about a type. No additional state + beyond BaseInfo is required.""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + self.additionalValidity = [] + self.removedValidity = [] + + def getMembers(self): + """Get a collection of all member elements for this type, if any.""" + return self.elem.findall('member') + + def resetState(self): + BaseInfo.resetState(self) + self.additionalValidity = [] + self.removedValidity = [] + + +class GroupInfo(BaseInfo): + """Registry information about a group of related enums + in an block, generally corresponding to a C "enum" type.""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + + +class EnumInfo(BaseInfo): + """Registry information about an enum""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + self.type = elem.get('type') + """numeric type of the value of the tag + ( '' for GLint, 'u' for GLuint, 'ull' for GLuint64 )""" + if self.type is None: + self.type = '' + + +class CmdInfo(BaseInfo): + """Registry information about a command""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + self.additionalValidity = [] + self.removedValidity = [] + + def getParams(self): + """Get a collection of all param elements for this command, if any.""" + return self.elem.findall('param') + + def resetState(self): + BaseInfo.resetState(self) + self.additionalValidity = [] + self.removedValidity = [] + + +class FeatureInfo(BaseInfo): + """Registry information about an API + or .""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + self.name = elem.get('name') + "feature name string (e.g. 'VK_KHR_surface')" + + self.emit = False + "has this feature been defined already?" + + self.sortorder = int(elem.get('sortorder', 0)) + """explicit numeric sort key within feature and extension groups. + Defaults to 0.""" + + # Determine element category (vendor). Only works + # for elements. + if elem.tag == 'feature': + # Element category (vendor) is meaningless for + self.category = 'VERSION' + """category, e.g. VERSION or khr/vendor tag""" + + self.version = elem.get('name') + """feature name string""" + + self.versionNumber = elem.get('number') + """versionNumber - API version number, taken from the 'number' + attribute of . Extensions do not have API version + numbers and are assigned number 0.""" + + self.number = 0 + self.supported = None + + self.deprecates = elem.findall('deprecate') + else: + # Extract vendor portion of __ + self.category = self.name.split('_', 2)[1] + self.version = "0" + self.versionNumber = "0" + + self.number = int(elem.get('number','0')) + """extension number, used for ordering and for assigning + enumerant offsets. features do not have extension + numbers and are assigned number 0, as are extensions without + numbers, so sorting works.""" + + self.supported = elem.get('supported', 'disabled') + +class SpirvInfo(BaseInfo): + """Registry information about an API + or .""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + +class FormatInfo(BaseInfo): + """Registry information about an API .""" + + def __init__(self, elem, condition): + BaseInfo.__init__(self, elem) + # Need to save the condition here when it is known + self.condition = condition + +class SyncStageInfo(BaseInfo): + """Registry information about .""" + + def __init__(self, elem, condition): + BaseInfo.__init__(self, elem) + # Need to save the condition here when it is known + self.condition = condition + +class SyncAccessInfo(BaseInfo): + """Registry information about .""" + + def __init__(self, elem, condition): + BaseInfo.__init__(self, elem) + # Need to save the condition here when it is known + self.condition = condition + +class SyncPipelineInfo(BaseInfo): + """Registry information about .""" + + def __init__(self, elem): + BaseInfo.__init__(self, elem) + +class Registry: + """Object representing an API registry, loaded from an XML file.""" + + def __init__(self, gen=None, genOpts=None): + if gen is None: + # If not specified, give a default object so messaging will work + self.gen = OutputGenerator() + else: + self.gen = gen + "Output generator used to write headers / messages" + + if genOpts is None: + # If no generator is provided, we may still need the XML API name + # (for example, in genRef.py). + self.genOpts = GeneratorOptions(apiname = APIConventions().xml_api_name) + else: + self.genOpts = genOpts + "Options controlling features to write and how to format them" + + self.gen.registry = self + self.gen.genOpts = self.genOpts + self.gen.genOpts.registry = self + + self.tree = None + "ElementTree containing the root ``" + + self.typedict = {} + "dictionary of TypeInfo objects keyed by type name" + + self.groupdict = {} + "dictionary of GroupInfo objects keyed by group name" + + self.enumdict = {} + "dictionary of EnumInfo objects keyed by enum name" + + self.cmddict = {} + "dictionary of CmdInfo objects keyed by command name" + + self.aliasdict = {} + "dictionary of type and command names mapped to their alias, such as VkFooKHR -> VkFoo" + + self.enumvaluedict = {} + "dictionary of enum values mapped to their type, such as VK_FOO_VALUE -> VkFoo" + + self.apidict = {} + "dictionary of FeatureInfo objects for `` elements keyed by API name" + + self.extensions = [] + "list of `` Elements" + + self.extdict = {} + "dictionary of FeatureInfo objects for `` elements keyed by extension name" + + self.spirvextdict = {} + "dictionary of FeatureInfo objects for `` elements keyed by spirv extension name" + + self.spirvcapdict = {} + "dictionary of FeatureInfo objects for `` elements keyed by spirv capability name" + + self.formatsdict = {} + "dictionary of FeatureInfo objects for `` elements keyed by VkFormat name" + + self.syncstagedict = {} + "dictionary of Sync*Info objects for `` elements keyed by VkPipelineStageFlagBits2 name" + + self.syncaccessdict = {} + "dictionary of Sync*Info objects for `` elements keyed by VkAccessFlagBits2 name" + + self.syncpipelinedict = {} + "dictionary of Sync*Info objects for `` elements keyed by pipeline type name" + + self.emitFeatures = False + """True to actually emit features for a version / extension, + or False to just treat them as emitted""" + + self.breakPat = None + "regexp pattern to break on when generating names" + # self.breakPat = re.compile('VkFenceImportFlagBits.*') + + self.requiredextensions = [] # Hack - can remove it after validity generator goes away + + # ** Global types for automatic source generation ** + # Length Member data + self.commandextensiontuple = namedtuple('commandextensiontuple', + ['command', # The name of the command being modified + 'value', # The value to append to the command + 'extension']) # The name of the extension that added it + self.validextensionstructs = defaultdict(list) + self.commandextensionsuccesses = [] + self.commandextensionerrors = [] + + self.filename = None + + def loadElementTree(self, tree): + """Load ElementTree into a Registry object and parse it.""" + self.tree = tree + self.parseTree() + + def loadFile(self, file): + """Load an API registry XML file into a Registry object and parse it""" + self.filename = file + self.tree = etree.parse(file) + self.parseTree() + + def setGenerator(self, gen): + """Specify output generator object. + + `None` restores the default generator.""" + self.gen = gen + self.gen.setRegistry(self) + + def addElementInfo(self, elem, info, infoName, dictionary): + """Add information about an element to the corresponding dictionary. + + Intended for internal use only. + + - elem - ``/``/``/``/``/``/``/``/``/``/``/`` Element + - info - corresponding {Type|Group|Enum|Cmd|Feature|Spirv|Format|SyncStage|SyncAccess|SyncPipeline}Info object + - infoName - 'type' / 'group' / 'enum' / 'command' / 'feature' / 'extension' / 'spirvextension' / 'spirvcapability' / 'format' / 'syncstage' / 'syncaccess' / 'syncpipeline' + - dictionary - self.{type|group|enum|cmd|api|ext|format|spirvext|spirvcap|sync}dict + + The dictionary key is the element 'name' attribute.""" + + # self.gen.logMsg('diag', 'Adding ElementInfo.required =', + # info.required, 'name =', elem.get('name')) + key = elem.get('name') + if key in dictionary: + if not dictionary[key].compareElem(info, infoName): + self.gen.logMsg('warn', 'Attempt to redefine', key, + '(this should not happen)') + else: + dictionary[key] = info + + def lookupElementInfo(self, fname, dictionary): + """Find a {Type|Enum|Cmd}Info object by name. + + Intended for internal use only. + + If an object qualified by API name exists, use that. + + - fname - name of type / enum / command + - dictionary - self.{type|enum|cmd}dict""" + key = (fname, self.genOpts.apiname) + if key in dictionary: + # self.gen.logMsg('diag', 'Found API-specific element for feature', fname) + return dictionary[key] + if fname in dictionary: + # self.gen.logMsg('diag', 'Found generic element for feature', fname) + return dictionary[fname] + + return None + + def breakOnName(self, regexp): + """Specify a feature name regexp to break on when generating features.""" + self.breakPat = re.compile(regexp) + + def addEnumValue(self, enum, type_name): + """Track aliasing and map back from enum values to their type""" + # Record alias, if any + value = enum.get('name') + alias = enum.get('alias') + if alias: + self.aliasdict[value] = alias + # Map the value back to the type + if type_name in self.aliasdict: + type_name = self.aliasdict[type_name] + if value in self.enumvaluedict: + # Some times the same enum is defined by multiple extensions + assert(type_name == self.enumvaluedict[value]) + else: + self.enumvaluedict[value] = type_name + + def parseTree(self): + """Parse the registry Element, once created""" + # This must be the Element for the root + if self.tree is None: + raise RuntimeError("Tree not initialized!") + self.reg = self.tree.getroot() + + # Preprocess the tree in one of the following ways: + # - either merge a set of APIs to another API based on their 'api' attributes + # - or remove all elements with non-matching 'api' attributes + # The preprocessing happens through a breath-first tree traversal. + # This is a blunt hammer, but eliminates the need to track and test + # the apis deeper in processing to select the correct elements and + # avoid duplicates. + # Schema validation should prevent duplicate elements with + # overlapping api attributes, or where one element has an api + # attribute and the other does not. + + if self.genOpts.mergeApiNames: + mergeAPIs(self.reg, self.genOpts.mergeApiNames.split(','), self.genOpts.apiname) + else: + stripNonmatchingAPIs(self.reg, self.genOpts.apiname, actuallyDelete = True) + + self.aliasdict = {} + self.enumvaluedict = {} + + # Create dictionary of registry types from toplevel tags + # and add 'name' attribute to each tag (where missing) + # based on its element. + # + # There is usually one block; more are OK + # Required attributes: 'name' or nested tag contents + self.typedict = {} + for type_elem in self.reg.findall('types/type'): + # If the does not already have a 'name' attribute, set + # it from contents of its tag. + name = type_elem.get('name') + if name is None: + name_elem = type_elem.find('name') + if name_elem is None or not name_elem.text: + raise RuntimeError("Type without a name!") + name = name_elem.text + type_elem.set('name', name) + self.addElementInfo(type_elem, TypeInfo(type_elem), 'type', self.typedict) + + # Record alias, if any + alias = type_elem.get('alias') + if alias: + self.aliasdict[name] = alias + + # Create dictionary of registry enum groups from tags. + # + # Required attributes: 'name'. If no name is given, one is + # generated, but that group cannot be identified and turned into an + # enum type definition - it is just a container for tags. + self.groupdict = {} + for group in self.reg.findall('enums'): + self.addElementInfo(group, GroupInfo(group), 'group', self.groupdict) + + # Create dictionary of registry enums from tags + # + # tags usually define different namespaces for the values + # defined in those tags, but the actual names all share the + # same dictionary. + # Required attributes: 'name', 'value' + # For containing which have type="enum" or type="bitmask", + # tag all contained s are required. This is a stopgap until + # a better scheme for tagging core and extension enums is created. + self.enumdict = {} + for enums in self.reg.findall('enums'): + required = (enums.get('type') is not None) + type_name = enums.get('name') + # Enum values are defined only for the type that is not aliased to something else. + assert(type_name not in self.aliasdict) + for enum in enums.findall('enum'): + enumInfo = EnumInfo(enum) + enumInfo.required = required + self.addElementInfo(enum, enumInfo, 'enum', self.enumdict) + self.addEnumValue(enum, type_name) + + # Create dictionary of registry commands from tags + # and add 'name' attribute to each tag (where missing) + # based on its element. + # + # There is usually only one block; more are OK. + # Required attributes: 'name' or tag contents + self.cmddict = {} + # List of commands which alias others. Contains + # [ name, aliasName, element ] + # for each alias + cmdAlias = [] + for cmd in self.reg.findall('commands/command'): + # If the does not already have a 'name' attribute, set + # it from contents of its tag. + name = cmd.get('name') + if name is None: + name_elem = cmd.find('proto/name') + if name_elem is None or not name_elem.text: + raise RuntimeError("Command without a name!") + name = cmd.set('name', name_elem.text) + ci = CmdInfo(cmd) + self.addElementInfo(cmd, ci, 'command', self.cmddict) + alias = cmd.get('alias') + if alias: + cmdAlias.append([name, alias, cmd]) + self.aliasdict[name] = alias + + # Now loop over aliases, injecting a copy of the aliased command's + # Element with the aliased prototype name replaced with the command + # name - if it exists. + # Copy the 'export' sttribute (whether it exists or not) from the + # original, aliased command, since that can be different for a + # command and its alias. + for (name, alias, cmd) in cmdAlias: + if alias in self.cmddict: + aliasInfo = self.cmddict[alias] + cmdElem = copy.deepcopy(aliasInfo.elem) + cmdElem.find('proto/name').text = name + cmdElem.set('name', name) + cmdElem.set('alias', alias) + export = cmd.get('export') + if export is not None: + # Replicate the command's 'export' attribute + cmdElem.set('export', export) + elif cmdElem.get('export') is not None: + # Remove the 'export' attribute, if the alias has one but + # the command does not. + del cmdElem.attrib['export'] + ci = CmdInfo(cmdElem) + # Replace the dictionary entry for the CmdInfo element + self.cmddict[name] = ci + + # @ newString = etree.tostring(base, encoding="unicode").replace(aliasValue, aliasName) + # @elem.append(etree.fromstring(replacement)) + else: + self.gen.logMsg('warn', 'No matching found for command', + cmd.get('name'), 'alias', alias) + + # Create dictionaries of API and extension interfaces + # from toplevel and tags. + self.apidict = {} + format_condition = dict() + for feature in self.reg.findall('feature'): + featureInfo = FeatureInfo(feature) + self.addElementInfo(feature, featureInfo, 'feature', self.apidict) + + # Add additional enums defined only in tags + # to the corresponding enumerated type. + # When seen here, the element, processed to contain the + # numeric enum value, is added to the corresponding + # element, as well as adding to the enum dictionary. It is no + # longer removed from the element it is introduced in. + # Instead, generateRequiredInterface ignores elements + # that extend enumerated types. + # + # For tags which are actually just constants, if there is + # no 'extends' tag but there is a 'value' or 'bitpos' tag, just + # add an EnumInfo record to the dictionary. That works because + # output generation of constants is purely dependency-based, and + # does not need to iterate through the XML tags. + for elem in feature.findall('require'): + for enum in elem.findall('enum'): + addEnumInfo = False + groupName = enum.get('extends') + if groupName is not None: + # self.gen.logMsg('diag', 'Found extension enum', + # enum.get('name')) + # Add version number attribute to the element + enum.set('version', featureInfo.version) + # Look up the GroupInfo with matching groupName + if groupName in self.groupdict: + # self.gen.logMsg('diag', 'Matching group', + # groupName, 'found, adding element...') + gi = self.groupdict[groupName] + gi.elem.append(copy.deepcopy(enum)) + else: + self.gen.logMsg('warn', 'NO matching group', + groupName, 'for enum', enum.get('name'), 'found.') + if groupName == "VkFormat": + format_name = enum.get('name') + if enum.get('alias'): + format_name = enum.get('alias') + format_condition[format_name] = featureInfo.name + addEnumInfo = True + elif enum.get('value') or enum.get('bitpos') or enum.get('alias'): + # self.gen.logMsg('diag', 'Adding extension constant "enum"', + # enum.get('name')) + addEnumInfo = True + if addEnumInfo: + enumInfo = EnumInfo(enum) + self.addElementInfo(enum, enumInfo, 'enum', self.enumdict) + self.addEnumValue(enum, groupName) + + sync_pipeline_stage_condition = dict() + sync_access_condition = dict() + + self.extensions = self.reg.findall('extensions/extension') + self.extdict = {} + for feature in self.extensions: + featureInfo = FeatureInfo(feature) + self.addElementInfo(feature, featureInfo, 'extension', self.extdict) + + # Add additional enums defined only in tags + # to the corresponding core type. + # Algorithm matches that of enums in a "feature" tag as above. + # + # This code also adds a 'extnumber' attribute containing the + # extension number, used for enumerant value calculation. + for elem in feature.findall('require'): + for enum in elem.findall('enum'): + addEnumInfo = False + groupName = enum.get('extends') + if groupName is not None: + # self.gen.logMsg('diag', 'Found extension enum', + # enum.get('name')) + + # Add block's extension number attribute to + # the element unless specified explicitly, such + # as when redefining an enum in another extension. + extnumber = enum.get('extnumber') + if not extnumber: + enum.set('extnumber', str(featureInfo.number)) + + enum.set('extname', featureInfo.name) + enum.set('supported', noneStr(featureInfo.supported)) + # Look up the GroupInfo with matching groupName + if groupName in self.groupdict: + # self.gen.logMsg('diag', 'Matching group', + # groupName, 'found, adding element...') + gi = self.groupdict[groupName] + gi.elem.append(copy.deepcopy(enum)) + else: + self.gen.logMsg('warn', 'NO matching group', + groupName, 'for enum', enum.get('name'), 'found.') + # This is Vulkan-specific + if groupName == "VkFormat": + format_name = enum.get('name') + if enum.get('alias'): + format_name = enum.get('alias') + if format_name in format_condition: + format_condition[format_name] += f",{featureInfo.name}" + else: + format_condition[format_name] = featureInfo.name + elif groupName == "VkPipelineStageFlagBits2": + stage_flag = enum.get('name') + if enum.get('alias'): + stage_flag = enum.get('alias') + featureName = elem.get('depends') if elem.get('depends') is not None else featureInfo.name + if stage_flag in sync_pipeline_stage_condition: + sync_pipeline_stage_condition[stage_flag] += f",{featureName}" + else: + sync_pipeline_stage_condition[stage_flag] = featureName + elif groupName == "VkAccessFlagBits2": + access_flag = enum.get('name') + if enum.get('alias'): + access_flag = enum.get('alias') + featureName = elem.get('depends') if elem.get('depends') is not None else featureInfo.name + if access_flag in sync_access_condition: + sync_access_condition[access_flag] += f",{featureName}" + else: + sync_access_condition[access_flag] = featureName + + addEnumInfo = True + elif enum.get('value') or enum.get('bitpos') or enum.get('alias'): + # self.gen.logMsg('diag', 'Adding extension constant "enum"', + # enum.get('name')) + addEnumInfo = True + if addEnumInfo: + enumInfo = EnumInfo(enum) + self.addElementInfo(enum, enumInfo, 'enum', self.enumdict) + self.addEnumValue(enum, groupName) + + # Parse out all spirv tags in dictionaries + # Use addElementInfo to catch duplicates + for spirv in self.reg.findall('spirvextensions/spirvextension'): + spirvInfo = SpirvInfo(spirv) + self.addElementInfo(spirv, spirvInfo, 'spirvextension', self.spirvextdict) + for spirv in self.reg.findall('spirvcapabilities/spirvcapability'): + spirvInfo = SpirvInfo(spirv) + self.addElementInfo(spirv, spirvInfo, 'spirvcapability', self.spirvcapdict) + + for format in self.reg.findall('formats/format'): + condition = None + format_name = format.get('name') + if format_name in format_condition: + condition = format_condition[format_name] + formatInfo = FormatInfo(format, condition) + self.addElementInfo(format, formatInfo, 'format', self.formatsdict) + + for stage in self.reg.findall('sync/syncstage'): + condition = None + stage_flag = stage.get('name') + if stage_flag in sync_pipeline_stage_condition: + condition = sync_pipeline_stage_condition[stage_flag] + syncInfo = SyncStageInfo(stage, condition) + self.addElementInfo(stage, syncInfo, 'syncstage', self.syncstagedict) + + for access in self.reg.findall('sync/syncaccess'): + condition = None + access_flag = access.get('name') + if access_flag in sync_access_condition: + condition = sync_access_condition[access_flag] + syncInfo = SyncAccessInfo(access, condition) + self.addElementInfo(access, syncInfo, 'syncaccess', self.syncaccessdict) + + for pipeline in self.reg.findall('sync/syncpipeline'): + syncInfo = SyncPipelineInfo(pipeline) + self.addElementInfo(pipeline, syncInfo, 'syncpipeline', self.syncpipelinedict) + + def dumpReg(self, maxlen=120, filehandle=sys.stdout): + """Dump all the dictionaries constructed from the Registry object. + + Diagnostic to dump the dictionaries to specified file handle (default stdout). + Truncates type / enum / command elements to maxlen characters (default 120)""" + write('***************************************', file=filehandle) + write(' ** Dumping Registry contents **', file=filehandle) + write('***************************************', file=filehandle) + write('// Types', file=filehandle) + for name in self.typedict: + tobj = self.typedict[name] + write(' Type', name, '->', etree.tostring(tobj.elem)[0:maxlen], file=filehandle) + write('// Groups', file=filehandle) + for name in self.groupdict: + gobj = self.groupdict[name] + write(' Group', name, '->', etree.tostring(gobj.elem)[0:maxlen], file=filehandle) + write('// Enums', file=filehandle) + for name in self.enumdict: + eobj = self.enumdict[name] + write(' Enum', name, '->', etree.tostring(eobj.elem)[0:maxlen], file=filehandle) + write('// Commands', file=filehandle) + for name in self.cmddict: + cobj = self.cmddict[name] + write(' Command', name, '->', etree.tostring(cobj.elem)[0:maxlen], file=filehandle) + write('// APIs', file=filehandle) + for key in self.apidict: + write(' API Version ', key, '->', + etree.tostring(self.apidict[key].elem)[0:maxlen], file=filehandle) + write('// Extensions', file=filehandle) + for key in self.extdict: + write(' Extension', key, '->', + etree.tostring(self.extdict[key].elem)[0:maxlen], file=filehandle) + write('// SPIR-V', file=filehandle) + for key in self.spirvextdict: + write(' SPIR-V Extension', key, '->', + etree.tostring(self.spirvextdict[key].elem)[0:maxlen], file=filehandle) + for key in self.spirvcapdict: + write(' SPIR-V Capability', key, '->', + etree.tostring(self.spirvcapdict[key].elem)[0:maxlen], file=filehandle) + write('// VkFormat', file=filehandle) + for key in self.formatsdict: + write(' VkFormat', key, '->', + etree.tostring(self.formatsdict[key].elem)[0:maxlen], file=filehandle) + + def markTypeRequired(self, typename, required): + """Require (along with its dependencies) or remove (but not its dependencies) a type. + + - typename - name of type + - required - boolean (to tag features as required or not) + """ + self.gen.logMsg('diag', 'tagging type:', typename, '-> required =', required) + + # Get TypeInfo object for tag corresponding to typename + typeinfo = self.lookupElementInfo(typename, self.typedict) + if typeinfo is not None: + if required: + # Tag type dependencies in 'alias' and 'required' attributes as + # required. This does not un-tag dependencies in a + # tag. See comments in markRequired() below for the reason. + for attrib_name in ['requires', 'alias']: + depname = typeinfo.elem.get(attrib_name) + if depname: + self.gen.logMsg('diag', 'Generating dependent type', + depname, 'for', attrib_name, 'type', typename) + # Do not recurse on self-referential structures. + if typename != depname: + self.markTypeRequired(depname, required) + else: + self.gen.logMsg('diag', 'type', typename, 'is self-referential') + # Tag types used in defining this type (e.g. in nested + # tags) + # Look for in entire tree, + # not just immediate children + for subtype in typeinfo.elem.findall('.//type'): + self.gen.logMsg('diag', 'markRequired: type requires dependent ', subtype.text) + if typename != subtype.text: + self.markTypeRequired(subtype.text, required) + else: + self.gen.logMsg('diag', 'type', typename, 'is self-referential') + # Tag enums used in defining this type, for example in + # member[MEMBER_SIZE] + for subenum in typeinfo.elem.findall('.//enum'): + self.gen.logMsg('diag', 'markRequired: type requires dependent ', subenum.text) + self.markEnumRequired(subenum.text, required) + # Tag type dependency in 'bitvalues' attributes as + # required. This ensures that the bit values for a flag + # are emitted + depType = typeinfo.elem.get('bitvalues') + if depType: + self.gen.logMsg('diag', 'Generating bitflag type', + depType, 'for type', typename) + self.markTypeRequired(depType, required) + group = self.lookupElementInfo(depType, self.groupdict) + if group is not None: + group.flagType = typeinfo + + typeinfo.required = required + elif '.h' not in typename: + self.gen.logMsg('warn', 'type:', typename, 'IS NOT DEFINED') + + def markEnumRequired(self, enumname, required): + """Mark an enum as required or not. + + - enumname - name of enum + - required - boolean (to tag features as required or not)""" + + self.gen.logMsg('diag', 'markEnumRequired: tagging enum:', enumname, '-> required =', required) + enum = self.lookupElementInfo(enumname, self.enumdict) + if enum is not None: + # If the enum is part of a group, and is being removed, then + # look it up in that tag and remove the Element there, + # so that it is not visible to generators (which traverse the + # tag elements rather than using the dictionaries). + if not required: + groupName = enum.elem.get('extends') + if groupName is not None: + self.gen.logMsg('diag', f'markEnumRequired: Removing extending enum {enum.elem.get("name")}') + + # Look up the Info with matching groupName + if groupName in self.groupdict: + gi = self.groupdict[groupName] + gienum = gi.elem.find(f"enum[@name='{enumname}']") + if gienum is not None: + # Remove copy of this enum from the group + gi.elem.remove(gienum) + else: + self.gen.logMsg('warn', 'markEnumRequired: Cannot remove enum', + enumname, 'not found in group', + groupName) + else: + self.gen.logMsg('warn', 'markEnumRequired: Cannot remove enum', + enumname, 'from nonexistent group', + groupName) + else: + # This enum is not an extending enum. + # The XML tree must be searched for all that + # might have it, so we know the parent to delete from. + + enumName = enum.elem.get('name') + + self.gen.logMsg('diag', f'markEnumRequired: Removing non-extending enum {enumName}') + + count = 0 + for enums in self.reg.findall('enums'): + for thisEnum in enums.findall('enum'): + if thisEnum.get('name') == enumName: + # Actually remove it + count = count + 1 + enums.remove(thisEnum) + + if count == 0: + self.gen.logMsg('warn', f'markEnumRequired: {enumName}) not found in any tag') + + enum.required = required + # Tag enum dependencies in 'alias' attribute as required + depname = enum.elem.get('alias') + if depname: + self.gen.logMsg('diag', 'markEnumRequired: Generating dependent enum', + depname, 'for alias', enumname, 'required =', enum.required) + self.markEnumRequired(depname, required) + else: + self.gen.logMsg('warn', f'markEnumRequired: {enumname} IS NOT DEFINED') + + def markCmdRequired(self, cmdname, required): + """Mark a command as required or not. + + - cmdname - name of command + - required - boolean (to tag features as required or not)""" + self.gen.logMsg('diag', 'tagging command:', cmdname, '-> required =', required) + cmd = self.lookupElementInfo(cmdname, self.cmddict) + if cmd is not None: + cmd.required = required + + # Tag command dependencies in 'alias' attribute as required + # + # This is usually not done, because command 'aliases' are not + # actual C language aliases like type and enum aliases. Instead + # they are just duplicates of the function signature of the + # alias. This means that there is no dependency of a command + # alias on what it aliases. One exception is validity includes, + # where the spec markup needs the promoted-to validity include + # even if only the promoted-from command is being built. + if self.genOpts.requireCommandAliases: + depname = cmd.elem.get('alias') + if depname: + self.gen.logMsg('diag', 'Generating dependent command', + depname, 'for alias', cmdname) + self.markCmdRequired(depname, required) + + # Tag all parameter types of this command as required. + # This does not remove types of commands in a + # tag, because many other commands may use the same type. + # We could be more clever and reference count types, + # instead of using a boolean. + if required: + # Look for in entire tree, + # not just immediate children + for type_elem in cmd.elem.findall('.//type'): + self.gen.logMsg('diag', 'markRequired: command implicitly requires dependent type', type_elem.text) + self.markTypeRequired(type_elem.text, required) + else: + self.gen.logMsg('warn', 'command:', cmdname, 'IS NOT DEFINED') + + def markRequired(self, featurename, feature, required): + """Require or remove features specified in the Element. + + - featurename - name of the feature + - feature - Element for `` or `` tag + - required - boolean (to tag features as required or not)""" + self.gen.logMsg('diag', 'markRequired (feature = , required =', required, ')') + + # Loop over types, enums, and commands in the tag + # @@ It would be possible to respect 'api' and 'profile' attributes + # in individual features, but that is not done yet. + for typeElem in feature.findall('type'): + self.markTypeRequired(typeElem.get('name'), required) + for enumElem in feature.findall('enum'): + self.markEnumRequired(enumElem.get('name'), required) + + for cmdElem in feature.findall('command'): + self.markCmdRequired(cmdElem.get('name'), required) + + # Extensions may need to extend existing commands or other items in the future. + # So, look for extend tags. + for extendElem in feature.findall('extend'): + extendType = extendElem.get('type') + if extendType == 'command': + commandName = extendElem.get('name') + successExtends = extendElem.get('successcodes') + if successExtends is not None: + for success in successExtends.split(','): + self.commandextensionsuccesses.append(self.commandextensiontuple(command=commandName, + value=success, + extension=featurename)) + errorExtends = extendElem.get('errorcodes') + if errorExtends is not None: + for error in errorExtends.split(','): + self.commandextensionerrors.append(self.commandextensiontuple(command=commandName, + value=error, + extension=featurename)) + else: + self.gen.logMsg('warn', 'extend type:', extendType, 'IS NOT SUPPORTED') + + def getAlias(self, elem, dict): + """Check for an alias in the same require block. + + - elem - Element to check for an alias""" + + # Try to find an alias + alias = elem.get('alias') + if alias is None: + name = elem.get('name') + typeinfo = self.lookupElementInfo(name, dict) + if not typeinfo: + self.gen.logMsg('error', name, 'is not a known name') + alias = typeinfo.elem.get('alias') + + return alias + + def checkForCorrectionAliases(self, alias, require, tag): + """Check for an alias in the same require block. + + - alias - String name of the alias + - require - `` block from the registry + - tag - tag to look for in the require block""" + + # For the time being, the code below is bypassed. It has the effect + # of excluding "spelling aliases" created to comply with the style + # guide, but this leaves references out of the specification and + # causes broken internal links. + # + # if alias and require.findall(tag + "[@name='" + alias + "']"): + # return True + + return False + + def fillFeatureDictionary(self, interface, featurename, api, profile): + """Capture added interfaces for a `` or ``. + + - interface - Element for `` or ``, containing + `` and `` tags + - featurename - name of the feature + - api - string specifying API name being generated + - profile - string specifying API profile being generated""" + + # Explicitly initialize known types - errors for unhandled categories + self.gen.featureDictionary[featurename] = { + "enumconstant": {}, + "command": {}, + "enum": {}, + "struct": {}, + "handle": {}, + "basetype": {}, + "include": {}, + "define": {}, + "bitmask": {}, + "union": {}, + "funcpointer": {}, + } + + # marks things that are required by this version/profile + for require in interface.findall('require'): + if matchAPIProfile(api, profile, require): + + # Determine the required extension or version needed for a require block + # Assumes that only one of these is specified + # 'extension', and therefore 'required_key', may be a boolean + # expression of extension names. + # 'required_key' is used only as a dictionary key at + # present, and passed through to the script generators, so + # they must be prepared to parse that boolean expression. + required_key = require.get('depends') + + # Loop over types, enums, and commands in the tag + for typeElem in require.findall('type'): + typename = typeElem.get('name') + typeinfo = self.lookupElementInfo(typename, self.typedict) + + if typeinfo: + # Remove aliases in the same extension/feature; these are always added as a correction. Do not need the original to be visible. + alias = self.getAlias(typeElem, self.typedict) + if not self.checkForCorrectionAliases(alias, require, 'type'): + # Resolve the type info to the actual type, so we get an accurate read for 'structextends' + while alias: + typeinfo = self.lookupElementInfo(alias, self.typedict) + if not typeinfo: + raise RuntimeError(f"Missing alias {alias}") + alias = typeinfo.elem.get('alias') + + typecat = typeinfo.elem.get('category') + typeextends = typeinfo.elem.get('structextends') + if not required_key in self.gen.featureDictionary[featurename][typecat]: + self.gen.featureDictionary[featurename][typecat][required_key] = {} + if not typeextends in self.gen.featureDictionary[featurename][typecat][required_key]: + self.gen.featureDictionary[featurename][typecat][required_key][typeextends] = [] + self.gen.featureDictionary[featurename][typecat][required_key][typeextends].append(typename) + else: + self.gen.logMsg('warn', f'fillFeatureDictionary: NOT filling for {typename}') + + + for enumElem in require.findall('enum'): + enumname = enumElem.get('name') + typeinfo = self.lookupElementInfo(enumname, self.enumdict) + + # Remove aliases in the same extension/feature; these are always added as a correction. Do not need the original to be visible. + alias = self.getAlias(enumElem, self.enumdict) + if not self.checkForCorrectionAliases(alias, require, 'enum'): + enumextends = enumElem.get('extends') + if not required_key in self.gen.featureDictionary[featurename]['enumconstant']: + self.gen.featureDictionary[featurename]['enumconstant'][required_key] = {} + if not enumextends in self.gen.featureDictionary[featurename]['enumconstant'][required_key]: + self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends] = [] + self.gen.featureDictionary[featurename]['enumconstant'][required_key][enumextends].append(enumname) + else: + self.gen.logMsg('warn', f'fillFeatureDictionary: NOT filling for {typename}') + + for cmdElem in require.findall('command'): + # Remove aliases in the same extension/feature; these are always added as a correction. Do not need the original to be visible. + alias = self.getAlias(cmdElem, self.cmddict) + if not self.checkForCorrectionAliases(alias, require, 'command'): + if not required_key in self.gen.featureDictionary[featurename]['command']: + self.gen.featureDictionary[featurename]['command'][required_key] = [] + self.gen.featureDictionary[featurename]['command'][required_key].append(cmdElem.get('name')) + else: + self.gen.logMsg('warn', f'fillFeatureDictionary: NOT filling for {typename}') + + def requireFeatures(self, interface, featurename, api, profile): + """Process `` tags for a `` or ``. + + - interface - Element for `` or ``, containing + `` tags + - featurename - name of the feature + - api - string specifying API name being generated + - profile - string specifying API profile being generated""" + + # marks things that are required by this version/profile + for feature in interface.findall('require'): + if matchAPIProfile(api, profile, feature): + self.markRequired(featurename, feature, True) + + def deprecateFeatures(self, interface, featurename, api, profile): + """Process `` tags for a `` or ``. + + - interface - Element for `` or ``, containing + `` tags + - featurename - name of the feature + - api - string specifying API name being generated + - profile - string specifying API profile being generated""" + + versionmatch = APIConventions().is_api_version_name(featurename) + + # marks things that are deprecated by this version/profile + for deprecation in interface.findall('deprecate'): + if matchAPIProfile(api, profile, deprecation): + for typeElem in deprecation.findall('type'): + type = self.lookupElementInfo(typeElem.get('name'), self.typedict) + if type: + if versionmatch is not False: + type.deprecatedbyversion = featurename + else: + type.deprecatedbyextensions.append(featurename) + type.deprecatedlink = deprecation.get('explanationlink') + else: + self.gen.logMsg('error', typeElem.get('name'), ' is tagged for deprecation but not present in registry') + for enumElem in deprecation.findall('enum'): + enum = self.lookupElementInfo(enumElem.get('name'), self.enumdict) + if enum: + if versionmatch is not False: + enum.deprecatedbyversion = featurename + else: + enum.deprecatedbyextensions.append(featurename) + enum.deprecatedlink = deprecation.get('explanationlink') + else: + self.gen.logMsg('error', enumElem.get('name'), ' is tagged for deprecation but not present in registry') + for cmdElem in deprecation.findall('command'): + cmd = self.lookupElementInfo(cmdElem.get('name'), self.cmddict) + if cmd: + if versionmatch is not False: + cmd.deprecatedbyversion = featurename + else: + cmd.deprecatedbyextensions.append(featurename) + cmd.deprecatedlink = deprecation.get('explanationlink') + else: + self.gen.logMsg('error', cmdElem.get('name'), ' is tagged for deprecation but not present in registry') + + def removeFeatures(self, interface, featurename, api, profile): + """Process `` tags for a `` or ``. + + - interface - Element for `` or ``, containing + `` tags + - featurename - name of the feature + - api - string specifying API name being generated + - profile - string specifying API profile being generated""" + + # marks things that are removed by this version/profile + for feature in interface.findall('remove'): + if matchAPIProfile(api, profile, feature): + self.markRequired(featurename, feature, False) + + def assignAdditionalValidity(self, interface, api, profile): + # Loop over all usage inside all tags. + for feature in interface.findall('require'): + if matchAPIProfile(api, profile, feature): + for v in feature.findall('usage'): + if v.get('command'): + self.cmddict[v.get('command')].additionalValidity.append(copy.deepcopy(v)) + if v.get('struct'): + self.typedict[v.get('struct')].additionalValidity.append(copy.deepcopy(v)) + + def removeAdditionalValidity(self, interface, api, profile): + # Loop over all usage inside all tags. + for feature in interface.findall('remove'): + if matchAPIProfile(api, profile, feature): + for v in feature.findall('usage'): + if v.get('command'): + self.cmddict[v.get('command')].removedValidity.append(copy.deepcopy(v)) + if v.get('struct'): + self.typedict[v.get('struct')].removedValidity.append(copy.deepcopy(v)) + + def generateFeature(self, fname, ftype, dictionary, explicit=False): + """Generate a single type / enum group / enum / command, + and all its dependencies as needed. + + - fname - name of feature (``/``/``) + - ftype - type of feature, 'type' | 'enum' | 'command' + - dictionary - of *Info objects - self.{type|enum|cmd}dict + - explicit - True if this is explicitly required by the top-level + XML tag, False if it is a dependency of an explicit + requirement.""" + + self.gen.logMsg('diag', 'generateFeature: generating', ftype, fname) + + if not (explicit or self.genOpts.requireDepends): + self.gen.logMsg('diag', 'generateFeature: NOT generating', ftype, fname, 'because generator does not require dependencies') + return + + f = self.lookupElementInfo(fname, dictionary) + if f is None: + # No such feature. This is an error, but reported earlier + self.gen.logMsg('diag', 'No entry found for feature', fname, + 'returning!') + return + + # If feature is not required, or has already been declared, return + if not f.required: + self.gen.logMsg('diag', 'Skipping', ftype, fname, '(not required)') + return + if f.declared: + self.gen.logMsg('diag', 'Skipping', ftype, fname, '(already declared)') + return + # Always mark feature declared, as though actually emitted + f.declared = True + + # Determine if this is an alias, and of what, if so + alias = f.elem.get('alias') + if alias: + self.gen.logMsg('diag', fname, 'is an alias of', alias) + + # Pull in dependent declaration(s) of the feature. + # For types, there may be one type in the 'requires' attribute of + # the element, one in the 'alias' attribute, and many in + # embedded and tags within the element. + # For commands, there may be many in tags within the element. + # For enums, no dependencies are allowed (though perhaps if you + # have a uint64 enum, it should require that type). + genProc = None + followupFeature = None + if ftype == 'type': + genProc = self.gen.genType + + # Generate type dependencies in 'alias' and 'requires' attributes + if alias: + self.generateFeature(alias, 'type', self.typedict) + requires = f.elem.get('requires') + if requires: + self.gen.logMsg('diag', 'Generating required dependent type', + requires) + self.generateFeature(requires, 'type', self.typedict) + + # Generate types used in defining this type (e.g. in nested + # tags) + # Look for in entire tree, + # not just immediate children + for subtype in f.elem.findall('.//type'): + self.gen.logMsg('diag', 'Generating required dependent ', + subtype.text) + self.generateFeature(subtype.text, 'type', self.typedict) + + # Generate enums used in defining this type, for example in + # member[MEMBER_SIZE] + for subtype in f.elem.findall('.//enum'): + self.gen.logMsg('diag', 'Generating required dependent ', + subtype.text) + self.generateFeature(subtype.text, 'enum', self.enumdict) + + # If the type is an enum group, look up the corresponding + # group in the group dictionary and generate that instead. + if f.elem.get('category') == 'enum': + self.gen.logMsg('diag', 'Type', fname, 'is an enum group, so generate that instead') + group = self.lookupElementInfo(fname, self.groupdict) + if alias is not None: + # An alias of another group name. + # Pass to genGroup with 'alias' parameter = aliased name + self.gen.logMsg('diag', 'Generating alias', fname, + 'for enumerated type', alias) + # Now, pass the *aliased* GroupInfo to the genGroup, but + # with an additional parameter which is the alias name. + genProc = self.gen.genGroup + f = self.lookupElementInfo(alias, self.groupdict) + elif group is None: + self.gen.logMsg('warn', 'Skipping enum type', fname, + ': No matching enumerant group') + return + else: + genProc = self.gen.genGroup + f = group + + # @ The enum group is not ready for generation. At this + # @ point, it contains all tags injected by + # @ tags without any verification of whether + # @ they are required or not. It may also contain + # @ duplicates injected by multiple consistent + # @ definitions of an . + + # @ Pass over each enum, marking its enumdict[] entry as + # @ required or not. Mark aliases of enums as required, + # @ too. + + enums = group.elem.findall('enum') + + self.gen.logMsg('diag', 'generateFeature: checking enums for group', fname) + + # Check for required enums, including aliases + # LATER - Check for, report, and remove duplicates? + enumAliases = [] + for elem in enums: + name = elem.get('name') + + required = False + + extname = elem.get('extname') + version = elem.get('version') + if extname is not None: + # 'supported' attribute was injected when the element was + # moved into the group in Registry.parseTree() + supported_list = elem.get('supported').split(",") + if self.genOpts.defaultExtensions in supported_list: + required = True + elif re.match(self.genOpts.addExtensions, extname) is not None: + required = True + elif version is not None: + required = re.match(self.genOpts.emitversions, version) is not None + else: + required = True + + self.gen.logMsg('diag', '* required =', required, 'for', name) + if required: + # Mark this element as required (in the element, not the EnumInfo) + elem.set('required', 'true') + # If it is an alias, track that for later use + enumAlias = elem.get('alias') + if enumAlias: + enumAliases.append(enumAlias) + for elem in enums: + name = elem.get('name') + if name in enumAliases: + elem.set('required', 'true') + self.gen.logMsg('diag', '* also need to require alias', name) + if f is None: + raise RuntimeError("Should not get here") + if f.elem.get('category') == 'bitmask': + followupFeature = f.elem.get('bitvalues') + elif ftype == 'command': + # Generate command dependencies in 'alias' attribute + if alias: + self.generateFeature(alias, 'command', self.cmddict) + + genProc = self.gen.genCmd + for type_elem in f.elem.findall('.//type'): + depname = type_elem.text + self.gen.logMsg('diag', 'Generating required parameter type', + depname) + self.generateFeature(depname, 'type', self.typedict) + elif ftype == 'enum': + # Generate enum dependencies in 'alias' attribute + if alias: + self.generateFeature(alias, 'enum', self.enumdict) + genProc = self.gen.genEnum + + # Actually generate the type only if emitting declarations + if self.emitFeatures: + self.gen.logMsg('diag', 'Emitting', ftype, 'decl for', fname) + if genProc is None: + raise RuntimeError("genProc is None when we should be emitting") + genProc(f, fname, alias) + else: + self.gen.logMsg('diag', 'Skipping', ftype, fname, + '(should not be emitted)') + + if followupFeature: + self.gen.logMsg('diag', 'Generating required bitvalues ', + followupFeature) + self.generateFeature(followupFeature, "type", self.typedict) + + def generateRequiredInterface(self, interface): + """Generate all interfaces required by an API version or extension. + + - interface - Element for `` or ``""" + + # Loop over all features inside all tags. + for features in interface.findall('require'): + for t in features.findall('type'): + self.generateFeature(t.get('name'), 'type', self.typedict, explicit=True) + for e in features.findall('enum'): + # If this is an enum extending an enumerated type, do not + # generate it - this has already been done in reg.parseTree, + # by copying this element into the enumerated type. + enumextends = e.get('extends') + if not enumextends: + self.generateFeature(e.get('name'), 'enum', self.enumdict, explicit=True) + for c in features.findall('command'): + self.generateFeature(c.get('name'), 'command', self.cmddict, explicit=True) + + def generateSpirv(self, spirv, dictionary): + if spirv is None: + self.gen.logMsg('diag', 'No entry found for element', name, + 'returning!') + return + + name = spirv.elem.get('name') + # No known alias for spirv elements + alias = None + if spirv.emit: + genProc = self.gen.genSpirv + genProc(spirv, name, alias) + + def stripUnsupportedAPIs(self, dictionary, attribute, supportedDictionary): + """Strip unsupported APIs from attributes of APIs. + dictionary - *Info dictionary of APIs to be updated + attribute - attribute name to look for in each API + supportedDictionary - dictionary in which to look for supported + API elements in the attribute""" + + for key in dictionary: + eleminfo = dictionary[key] + attribstring = eleminfo.elem.get(attribute) + if attribstring is not None: + apis = [] + stripped = False + for api in attribstring.split(','): + ##print('Checking API {} referenced by {}'.format(api, key)) + if api in supportedDictionary and supportedDictionary[api].required: + apis.append(api) + else: + stripped = True + ##print('\t**STRIPPING API {} from {}'.format(api, key)) + + # Update the attribute after stripping stuff. + # Could sort apis before joining, but it is not a clear win + if stripped: + eleminfo.elem.set(attribute, ','.join(apis)) + + def stripUnsupportedAPIsFromList(self, dictionary, supportedDictionary): + """Strip unsupported APIs from attributes of APIs. + dictionary - dictionary of list of structure name strings + supportedDictionary - dictionary in which to look for supported + API elements in the attribute""" + + for key in dictionary: + attribstring = dictionary[key] + if attribstring is not None: + apis = [] + stripped = False + for api in attribstring: + ##print('Checking API {} referenced by {}'.format(api, key)) + if supportedDictionary[api].required: + apis.append(api) + else: + stripped = True + ##print('\t**STRIPPING API {} from {}'.format(api, key)) + + # Update the attribute after stripping stuff. + # Could sort apis before joining, but it is not a clear win + if stripped: + dictionary[key] = apis + + def generateFormat(self, format, dictionary): + if format is None: + self.gen.logMsg('diag', 'No entry found for format element', + 'returning!') + return + + name = format.elem.get('name') + # No known alias for VkFormat elements + alias = None + if format.emit: + genProc = self.gen.genFormat + genProc(format, name, alias) + + def generateSyncStage(self, sync): + genProc = self.gen.genSyncStage + genProc(sync) + + def generateSyncAccess(self, sync): + genProc = self.gen.genSyncAccess + genProc(sync) + + def generateSyncPipeline(self, sync): + genProc = self.gen.genSyncPipeline + genProc(sync) + + def tagValidExtensionStructs(self): + """Construct a "validextensionstructs" list for parent structures + based on "structextends" tags in child structures. + Only do this for structures tagged as required.""" + + for typeinfo in self.typedict.values(): + type_elem = typeinfo.elem + if typeinfo.required and type_elem.get('category') == 'struct': + struct_extends = type_elem.get('structextends') + if struct_extends is not None: + for parent in struct_extends.split(','): + # self.gen.logMsg('diag', type_elem.get('name'), 'extends', parent) + self.validextensionstructs[parent].append(type_elem.get('name')) + + # Sort the lists so they do not depend on the XML order + for parent in self.validextensionstructs: + self.validextensionstructs[parent].sort() + + def apiGen(self): + """Generate interface for specified versions using the current + generator and generator options""" + + self.gen.logMsg('diag', '*******************************************') + self.gen.logMsg('diag', ' Registry.apiGen file:', self.genOpts.filename, + 'api:', self.genOpts.apiname, + 'profile:', self.genOpts.profile) + self.gen.logMsg('diag', '*******************************************') + + # Could reset required/declared flags for all features here. + # This has been removed as never used. The initial motivation was + # the idea of calling apiGen() repeatedly for different targets, but + # this has never been done. The 20% or so build-time speedup that + # might result is not worth the effort to make it actually work. + # + # self.apiReset() + + # Compile regexps used to select versions & extensions + regVersions = re.compile(self.genOpts.versions) + regEmitVersions = re.compile(self.genOpts.emitversions) + regAddExtensions = re.compile(self.genOpts.addExtensions) + regRemoveExtensions = re.compile(self.genOpts.removeExtensions) + regEmitExtensions = re.compile(self.genOpts.emitExtensions) + regEmitSpirv = re.compile(self.genOpts.emitSpirv) + regEmitFormats = re.compile(self.genOpts.emitFormats) + + # Get all matching API feature names & add to list of FeatureInfo + # Note we used to select on feature version attributes, not names. + features = [] + apiMatch = False + for key in self.apidict: + fi = self.apidict[key] + api = fi.elem.get('api') + if apiNameMatch(self.genOpts.apiname, api): + apiMatch = True + if regVersions.match(fi.name): + # Matches API & version #s being generated. Mark for + # emission and add to the features[] list . + # @@ Could use 'declared' instead of 'emit'? + fi.emit = (regEmitVersions.match(fi.name) is not None) + features.append(fi) + if not fi.emit: + self.gen.logMsg('diag', 'NOT tagging feature api =', api, + 'name =', fi.name, 'version =', fi.version, + 'for emission (does not match emitversions pattern)') + else: + self.gen.logMsg('diag', 'Including feature api =', api, + 'name =', fi.name, 'version =', fi.version, + 'for emission (matches emitversions pattern)') + else: + self.gen.logMsg('diag', 'NOT including feature api =', api, + 'name =', fi.name, 'version =', fi.version, + '(does not match requested versions)') + else: + self.gen.logMsg('diag', 'NOT including feature api =', api, + 'name =', fi.name, + '(does not match requested API)') + if not apiMatch: + self.gen.logMsg('warn', 'No matching API versions found!') + + # Get all matching extensions, in order by their extension number, + # and add to the list of features. + # Start with extensions whose 'supported' attributes match the API + # being generated. Add extensions matching the pattern specified in + # regExtensions, then remove extensions matching the pattern + # specified in regRemoveExtensions + for (extName, ei) in sorted(self.extdict.items(), key=lambda x: x[1].number if x[1].number is not None else '0'): + extName = ei.name + include = False + + # Include extension if defaultExtensions is not None and is + # exactly matched by the 'supported' attribute. + if apiNameMatch(self.genOpts.defaultExtensions, + ei.elem.get('supported')): + self.gen.logMsg('diag', 'Including extension', + extName, "(defaultExtensions matches the 'supported' attribute)") + include = True + + # Include additional extensions if the extension name matches + # the regexp specified in the generator options. This allows + # forcing extensions into an interface even if they are not + # tagged appropriately in the registry. + # However, we still respect the 'supported' attribute. + if regAddExtensions.match(extName) is not None: + if not apiNameMatch(self.genOpts.apiname, ei.elem.get('supported')): + self.gen.logMsg('diag', 'NOT including extension', + extName, '(matches explicitly requested, but does not match the \'supported\' attribute)') + include = False + else: + self.gen.logMsg('diag', 'Including extension', + extName, '(matches explicitly requested extensions to add)') + include = True + # Remove extensions if the name matches the regexp specified + # in generator options. This allows forcing removal of + # extensions from an interface even if they are tagged that + # way in the registry. + if regRemoveExtensions.match(extName) is not None: + self.gen.logMsg('diag', 'Removing extension', + extName, '(matches explicitly requested extensions to remove)') + include = False + + # If the extension is to be included, add it to the + # extension features list. + if include: + ei.emit = (regEmitExtensions.match(extName) is not None) + features.append(ei) + if not ei.emit: + self.gen.logMsg('diag', 'NOT tagging extension', + extName, + 'for emission (does not match emitextensions pattern)') + + # Hack - can be removed when validity generator goes away + # (Jon) I am not sure what this does, or if it should + # respect the ei.emit flag above. + self.requiredextensions.append(extName) + else: + self.gen.logMsg('diag', 'NOT including extension', + extName, '(does not match api attribute or explicitly requested extensions)') + + # Add all spirv elements to list + # generators decide to emit them all or not + # Currently no filtering as no client of these elements needs filtering + spirvexts = [] + for key in self.spirvextdict: + si = self.spirvextdict[key] + si.emit = (regEmitSpirv.match(key) is not None) + spirvexts.append(si) + spirvcaps = [] + for key in self.spirvcapdict: + si = self.spirvcapdict[key] + si.emit = (regEmitSpirv.match(key) is not None) + spirvcaps.append(si) + + formats = [] + for key in self.formatsdict: + si = self.formatsdict[key] + si.emit = (regEmitFormats.match(key) is not None) + formats.append(si) + + # Sort the features list, if a sort procedure is defined + if self.genOpts.sortProcedure: + self.genOpts.sortProcedure(features) + + # Passes 1+2: loop over requested API versions and extensions tagging + # types/commands/features as required (in an block) or no + # longer required (in an block). s are processed + # after all s, so removals win. + # If a profile other than 'None' is being generated, it must + # match the profile attribute (if any) of the and + # tags. + self.gen.logMsg('diag', 'PASS 1: TAG FEATURES') + for f in features: + self.gen.logMsg('diag', 'PASS 1: Tagging required and features for', f.name) + self.fillFeatureDictionary(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile) + self.requireFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile) + self.deprecateFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile) + self.assignAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile) + + for f in features: + self.gen.logMsg('diag', 'PASS 2: Tagging removed features for', f.name) + self.removeFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile) + self.removeAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile) + + # Now, strip references to APIs that are not required. + # At present such references may occur in: + # Structs in 'structextends' attributes + # Enums in 'successcodes' and 'errorcodes' attributes + self.stripUnsupportedAPIs(self.typedict, 'structextends', self.typedict) + self.stripUnsupportedAPIs(self.cmddict, 'successcodes', self.enumdict) + self.stripUnsupportedAPIs(self.cmddict, 'errorcodes', self.enumdict) + self.stripUnsupportedAPIsFromList(self.validextensionstructs, self.typedict) + + # Construct lists of valid extension structures + self.tagValidExtensionStructs() + + # @@May need to strip / + # tags of these forms: + # + # + # + # + + # Pass 3: loop over specified API versions and extensions printing + # declarations for required things which have not already been + # generated. + self.gen.logMsg('diag', 'PASS 3: GENERATE INTERFACES FOR FEATURES') + self.gen.beginFile(self.genOpts) + for f in features: + self.gen.logMsg('diag', 'PASS 3: Generating interface for', + f.name) + emit = self.emitFeatures = f.emit + if not emit: + self.gen.logMsg('diag', 'PASS 3: NOT declaring feature', + f.elem.get('name'), 'because it is not tagged for emission') + # Generate the interface (or just tag its elements as having been + # emitted, if they have not been). + self.gen.beginFeature(f.elem, emit) + self.generateRequiredInterface(f.elem) + self.gen.endFeature() + # Generate spirv elements + for s in spirvexts: + self.generateSpirv(s, self.spirvextdict) + for s in spirvcaps: + self.generateSpirv(s, self.spirvcapdict) + for s in formats: + self.generateFormat(s, self.formatsdict) + for s in self.syncstagedict: + self.generateSyncStage(self.syncstagedict[s]) + for s in self.syncaccessdict: + self.generateSyncAccess(self.syncaccessdict[s]) + for s in self.syncpipelinedict: + self.generateSyncPipeline(self.syncpipelinedict[s]) + self.gen.endFile() + + def apiReset(self): + """Reset type/enum/command dictionaries before generating another API. + + Use between apiGen() calls to reset internal state.""" + for datatype in self.typedict: + self.typedict[datatype].resetState() + for enum in self.enumdict: + self.enumdict[enum].resetState() + for cmd in self.cmddict: + self.cmddict[cmd].resetState() + for cmd in self.apidict: + self.apidict[cmd].resetState() diff --git a/libs/VulkanHeaders/spec_tools/__init__.py b/libs/VulkanHeaders/spec_tools/__init__.py new file mode 100644 index 0000000000..e1b15c5bc0 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 -i +# +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik diff --git a/libs/VulkanHeaders/spec_tools/algo.py b/libs/VulkanHeaders/spec_tools/algo.py new file mode 100644 index 0000000000..4bb0bf96b5 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/algo.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 -i +# +# Copyright (c) 2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik +"""RecursiveMemoize serves as a base class for a function modeled +as a dictionary computed on-the-fly.""" + + +class RecursiveMemoize: + """Base class for functions that are recursive. + + Derive and implement `def compute(self, key):` to perform the computation: + you may use __getitem__ (aka self[otherkey]) to access the results for + another key. Each value will be computed at most once. Your + function should never return None, since it is used as a sentinel here. + + """ + + def __init__(self, func, key_iterable=None, permit_cycles=False): + """Initialize data structures, and optionally compute/cache the answer + for all elements of an iterable. + + If permit_cycles is False, then __getitem__ on something that's + currently being computed raises an exception. + If permit_cycles is True, then __getitem__ on something that's + currently being computed returns None. + """ + self._compute = func + self.permit_cycles = permit_cycles + self.d = {} + if key_iterable: + # If we were given an iterable, let's populate those. + for key in key_iterable: + _ = self[key] + + def __getitem__(self, key): + """Access the result of computing the function on the input. + + Performed lazily and cached. + Implement `def compute(self, key):` with the actual function, + which will be called on demand.""" + if key in self.d: + ret = self.d[key] + # Detect "we're computing this" sentinel and + # fail if cycles not permitted + if ret is None and not self.permit_cycles: + raise RuntimeError("Cycle detected when computing function: " + + f"f({key}) depends on itself") + # return the memoized value + # (which might be None if we're in a cycle that's permitted) + return ret + + # Set sentinel for "we're computing this" + self.d[key] = None + # Delegate to function to actually compute + ret = self._compute(key) + # Memoize + self.d[key] = ret + + return ret + + def get_dict(self): + """Return the dictionary where memoized results are stored. + + DO NOT MODIFY!""" + return self.d + + +def longest_common_prefix(strings): + """ + Find the longest common prefix of a list of 2 or more strings. + + Args: + strings (collection): at least 2 strings. + + Returns: + string: The longest string that all submitted strings start with. + + >>> longest_common_prefix(["abcd", "abce"]) + 'abc' + + """ + assert len(strings) > 1 + a = min(strings) + b = max(strings) + prefix = [] + for a_char, b_char in zip(a, b): + if a_char == b_char: + prefix.append(a_char) + else: + break + return "".join(prefix) + + +def longest_common_token_prefix(strings, delimiter='_'): + """ + Find the longest common token-wise prefix of a list of 2 or more strings. + + Args: + strings (collection): at least 2 strings. + delimiter (character): the character to split on. + + Returns: + string: The longest string that all submitted strings start with. + + >>> longest_common_token_prefix(["xr_abc_123", "xr_abc_567"]) + 'xr_abc_' + + "1" is in the per-character longest common prefix, but 123 != 135, + so it's not in the per-token prefix. + + >>> longest_common_token_prefix(["xr_abc_123", "xr_abc_135"]) + 'xr_abc_' + + Here, the prefix is actually the entirety of one string, so no trailing delimiter. + + >>> longest_common_token_prefix(["xr_abc_123", "xr_abc"]) + 'xr_abc' + + + No common prefix here, because it's per-token: + + >>> longest_common_token_prefix(["abc_123", "ab_123"]) + '' + + """ + assert len(strings) > 1 + a = min(strings).split(delimiter) + b = max(strings).split(delimiter) + prefix_tokens = [] + for a_token, b_token in zip(a, b): + if a_token == b_token: + prefix_tokens.append(a_token) + else: + break + if prefix_tokens: + prefix = delimiter.join(prefix_tokens) + if len(prefix_tokens) < min(len(a), len(b)): + # This is truly a prefix, not just one of the strings. + prefix += delimiter + return prefix + return '' diff --git a/libs/VulkanHeaders/spec_tools/attributes.py b/libs/VulkanHeaders/spec_tools/attributes.py new file mode 100644 index 0000000000..60ebcd6b77 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/attributes.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 +"""Utilities for working with attributes of the XML registry.""" + +import re + +_PARAM_REF_NAME_RE = re.compile( + r"(?P[\w]+)(?P\[\])?(?P\.|::|->)?") + + +def _split_param_ref(val): + return [name for name, _, _ in _PARAM_REF_NAME_RE.findall(val)] + + +def _human_readable_deref(val, make_param_name=None): + """Turn the "name[].member[]" notation into plain English.""" + parts = [] + matches = _PARAM_REF_NAME_RE.findall(val) + for name, brackets, delim in reversed(matches): + if make_param_name: + name = make_param_name(name) + if delim: + parts.append('member of') + if brackets: + parts.append('each element of') + parts.append('the') + parts.append(name) + parts.append('parameter') + return ' '.join(parts) + + +class LengthEntry: + """An entry in a (comma-separated) len attribute""" + NULL_TERMINATED_STRING = 'null-terminated' + MATH_STRING = 'latexmath:' + + def __init__(self, val): + self.full_reference = val + self.other_param_name = None + self.null_terminated = False + self.number = None + self.math = None + self.param_ref_parts = None + if val == LengthEntry.NULL_TERMINATED_STRING: + self.null_terminated = True + return + + if val.startswith(LengthEntry.MATH_STRING): + self.math = val.replace(LengthEntry.MATH_STRING, '')[1:-1] + return + + if val.isdigit(): + self.number = int(val) + return + + # Must be another param name. + self.param_ref_parts = _split_param_ref(val) + self.other_param_name = self.param_ref_parts[0] + + def __str__(self): + return self.full_reference + + def get_human_readable(self, make_param_name=None): + assert self.other_param_name + return _human_readable_deref(self.full_reference, make_param_name=make_param_name) + + def __repr__(self): + "Formats an object for repr(), debugger display, etc." + return f'spec_tools.attributes.LengthEntry("{self.full_reference}")' + + @staticmethod + def parse_len_from_param(param): + """Get a list of LengthEntry, or None.""" + len_str = param.get('len') + if len_str is None: + return None + return [LengthEntry(elt) for elt in len_str.split(',')] + + +class ExternSyncEntry: + """An entry in a (comma-separated) externsync attribute""" + + def __init__(self, val): + # externsync will be 'true', 'maybe', '' or 'maybe:' + is_true = val == 'true' + is_maybe = val == 'maybe' + is_maybe_subtype = val.startswith('maybe:') + + if is_maybe_subtype: + val = val.removeprefix('maybe:') + + self.full_reference = val + # If 'true' or 'maybe', externsync applies to the entire parameter + self.entirely_extern_sync = is_true or is_maybe + # If 'maybe' or 'maybe:', externsync applies to a member of the parameter only + self.conditionally_extern_sync = is_maybe or is_maybe_subtype + if self.entirely_extern_sync: + return + + # Parse the expression to separate the param name from the member of that param + self.param_ref_parts = _split_param_ref(val) + self.member = self.param_ref_parts[0] + + def get_human_readable(self, make_param_name=None): + assert not self.entirely_extern_sync + return _human_readable_deref(self.full_reference, make_param_name=make_param_name) + + @staticmethod + def parse_externsync_from_param(param): + """Get a list of ExternSyncEntry.""" + sync_str = param.get('externsync') + if sync_str is None: + return None + return [ExternSyncEntry(elt) for elt in sync_str.split(',')] + + def __repr__(self): + "Formats an object for repr(), debugger display, etc." + return f'spec_tools.attributes.ExternSyncEntry("{self.full_reference}")' + + +_TRUE_STRING = 'true' +_FALSE_STRING = 'false' + + +def _parse_optional_elt(val): + if val not in (_TRUE_STRING, _FALSE_STRING): + raise ValueError("Each element of the optional attribute must be 'true', or 'false'") + return val == _TRUE_STRING + + +def parse_optional_from_param(param): + """Get a list of booleans from a param: always returns at least one element.""" + optional_str = param.get('optional', _FALSE_STRING) + return [_parse_optional_elt(elt) for elt in optional_str.split(',')] + + +def has_any_optional_in_param(param): + """Returns True if we have any true in an optional attribute.""" + return any(parse_optional_from_param(param)) diff --git a/libs/VulkanHeaders/spec_tools/base_printer.py b/libs/VulkanHeaders/spec_tools/base_printer.py new file mode 100644 index 0000000000..ab18e506a8 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/base_printer.py @@ -0,0 +1,213 @@ +"""Provides the BasePrinter base class for MacroChecker/Message output techniques.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +from abc import ABC, abstractmethod +from pathlib import Path + +from .macro_checker import MacroChecker +from .macro_checker_file import MacroCheckerFile +from .shared import EntityData, Message, MessageContext, MessageType + + +def getColumn(message_context): + """Return the (zero-based) column number of the message context. + + If a group is specified: returns the column of the start of the group. + If no group, but a match is specified: returns the column of the start of + the match. + If no match: returns column 0 (whole line). + """ + if not message_context.match: + # whole line + return 0 + if message_context.group is not None: + return message_context.match.start(message_context.group) + return message_context.match.start() + + +class BasePrinter(ABC): + """Base class for a way of outputting results of a checker execution.""" + + def __init__(self): + """Constructor.""" + self._cwd = None + + def close(self): + """Write the tail end of the output and close it, if applicable. + + Override if you want to print a summary or are writing to a file. + """ + pass + + ### + # Output methods: these should all print/output directly. + def output(self, obj): + """Output any object. + + Delegates to other output* methods, if type known, + otherwise uses self.outputFallback(). + """ + if isinstance(obj, Message): + self.outputMessage(obj) + elif isinstance(obj, MacroCheckerFile): + self.outputCheckerFile(obj) + elif isinstance(obj, MacroChecker): + self.outputChecker(obj) + else: + self.outputFallback(self.formatBrief(obj)) + + @abstractmethod + def outputResults(self, checker, broken_links=True, + missing_includes=False): + """Output the full results of a checker run. + + Must be implemented. + + Typically will call self.output() on the MacroChecker, + as well as calling self.outputBrokenAndMissing() + """ + raise NotImplementedError + + @abstractmethod + def outputBrokenLinks(self, checker, broken): + """Output the collection of broken links. + + `broken` is a dictionary of entity names: usage contexts. + + Must be implemented. + + Called by self.outputBrokenAndMissing() if requested. + """ + raise NotImplementedError + + @abstractmethod + def outputMissingIncludes(self, checker, missing): + """Output a table of missing includes. + + `missing` is a iterable entity names. + + Must be implemented. + + Called by self.outputBrokenAndMissing() if requested. + """ + raise NotImplementedError + + def outputChecker(self, checker): + """Output the contents of a MacroChecker object. + + Default implementation calls self.output() on every MacroCheckerFile. + """ + for f in checker.files: + self.output(f) + + def outputCheckerFile(self, fileChecker): + """Output the contents of a MacroCheckerFile object. + + Default implementation calls self.output() on every Message. + """ + for m in fileChecker.messages: + self.output(m) + + def outputBrokenAndMissing(self, checker, broken_links=True, + missing_includes=False): + """Outputs broken links and missing includes, if desired. + + Delegates to self.outputBrokenLinks() (if broken_links==True) + and self.outputMissingIncludes() (if missing_includes==True). + """ + if broken_links: + broken = checker.getBrokenLinks() + if broken: + self.outputBrokenLinks(checker, broken) + if missing_includes: + missing = checker.getMissingUnreferencedApiIncludes() + if missing: + self.outputMissingIncludes(checker, missing) + + @abstractmethod + def outputMessage(self, msg): + """Output a Message. + + Must be implemented. + """ + raise NotImplementedError + + @abstractmethod + def outputFallback(self, msg): + """Output some text in a general way. + + Must be implemented. + """ + raise NotImplementedError + + ### + # Format methods: these should all return a string. + def formatContext(self, context, _message_type=None): + """Format a message context in a verbose way, if applicable. + + May override, default implementation delegates to + self.formatContextBrief(). + """ + return self.formatContextBrief(context) + + def formatContextBrief(self, context, _with_color=True): + """Format a message context in a brief way. + + May override, default is relativeFilename:line:column + """ + return '{}:{}:{}'.format(self.getRelativeFilename(context.filename), + context.lineNum, getColumn(context)) + + def formatMessageTypeBrief(self, message_type, _with_color=True): + """Format a message type in a brief way. + + May override, default is message_type: + """ + return f'{message_type}:' + + def formatEntityBrief(self, entity_data, _with_color=True): + """Format an entity in a brief way. + + May override, default is macro:entity. + """ + return f'{entity_data.macro}:{entity_data.entity}' + + def formatBrief(self, obj, with_color=True): + """Format any object in a brief way. + + Delegates to other format*Brief methods, if known, + otherwise uses str(). + """ + if isinstance(obj, MessageContext): + return self.formatContextBrief(obj, with_color) + if isinstance(obj, MessageType): + return self.formatMessageTypeBrief(obj, with_color) + if isinstance(obj, EntityData): + return self.formatEntityBrief(obj, with_color) + return str(obj) + + @property + def cwd(self): + """Get the current working directory, fully resolved. + + Lazy initialized. + """ + if not self._cwd: + self._cwd = Path('.').resolve() + return self._cwd + + ### + # Helper function + def getRelativeFilename(self, fn): + """Return the given filename relative to the current directory, + if possible. + """ + try: + return str(Path(fn).relative_to(self.cwd)) + except ValueError: + return str(Path(fn)) diff --git a/libs/VulkanHeaders/spec_tools/consistency_tools.py b/libs/VulkanHeaders/spec_tools/consistency_tools.py new file mode 100644 index 0000000000..de03c089b8 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/consistency_tools.py @@ -0,0 +1,864 @@ +#!/usr/bin/env python3 -i +# +# Copyright (c) 2019 Collabora, Ltd. +# Copyright 2018-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik +"""Provides utilities to write a script to verify XML registry consistency.""" + +import re +from typing import Set + +import networkx as nx +from networkx.algorithms import shortest_path + +from .algo import RecursiveMemoize +from .attributes import ExternSyncEntry, LengthEntry +from .data_structures import DictOfStringSets +from .util import findNamedElem, getElemName, getElemType +from .conventions import ConventionsBase + + +def _get_extension_tags(reg): + """Get a set of all author tags registered for use.""" + return set(elt.get("name") for elt in reg.tree.findall("./tags/tag[@name]")) + + +class XMLChecker: + def __init__(self, entity_db, conventions: ConventionsBase, manual_types_to_codes=None, + forward_only_types_to_codes=None, + reverse_only_types_to_codes=None, + suppressions=None, + display_warnings=True): + """Set up data structures. + + May extend - call: + `super().__init__(db, conventions, manual_types_to_codes)` + as the last statement in your function. + + manual_types_to_codes is a dictionary of hard-coded + "manual" return codes: + the codes of the value are available for a command if-and-only-if + the key type is passed as an input. + + forward_only_types_to_codes is additional entries to the above + that should only be used in the "forward" direction + (arg type implies return code) + + reverse_only_types_to_codes is additional entries to + manual_types_to_codes that should only be used in the + "reverse" direction + (return code implies arg type) + """ + self.fail = False + self.entity = None + self.errors = DictOfStringSets() + self.warnings = DictOfStringSets() + self.db = entity_db + self.reg = entity_db.registry + self.handle_data = HandleData(self.reg) + self.conventions = conventions + self.display_warnings = display_warnings + + self.CONST_RE = re.compile(r"\bconst\b") + self.ARRAY_RE = re.compile(r"\[[^]]+\]") + + # Init memoized properties + self._handle_data = None + + if not manual_types_to_codes: + manual_types_to_codes = {} + if not reverse_only_types_to_codes: + reverse_only_types_to_codes = {} + if not forward_only_types_to_codes: + forward_only_types_to_codes = {} + + reverse_codes = DictOfStringSets(reverse_only_types_to_codes) + forward_codes = DictOfStringSets(forward_only_types_to_codes) + for k, v in manual_types_to_codes.items(): + forward_codes.add(k, v) + reverse_codes.add(k, v) + + self.forward_only_manual_types_to_codes = forward_codes.get_dict() + self.reverse_only_manual_types_to_codes = reverse_codes.get_dict() + + # The presence of some types as input to a function imply the + # availability of some return codes. + self.input_type_to_codes = compute_type_to_codes( + self.handle_data, + forward_codes, + extra_op=self.add_extra_codes) + + # Some return codes require a type (or its child) in the input. + self.codes_requiring_input_type = compute_codes_requiring_type( + self.handle_data, + reverse_codes + ) + + specified_codes = set(self.codes_requiring_input_type.keys()) + for codes in self.forward_only_manual_types_to_codes.values(): + specified_codes.update(codes) + for codes in self.reverse_only_manual_types_to_codes.values(): + specified_codes.update(codes) + for codes in self.input_type_to_codes.values(): + specified_codes.update(codes) + + unrecognized = [code for code in specified_codes if not self.is_enum_value(code, 'VkResult')] + if len(unrecognized) > 0: + raise RuntimeError("Return code mentioned in script that isn't in the registry: " + + ', '.join(unrecognized)) + + self.referenced_input_types = ReferencedTypes(self.db, self.is_input) + self.referenced_types = ReferencedTypes(self.db) + if not suppressions: + suppressions = {} + self.suppressions = DictOfStringSets(suppressions) + self.tags = _get_extension_tags(self.db.registry) + + def is_api_type(self, member_elem): + """Return true if the member/parameter ElementTree passed is from this API. + + May override or extend.""" + membertext = "".join(member_elem.itertext()) + + return self.conventions.type_prefix in membertext + + def is_input(self, member_elem): + """Return true if the member/parameter ElementTree passed is + considered "input". + + May override or extend.""" + membertext = "".join(member_elem.itertext()) + + if self.conventions.type_prefix not in membertext: + return False + + ret = True + # Const is always input. + if self.CONST_RE.search(membertext): + ret = True + + # Arrays and pointers that aren't const are always output. + elif "*" in membertext: + ret = False + elif self.ARRAY_RE.search(membertext): + ret = False + + return ret + + def is_enum_value(self, value, expected_type): + if value not in self.reg.enumvaluedict: + return False + + enumtype = self.reg.enumvaluedict[value] + if enumtype in self.reg.aliasdict: + enumtype = self.reg.aliasdict + return enumtype == expected_type + + def strip_extension_tag(self, name): + """Remove a single author tag from the end of a name, if any. + + Returns the stripped name and the tag, or the input and None if there was no tag. + """ + # Author tag can be suffixed with experimental version + name_no_experimental = re.sub("X[0-9]*$", "", name) + + for t in self.tags: + if ( + self.conventions.allows_x_number_suffix + and name_no_experimental.endswith(t) + ): + name = name_no_experimental + + if name.endswith(t): + name = name[:-(len(t))] + if name[-1] == "_": + # remove trailing underscore + name = name[:-1] + return name, t + return name, None + + def add_extra_codes(self, types_to_codes): + """Add any desired entries to the types-to-codes DictOfStringSets + before performing "ancestor propagation". + + Passed to compute_type_to_codes as the extra_op. + + May override.""" + pass + + def should_skip_checking_codes(self, name): + """Return True if more than the basic validation of return codes should + be skipped for a command. + + May override.""" + + return self.conventions.should_skip_checking_codes + + def get_codes_for_command_and_type(self, cmd_name, type_name): + """Return a set of return codes expected due to having + an input argument of type type_name. + + The cmd_name is passed for use by extending methods. + Note that you should not use cmd_name to add codes, just to + filter them out. See get_required_codes_for_command() to do that. + + May extend.""" + return self.input_type_to_codes.get(type_name, set()) + + def get_required_codes_for_command(self, cmd_name): + """Return a set of return codes required due to having a particular name. + + May override.""" + return set() + + def get_forbidden_codes_for_command(self, cmd_name): + """Return a set of return codes not permittted due to having a particular name. + + May override.""" + return set() + + def check(self): + """Iterate through the registry, looking for consistency problems. + + Outputs error messages at the end.""" + # Iterate through commands, looking for consistency problems. + for name, info in self.reg.cmddict.items(): + self.set_error_context(entity=name, elem=info.elem) + + self.check_command(name, info) + + for name, info in self.reg.typedict.items(): + cat = info.elem.get('category') + if not cat: + # This is an external thing, skip it. + continue + self.set_error_context(entity=name, elem=info.elem) + + self.check_type(name, info, cat) + + self.ext_numbers = set() + for name, info in self.reg.extdict.items(): + self.set_error_context(entity=name, elem=info.elem) + + # Determine if this extension is supported by the API we're + # testing, and pass that flag to check_extension. + # For Vulkan, multiple APIs can be specified in the 'supported' + # attribute. + supported_apis = info.elem.get('supported', '').split(',') + supported = self.conventions.xml_api_name in supported_apis + self.check_extension(name, info, supported) + + self.check_format() + + entities_with_messages = set( + self.errors.keys()).union(self.warnings.keys()) + if entities_with_messages: + print('xml_consistency/consistency_tools error and warning messages follow.') + + # Track whether warnings were issued (and not printed) to avoid lots of noise + warning_flag = False + + for entity in entities_with_messages: + # Track whether header for this entity was printed + header_done = False + def msg_header(entity, done): + if not done: + print() + print('-------------------') + print('Messages for', entity) + print() + return True + + messages = self.errors.get(entity) + if messages: + header_done = msg_header(entity, header_done) + + for m in messages: + print('Error:', m) + + messages = self.warnings.get(entity) + if messages: + if self.display_warnings: + header_done = msg_header(entity, header_done) + + for m in messages: + print('Warning:', m) + else: + warning_flag = True + + # If not displaying warnings, but they existed, acknowledge that + if not self.display_warnings and warning_flag: + print('Warnings found, but were not printed - try using "xml_consistency.py -warn" or "check_spec_links.py --include_warn"') + + + def check_param(self, param): + """Check a member of a struct or a param of a function. + + Called from check_params. + + May extend.""" + param_name = getElemName(param) + # Make sure there's something between the type and the name + # Can't just look at the .tail of for some reason, + # so instead we look to see if anything's between + # type's text and name's text in the itertext. + # If there's no text between the tags, there will be no string + # between those tags' text in itertext() + text_parts = list(param.itertext()) + type_idx = text_parts.index(getElemType(param)) + name_idx = text_parts.index(param_name) + if name_idx - type_idx == 1: + self.record_error( + "Space (or other delimiter text) missing between and for param/member named", + param_name) + + # Check external sync entries + externsyncs = ExternSyncEntry.parse_externsync_from_param(param) + if externsyncs: + for entry in externsyncs: + if len(externsyncs) > 1: + self.record_error("externsync attribute cannot be a comma-separated list", + param_name) + if not entry.entirely_extern_sync: + # member name + # TODO only looking at the superficial feature here, + # not entry.param_ref_parts + if entry.member != param_name: + self.record_error("externsync attribute for", param_name, + "refers to some other member/parameter:", entry.member) + + def check_params(self, params): + """Check the members of a struct or params of a function. + + Called from check_type and check_command. + + May extend.""" + for param in params: + self.check_param(param) + + # Check for parameters referenced by len= attribute + lengths = LengthEntry.parse_len_from_param(param) + if lengths: + for entry in lengths: + if not entry.other_param_name: + continue + # TODO only looking at the superficial feature here, + # not entry.param_ref_parts + other_param = findNamedElem(params, entry.other_param_name) + if other_param is None: + self.record_error("References a non-existent parameter/member in the length of", + getElemName(param), ":", entry.other_param_name) + + def check_referenced_type(self, desc, ref_name): + """ + Record an error if a type mentioned somewhere doesn't exist. + + :param desc: Description of where this type reference was found, + for the error message. + :param ref_name: The name of the referenced type. If false-ish (incl. None), + checking is skipped, so OK to pass the results of + info.elem.get() directly + """ + if ref_name: + entity = self.db.findEntity(ref_name) + if not entity: + self.record_error("Unknown type named in", desc, ":", + ref_name) + + def check_type(self, name, info, category): + """Check a type's XML data for consistency. + + Called from check. + + May extend.""" + if category == 'struct': + if not name.startswith(self.conventions.type_prefix): + self.record_error("Name does not start with", + self.conventions.type_prefix) + members = info.elem.findall('member') + self.check_params(members) + + # Check the structure type member, if present. + type_member = findNamedElem( + members, self.conventions.structtype_member_name) + if type_member is not None: + val = type_member.get('values') + if val: + expected = self.conventions.generate_structure_type_from_name( + name) + if val != expected: + self.record_error("Type has incorrect type-member value: expected", + expected, "got", val) + + # Check structextends attribute, if present. + # For Vulkan, this may be a comma-separated list of multiple types + for type in info.elem.get("structextends", '').split(','): + self.check_referenced_type("'structextends' attribute", type) + + # Check parentstruct attribute, if present. + self.check_referenced_type("'parentstruct' attribute", info.elem.get("parentstruct")) + + elif category == "bitmask": + if 'Flags' not in name: + self.record_error("Name of bitmask doesn't include 'Flags'") + elif category == "handle": + # Check parent attribute, if present. + self.check_referenced_type("'parent' attribute", info.elem.get("parent")) + + def check_extension(self, name, info, supported): + """Check an extension's XML data for consistency. + + Called from check. + + May extend.""" + + # Verify that each extension has a unique number + extension_number = info.elem.get('number') + if extension_number is not None and extension_number != '0': + if extension_number in self.ext_numbers: + self.record_error(f"Duplicate extension number {extension_number}") + else: + self.ext_numbers.add(extension_number) + + def check_format(self): + """Check an extension's XML data for consistency. + + Called from check. + + May extend.""" + pass + + def check_command(self, name, info): + """Check a command's XML data for consistency. + + Called from check. + + May extend.""" + elem = info.elem + + self.check_params(elem.findall('param')) + + # Some minimal return code checking + errorcodes = elem.get("errorcodes") + if errorcodes: + errorcodes = errorcodes.split(",") + else: + errorcodes = [] + + successcodes = elem.get("successcodes") + if successcodes: + successcodes = successcodes.split(",") + else: + successcodes = [] + + if not successcodes and not errorcodes: + # Early out if no return codes. + return + + # Create a set for each group of codes, and check that + # they aren't duplicated within or between groups. + errorcodes_set = set(errorcodes) + if len(errorcodes) != len(errorcodes_set): + self.record_error("Contains a duplicate in errorcodes") + + successcodes_set = set(successcodes) + if len(successcodes) != len(successcodes_set): + self.record_error("Contains a duplicate in successcodes") + + if not successcodes_set.isdisjoint(errorcodes_set): + self.record_error("Has errorcodes and successcodes that overlap") + + self.check_command_return_codes_basic( + name, info, successcodes_set, errorcodes_set) + + # Continue to further return code checking if not "complicated" + if not self.should_skip_checking_codes(name): + codes_set = successcodes_set.union(errorcodes_set) + self.check_command_return_codes( + name, info, successcodes_set, errorcodes_set, codes_set) + + def check_command_return_codes_basic(self, name, info, + successcodes, errorcodes): + """Check a command's return codes for consistency. + + Called from check_command on every command. + + May extend.""" + + # Check that all error codes include _ERROR_, + # and that no success codes do. + for code in errorcodes: + if "_ERROR_" not in code: + self.record_error( + code, "in errorcodes but doesn't contain _ERROR_") + + for code in successcodes: + if "_ERROR_" in code: + self.record_error(code, "in successcodes but contain _ERROR_") + + def check_command_return_codes(self, name, type_info, + successcodes, errorcodes, + codes): + """Check a command's return codes in-depth for consistency. + + Called from check_command, only if + `self.should_skip_checking_codes(name)` is False. + + May extend.""" + referenced_input = self.referenced_input_types[name] + referenced_types = self.referenced_types[name] + error_prefix = f"{self.conventions.api_prefix}ERROR" + + bad_success = {x for x in successcodes if x.startswith(error_prefix)} + if bad_success: + self.record_error("Found error code(s)", + ",".join(bad_success), + "listed in the successcodes attributes") + + bad_errors = {x for x in errorcodes if not x.startswith(error_prefix)} + if bad_errors: + self.record_error("Found success code(s)", + ",".join(bad_errors), + "listed in the errorcodes attributes") + + # Check that we have all the codes we expect, based on input types. + for referenced_type in referenced_input: + required_codes = self.get_codes_for_command_and_type( + name, referenced_type) + missing_codes = required_codes - codes + if missing_codes: + path = self.referenced_input_types.shortest_path( + name, referenced_type) + path_str = " -> ".join(path) + self.record_error("Missing expected return code(s)", + ",".join(missing_codes), + "implied because of input of type", + referenced_type, + "found via path", + path_str) + + # Check that we have all the codes we expect based on command name. + missing_codes = self.get_required_codes_for_command(name) - codes + if missing_codes: + self.record_error("Missing expected return code(s)", + ",".join(missing_codes), + "implied because of the name of this command") + + # Check that we don't have any codes forbidden based on command name. + forbidden = self.get_forbidden_codes_for_command(name).intersection(codes) + if forbidden: + self.record_error("Got return code(s)", + ", ".join(forbidden), + "that were forbidden due to the name of this command") + + # Check that, for each code returned by this command that we can + # associate with a type, we have some type that can provide it. + # e.g. can't have INSTANCE_LOST without an Instance + # (or child of Instance). + for code in codes: + + required_types = self.codes_requiring_input_type.get(code) + if not required_types: + # This code doesn't have a known requirement + continue + + # TODO: do we look at referenced_types or referenced_input here? + # the latter is stricter + if not referenced_types.intersection(required_types): + self.record_error("Unexpected return code", code, + "- none of these types:", + required_types, + "found in the set of referenced types", + referenced_types) + + ### + # Utility properties/methods + ### + + def set_error_context(self, entity=None, elem=None): + """Set the entity and/or element for future record_error calls.""" + self.entity = entity + self.elem = elem + self.name = getElemName(elem) + self.entity_suppressions = self.suppressions.get(getElemName(elem)) + + def record_error(self, *args, **kwargs): + """Record failure and an error message for the current context.""" + message = " ".join((str(x) for x in args)) + + if self._is_message_suppressed(message): + return + + message = self._prepend_sourceline_to_message(message, **kwargs) + self.fail = True + self.errors.add(self.entity, message) + + def record_warning(self, *args, **kwargs): + """Record a warning message for the current context.""" + message = " ".join((str(x) for x in args)) + + if self._is_message_suppressed(message): + return + + message = self._prepend_sourceline_to_message(message, **kwargs) + self.warnings.add(self.entity, message) + + def _is_message_suppressed(self, message): + """Return True if the given message, for this entity, should be suppressed.""" + if not self.entity_suppressions: + return False + for suppress in self.entity_suppressions: + if suppress in message: + return True + + return False + + def _prepend_sourceline_to_message(self, message, **kwargs): + """Prepend a file and/or line reference to the message, if possible. + + If filename is given as a keyword argument, it is used on its own. + + If filename is not given, this will attempt to retrieve the filename and line from an XML element. + If 'elem' is given as a keyword argument and is not None, it is used to find the line. + If 'elem' is given as None, no XML elements are looked at. + If 'elem' is not supplied, the error context element is used. + + If using XML, the filename, if available, is retrieved from the Registry class. + If using XML and python-lxml is installed, the source line is retrieved from whatever element is chosen.""" + fn = kwargs.get('filename') + sourceline = None + + if fn is None: + elem = kwargs.get('elem', self.elem) + if elem is not None: + sourceline = getattr(elem, 'sourceline', None) + if self.reg.filename: + fn = self.reg.filename + + if fn is None and sourceline is None: + return message + + if fn is None: + return f"Line {sourceline}: {message}" + + if sourceline is None: + return f"{fn}: {message}" + + return f"{fn}:{sourceline}: {message}" + + +class HandleParents(RecursiveMemoize): + def __init__(self, handle_types): + self.handle_types = handle_types + + def compute(handle_type): + immediate_parent = self.handle_types[handle_type].elem.get( + 'parent') + + if immediate_parent is None: + # No parents, no need to recurse + return [] + + # Support multiple (alternate) parents + immediate_parents = immediate_parent.split(',') + + # Recurse, combine, and return + all_parents = immediate_parents[:] + for parent in immediate_parents: + all_parents.extend(self[parent]) + return all_parents + + super().__init__(compute, handle_types.keys()) + + +def _always_true(x): + return True + + +class ReferencedTypes(RecursiveMemoize): + """Find all types(optionally matching a predicate) that are referenced + by a struct or function, recursively.""" + + def __init__(self, db, predicate=None): + """Initialize. + + Provide an EntityDB object and a predicate function.""" + self.db = db + + self.predicate = predicate + if not self.predicate: + # Default predicate is "anything goes" + self.predicate = _always_true + + self._directly_referenced = {} + self.graph = nx.DiGraph() + + def compute(type_name): + """Compute and return all types referenced by type_name, recursively, that satisfy the predicate. + + Called by the [] operator in the base class.""" + types = self.directly_referenced(type_name) + if not types: + return types + + all_types = set() + all_types.update(types) + for t in types: + referenced = self[t] + if referenced is not None: + # If not leading to a cycle + all_types.update(referenced) + return all_types + + # Initialize base class + super().__init__(compute, permit_cycles=True) + + def shortest_path(self, source, target): + """Get the shortest path between one type/function name and another.""" + # Trigger computation + _ = self[source] + + return shortest_path(self.graph, source=source, target=target) + + def directly_referenced(self, type_name): + """Get all types referenced directly by type_name that satisfy the predicate. + + Memoizes its results.""" + if type_name not in self._directly_referenced: + members = self.db.getMemberElems(type_name) + if members: + types = ((member, member.find("type")) for member in members) + self._directly_referenced[type_name] = set(type_elem.text for (member, type_elem) in types + if type_elem is not None and self.predicate(member)) + + else: + self._directly_referenced[type_name] = set() + children = self.db.childTypes(type_name) + if children: + self._directly_referenced[type_name].update(children) + # Update graph + self.graph.add_node(type_name) + self.graph.add_edges_from((type_name, t) + for t in self._directly_referenced[type_name]) + + return self._directly_referenced[type_name] + + +class HandleData: + """Data about all the handle types available in an API specification.""" + + def __init__(self, registry): + self.reg = registry + self._handle_types = None + self._ancestors = None + self._descendants = None + + @property + def handle_types(self): + """Return a dictionary of handle type names to type info.""" + if not self._handle_types: + # First time requested - compute it. + self._handle_types = { + type_name: type_info + for type_name, type_info in self.reg.typedict.items() + if type_info.elem.get('category') == 'handle' + } + return self._handle_types + + @property + def ancestors_dict(self): + """Return a dictionary of handle type names to sets of ancestors.""" + if not self._ancestors: + # First time requested - compute it. + self._ancestors = HandleParents(self.handle_types).get_dict() + return self._ancestors + + @property + def descendants_dict(self): + """Return a dictionary of handle type names to sets of descendants.""" + if not self._descendants: + # First time requested - compute it. + + handle_parents = self.ancestors_dict + + def get_descendants(handle): + return set(h for h in handle_parents.keys() + if handle in handle_parents[h]) + + self._descendants = { + h: get_descendants(h) + for h in handle_parents.keys() + } + return self._descendants + + +def compute_type_to_codes(handle_data, types_to_codes, extra_op=None): + """Compute a DictOfStringSets of input type to required return codes. + + - handle_data is a HandleData instance. + - d is a dictionary of type names to strings or string collections of + return codes. + - extra_op, if any, is called after populating the output from the input + dictionary, but before propagation of parent codes to child types. + extra_op is called with the in-progress DictOfStringSets. + + Returns a DictOfStringSets of input type name to set of required return + code names. + """ + # Initialize with the supplied "manual" codes + types_to_codes = DictOfStringSets(types_to_codes) + + # Dynamically generate more codes, if desired + if extra_op: + extra_op(types_to_codes) + + # Final post-processing + + # Any handle can result in its parent handle's codes too. + + handle_ancestors = handle_data.ancestors_dict + + extra_handle_codes = {} + for handle_type, ancestors in handle_ancestors.items(): + # The sets of return codes corresponding to each ancestor type. + ancestors_codes = [types_to_codes.get(ancestor, set()) + for ancestor in ancestors] + extra_handle_codes[handle_type] = set().union(*ancestors_codes) + + for handle_type, extras in extra_handle_codes.items(): + types_to_codes.add(handle_type, extras) + + return types_to_codes + + +def compute_codes_requiring_type(handle_data, types_to_codes, registry=None): + """Compute a DictOfStringSets of return codes to a set of input types able + to provide the ability to generate that code. + + handle_data is a HandleData instance. + d is a dictionary of input types to associated return codes(same format + as for input to compute_type_to_codes, may use same dict). + This will invert that relationship, and also permit any "child handles" + to satisfy a requirement for a parent in producing a code. + + Returns a DictOfStringSets of return code name to the set of parameter + types that would allow that return code. + """ + # Use DictOfStringSets to normalize the input into a dict with values + # that are sets of strings + in_dict = DictOfStringSets(types_to_codes) + + handle_descendants = handle_data.descendants_dict + + out = DictOfStringSets() + for in_type, code_set in in_dict.items(): + descendants = handle_descendants.get(in_type) + for code in code_set: + out.add(code, in_type) + if descendants: + out.add(code, descendants) + + return out diff --git a/libs/VulkanHeaders/spec_tools/console_printer.py b/libs/VulkanHeaders/spec_tools/console_printer.py new file mode 100644 index 0000000000..7125a87fd9 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/console_printer.py @@ -0,0 +1,273 @@ +"""Defines ConsolePrinter, a BasePrinter subclass for appealing console output.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +from sys import stdout + +from .base_printer import BasePrinter +from .shared import (colored, getHighlightedRange, getInterestedRange, + toNameAndLine) + +try: + from tabulate import tabulate_impl + HAVE_TABULATE = True +except ImportError: + HAVE_TABULATE = False + + +def colWidth(collection, columnNum): + """Compute the required width of a column in a collection of row-tuples.""" + MIN_PADDING = 5 + return MIN_PADDING + max((len(row[columnNum]) for row in collection)) + + +def alternateTabulate(collection, headers=None): + """Minimal re-implementation of the tabulate module.""" + # We need a list, not a generator or anything else. + if not isinstance(collection, list): + collection = list(collection) + + # Empty collection means no table + if not collection: + return None + + if headers is None: + fullTable = collection + else: + underline = ['-' * len(header) for header in headers] + fullTable = [headers, underline] + collection + widths = [colWidth(collection, colNum) + for colNum in range(len(fullTable[0]))] + widths[-1] = None + + lines = [] + for row in fullTable: + fields = [] + for data, width in zip(row, widths): + if width: + spaces = ' ' * (width - len(data)) + fields.append(data + spaces) + else: + fields.append(data) + lines.append(''.join(fields)) + return '\n'.join(lines) + + +def printTabulated(collection, headers=None): + """Call either tabulate.tabulate(), or our internal alternateTabulate().""" + if HAVE_TABULATE: + tabulated = tabulate_impl(collection, headers=headers) + else: + tabulated = alternateTabulate(collection, headers=headers) + if tabulated: + print(tabulated) + + +def printLineSubsetWithHighlighting( + line, start, end, highlightStart=None, highlightEnd=None, maxLen=120, replacement=None): + """Print a (potential subset of a) line, with highlighting/underline and optional replacement. + + Will print at least the characters line[start:end], and potentially more if possible + to do so without making the output too wide. + Will highlight (underline) line[highlightStart:highlightEnd], where the default + value for highlightStart is simply start, and the default value for highlightEnd is simply end. + replacement, if supplied, will be aligned with the highlighted range. + + Output is intended to look like part of a Clang compile error/warning message. + """ + # Fill in missing start/end with start/end of range. + if highlightStart is None: + highlightStart = start + if highlightEnd is None: + highlightEnd = end + + # Expand interested range start/end. + start = min(start, highlightStart) + end = max(end, highlightEnd) + + tildeLength = highlightEnd - highlightStart - 1 + caretLoc = highlightStart + continuation = '[...]' + + if len(line) > maxLen: + # Too long + + # the max is to handle -1 from .find() (which indicates "not found") + followingSpaceIndex = max(end, line.find(' ', min(len(line), end + 1))) + + # Maximum length has decreased by at least + # the length of a single continuation we absolutely need. + maxLen -= len(continuation) + + if followingSpaceIndex <= maxLen: + # We can grab the whole beginning of the line, + # and not adjust caretLoc + line = line[:maxLen] + continuation + + elif (len(line) - followingSpaceIndex) < 5: + # We need to truncate the beginning, + # but we're close to the end of line. + newBeginning = len(line) - maxLen + + caretLoc += len(continuation) + caretLoc -= newBeginning + line = continuation + line[newBeginning:] + else: + # Need to truncate the beginning of the string too. + newEnd = followingSpaceIndex + + # Now we need two continuations + # (and to adjust caret to the right accordingly) + maxLen -= len(continuation) + caretLoc += len(continuation) + + newBeginning = newEnd - maxLen + caretLoc -= newBeginning + + line = continuation + line[newBeginning:newEnd] + continuation + + stdout.buffer.write(line.encode('utf-8')) + print() + + spaces = ' ' * caretLoc + tildes = '~' * tildeLength + print(spaces + colored(f"^{tildes}", 'green')) + if replacement is not None: + print(spaces + colored(replacement, 'green')) + + +class ConsolePrinter(BasePrinter): + """Implementation of BasePrinter for generating diagnostic reports in colored, helpful console output.""" + + def __init__(self): + self.show_script_location = False + super().__init__() + + ### + # Output methods: these all print directly. + def outputResults(self, checker, broken_links=True, + missing_includes=False): + """Output the full results of a checker run. + + Includes the diagnostics, broken links (if desired), + and missing includes (if desired). + """ + self.output(checker) + if broken_links: + broken = checker.getBrokenLinks() + if broken: + self.outputBrokenLinks(checker, broken) + if missing_includes: + missing = checker.getMissingUnreferencedApiIncludes() + if missing: + self.outputMissingIncludes(checker, missing) + + def outputBrokenLinks(self, checker, broken): + """Output a table of broken links. + + Called by self.outputBrokenAndMissing() if requested. + """ + print('Missing API includes that are referenced by a linking macro: these result in broken links in the spec!') + + def makeRowOfBroken(entity, uses): + fn = checker.findEntity(entity).filename + anchor = f'[[{entity}]]' + locations = ', '.join((toNameAndLine(context, root_path=checker.root_path) + for context in uses)) + return (fn, anchor, locations) + printTabulated((makeRowOfBroken(entity, uses) + for entity, uses in sorted(broken.items())), + headers=['Include File', 'Anchor in lieu of include', 'Links to this entity']) + + def outputMissingIncludes(self, checker, missing): + """Output a table of missing includes. + + Called by self.outputBrokenAndMissing() if requested. + """ + missing = list(sorted(missing)) + if not missing: + # Exit if none + return + print( + 'Missing, but unreferenced, API includes/anchors - potentially not-documented entities:') + + def makeRowOfMissing(entity): + fn = checker.findEntity(entity).filename + anchor = f'[[{entity}]]' + return (fn, anchor) + printTabulated((makeRowOfMissing(entity) for entity in missing), + headers=['Include File', 'Anchor in lieu of include']) + + def outputMessage(self, msg): + """Output a Message, with highlighted range and replacement, if appropriate.""" + highlightStart, highlightEnd = getHighlightedRange(msg.context) + + if '\n' in msg.context.filename: + # This is a multi-line string "filename". + # Extra blank line and delimiter line for readability: + print() + print('--------------------------------------------------------------------') + + fileAndLine = colored(f'{self.formatBrief(msg.context)}:', attrs=['bold']) + + headingSize = len('{context}: {mtype}: '.format( + context=self.formatBrief(msg.context), + mtype=self.formatBrief(msg.message_type, False))) + indent = ' ' * headingSize + printedHeading = False + + lines = msg.message[:] + if msg.see_also: + lines.append('See also:') + lines.extend((f' {self.formatBrief(see)}' + for see in msg.see_also)) + + if msg.fix: + lines.append('Note: Auto-fix available') + + for line in msg.message: + if not printedHeading: + scriptloc = '' + if msg.script_location and self.show_script_location: + scriptloc = f", {msg.script_location}" + print('{fileLine} {mtype} {msg} (-{arg}{loc})'.format( + fileLine=fileAndLine, mtype=msg.message_type.formattedWithColon(), + msg=colored(line, attrs=['bold']), arg=msg.message_id.enable_arg(), loc=scriptloc)) + printedHeading = True + else: + print(colored(indent + line, attrs=['bold'])) + + if len(msg.message) > 1: + # extra blank line after multiline message + print('') + + start, end = getInterestedRange(msg.context) + printLineSubsetWithHighlighting( + msg.context.line, + start, end, + highlightStart, highlightEnd, + replacement=msg.replacement) + + def outputFallback(self, obj): + """Output by calling print.""" + print(obj) + + ### + # Format methods: these all return a string. + def formatFilename(self, fn, _with_color=True): + """Format a local filename, as a relative path if possible.""" + return self.getRelativeFilename(fn) + + def formatMessageTypeBrief(self, message_type, with_color=True): + """Format a message type briefly, applying color if desired and possible. + + Delegates to the superclass if not formatting with color. + """ + if with_color: + return message_type.formattedWithColon() + return super(ConsolePrinter, self).formatMessageTypeBrief( + message_type, with_color) diff --git a/libs/VulkanHeaders/spec_tools/conventions.py b/libs/VulkanHeaders/spec_tools/conventions.py new file mode 100644 index 0000000000..7d827caaa3 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/conventions.py @@ -0,0 +1,562 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +# Base class for working-group-specific style conventions, +# used in generation. + +from enum import Enum +import abc +import re + +# Type categories that respond "False" to isStructAlwaysValid +# basetype is home to typedefs like ..Bool32 +CATEGORIES_REQUIRING_VALIDATION = set(('handle', + 'enum', + 'bitmask', + 'basetype', + None)) + +# These are basic C types pulled in via openxr_platform_defines.h +TYPES_KNOWN_ALWAYS_VALID = set(('char', + 'float', + 'int8_t', 'uint8_t', + 'int16_t', 'uint16_t', + 'int32_t', 'uint32_t', + 'int64_t', 'uint64_t', + 'size_t', + 'intptr_t', 'uintptr_t', + 'int', + )) + +# Split an extension name into vendor ID and name portions +EXT_NAME_DECOMPOSE_RE = re.compile(r'(?P[A-Za-z]+)_(?P[A-Za-z]+)_(?P[\w_]+)') + +# Match an API version name. +# Match object includes API prefix, major, and minor version numbers. +# This could be refined further for specific APIs. +API_VERSION_NAME_RE = re.compile(r'(?P[A-Za-z]+)_VERSION_(?P[0-9]+)_(?P[0-9]+)') + +class ProseListFormats(Enum): + """A connective, possibly with a quantifier.""" + AND = 0 + EACH_AND = 1 + OR = 2 + ANY_OR = 3 + + @classmethod + def from_string(cls, s): + if s == 'or': + return cls.OR + if s == 'and': + return cls.AND + raise RuntimeError(f"Unrecognized string connective: {s}") + + @property + def connective(self): + if self in (ProseListFormats.OR, ProseListFormats.ANY_OR): + return 'or' + return 'and' + + def quantifier(self, n): + """Return the desired quantifier for a list of a given length.""" + if self == ProseListFormats.ANY_OR: + if n > 1: + return 'any of ' + elif self == ProseListFormats.EACH_AND: + if n > 2: + return 'each of ' + if n == 2: + return 'both of ' + return '' + + +class ConventionsBase(abc.ABC): + """WG-specific conventions.""" + + def __init__(self): + self._command_prefix = None + self._type_prefix = None + + def formatVersionOrExtension(self, name): + """Mark up an API version or extension name as a link in the spec.""" + + # Is this a version name? + match = API_VERSION_NAME_RE.match(name) + if match is not None: + return self.formatVersion(name, + match.group('apivariant'), + match.group('major'), + match.group('minor')) + else: + # If not, assumed to be an extension name. Might be worth checking. + return self.formatExtension(name) + + def formatVersion(self, name, apivariant, major, minor): + """Mark up an API version name as a link in the spec.""" + return f'`<<{name}>>`' + + def formatExtension(self, name): + """Mark up an extension name as a link in the spec.""" + return f'`<<{name}>>`' + + def formatSPIRVlink(self, name): + """Mark up a SPIR-V extension name as an external link in the spec. + Since these are external links, the formatting probably will be + the same for all APIs creating such links, so long as they use + the asciidoctor {spirv} attribute for the base path to the SPIR-V + extensions.""" + + (vendor, _) = self.extension_name_split(name) + + return f'{{spirv}}/{vendor}/{name}.html[{name}]' + + @property + @abc.abstractmethod + def null(self): + """Preferred spelling of NULL.""" + raise NotImplementedError + + def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs): + """Make a (comma-separated) list for use in prose. + + Adds a connective (by default, 'and') + before the last element if there are more than 1. + + Adds the right one of "is" or "are" to the end if with_verb is true. + + Optionally adds a quantifier (like 'any') before a list of 2 or more, + if specified by fmt. + + Override with a different method or different call to + _implMakeProseList if you want to add a comma for two elements, + or not use a serial comma. + """ + return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs) + + @property + def struct_macro(self): + """Get the appropriate format macro for a structure. + + May override. + """ + return 'slink:' + + @property + def external_macro(self): + """Get the appropriate format macro for an external type like uint32_t. + + May override. + """ + return 'code:' + + @property + def allows_x_number_suffix(self): + """Whether vendor tags can be suffixed with X and a number to mark experimental extensions.""" + return False + + @property + @abc.abstractmethod + def structtype_member_name(self): + """Return name of the structure type member. + + Must implement. + """ + raise NotImplementedError() + + @property + @abc.abstractmethod + def nextpointer_member_name(self): + """Return name of the structure pointer chain member. + + Must implement. + """ + raise NotImplementedError() + + @property + @abc.abstractmethod + def xml_api_name(self): + """Return the name used in the default API XML registry for the default API""" + raise NotImplementedError() + + @abc.abstractmethod + def generate_structure_type_from_name(self, structname): + """Generate a structure type name, like XR_TYPE_CREATE_INSTANCE_INFO. + + Must implement. + """ + raise NotImplementedError() + + def makeStructName(self, name): + """Prepend the appropriate format macro for a structure to a structure type name. + + Uses struct_macro, so just override that if you want to change behavior. + """ + return self.struct_macro + name + + def makeExternalTypeName(self, name): + """Prepend the appropriate format macro for an external type like uint32_t to a type name. + + Uses external_macro, so just override that if you want to change behavior. + """ + return self.external_macro + name + + def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True): + """Internal-use implementation to make a (comma-separated) list for use in prose. + + Adds a connective (by default, 'and') + before the last element if there are more than 1, + and only includes commas if there are more than 2 + (if comma_for_two_elts is False). + + Adds the right one of "is" or "are" to the end if with_verb is true. + + Optionally adds a quantifier (like 'any') before a list of 2 or more, + if specified by fmt. + + Do not edit these defaults, override self.makeProseList(). + """ + assert serial_comma # did not implement what we did not need + if isinstance(fmt, str): + fmt = ProseListFormats.from_string(fmt) + + my_elts = list(elements) + if len(my_elts) > 1: + my_elts[-1] = f'{fmt.connective} {my_elts[-1]}' + + if not comma_for_two_elts and len(my_elts) <= 2: + prose = ' '.join(my_elts) + else: + prose = ', '.join(my_elts) + + quantifier = fmt.quantifier(len(my_elts)) + + parts = [quantifier, prose] + + if with_verb: + if len(my_elts) > 1: + parts.append(' are') + else: + parts.append(' is') + return ''.join(parts) + + @property + @abc.abstractmethod + def file_suffix(self): + """Return suffix of generated Asciidoctor files""" + raise NotImplementedError + + @abc.abstractmethod + def api_name(self, spectype=None): + """Return API or specification name for citations in ref pages. + + spectype is the spec this refpage is for. + 'api' (the default value) is the main API Specification. + If an unrecognized spectype is given, returns None. + + Must implement.""" + raise NotImplementedError + + def should_insert_may_alias_macro(self, genOpts): + """Return true if we should insert a "may alias" macro in this file. + + Only used by OpenXR right now.""" + return False + + @property + def command_prefix(self): + """Return the expected prefix of commands/functions. + + Implemented in terms of api_prefix.""" + if not self._command_prefix: + self._command_prefix = self.api_prefix[:].replace('_', '').lower() + return self._command_prefix + + @property + def type_prefix(self): + """Return the expected prefix of type names. + + Implemented in terms of command_prefix (and in turn, api_prefix).""" + if not self._type_prefix: + self._type_prefix = ''.join( + (self.command_prefix[0:1].upper(), self.command_prefix[1:])) + return self._type_prefix + + @property + @abc.abstractmethod + def api_prefix(self): + """Return API token prefix. + + Typically two uppercase letters followed by an underscore. + + Must implement.""" + raise NotImplementedError + + @property + def extension_name_prefix(self): + """Return extension name prefix. + + Typically two uppercase letters followed by an underscore. + + Assumed to be the same as api_prefix, but some APIs use different + case conventions.""" + + return self.api_prefix + + def extension_short_description(self, elem): + """Return a short description of an extension for use in refpages. + + elem is an ElementTree for the tag in the XML. + The default behavior is to use the 'type' field of this tag, but not + all APIs support this field.""" + + ext_type = elem.get('type') + + if ext_type is not None: + return f'{ext_type} extension' + else: + return '' + + @property + def write_contacts(self): + """Return whether contact list should be written to extension appendices""" + return False + + @property + def write_extension_type(self): + """Return whether extension type should be written to extension appendices""" + return True + + @property + def write_extension_number(self): + """Return whether extension number should be written to extension appendices""" + return True + + @property + def write_extension_revision(self): + """Return whether extension revision number should be written to extension appendices""" + return True + + @property + def write_refpage_include(self): + """Return whether refpage include should be written to extension appendices""" + return True + + @property + def api_version_prefix(self): + """Return API core version token prefix. + + Implemented in terms of api_prefix. + + May override.""" + return f"{self.api_prefix}VERSION_" + + @property + def KHR_prefix(self): + """Return extension name prefix for KHR extensions. + + Implemented in terms of api_prefix. + + May override.""" + return f"{self.api_prefix}KHR_" + + @property + def EXT_prefix(self): + """Return extension name prefix for EXT extensions. + + Implemented in terms of api_prefix. + + May override.""" + return f"{self.api_prefix}EXT_" + + def writeFeature(self, featureName, featureExtraProtect, filename): + """Return True if OutputGenerator.endFeature should write this feature. + + Defaults to always True. + Used in COutputGenerator. + + May override.""" + return True + + def requires_error_validation(self, return_type): + """Return True if the return_type element is an API result code + requiring error validation. + + Defaults to always False. + + May override.""" + return False + + @property + def required_errors(self): + """Return a list of required error codes for validation. + + Defaults to an empty list. + + May override.""" + return [] + + def is_voidpointer_alias(self, tag, text, tail): + """Return True if the declaration components (tag,text,tail) of an + element represents a void * type. + + Defaults to a reasonable implementation. + + May override.""" + return tag == 'type' and text == 'void' and tail.startswith('*') + + def make_voidpointer_alias(self, tail): + """Reformat a void * declaration to include the API alias macro. + + Defaults to a no-op. + + Must override if you actually want to use this feature in your project.""" + return tail + + def category_requires_validation(self, category): + """Return True if the given type 'category' always requires validation. + + Defaults to a reasonable implementation. + + May override.""" + return category in CATEGORIES_REQUIRING_VALIDATION + + def type_always_valid(self, typename): + """Return True if the given type name is always valid (never requires validation). + + This is for things like integers. + + Defaults to a reasonable implementation. + + May override.""" + return typename in TYPES_KNOWN_ALWAYS_VALID + + @property + def should_skip_checking_codes(self): + """Return True if more than the basic validation of return codes should + be skipped for a command.""" + + return False + + @property + def generate_index_terms(self): + """Return True if asiidoctor index terms should be generated as part + of an API interface from the docgenerator.""" + + return False + + @property + def generate_enum_table(self): + """Return True if asciidoctor tables describing enumerants in a + group should be generated as part of group generation.""" + return False + + @property + def generate_max_enum_in_docs(self): + """Return True if MAX_ENUM tokens should be generated in + documentation includes.""" + return False + + def extension_name_split(self, name): + """Split an extension name, returning (vendor, rest of name). + The API prefix of the name is ignored.""" + + match = EXT_NAME_DECOMPOSE_RE.match(name) + vendor = match.group('vendor') + bare_name = match.group('name') + + return (vendor, bare_name) + + @abc.abstractmethod + def extension_file_path(self, name): + """Return file path to an extension appendix relative to a directory + containing all such appendices. + - name - extension name + + Must implement.""" + raise NotImplementedError + + def extension_include_string(self, name): + """Return format string for include:: line for an extension appendix + file. + - name - extension name""" + + return f'include::{{appendices}}/{self.extension_file_path(name)}[]' + + @property + def provisional_extension_warning(self): + """Return True if a warning should be included in extension + appendices for provisional extensions.""" + return True + + @property + def generated_include_path(self): + """Return path relative to the generated reference pages, to the + generated API include files.""" + + return '{generated}' + + @property + def include_extension_appendix_in_refpage(self): + """Return True if generating extension refpages by embedding + extension appendix content (default), False otherwise + (OpenXR).""" + + return True + + def valid_flag_bit(self, bitpos): + """Return True if bitpos is an allowed numeric bit position for + an API flag. + + Behavior depends on the data type used for flags (which may be 32 + or 64 bits), and may depend on assumptions about compiler + handling of sign bits in enumerated types, as well.""" + return True + + @property + def duplicate_aliased_structs(self): + """ + Should aliased structs have the original struct definition listed in the + generated docs snippet? + """ + return False + + @property + def protectProtoComment(self): + """Return True if generated #endif should have a comment matching + the protection symbol used in the opening #ifdef/#ifndef.""" + return False + + @property + def extra_refpage_headers(self): + """Return any extra headers (preceding the title) for generated + reference pages.""" + return '' + + @property + def extra_refpage_body(self): + """Return any extra text (following the title) for generated + reference pages.""" + return '' + + def is_api_version_name(self, name): + """Return True if name is an API version name.""" + + return API_VERSION_NAME_RE.match(name) is not None + + @property + def docgen_language(self): + """Return the language to be used in docgenerator [source] + blocks.""" + + return 'c++' + + @property + def docgen_source_options(self): + """Return block options to be used in docgenerator [source] blocks, + which are appended to the 'source' block type. + Can be empty.""" + + return '%unbreakable' diff --git a/libs/VulkanHeaders/spec_tools/data_structures.py b/libs/VulkanHeaders/spec_tools/data_structures.py new file mode 100644 index 0000000000..1eba0072e2 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/data_structures.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 -i +# +# Copyright (c) 2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik +"""Provides general-purpose data structures.""" + + +class DictOfStringSets: + """A dictionary where the values are sets of strings. + + Has some convenience functions to allow easier maintenance via + the .add method.""" + + def __init__(self, d=None): + self.d = {} + if d: + for k, v in d.items(): + self.add(k, v) + + def __getitem__(self, k): + return self.d[k] + + def __contains__(self, k): + return k in self.d + + def get(self, k, default=None): + return self.d.get(k, default) + + def get_dict(self): + return self.d + + def items(self): + """Return an iterator like dict().items().""" + return self.d.items() + + def keys(self): + """Return an iterator over keys.""" + return self.d.keys() + + def values(self): + """Return an iterator over values.""" + return self.d.values() + + def add_key(self, k): + """Ensure the set for the given key exists.""" + if k not in self.d: + self.d[k] = set() + + def add(self, k, v): + self.add_key(k) + if isinstance(v, str): + v = (v, ) + if not isinstance(v, set): + v = set(v) + self.d[k].update(v) diff --git a/libs/VulkanHeaders/spec_tools/entity_db.py b/libs/VulkanHeaders/spec_tools/entity_db.py new file mode 100644 index 0000000000..9c2d52a7c7 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/entity_db.py @@ -0,0 +1,666 @@ +"""Provides EntityDatabase, a class that keeps track of spec-defined entities and associated macros.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +from abc import ABC, abstractmethod + +from .shared import (CATEGORIES_WITH_VALIDITY, EXTENSION_CATEGORY, + NON_EXISTENT_MACROS, EntityData) +from .util import getElemName + + +def _entityToDict(data): + return { + 'macro': data.macro, + 'filename': data.filename, + 'category': data.category, + 'directory': data.directory + } + + +class EntityDatabase(ABC): + """Parsed and processed information from the registry XML. + + Must be subclasses for each specific API. + """ + + ### + # Methods that must be implemented in subclasses. + ### + @abstractmethod + def makeRegistry(self): + """Return a Registry object that has already had loadFile() and parseTree() called. + + Called only once during construction. + """ + raise NotImplementedError + + @abstractmethod + def getNamePrefix(self): + """Return the (two-letter) prefix of all entity names for this API. + + Called only once during construction. + """ + raise NotImplementedError + + @abstractmethod + def getPlatformRequires(self): + """Return the 'requires' string associated with external/platform definitions. + + This is the string found in the requires attribute of the XML for entities that + are externally defined in a platform include file, like the question marks in: + + + + In Vulkan, this is 'vk_platform'. + + Called only once during construction. + """ + raise NotImplementedError + + ### + # Methods that it is optional to **override** + ### + def getSystemTypes(self): + """Return an enumerable of strings that name system types. + + System types use the macro `code`, and they do not generate API/validity includes. + + Called only once during construction. + """ + return [] + + def getGeneratedDirs(self): + """Return a sequence of strings that are the subdirectories of generates API includes. + + Called only once during construction. + """ + return ['basetypes', + 'defines', + 'enums', + 'flags', + 'funcpointers', + 'handles', + 'protos', + 'structs'] + + def populateMacros(self): + """Perform API-specific calls, if any, to self.addMacro() and self.addMacros(). + + It is recommended to implement/override this and call + self.addMacros(..., ..., [..., "flags"]), + since the base implementation, in _basicPopulateMacros(), + does not add any macros as pertaining to the category "flags". + + Called only once during construction. + """ + pass + + def populateEntities(self): + """Perform API-specific calls, if any, to self.addEntity().""" + pass + + def getEntitiesWithoutValidity(self): + """Return an enumerable of entity names that do not generate validity includes.""" + return [self.mixed_case_name_prefix + + x for x in ['BaseInStructure', 'BaseOutStructure']] + + def getExclusionSet(self): + """Return a set of "support=" attribute strings that should not be included in the database. + + Called only during construction.""" + return set(('disabled',)) + + ### + # Methods that it is optional to **extend** + ### + def handleType(self, name, info, requires): + """Add entities, if appropriate, for an item in registry.typedict. + + Called at construction for every name, info in registry.typedict.items() + not immediately skipped, + to perform the correct associated addEntity() call, if applicable. + The contents of the requires attribute, if any, is passed in requires. + + May be extended by API-specific code to handle some cases preferentially, + then calling the super implementation to handle the rest. + """ + if requires == self.platform_requires: + # Ah, no, don't skip this, it's just in the platform header file. + # TODO are these code or basetype? + self.addEntity(name, 'code', elem=info.elem, generates=False) + return + + protect = info.elem.get('protect') + if protect: + self.addEntity(protect, 'dlink', + category='configdefines', generates=False) + + alias = info.elem.get('alias') + if alias: + self.addAlias(name, alias) + + cat = info.elem.get('category') + if cat == 'struct': + self.addEntity(name, 'slink', elem=info.elem) + + elif cat == 'union': + # TODO: is this right? + self.addEntity(name, 'slink', elem=info.elem) + + elif cat == 'enum': + self.addEntity( + name, 'elink', elem=info.elem) + + elif cat == 'handle': + self.addEntity(name, 'slink', elem=info.elem, + category='handles') + + elif cat == 'bitmask': + self.addEntity( + name, 'tlink', elem=info.elem, category='flags') + + elif cat == 'basetype': + self.addEntity(name, 'basetype', + elem=info.elem) + + elif cat == 'define': + self.addEntity(name, 'dlink', elem=info.elem) + + elif cat == 'funcpointer': + self.addEntity(name, 'tlink', elem=info.elem) + + elif cat == 'include': + # skip + return + + elif cat is None: + self.addEntity(name, 'code', elem=info.elem, generates=False) + + else: + raise RuntimeError(f'unrecognized category {cat}') + + def handleCommand(self, name, info): + """Add entities, if appropriate, for an item in registry.cmddict. + + Called at construction for every name, info in registry.cmddict.items(). + Calls self.addEntity() accordingly. + """ + self.addEntity(name, 'flink', elem=info.elem, + category='commands', directory='protos') + + def handleExtension(self, name, info): + """Add entities, if appropriate, for an item in registry.extdict. + + Called at construction for every name, info in registry.extdict.items(). + Calls self.addEntity() accordingly. + """ + if info.supported in self._supportExclusionSet: + # Don't populate with disabled extensions. + return + + # Only get the protect strings and name from extensions + + self.addEntity(name, None, category=EXTENSION_CATEGORY, + generates=False) + protect = info.elem.get('protect') + if protect: + self.addEntity(protect, 'dlink', + category='configdefines', generates=False) + + def handleEnumValue(self, name, info): + """Add entities, if appropriate, for an item in registry.enumdict. + + Called at construction for every name, info in registry.enumdict.items(). + Calls self.addEntity() accordingly. + """ + self.addEntity(name, 'ename', elem=info.elem, + category='enumvalues', generates=False) + + ### + # END of methods intended to be implemented, overridden, or extended in child classes! + ### + + ### + # Accessors + ### + def findMacroAndEntity(self, macro, entity): + """Look up EntityData by macro and entity pair. + + Does **not** resolve aliases.""" + return self._byMacroAndEntity.get((macro, entity)) + + def findEntity(self, entity): + """Look up EntityData by entity name (case-sensitive). + + If it fails, it will try resolving aliases. + """ + result = self._byEntity.get(entity) + if result: + return result + + alias_set = self._aliasSetsByEntity.get(entity) + if alias_set: + for alias in alias_set: + if alias in self._byEntity: + return self.findEntity(alias) + + assert not "Alias without main entry!" + + return None + + def findEntityCaseInsensitive(self, entity): + """Look up EntityData by entity name (case-insensitive). + + Does **not** resolve aliases.""" + return self._byLowercaseEntity.get(entity.lower()) + + def getMemberElems(self, commandOrStruct): + """Given a command or struct name, retrieve the ETree elements for each member/param. + + Returns None if the entity is not found or doesn't have members/params. + """ + data = self.findEntity(commandOrStruct) + + if not data: + return None + if data.elem is None: + return None + if data.macro == 'slink': + tag = 'member' + else: + tag = 'param' + return data.elem.findall(f'.//{tag}') + + def getMemberNames(self, commandOrStruct): + """Given a command or struct name, retrieve the names of each member/param. + + Returns an empty list if the entity is not found or doesn't have members/params. + """ + members = self.getMemberElems(commandOrStruct) + if not members: + return [] + ret = [] + for member in members: + name_tag = member.find('name') + if name_tag: + ret.append(name_tag.text) + return ret + + def getEntityJson(self): + """Dump the internal entity dictionary to JSON for debugging.""" + import json + d = {entity: _entityToDict(data) + for entity, data in self._byEntity.items()} + return json.dumps(d, sort_keys=True, indent=4) + + def entityHasValidity(self, entity): + """Estimate if we expect to see a validity include for an entity name. + + Returns None if the entity name is not known, + otherwise a boolean: True if a validity include is expected. + + Related to Generator.isStructAlwaysValid. + """ + data = self.findEntity(entity) + if not data: + return None + + if entity in self.entities_without_validity: + return False + + if data.category == 'protos': + # All protos have validity + return True + + if data.category not in CATEGORIES_WITH_VALIDITY: + return False + + # Handle structs here. + members = self.getMemberElems(entity) + if not members: + return None + for member in members: + member_name = getElemName(member) + member_type = member.find('type').text + member_category = member.get('category') + + if member_name in ('next', 'type'): + return True + + if member_type in ('void', 'char'): + return True + + if member.get('noautovalidity'): + # Not generating validity for this member, skip it + continue + + if member.get('len'): + # Array + return True + + typetail = member.find('type').tail + if typetail and '*' in typetail: + # Pointer + return True + + if member_category in ('handle', 'enum', 'bitmask'): + return True + + if member.get('category') in ('struct', 'union') \ + and self.entityHasValidity(member_type): + # struct or union member - recurse + return True + + # Got this far - no validity needed + return False + + def entityGenerates(self, entity_name): + """Return True if the named entity generates include file(s).""" + return entity_name in self._generating_entities + + @property + def generating_entities(self): + """Return a sequence of all generating entity names.""" + return self._generating_entities.keys() + + def shouldBeRecognized(self, macro, entity_name): + """Determine, based on the macro and the name provided, if we should expect to recognize the entity. + + True if it is linked. Specific APIs may also provide additional cases where it is True.""" + return self.isLinkedMacro(macro) + + def likelyRecognizedEntity(self, entity_name): + """Guess (based on name prefix alone) if an entity is likely to be recognized.""" + return entity_name.lower().startswith(self.name_prefix) + + def isLinkedMacro(self, macro): + """Identify if a macro is considered a "linked" macro.""" + return macro in self._linkedMacros + + def isValidMacro(self, macro): + """Identify if a macro is known and valid.""" + if macro not in self._categoriesByMacro: + return False + + return macro not in NON_EXISTENT_MACROS + + def getCategoriesForMacro(self, macro): + """Identify the categories associated with a (known, valid) macro.""" + if macro in self._categoriesByMacro: + return self._categoriesByMacro[macro] + return None + + def areAliases(self, first_entity_name, second_entity_name): + """Return true if the two entity names are equivalent (aliases of each other).""" + alias_set = self._aliasSetsByEntity.get(first_entity_name) + if not alias_set: + # If this assert fails, we have goofed in addAlias + assert second_entity_name not in self._aliasSetsByEntity + + return False + + return second_entity_name in alias_set + + @property + def macros(self): + """Return the collection of all known entity-related markup macros.""" + return self._categoriesByMacro.keys() + + def childTypes(self, typename): + """Return the list of types specifying typename as their parent type.""" + children = [childname + for childname, entity in self._byEntity.items() + if entity.elem is not None and entity.elem.get("parentstruct") == typename] + return children + + ### + # Methods only used during initial setup/population of this data structure + ### + def addMacro(self, macro, categories, link=False): + """Add a single markup macro to the collection of categories by macro. + + Also adds the macro to the set of linked macros if link=True. + + If a macro has already been supplied to a call, later calls for that macro have no effect. + """ + if macro in self._categoriesByMacro: + return + self._categoriesByMacro[macro] = categories + if link: + self._linkedMacros.add(macro) + + def addMacros(self, letter, macroTypes, categories): + """Add markup macros associated with a leading letter to the collection of categories by macro. + + Also, those macros created using 'link' in macroTypes will also be added to the set of linked macros. + + Basically automates a number of calls to addMacro(). + """ + for macroType in macroTypes: + macro = letter + macroType + self.addMacro(macro, categories, link=(macroType == 'link')) + + def addAlias(self, entityName, aliasName): + """Record that entityName is an alias for aliasName.""" + # See if we already have something with this as the alias. + alias_set = self._aliasSetsByEntity.get(aliasName) + other_alias_set = self._aliasSetsByEntity.get(entityName) + if alias_set and other_alias_set: + # If this fails, we need to merge sets and update. + assert alias_set is other_alias_set + + if not alias_set: + # Try looking by the other name. + alias_set = other_alias_set + + if not alias_set: + # Nope, this is a new set. + alias_set = set() + self._aliasSets.append(alias_set) + + # Add both names to the set + alias_set.add(entityName) + alias_set.add(aliasName) + + # Associate the set with each name + self._aliasSetsByEntity[aliasName] = alias_set + self._aliasSetsByEntity[entityName] = alias_set + + def addEntity(self, entityName, macro, category=None, elem=None, + generates=None, directory=None, filename=None): + """Add an entity (command, structure type, enum, enum value, etc) in the database. + + If an entityName has already been supplied to a call, later calls for that entityName have no effect. + + Arguments: + entityName -- the name of the entity. + macro -- the macro (without the trailing colon) that should be used to refer to this entity. + + Optional keyword arguments: + category -- If not manually specified, looked up based on the macro. + elem -- The ETree element associated with the entity in the registry XML. + generates -- Indicates whether this entity generates api and validity include files. + Default depends on directory (or if not specified, category). + directory -- The directory that include files (under api/ and validity/) are generated in. + If not specified (and generates is True), the default is the same as the category, + which is almost always correct. + filename -- The relative filename (under api/ or validity/) where includes are generated for this. + This only matters if generates is True (default). If not specified and generates is True, + one will be generated based on directory and entityName. + """ + # Probably dealt with in handleType(), but just in case it wasn't. + if elem is not None: + alias = elem.get('alias') + if alias: + self.addAlias(entityName, alias) + + if entityName in self._byEntity: + # skip if already recorded. + return + + # Look up category based on the macro, if category isn't specified. + if category is None: + category = self._categoriesByMacro.get(macro)[0] + + if generates is None: + potential_dir = directory or category + generates = potential_dir in self._generated_dirs + + # If directory isn't specified and this entity generates, + # the directory is the same as the category. + if directory is None and generates: + directory = category + + # Don't generate a filename if this entity doesn't generate includes. + if filename is None and generates: + filename = f'{directory}/{entityName}.adoc' + + data = EntityData( + entity=entityName, + macro=macro, + elem=elem, + filename=filename, + category=category, + directory=directory + ) + if entityName.lower() not in self._byLowercaseEntity: + self._byLowercaseEntity[entityName.lower()] = [] + + self._byEntity[entityName] = data + self._byLowercaseEntity[entityName.lower()].append(data) + self._byMacroAndEntity[(macro, entityName)] = data + if generates and filename is not None: + self._generating_entities[entityName] = data + + def __init__(self): + """Constructor: Do not extend or override. + + Changing the behavior of other parts of this logic should be done by + implementing, extending, or overriding (as documented): + + - Implement makeRegistry() + - Implement getNamePrefix() + - Implement getPlatformRequires() + - Override getSystemTypes() + - Override populateMacros() + - Override populateEntities() + - Extend handleType() + - Extend handleCommand() + - Extend handleExtension() + - Extend handleEnumValue() + """ + # Internal data that we don't want consumers of the class touching for fear of + # breaking invariants + self._byEntity = {} + self._byLowercaseEntity = {} + self._byMacroAndEntity = {} + self._categoriesByMacro = {} + self._linkedMacros = set() + self._aliasSetsByEntity = {} + self._aliasSets = [] + + self._registry = None + + # Retrieve from subclass, if overridden, then store locally. + self._supportExclusionSet = set(self.getExclusionSet()) + + # Entities that get a generated/api/category/entity.adoc file. + self._generating_entities = {} + + # Name prefix members + self.name_prefix = self.getNamePrefix().lower() + self.mixed_case_name_prefix = self.name_prefix[:1].upper( + ) + self.name_prefix[1:] + # Regex string for the name prefix that is case-insensitive. + self.case_insensitive_name_prefix_pattern = ''.join( + (f'[{c.upper()}{c}]' for c in self.name_prefix)) + + self.platform_requires = self.getPlatformRequires() + + self._generated_dirs = set(self.getGeneratedDirs()) + + # Note: Default impl requires self.mixed_case_name_prefix + self.entities_without_validity = set(self.getEntitiesWithoutValidity()) + + # TODO: Where should flags actually go? Not mentioned in the style guide. + # TODO: What about flag wildcards? There are a few such uses... + + # Abstract method: subclass must implement to define macros for flags + self.populateMacros() + + # Now, do default macro population + self._basicPopulateMacros() + + # Abstract method: subclass must implement to add any "not from the registry" (and not system type) + # entities + self.populateEntities() + + # Now, do default entity population + self._basicPopulateEntities(self.registry) + + ### + # Methods only used internally during initial setup/population of this data structure + ### + @property + def registry(self): + """Return a Registry.""" + if not self._registry: + self._registry = self.makeRegistry() + return self._registry + + def _basicPopulateMacros(self): + """Contains calls to self.addMacro() and self.addMacros(). + + If you need to change any of these, do so in your override of populateMacros(), + which will be called first. + """ + self.addMacro('basetype', ['basetypes']) + self.addMacro('code', ['code']) + self.addMacros('f', ['link', 'name', 'text'], ['protos']) + self.addMacros('s', ['link', 'name', 'text'], ['structs', 'handles']) + self.addMacros('e', ['link', 'name', 'text'], ['enums']) + self.addMacros('p', ['name', 'text'], ['parameter', 'member']) + self.addMacros('t', ['link', 'name'], ['funcpointers']) + self.addMacros('d', ['link', 'name'], ['defines', 'configdefines']) + + for macro in NON_EXISTENT_MACROS: + # Still search for them + self.addMacro(macro, None) + + def _basicPopulateEntities(self, registry): + """Contains typical calls to self.addEntity(). + + If you need to change any of these, do so in your override of populateEntities(), + which will be called first. + """ + system_types = set(self.getSystemTypes()) + for t in system_types: + self.addEntity(t, 'code', generates=False) + + for name, info in registry.typedict.items(): + if name in system_types: + # We already added these. + continue + + requires = info.elem.get('requires') + + if requires and not requires.lower().startswith(self.name_prefix): + # This is an externally-defined type, will skip it. + continue + + # OK, we might actually add an entity here + self.handleType(name=name, info=info, requires=requires) + + for name, info in registry.enumdict.items(): + self.handleEnumValue(name, info) + + for name, info in registry.cmddict.items(): + self.handleCommand(name, info) + + for name, info in registry.extdict.items(): + self.handleExtension(name, info) diff --git a/libs/VulkanHeaders/spec_tools/file_process.py b/libs/VulkanHeaders/spec_tools/file_process.py new file mode 100644 index 0000000000..7c78ddd87a --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/file_process.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik +"Utilities for processing files." + +from pathlib import Path + + +class LinewiseFileProcessor: + """A base class for code that processes an input file (or file handle) one line at a time.""" + + def __init__(self): + self._lines = [] + self._line_num = 0 + self._next_line = None + self._line = '' + self._filename = Path() + + @property + def filename(self): + """The Path object of the currently processed file""" + return self._filename + + @property + def relative_filename(self): + """The current file's Path relative to the current working directory""" + return self.filename.relative_to(Path('.').resolve()) + + @property + def line(self): + """The current line, including any trailing whitespace and the line ending.""" + return self._line + + @property + def line_number(self): + """Get 1-indexed line number.""" + return self._line_num + + @property + def line_rstripped(self): + """The current line without any trailing whitespace.""" + if self.line is None: + return None + return self.line.rstrip() + + @property + def trailing_whitespace(self): + """The trailing whitespace of the current line that gets removed when accessing rstrippedLine""" + non_whitespace_length = len(self.line_rstripped) + return self.line[non_whitespace_length:] + + @property + def next_line(self): + """Peek at the next line, if any.""" + return self._next_line + + @property + def next_line_rstripped(self): + """Peek at the next line, if any, without any trailing whitespace.""" + if self.next_line is None: + return None + return self.next_line.rstrip() + + def get_preceding_line(self, relative_index=-1): + """Retrieve the line at an line number at the given relative index, if one exists. Returns None if there is no line there.""" + if relative_index >= 0: + raise RuntimeError( + 'relativeIndex must be negative, to retrieve a preceding line.') + if relative_index + self.line_number <= 0: + # There is no line at this index + return None + return self._lines[self.line_number + relative_index - 1] + + def get_preceding_lines(self, num): + """Get *up to* the preceding num lines. Fewer may be returned if the requested number aren't available.""" + return self._lines[- (num + 1):-1] + + def process_line(self, line_num, line): + """Implement in your subclass to handle each new line.""" + raise NotImplementedError + + def _process_file_handle(self, file_handle): + # These are so we can process one line earlier than we're actually iterating thru. + processing_line_num = None + processing_line = None + + def do_process_line(): + self._line_num = processing_line_num + self._line = processing_line + if processing_line is not None: + self._lines.append(processing_line) + self.process_line(processing_line_num, processing_line) + + for line_num, line in enumerate(file_handle, 1): + self._next_line = line + do_process_line() + processing_line_num = line_num + processing_line = line + + # Finally process the left-over line + self._next_line = None + do_process_line() + + def process_file(self, filename, file_handle=None): + """Main entry point - call with a filename and optionally the file handle to read from.""" + if isinstance(filename, str): + filename = Path(filename).resolve() + + self._filename = filename + + if file_handle: + self._process_file_handle(file_handle) + else: + with self._filename.open('r', encoding='utf-8') as f: + self._process_file_handle(f) diff --git a/libs/VulkanHeaders/spec_tools/html_printer.py b/libs/VulkanHeaders/spec_tools/html_printer.py new file mode 100644 index 0000000000..85fc329305 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/html_printer.py @@ -0,0 +1,434 @@ +"""Defines HTMLPrinter, a BasePrinter subclass for a single-page HTML results file.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +import html +import re +from collections import namedtuple + +from .base_printer import BasePrinter, getColumn +from .shared import (MessageContext, MessageType, generateInclude, + getHighlightedRange) + +# Bootstrap styles (for constructing CSS class names) associated with MessageType values. +MESSAGE_TYPE_STYLES = { + MessageType.ERROR: 'danger', + MessageType.WARNING: 'warning', + MessageType.NOTE: 'secondary' +} + + +# HTML Entity for a little emoji-icon associated with MessageType values. +MESSAGE_TYPE_ICONS = { + MessageType.ERROR: '⊗', # makeIcon('times-circle'), + MessageType.WARNING: '⚠', # makeIcon('exclamation-triangle'), + MessageType.NOTE: 'ℹ' # makeIcon('info-circle') +} + +LINK_ICON = '🔗' # link icon + + +class HTMLPrinter(BasePrinter): + """Implementation of BasePrinter for generating diagnostic reports in HTML format. + + Generates a single file containing neatly-formatted messages. + + The HTML file loads Bootstrap 4 as well as 'prism' syntax highlighting from CDN. + """ + + def __init__(self, filename): + """Construct by opening the file.""" + self.f = open(filename, 'w', encoding='utf-8') + self.f.write(""" + + + + + + + + + check_spec_links results + + +
+

check_spec_links.py Scan Results

+ """) + # + self.filenameTransformer = re.compile(r'[^\w]+') + self.fileRange = {} + self.fileLines = {} + self.backLink = namedtuple( + 'BackLink', ['lineNum', 'col', 'end_col', 'target', 'tooltip', 'message_type']) + self.fileBackLinks = {} + + self.nextAnchor = 0 + super().__init__() + + def close(self): + """Write the tail end of the file and close it.""" + self.f.write(""" +
+ + + + + + + + + + + """) + self.f.close() + + ### + # Output methods: these all write to the HTML file. + def outputResults(self, checker, broken_links=True, + missing_includes=False): + """Output the full results of a checker run. + + Includes the diagnostics, broken links (if desired), + missing includes (if desired), and excerpts of all files with diagnostics. + """ + self.output(checker) + self.outputBrokenAndMissing( + checker, broken_links=broken_links, missing_includes=missing_includes) + + self.f.write(""" +
+

Excerpts of referenced files

""") + for fn in self.fileRange: + self.outputFileExcerpt(fn) + self.f.write('
\n') + + def outputChecker(self, checker): + """Output the contents of a MacroChecker object. + + Starts and ends the accordion populated by outputCheckerFile(). + """ + self.f.write( + '

Per-File Warnings and Errors

\n') + self.f.write('
\n') + super(HTMLPrinter, self).outputChecker(checker) + self.f.write("""
+
\n""") + + def outputCheckerFile(self, fileChecker): + """Output the contents of a MacroCheckerFile object. + + Stashes the lines of the file for later excerpts, + and outputs any diagnostics in an accordion card. + """ + # Save lines for later + self.fileLines[fileChecker.filename] = fileChecker.lines + + if not fileChecker.numDiagnostics(): + return + + self.f.write(""" +
+
+
+
+ +
+ """.format(id=self.makeIdentifierFromFilename(fileChecker.filename), relativefn=html.escape(self.getRelativeFilename(fileChecker.filename)))) + self.f.write('
') + warnings = fileChecker.numMessagesOfType(MessageType.WARNING) + if warnings > 0: + self.f.write(""" + {icon} + {num} warnings""".format(num=warnings, icon=MESSAGE_TYPE_ICONS[MessageType.WARNING])) + self.f.write('
\n
') + errors = fileChecker.numMessagesOfType(MessageType.ERROR) + if errors > 0: + self.f.write(""" + {icon} + {num} errors""".format(num=errors, icon=MESSAGE_TYPE_ICONS[MessageType.ERROR])) + self.f.write(""" +
+
+
+
+
+ """.format(id=self.makeIdentifierFromFilename(fileChecker.filename))) + super(HTMLPrinter, self).outputCheckerFile(fileChecker) + + self.f.write(""" +
+
+
+ + """) + + def outputMessage(self, msg): + """Output a Message.""" + anchor = self.getUniqueAnchor() + + self.recordUsage(msg.context, + linkBackTarget=anchor, + linkBackTooltip=f'{msg.message_type}: {msg.message[0]} [...]', + linkBackType=msg.message_type) + + self.f.write(""" +
+
+
{icon} {t} Line {lineNum}, Column {col} (-{arg})
+

+ """.format( + anchor=anchor, + icon=MESSAGE_TYPE_ICONS[msg.message_type], + style=MESSAGE_TYPE_STYLES[msg.message_type], + t=self.formatBrief(msg.message_type), + lineNum=msg.context.lineNum, + col=getColumn(msg.context), + arg=msg.message_id.enable_arg())) + self.f.write(self.formatContext(msg.context)) + self.f.write('
') + for line in msg.message: + self.f.write(html.escape(line)) + self.f.write('
\n') + self.f.write('

\n') + if msg.see_also: + self.f.write('

See also:

    \n') + for see in msg.see_also: + if isinstance(see, MessageContext): + self.f.write( + f'
  • {self.formatContext(see)}
  • \n') + self.recordUsage(see, + linkBackTarget=anchor, + linkBackType=MessageType.NOTE, + linkBackTooltip=f'see-also associated with {msg.message_type} at {self.formatContextBrief(see)}') + else: + self.f.write(f'
  • {self.formatBrief(see)}
  • \n') + self.f.write('
') + if msg.replacement is not None: + self.f.write( + '
Hover the highlight text to view suggested replacement.
') + if msg.fix is not None: + self.f.write( + '
Note: Auto-fix available.
') + if msg.script_location: + self.f.write( + f'

Message originated at {msg.script_location}

') + self.f.write('
'.format(
+            msg.context.lineNum))
+        highlightStart, highlightEnd = getHighlightedRange(msg.context)
+        self.f.write(html.escape(msg.context.line[:highlightStart]))
+        self.f.write(
+            f'')
+        self.f.write(html.escape(
+            msg.context.line[highlightStart:highlightEnd]))
+        self.f.write('')
+        self.f.write(html.escape(msg.context.line[highlightEnd:]))
+        self.f.write('
') + + def outputBrokenLinks(self, checker, broken): + """Output a table of broken links. + + Called by self.outputBrokenAndMissing() if requested. + """ + self.f.write(""" +
+

Missing Referenced API Includes

+

Items here have been referenced by a linking macro, so these are all broken links in the spec!

+ + + + + + """) + + for entity_name, uses in sorted(broken.items()): + category = checker.findEntity(entity_name).category + anchor = self.getUniqueAnchor() + asciidocAnchor = f'[[{entity_name}]]' + include = generateInclude(dir_traverse='../../generated/', + generated_type='api', + category=category, + entity=entity_name) + self.f.write(""" + + + + """) + self.f.write("""
Add line to include this fileor add this macro insteadLinks to this entity
{}{}
    + """.format(anchor, include, asciidocAnchor)) + for context in uses: + self.f.write( + f'
  • {self.formatContext(context, MessageType.NOTE)}
  • ') + self.recordUsage( + context, + linkBackTooltip=f'Link broken in spec: {include} not seen', + linkBackTarget=anchor, + linkBackType=MessageType.NOTE) + self.f.write("""
""") + + def outputMissingIncludes(self, checker, missing): + """Output a table of missing includes. + + Called by self.outputBrokenAndMissing() if requested. + """ + self.f.write(""" +
+

Missing Unreferenced API Includes

+

These items are expected to be generated in the spec build process, but aren't included. + However, as they also are not referenced by any linking macros, they aren't broken links - at worst they are undocumented entities, + at best they are errors in check_spec_links.py logic computing which entities get generated files.

+ + + + + """) + + for entity in sorted(missing): + fn = checker.findEntity(entity).filename + anchor = f'[[{entity}]]' + self.f.write(f""" + + + + """) + self.f.write("""
Add line to include this fileor add this macro instead
{fn}{anchor}
""") + + def outputFileExcerpt(self, filename): + """Output a card containing an excerpt of a file, sufficient to show locations of all diagnostics plus some context. + + Called by self.outputResults(). + """ + self.f.write("""
+
+
+
+ """.format(id=self.makeIdentifierFromFilename(filename), fn=self.getRelativeFilename(filename))) + lines = self.fileLines[filename] + r = self.fileRange[filename] + self.f.write("""
""".format(
+            id=self.makeIdentifierFromFilename(filename),
+            start=r.start))
+        for lineNum, line in enumerate(
+                lines[(r.start - 1):(r.stop - 1)], r.start):
+            # self.f.write(line)
+            lineLinks = [x for x in self.fileBackLinks[filename]
+                         if x.lineNum == lineNum]
+            for col, char in enumerate(line):
+                colLinks = (x for x in lineLinks if x.col == col)
+                for link in colLinks:
+                    # TODO right now the syntax highlighting is interfering with the link! so the link-generation is commented out,
+                    # only generating the emoji icon.
+
+                    # self.f.write('{icon}'.format(
+                    # target=link.target, title=html.escape(link.tooltip),
+                    # icon=MESSAGE_TYPE_ICONS[link.message_type]))
+                    self.f.write(MESSAGE_TYPE_ICONS[link.message_type])
+                    self.f.write('Cross reference: {t} {title}'.format(
+                        title=html.escape(link.tooltip, False), t=link.message_type))
+
+                    # self.f.write('')
+
+                # Write the actual character
+                self.f.write(html.escape(char))
+            self.f.write('\n')
+
+        self.f.write('
') + self.f.write('
\n') + self.f.write('
\n') + + def outputFallback(self, obj): + """Output some text in a general way.""" + self.f.write(obj) + + ### + # Format method: return a string. + def formatContext(self, context, message_type=None): + """Format a message context in a verbose way.""" + if message_type is None: + icon = LINK_ICON + else: + icon = MESSAGE_TYPE_ICONS[message_type] + return 'In context: {icon}{relative}:{lineNum}:{col}'.format( + href=self.getAnchorLinkForContext(context), + icon=icon, + # id=self.makeIdentifierFromFilename(context.filename), + relative=self.getRelativeFilename(context.filename), + lineNum=context.lineNum, + col=getColumn(context)) + + ### + # Internal methods: not mandated by parent class. + def recordUsage(self, context, linkBackTooltip=None, + linkBackTarget=None, linkBackType=MessageType.NOTE): + """Internally record a 'usage' of something. + + Increases the range of lines that are included in the excerpts, + and records back-links if appropriate. + """ + BEFORE_CONTEXT = 6 + AFTER_CONTEXT = 3 + # Clamp because we need accurate start line number to make line number + # display right + start = max(1, context.lineNum - BEFORE_CONTEXT) + stop = context.lineNum + AFTER_CONTEXT + 1 + if context.filename not in self.fileRange: + self.fileRange[context.filename] = range(start, stop) + self.fileBackLinks[context.filename] = [] + else: + oldRange = self.fileRange[context.filename] + self.fileRange[context.filename] = range( + min(start, oldRange.start), max(stop, oldRange.stop)) + + if linkBackTarget is not None: + start_col, end_col = getHighlightedRange(context) + self.fileBackLinks[context.filename].append(self.backLink( + lineNum=context.lineNum, col=start_col, end_col=end_col, + target=linkBackTarget, tooltip=linkBackTooltip, + message_type=linkBackType)) + + def makeIdentifierFromFilename(self, fn): + """Compute an acceptable HTML anchor name from a filename.""" + return self.filenameTransformer.sub('_', self.getRelativeFilename(fn)) + + def getAnchorLinkForContext(self, context): + """Compute the anchor link to the excerpt for a MessageContext.""" + return '#excerpt-{}.{}'.format( + self.makeIdentifierFromFilename(context.filename), context.lineNum) + + def getUniqueAnchor(self): + """Create and return a new unique string usable as a link anchor.""" + anchor = f'anchor-{self.nextAnchor}' + self.nextAnchor += 1 + return anchor diff --git a/libs/VulkanHeaders/spec_tools/macro_checker.py b/libs/VulkanHeaders/spec_tools/macro_checker.py new file mode 100644 index 0000000000..5a7a2a998a --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/macro_checker.py @@ -0,0 +1,228 @@ +"""Provides the MacroChecker class.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +from io import StringIO +import re + + +class MacroChecker(object): + """Perform and track checking of one or more files in an API spec. + + This does not necessarily need to be subclassed per-API: it is sufficiently + parameterized in the constructor for expected usage. + """ + + def __init__(self, enabled_messages, entity_db, + macro_checker_file_type, root_path, conventions): + """Construct an object that tracks checking one or more files in an API spec. + + enabled_messages -- a set of MessageId that should be enabled. + entity_db -- an object of a EntityDatabase subclass for this API. + macro_checker_file_type -- Type to instantiate to create the right + MacroCheckerFile subclass for this API. + root_path -- A Path object for the root of this repository. + conventions -- A ConventionsBase object. + """ + self.enabled_messages = enabled_messages + self.entity_db = entity_db + self.macro_checker_file_type = macro_checker_file_type + self.root_path = root_path + self.conventions = conventions + + self.files = [] + + self.refpages = set() + + # keys: entity names. values: MessageContext + self.links = {} + self.apiIncludes = {} + self.validityIncludes = {} + self.headings = {} + + # Regexes that are members because they depend on the name prefix. + + # apiPrefix, followed by some word characters or * as many times as desired, + # NOT followed by >> and NOT preceded by one of the characters in that first character class. + # (which distinguish "names being used somewhere other than prose"). + self.suspected_missing_macro_re = re.compile( fr''' + \b(?{self.entity_db.case_insensitive_name_prefix_pattern}[\w*]+) # Something that looks like our entity names + \b(?!>>) # NOT followed by >> + ''', re.VERBOSE + ) + self.heading_command_re = re.compile( + fr'=+ (?P{self.entity_db.name_prefix}[\w]+)' + ) + + macros_pattern = '|'.join((re.escape(macro) + for macro in self.entity_db.macros)) + # the "formatting" group is to strip matching */**/_/__ + # surrounding an entire macro. + self.macro_re = re.compile(fr''' + (?P\**|_*) # opening formatting + (?P{macros_pattern}): # macro name and colon + (?P[\w*]+(?P\[([^\]]*)\])?) + (?P=formatting) # matching trailing formatting + ''', + re.VERBOSE) + + def haveLinkTarget(self, entity): + """Report if we have parsed an API include (or heading) for an entity. + + None if there is no entity with that name. + """ + if not self.findEntity(entity): + return None + if entity in self.apiIncludes: + return True + return entity in self.headings + + def hasFixes(self): + """Report if any files have auto-fixes.""" + for f in self.files: + if f.hasFixes(): + return True + return False + + def addLinkToEntity(self, entity, context): + """Record seeing a link to an entity's docs from a context.""" + if entity not in self.links: + self.links[entity] = [] + self.links[entity].append(context) + + def seenRefPage(self, entity): + """Check if a ref-page markup block has been seen for an entity.""" + return entity in self.refpages + + def addRefPage(self, entity): + """Record seeing a ref-page markup block for an entity.""" + self.refpages.add(entity) + + def findMacroAndEntity(self, macro, entity): + """Look up EntityData by macro and entity pair. + + Forwards to the EntityDatabase. + """ + return self.entity_db.findMacroAndEntity(macro, entity) + + def findEntity(self, entity): + """Look up EntityData by entity name (case-sensitive). + + Forwards to the EntityDatabase. + """ + return self.entity_db.findEntity(entity) + + def findEntityCaseInsensitive(self, entity): + """Look up EntityData by entity name (case-insensitive). + + Forwards to the EntityDatabase. + """ + return self.entity_db.findEntityCaseInsensitive(entity) + + def getMemberNames(self, commandOrStruct): + """Given a command or struct name, retrieve the names of each member/param. + + Returns an empty list if the entity is not found or doesn't have members/params. + + Forwards to the EntityDatabase. + """ + return self.entity_db.getMemberNames(commandOrStruct) + + def likelyRecognizedEntity(self, entity_name): + """Guess (based on name prefix alone) if an entity is likely to be recognized. + + Forwards to the EntityDatabase. + """ + return self.entity_db.likelyRecognizedEntity(entity_name) + + def isLinkedMacro(self, macro): + """Identify if a macro is considered a "linked" macro. + + Forwards to the EntityDatabase. + """ + return self.entity_db.isLinkedMacro(macro) + + def processFile(self, filename): + """Parse an .adoc file belonging to the spec and check it for errors.""" + class FileStreamMaker(object): + def __init__(self, filename): + self.filename = filename + + def make_stream(self): + return open(self.filename, 'r', encoding='utf-8') + + f = self.macro_checker_file_type(self, filename, self.enabled_messages, + FileStreamMaker(filename)) + f.process() + self.files.append(f) + + def processString(self, s): + """Process a string as if it were a spec file. + + Used for testing purposes. + """ + if "\n" in s.rstrip(): + # remove leading spaces from each line to allow easier + # block-quoting in tests + s = "\n".join((line.lstrip() for line in s.split("\n"))) + # fabricate a "filename" that will display better. + filename = "string{}\n****START OF STRING****\n{}\n****END OF STRING****\n".format( + len(self.files), s.rstrip()) + + else: + filename = f"string{len(self.files)}: {s.rstrip()}" + + class StringStreamMaker(object): + def __init__(self, string): + self.string = string + + def make_stream(self): + return StringIO(self.string) + + f = self.macro_checker_file_type(self, filename, self.enabled_messages, + StringStreamMaker(s)) + f.process() + self.files.append(f) + return f + + def numDiagnostics(self): + """Return the total number of diagnostics (warnings and errors) over all the files processed.""" + return sum((f.numDiagnostics() for f in self.files)) + + def numErrors(self): + """Return the total number of errors over all the files processed.""" + return sum((f.numErrors() for f in self.files)) + + def getMissingUnreferencedApiIncludes(self): + """Return the unreferenced entity names that we expected to see an API include or link target for, but did not. + + Counterpart to getBrokenLinks(): This method returns the entity names + that were not used in a linking macro (and thus wouldn't create a broken link), + but were nevertheless expected and not seen. + """ + return (entity for entity in self.entity_db.generating_entities + if (not self.haveLinkTarget(entity)) and entity not in self.links) + + def getBrokenLinks(self): + """Return the entity names and usage contexts that we expected to see an API include or link target for, but did not. + + Counterpart to getMissingUnreferencedApiIncludes(): This method returns only the + entity names that were used in a linking macro (and thus create a broken link), + but were not seen. The values of the dictionary are a list of MessageContext objects + for each linking macro usage for this entity name. + """ + return {entity: contexts for entity, contexts in self.links.items() + if self.entity_db.entityGenerates(entity) and not self.haveLinkTarget(entity)} + + def getMissingRefPages(self): + """Return a list of entities that we expected, but did not see, a ref page block for. + + The heuristics here are rather crude: we expect a ref page for every generating entry. + """ + return (entity for entity in sorted(self.entity_db.generating_entities) + if entity not in self.refpages) diff --git a/libs/VulkanHeaders/spec_tools/macro_checker_file.py b/libs/VulkanHeaders/spec_tools/macro_checker_file.py new file mode 100644 index 0000000000..2e824d72b4 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/macro_checker_file.py @@ -0,0 +1,1673 @@ +"""Provides MacroCheckerFile, a subclassable type that validates a single file in the spec.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +import logging +import re +from collections import OrderedDict, namedtuple +from enum import Enum +from inspect import currentframe +from typing import Set + +from .shared import (AUTO_FIX_STRING, CATEGORIES_WITH_VALIDITY, + EXTENSION_CATEGORY, NON_EXISTENT_MACROS, EntityData, + Message, MessageContext, MessageId, MessageType, + generateInclude, toNameAndLine) + +# Code blocks may start and end with any number of ---- +CODE_BLOCK_DELIM = '----' + +# Mostly for ref page blocks, but also used elsewhere? +REF_PAGE_LIKE_BLOCK_DELIM = '--' + +# For insets/blocks like the implicit valid usage +# TODO think it must start with this - does it have to be exactly this? +BOX_BLOCK_DELIM = '****' + + +INTERNAL_PLACEHOLDER = re.compile( + r'(?P__+)([a-zA-Z]+)(?P=delim)' +) + +# Matches any include line. +# Used to check for a leading path attribute. +INCLUDE_PATH_ATTRIBUTE = re.compile( + r'include::(\{(?P[a-z]+)\})?.*\[\]') + +allowed_path_attributes = { + '{appendices}', + '{chapters}', + '{config}', + '{generated}', + '{promoted}', + '{style}', +} + +# Matches a generated (api or validity) include line. +INCLUDE = re.compile( + r'include::(?P((../){1,4}|\{generated\}/)(generated/)?)(?P(api|validity))/(?P\w+)/(?P[^./]+).adoc[\[][\]]') # noqa + +# Matches an [[AnchorLikeThis]] +ANCHOR = re.compile(r'\[\[(?P[^\]]+)\]\]') + +# Looks for flink:foo:: or slink:foo:: at the end of string: +# used to detect explicit pname context. +PRECEDING_MEMBER_REFERENCE = re.compile( + r'\b(?P[fs](text|link)):(?P[\w*]+)::$') + +# Matches something like slink:foo::pname:bar as well as +# the under-marked-up slink:foo::bar. +MEMBER_REFERENCE = re.compile( + r'\b(?P(?P[fs](text|link)):(?P[\w*]+))(?P::)(?P(?Ppname:?)(?P[\w]+))\b' # noqa +) + +# Matches if a string ends while a link is still "open". +# (first half of a link being broken across two lines, +# or containing our interested area when matched against the text preceding). +# Used to skip checking in some places. +OPEN_LINK = re.compile( + r'.*(?]*$' +) + +# Matches if a string begins and is followed by a link "close" without a matching open. +# (second half of a link being broken across two lines) +# Used to skip checking in some places. +CLOSE_LINK = re.compile( + r'[^<]*>>.*$' +) + +# Matches if a line should be skipped without further considering. +# Matches lines starting with: +# - `ifdef:` +# - `endif:` +# - `todo` (followed by something matching \b, like : or (. capitalization ignored) +SKIP_LINE = re.compile( + r'^(ifdef:)|(endif:)|([tT][oO][dD][oO]\b).*' +) + +# Matches the whole inside of a refpage tag. +BRACKETS = re.compile(r'\[(?P.*)\]') + +# Matches a key='value' pair from a ref page tag. +REF_PAGE_ATTRIB = re.compile( + r"(?P[a-z]+)='(?P[^'\\]*(?:\\.[^'\\]*)*)'") + + +class Attrib(Enum): + """Attributes of a ref page.""" + + REFPAGE = 'refpage' + DESC = 'desc' + TYPE = 'type' + ALIAS = 'alias' + XREFS = 'xrefs' + ANCHOR = 'anchor' + + +VALID_REF_PAGE_ATTRIBS = set( + (e.value for e in Attrib)) + +AttribData = namedtuple('AttribData', ['match', 'key', 'value']) + + +def makeAttribFromMatch(match): + """Turn a match of REF_PAGE_ATTRIB into an AttribData value.""" + return AttribData(match=match, key=match.group( + 'key'), value=match.group('value')) + + +def parseRefPageAttribs(line): + """Parse a ref page tag into a dictionary of attribute_name: AttribData.""" + return {m.group('key'): makeAttribFromMatch(m) + for m in REF_PAGE_ATTRIB.finditer(line)} + + +def regenerateIncludeFromMatch(match, generated_type): + """Create an include directive from an INCLUDE match and a (new or replacement) generated_type.""" + return generateInclude( + match.group('directory_traverse'), + generated_type, + match.group('category'), + match.group('entity_name')) + + +BlockEntry = namedtuple( + 'BlockEntry', ['delimiter', 'context', 'block_type', 'refpage']) + + +class BlockType(Enum): + """Enumeration of the various distinct block types known.""" + CODE = 'code' + REF_PAGE_LIKE = 'ref-page-like' # with or without a ref page tag before + BOX = 'box' + + @classmethod + def lineToBlockType(self, line): + """Return a BlockType if the given line is a block delimiter. + + Returns None otherwise. + """ + if line == REF_PAGE_LIKE_BLOCK_DELIM: + return BlockType.REF_PAGE_LIKE + if line.startswith(CODE_BLOCK_DELIM): + return BlockType.CODE + if line.startswith(BOX_BLOCK_DELIM): + return BlockType.BOX + + return None + + +def _pluralize(word, num): + if num == 1: + return word + if word.endswith('y'): + return f"{word[:-1]}ies" + return f"{word}s" + + +def _s_suffix(num): + """Simplify pluralization.""" + if num > 1: + return 's' + return '' + + +def shouldEntityBeText(entity, subscript): + """Determine if an entity name appears to use placeholders, wildcards, etc. and thus merits use of a *text macro. + + Call with the entity and subscript groups from a match of MacroChecker.macro_re. + """ + entity_only = entity + if subscript: + if subscript == '[]' or subscript == '[i]' or subscript.startswith( + '[_') or subscript.endswith('_]'): + return True + entity_only = entity[:-len(subscript)] + + if ('*' in entity) or entity.startswith('_') or entity_only.endswith('_'): + return True + + if INTERNAL_PLACEHOLDER.search(entity): + return True + return False + + +class MacroCheckerFile: + """Object performing processing of a single AsciiDoctor file from a specification. + + For testing purposes, may also process a string as if it were a file. + """ + + def __init__(self, checker, filename: str, enabled_messages: Set[MessageId], stream_maker): + """Construct a MacroCheckerFile object. + + Typically called by MacroChecker.processFile or MacroChecker.processString(). + + Arguments: + checker -- A MacroChecker object. + filename -- A string to use in messages to refer to this checker, typically the file name. + enabled_messages -- A set() of MessageId values that should be considered "enabled" and thus stored. + stream_maker -- An object with a makeStream() method that returns a stream. + """ + self.checker = checker + self.filename = filename + self.stream_maker = stream_maker + self.enabled_messages = enabled_messages + self.missing_validity_suppressions = set( + self.getMissingValiditySuppressions()) + + self.logger = logging.getLogger(__name__) + self.logger.addHandler(logging.NullHandler()) + + self.fixes = set() + self.messages = [] + + self.pname_data = None + self.pname_mentions = {} + + self.refpage_includes = {} + + self.lines = [] + + # For both of these: + # keys: entity name + # values: MessageContext + self.fs_api_includes = {} + self.validity_includes = {} + + self.in_code_block = False + self.in_ref_page = False + self.prev_line_ref_page_tag = None + self.current_ref_page = None + + # Stack of block-starting delimiters. + self.block_stack = [] + + # Regexes that are members because they depend on the name prefix. + self.suspected_missing_macro_re = self.checker.suspected_missing_macro_re + self.heading_command_re = self.checker.heading_command_re + + ### + # Main process/checking methods, arranged roughly from largest scope to smallest scope. + ### + + def process(self): + """Check the stream (file, string) created by the streammaker supplied to the constructor. + + This is the top-level method for checking a spec file. + """ + self.logger.info("processing file %s", self.filename) + + # File content checks - performed line-by-line + with self.stream_maker.make_stream() as f: + # Iterate through lines, calling processLine on each. + for lineIndex, line in enumerate(f): + trimmedLine = line.rstrip() + self.lines.append(trimmedLine) + self.processLine(lineIndex + 1, trimmedLine) + + # End of file checks follow: + + # Check "state" at end of file: should have blocks closed. + if self.prev_line_ref_page_tag: + self.error(MessageId.REFPAGE_BLOCK, + "Reference page tag seen, but block not opened before end of file.", + context=self.storeMessageContext(match=None)) + + if self.block_stack: + locations = (x.context for x in self.block_stack) + formatted_locations = [f'{x.delimiter} opened at {self.getBriefLocation(x.context)}' + for x in self.block_stack] + self.logger.warning("Unclosed blocks: %s", + ', '.join(formatted_locations)) + + self.error(MessageId.UNCLOSED_BLOCK, + ["Reached end of page, with these unclosed blocks remaining:"] + + formatted_locations, + context=self.storeMessageContext(match=None), + see_also=locations) + + # Check that every include of an /api/ file in the protos or structs category + # had a matching /validity/ include + for entity, includeContext in self.fs_api_includes.items(): + if not self.checker.entity_db.entityHasValidity(entity): + continue + + if entity in self.missing_validity_suppressions: + continue + + if entity not in self.validity_includes: + self.warning(MessageId.MISSING_VALIDITY_INCLUDE, + [f'Saw /api/ include for {entity}, but no matching /validity/ include', + f"Expected a line with {regenerateIncludeFromMatch(includeContext.match, 'validity')}"], + context=includeContext) + + # Check that we never include a /validity/ file + # without a matching /api/ include + for entity, includeContext in self.validity_includes.items(): + if entity not in self.fs_api_includes: + self.error(MessageId.MISSING_API_INCLUDE, + [f'Saw /validity/ include for {entity}, but no matching /api/ include', + f"Expected a line with {regenerateIncludeFromMatch(includeContext.match, 'api')}"], + context=includeContext) + + if not self.numDiagnostics(): + # no problems, exit quietly + return + + print(f'\nFor file {self.filename}:') + + self.printMessageCounts() + numFixes = len(self.fixes) + if numFixes > 0: + fixes = ', '.join((f'{search} -> {replace}' + for search, replace in self.fixes)) + + print('{} unique auto-fix {} recorded: {}'.format(numFixes, + _pluralize('pattern', numFixes), fixes)) + + def processLine(self, lineNum, line): + """Check the contents of a single line from a file. + + Eventually populates self.match, self.entity, self.macro, + before calling processMatch. + """ + self.lineNum = lineNum + self.line = line + self.match = None + self.entity = None + self.macro = None + + self.logger.debug("processing line %d", lineNum) + + if self.processPossibleBlockDelimiter(): + # This is a block delimiter - proceed to next line. + # Block-type-specific stuff goes in processBlockOpen and processBlockClosed. + return + + if self.in_code_block: + # We do no processing in a code block. + return + + ### + # Detect if the previous line was [open,...] starting a refpage + # but this line isn't -- + # If the line is some other block delimiter, + # the related code in self.processPossibleBlockDelimiter() + # would have handled it. + # (because execution would never get to here for that line) + if self.prev_line_ref_page_tag: + self.handleExpectedRefpageBlock() + + ### + # Detect headings + if line.startswith('=='): + # Headings cause us to clear our pname_context + self.pname_data = None + + command = self.heading_command_re.match(line) + if command: + data = self.checker.findEntity(command) + if data: + self.pname_data = data + return + + ### + # Detect [open, lines for manpages + if line.startswith('[open,'): + self.checkRefPage() + return + + ### + # Skip comments + if line.lstrip().startswith('//'): + return + + ### + # Skip ifdef/endif + if SKIP_LINE.match(line): + return + + ### + # Detect any include:: lines + match = INCLUDE_PATH_ATTRIBUTE.match(line) + if match: + path_attribute = match.group(1) + if path_attribute is None: + self.error(MessageId.MISSING_INCLUDE_PATH_ATTRIBUTE, + '(no path attribute is present)') + return + if path_attribute not in allowed_path_attributes: + self.error(MessageId.MISSING_INCLUDE_PATH_ATTRIBUTE, + f'(path attribute {{path_attribute}} is not one of {sorted(allowed_path_attributes)})') + return + + ### + # Detect include:::....[] lines for generated API fragments + match = INCLUDE.match(line) + if match: + self.match = match + entity = match.group('entity_name') + + data = self.checker.findEntity(entity) + if not data: + self.error(MessageId.UNKNOWN_INCLUDE, + f'Saw include for {entity}, but that entity is unknown.') + self.pname_data = None + return + + self.pname_data = data + + if match.group('generated_type') == 'api': + self.recordInclude(self.checker.apiIncludes) + + # Set mentions to None. The first time we see something like `* pname:paramHere`, + # we will set it to an empty set + self.pname_mentions[entity] = None + + if match.group('category') in CATEGORIES_WITH_VALIDITY: + self.fs_api_includes[entity] = self.storeMessageContext() + + if entity in self.validity_includes: + name_and_line = toNameAndLine( + self.validity_includes[entity], root_path=self.checker.root_path) + self.error(MessageId.API_VALIDITY_ORDER, + [f'/api/ include found for {entity} after a corresponding /validity/ include', + f'Validity include located at {name_and_line}']) + + elif match.group('generated_type') == 'validity': + self.recordInclude(self.checker.validityIncludes) + self.validity_includes[entity] = self.storeMessageContext() + + if entity not in self.pname_mentions: + self.error(MessageId.API_VALIDITY_ORDER, + f'/validity/ include found for {entity} without a preceding /api/ include') + return + + if self.pname_mentions[entity]: + # Got a validity include and we have seen at least one * pname: line + # since we got the API include + # so we can warn if we haven't seen a reference to every + # parameter/member. + members = self.checker.getMemberNames(entity) + missing = [member for member in members + if member not in self.pname_mentions[entity]] + if missing: + self.error(MessageId.UNDOCUMENTED_MEMBER, + [f'Validity include found for {entity}, but not all members/params apparently documented', + f"Members/params not mentioned with pname: {', '.join(missing)}"]) + + # If we found an include line, we're done with this line. + return + + if self.pname_data is not None and '* pname:' in line: + context_entity = self.pname_data.entity + if self.pname_mentions[context_entity] is None: + # First time seeing * pname: after an api include, prepare the set that + # tracks + self.pname_mentions[context_entity] = set() + + ### + # Detect [[Entity]] anchors + for match in ANCHOR.finditer(line): + entity = match.group('entity_name') + if self.checker.findEntity(entity): + # We found an anchor with the same name as an entity: + # treat it (mostly) like an API include + self.match = match + self.recordInclude(self.checker.apiIncludes, + generated_type='api (manual anchor)') + + ### + # Detect :: without pname + for match in MEMBER_REFERENCE.finditer(line): + if not match.group('member_macro'): + self.match = match + # Got :: but not followed by pname + + search = match.group() + replacement = match.group( + 'first_part') + '::pname:' + match.group('second_part') + self.error(MessageId.MEMBER_PNAME_MISSING, + 'Found a function parameter or struct member reference with :: but missing pname:', + group='double_colons', + replacement='::pname:', + fix=(search, replacement)) + + # check pname here because it won't come up in normal iteration below + # because of the missing macro + self.entity = match.group('entity_name') + self.checkPname(match.group('scope')) + + ### + # Look for things that seem like a missing macro. + for match in self.suspected_missing_macro_re.finditer(line): + if OPEN_LINK.match(line, endpos=match.start()): + # this is in a link, skip it. + continue + if CLOSE_LINK.match(line[match.end():]): + # this is in a link, skip it. + continue + + entity = match.group('entity_name') + self.match = match + self.entity = entity + data = self.checker.findEntity(entity) + if data: + + if data.category == EXTENSION_CATEGORY: + # Ah, this is an extension + self.warning(MessageId.EXTENSION, "Seems like this is an extension name that was not linked.", + group='entity_name', replacement=self.makeExtensionLink()) + else: + macro = data.macro + category = data.category + self.warning(MessageId.MISSING_MACRO, + [f'Seems like a "{macro}" macro was omitted for this reference to a known entity in category "{category}".', + 'Wrap in ` ` to silence this if you do not want a verified macro here.'], + group='entity_name', + replacement=self.makeMacroMarkup(data.macro)) + else: + + dataArray = self.checker.findEntityCaseInsensitive(entity) + # We might have found the goof... + + if dataArray: + if len(dataArray) == 1: + # Yep, found the goof: + # incorrect macro and entity capitalization + data = dataArray[0] + if data.category == EXTENSION_CATEGORY: + # Ah, this is an extension + self.warning(MessageId.EXTENSION, + "Seems like this is an extension name that was not linked.", + group='entity_name', replacement=self.makeExtensionLink(data.entity)) + else: + self.warning(MessageId.MISSING_MACRO, + 'Seems like a macro was omitted for this reference to a known entity in category "{}"' + ', found by searching case-insensitively.'.format( + data.category), + replacement=self.makeMacroMarkup(data=data)) + + else: + # Ugh, more than one resolution + + self.warning(MessageId.MISSING_MACRO, + ['Seems like a macro was omitted for this reference to a known entity, found by searching case-insensitively.', + 'More than one apparent match.'], + group='entity_name', see_also=dataArray[:]) + + ### + # Main operations: detect markup macros + for match in self.checker.macro_re.finditer(line): + self.match = match + self.macro = match.group('macro') + self.entity = match.group('entity_name') + self.subscript = match.group('subscript') + self.processMatch() + + def processPossibleBlockDelimiter(self): + """Look at the current line, and if it's a delimiter, update the block stack. + + Calls self.processBlockDelimiter() as required. + + Returns True if a delimiter was processed, False otherwise. + """ + line = self.line + new_block_type = BlockType.lineToBlockType(line) + if not new_block_type: + return False + + ### + # Detect if the previous line was [open,...] starting a refpage + # but this line is some block delimiter other than -- + # Must do this here because if we get a different block open instead of the one we want, + # the order of block opening will be wrong. + if new_block_type != BlockType.REF_PAGE_LIKE and self.prev_line_ref_page_tag: + self.handleExpectedRefpageBlock() + + # Delegate to the main process for delimiters. + self.processBlockDelimiter(line, new_block_type) + + return True + + def processBlockDelimiter(self, line, new_block_type, context=None): + """Update the block stack based on the current or supplied line. + + Calls self.processBlockOpen() or self.processBlockClosed() as required. + + Called by self.processPossibleBlockDelimiter() both in normal operation, as well as + when "faking" a ref page block open. + + Returns BlockProcessResult. + """ + if not context: + context = self.storeMessageContext() + + location = self.getBriefLocation(context) + + top = self.getInnermostBlockEntry() + top_delim = self.getInnermostBlockDelimiter() + if top_delim == line: + self.processBlockClosed() + return + + if top and top.block_type == new_block_type: + # Same block type, but not matching - might be an error? + # TODO maybe create a diagnostic here? + self.logger.warning( + "processPossibleBlockDelimiter: %s: Matched delimiter type %s, but did not exactly match current delim %s to top of stack %s, may be a typo?", + location, new_block_type, line, top_delim) + + # Empty stack, or top doesn't match us. + self.processBlockOpen(new_block_type, delimiter=line) + + def processBlockOpen(self, block_type, context=None, delimiter=None): + """Do any block-type-specific processing and push the new block. + + Must call self.pushBlock(). + May be overridden (carefully) or extended. + + Called by self.processBlockDelimiter(). + """ + if block_type == BlockType.REF_PAGE_LIKE: + if self.prev_line_ref_page_tag: + if self.current_ref_page: + refpage = self.current_ref_page + else: + refpage = '?refpage-with-invalid-tag?' + + self.logger.info( + 'processBlockOpen: Opening refpage for %s', refpage) + # Opening of refpage block "consumes" the preceding ref + # page context + self.prev_line_ref_page_tag = None + self.pushBlock(block_type, refpage=refpage, + context=context, delimiter=delimiter) + self.in_ref_page = True + return + + if block_type == BlockType.CODE: + self.in_code_block = True + + self.pushBlock(block_type, context=context, delimiter=delimiter) + + def processBlockClosed(self): + """Do any block-type-specific processing and pop the top block. + + Must call self.popBlock(). + May be overridden (carefully) or extended. + + Called by self.processPossibleBlockDelimiter(). + """ + old_top = self.popBlock() + + if old_top.block_type == BlockType.CODE: + self.in_code_block = False + + elif old_top.block_type == BlockType.REF_PAGE_LIKE and old_top.refpage: + self.logger.info( + 'processBlockClosed: Closing refpage for %s', old_top.refpage) + # leaving a ref page so reset associated state. + self.current_ref_page = None + self.prev_line_ref_page_tag = None + self.in_ref_page = False + + def processMatch(self): + """Process a match of the macro:entity regex for correctness.""" + match = self.match + entity = self.entity + macro = self.macro + + ### + # Track entities that we're actually linking to. + ### + if self.checker.entity_db.isLinkedMacro(macro): + self.checker.addLinkToEntity(entity, self.storeMessageContext()) + + ### + # Link everything that should be, and nothing that shouldn't be + ### + if self.checkRecognizedEntity(): + # if this returns true, + # then there is no need to do the remaining checks on this match + return + + ### + # Non-existent macros + if macro in NON_EXISTENT_MACROS: + self.error(MessageId.BAD_MACRO, '{} is not a macro provided in the specification, despite resembling other macros.'.format( + macro), group='macro') + + ### + # Wildcards (or leading underscore, or square brackets) + # if and only if a 'text' macro + self.checkText() + + # Do some validation of pname references. + if macro == 'pname': + # there is only a macro if there is a match + assert match + # See if there's an immediately-preceding entity + preceding = self.line[:match.start()] + scope = PRECEDING_MEMBER_REFERENCE.search(preceding) + if scope: + # Yes there is, check it out. + self.checkPname(scope.group('entity_name')) + elif self.current_ref_page is not None: + # No, but there is a current ref page: very reliable + self.checkPnameImpliedContext(self.current_ref_page) + elif self.pname_data is not None: + # No, but there is a pname_context - better than nothing. + self.checkPnameImpliedContext(self.pname_data) + else: + # no, and no existing context we can imply: + # can't check this. + pass + + def shouldSkipUnrecognizedEntity(self, macro, entity_name): + """Return True if we should not warn about not recognizing a macro invocation for entity_name.""" + return False + + def checkRecognizedEntity(self): + """Check the current macro:entity match to see if it is recognized. + + Returns True if there is no need to perform further checks on this match. + + Helps avoid duplicate warnings/errors: typically each macro should have at most + one of this class of errors. + """ + entity = self.entity + macro = self.macro + assert macro + if self.checker.findMacroAndEntity(macro, entity) is not None: + # We know this macro-entity combo + return True + + # We don't know this macro-entity combo. + possibleCats = self.checker.entity_db.getCategoriesForMacro(macro) + if possibleCats is None: + possibleCats = ['???'] + msg = ['Definition of link target {} with macro {} (used for {} {}) does not exist.'.format( + entity, + macro, + _pluralize('category', len(possibleCats)), + ', '.join(possibleCats))] + + if self.shouldSkipUnrecognizedEntity(macro, entity): + return False + + data = self.checker.findEntity(entity) + if data: + # We found the goof: incorrect macro + msg.append(f'Apparently matching entity in category {data.category} found.') + self.handleWrongMacro(msg, data) + return True + + see_also = [] + dataArray = self.checker.findEntityCaseInsensitive(entity) + if dataArray: + # We might have found the goof... + + if len(dataArray) == 1: + # Yep, found the goof: + # incorrect macro and entity capitalization + data = dataArray[0] + msg.append('Apparently matching entity in category {} found by searching case-insensitively.'.format( + data.category)) + self.handleWrongMacro(msg, data) + return True + else: + # Ugh, more than one resolution + msg.append( + 'More than one apparent match found by searching case-insensitively, cannot auto-fix.') + see_also = dataArray[:] + + # OK, so we don't recognize this entity (and couldn't auto-fix it). + + if self.checker.entity_db.shouldBeRecognized(macro, entity): + # We should know the target - it's a link macro, + # or there's some reason the entity DB thinks we should know it. + if self.checker.likelyRecognizedEntity(entity): + # Should be linked and it matches our pattern, + # so probably not wrong macro. + # Human brains required. + if not self.checkText(): + self.error(MessageId.BAD_ENTITY, msg + ['Might be a misspelling, or, less likely, the wrong macro.'], + see_also=see_also) + else: + # Doesn't match our pattern, + # so probably should be name instead of link. + newMacro = f"{macro[0]}name" + if self.checker.entity_db.isValidMacro(newMacro): + self.error(MessageId.BAD_ENTITY, msg + + ['Entity name does not fit the pattern for this API, which would mean it should be a "name" macro instead of a "link" macro'], + group='macro', replacement=newMacro, fix=self.makeFix(newMacro=newMacro), see_also=see_also) + else: + self.error(MessageId.BAD_ENTITY, msg + + ['Entity name does not fit the pattern for this API, which would mean it should be a "name" macro instead of a "link" macro', + f'However, {newMacro} is not a known macro so cannot auto-fix.'], see_also=see_also) + + elif macro == 'ename': + # TODO This might be an ambiguity in the style guide - ename might be a known enumerant value, + # or it might be an enumerant value in an external library, etc. that we don't know about - so + # hard to check this. + if self.checker.likelyRecognizedEntity(entity): + if not self.checkText(): + self.warning(MessageId.BAD_ENUMERANT, msg + + [f'Unrecognized ename:{entity} that we would expect to recognize since it fits the pattern for this API.'], + see_also=see_also) + else: + # This is fine: + # it doesn't need to be recognized since it's not linked. + pass + # Don't skip other tests. + return False + + def checkText(self): + """Evaluate the usage (or non-usage) of a *text macro. + + Wildcards (or leading or trailing underscore, or square brackets with + nothing or a placeholder) if and only if a 'text' macro. + + Called by checkRecognizedEntity() when appropriate. + """ + macro = self.macro + entity = self.entity + shouldBeText = shouldEntityBeText(entity, self.subscript) + assert macro + if shouldBeText and not macro.endswith('text') and not macro == 'code': + newMacro = f"{macro[0]}text" + if self.checker.entity_db.getCategoriesForMacro(newMacro): + self.error(MessageId.MISSING_TEXT, + [f'Asterisk/leading or trailing underscore/bracket found - macro should end with "text:", probably {newMacro}:', + AUTO_FIX_STRING], + group='macro', replacement=newMacro, fix=self.makeFix(newMacro=newMacro)) + else: + self.error(MessageId.MISSING_TEXT, + ['Asterisk/leading or trailing underscore/bracket found, so macro should end with "text:".', + f'However {newMacro}: is not a known macro so cannot auto-fix.'], + group='macro') + return True + elif macro.endswith('text') and not shouldBeText: + msg = [ + f"No asterisk/leading or trailing underscore/bracket in the entity, so this might be a mistaken use of the 'text' macro {macro}:"] + data = self.checker.findEntity(entity) + if data: + if self.shouldSkipUnrecognizedEntity(macro, entity): + return False + + # We found the goof: incorrect macro + msg.append('Apparently matching entity in category {} found.'.format( + data.category)) + msg.append(AUTO_FIX_STRING) + replacement = self.makeFix(data=data) + if data.category == EXTENSION_CATEGORY: + self.error(MessageId.EXTENSION, msg, + replacement=replacement, fix=replacement) + else: + self.error(MessageId.WRONG_MACRO, msg, + group='macro', replacement=data.macro, fix=replacement) + else: + if self.checker.likelyRecognizedEntity(entity): + # This is a use of *text: for something that fits the pattern but isn't in the spec. + # This is OK. + return False + msg.append('Entity not found in spec, either.') + if macro[0] != 'e': + # Only suggest a macro if we aren't in elink/ename/etext, + # since ename and elink are not related in an equivalent way + # to the relationship between flink and fname. + newMacro = f"{macro[0]}name" + if self.checker.entity_db.getCategoriesForMacro(newMacro): + msg.append( + f'Consider if {newMacro}: might be the correct macro to use here.') + else: + msg.append( + f'Cannot suggest a new macro because {newMacro}: is not a known macro.') + self.warning(MessageId.MISUSED_TEXT, msg) + return True + return False + + def checkPnameImpliedContext(self, pname_context): + """Handle pname: macros not immediately preceded by something like flink:entity or slink:entity. + + Also records pname: mentions of members/parameters for completeness checking in doc blocks. + + Contains call to self.checkPname(). + Called by self.processMatch() + """ + self.checkPname(pname_context.entity) + if pname_context.entity in self.pname_mentions and \ + self.pname_mentions[pname_context.entity] is not None: + # Record this mention, + # in case we're in the documentation block. + self.pname_mentions[pname_context.entity].add(self.entity) + + def checkPname(self, pname_context): + """Check the current match (as a pname: usage) with the given entity as its 'pname context', if possible. + + e.g. slink:foo::pname:bar, pname_context would be 'foo', while self.entity would be 'bar', etc. + + Called by self.processLine(), self.processMatch(), as well as from self.checkPnameImpliedContext(). + """ + if '*' in pname_context: + # This context has a placeholder, can't verify it. + return + + entity = self.entity + + context_data = self.checker.findEntity(pname_context) + members = self.checker.getMemberNames(pname_context) + + if context_data and not members: + # This is a recognized parent entity that doesn't have detectable member names, + # skip validation + # TODO: Annotate parameters of function pointer types with + # and ? + return + if not members: + self.warning(MessageId.UNRECOGNIZED_CONTEXT, + f'pname context entity was un-recognized {pname_context}') + return + + if entity not in members: + self.warning(MessageId.UNKNOWN_MEMBER, [f"Could not find member/param named '{entity}' in {pname_context}", + 'Known {} member/param names are: {}'.format( + pname_context, ', '.join(members))], group='entity_name') + + def checkIncludeRefPageRelation(self, entity, generated_type): + """Identify if our current ref page (or lack thereof) is appropriate for an include just recorded. + + Called by self.recordInclude(). + """ + if not self.in_ref_page: + # Not in a ref page block: This probably means this entity needs a + # ref-page block added. + self.handleIncludeMissingRefPage(entity, generated_type) + return + + if not isinstance(self.current_ref_page, EntityData): + # This isn't a fully-valid ref page, so can't check the includes any better. + return + + ref_page_entity = self.current_ref_page.entity + if ref_page_entity not in self.refpage_includes: + self.refpage_includes[ref_page_entity] = set() + expected_ref_page_entity = self.computeExpectedRefPageFromInclude( + entity) + self.refpage_includes[ref_page_entity].add((generated_type, entity)) + + if ref_page_entity == expected_ref_page_entity: + # OK, this is a total match. + pass + elif self.checker.entity_db.areAliases(expected_ref_page_entity, ref_page_entity): + # This appears to be a promoted synonym which is OK. + pass + else: + # OK, we are in a ref page block that doesn't match + self.handleIncludeMismatchRefPage(entity, generated_type) + + def perform_entity_check(self, type): + """Returns True if an entity check should be performed on this + refpage type. + + May override.""" + + return True + + def checkRefPage(self): + """Check if the current line (a refpage tag) meets requirements. + + Called by self.processLine(). + """ + line = self.line + + # Should always be found + self.match = BRACKETS.match(line) + + data = None + directory = None + if self.in_ref_page: + msg = ["Found reference page markup, but we are already in a refpage block.", + "The block before the first message of this type is most likely not closed.", ] + # Fake-close the previous ref page, if it's trivial to do so. + innermost_block = self.getInnermostBlockEntry() + # self.in_ref_page is true only when the innermost block is something + assert innermost_block + if innermost_block.block_type == BlockType.REF_PAGE_LIKE: + msg.append( + "Pretending that there was a line with `--` immediately above to close that ref page, for more readable messages.") + self.processBlockDelimiter( + REF_PAGE_LIKE_BLOCK_DELIM, BlockType.REF_PAGE_LIKE) + else: + msg.append( + "Ref page wasn't the last block opened, so not pretending to auto-close it for more readable messages.") + + self.error(MessageId.REFPAGE_BLOCK, msg) + + attribs = parseRefPageAttribs(line) + + unknown_attribs = set(attribs.keys()).difference( + VALID_REF_PAGE_ATTRIBS) + if unknown_attribs: + self.error(MessageId.REFPAGE_UNKNOWN_ATTRIB, + f"Found unknown attrib(s) in reference page markup: {','.join(unknown_attribs)}") + + # Required field: refpage='xrValidEntityHere' + if Attrib.REFPAGE.value in attribs: + attrib = attribs[Attrib.REFPAGE.value] + text = attrib.value + self.entity = text + + context = self.storeMessageContext( + group='value', match=attrib.match) + if self.checker.seenRefPage(text): + self.error(MessageId.REFPAGE_DUPLICATE, + ["Found reference page markup when we already saw refpage='{}' elsewhere.".format( + text), + "This (or the other mention) may be a copy-paste error."], + context=context) + self.checker.addRefPage(text) + + # Entity check can be skipped depending on the refpage type + # Determine page type for use in several places + type_text = '' + if Attrib.TYPE.value in attribs: + type_text = attribs[Attrib.TYPE.value].value + + if self.perform_entity_check(type_text): + data = self.checker.findEntity(text) + if data: + # OK, this is a known entity that we're seeing a refpage for. + directory = data.directory + self.current_ref_page = data + else: + # TODO suggest fixes here if applicable + self.error(MessageId.REFPAGE_NAME, + ["Found reference page markup, but refpage='{}' type='{}' does not refer to a recognized entity".format( + text, type_text), + 'If this is intentional, add the entity to EXTRA_DEFINES or EXTRA_REFPAGES in check_spec_links.py.'], + context=context) + else: + self.error(MessageId.REFPAGE_TAG, + "Found apparent reference page markup, but missing refpage='...'", + group=None) + + # Required field: desc='preferably non-empty' + if Attrib.DESC.value in attribs: + attrib = attribs[Attrib.DESC.value] + text = attrib.value + if not text: + context = self.storeMessageContext( + group=None, match=attrib.match) + self.warning(MessageId.REFPAGE_MISSING_DESC, + "Found reference page markup, but desc='' is empty", + context=context) + else: + self.error(MessageId.REFPAGE_TAG, + "Found apparent reference page markup, but missing desc='...'", + group=None) + + # Required field: type='protos' for example + # (used by genRef.py to compute the macro to use) + if Attrib.TYPE.value in attribs: + attrib = attribs[Attrib.TYPE.value] + text = attrib.value + if directory and not text == directory: + context = self.storeMessageContext( + group='value', match=attrib.match) + self.error(MessageId.REFPAGE_TYPE, + "Found reference page markup, but type='{}' is not the expected value '{}'".format( + text, directory), + context=context) + else: + self.error(MessageId.REFPAGE_TAG, + "Found apparent reference page markup, but missing type='...'", + group=None) + + # Optional field: alias='spaceDelimited validEntities' + # Currently does nothing. Could modify checkRefPageXrefs to also + # check alias= attribute value + # if Attrib.ALIAS.value in attribs: + # # This field is optional + # self.checkRefPageXrefs(attribs[Attrib.XREFS.value]) + + # Optional field: xrefs='spaceDelimited validEntities' + if Attrib.XREFS.value in attribs: + # This field is optional + self.checkRefPageXrefs(attribs[Attrib.XREFS.value]) + self.prev_line_ref_page_tag = self.storeMessageContext() + + def checkRefPageXrefs(self, xrefs_attrib): + """Check all cross-refs indicated in an xrefs attribute for a ref page. + + Called by self.checkRefPage(). + + Argument: + xrefs_attrib -- A match of REF_PAGE_ATTRIB where the group 'key' is 'xrefs'. + """ + text = xrefs_attrib.value + context = self.storeMessageContext( + group='value', match=xrefs_attrib.match) + + def splitRefs(s): + """Split the string on whitespace, into individual references.""" + return s.split() # [x for x in s.split() if x] + + def remakeRefs(refs): + """Re-create a xrefs string from something list-shaped.""" + return ' '.join(refs) + + refs = splitRefs(text) + + # Pre-checking if messages are enabled, so that we can correctly determine + # the current string following any auto-fixes: + # the fixes for messages directly in this method would interact, + # and thus must be in the order specified here. + + if self.messageEnabled(MessageId.REFPAGE_XREFS_COMMA) and ',' in text: + old_text = text + # Re-split after replacing commas. + refs = splitRefs(text.replace(',', ' ')) + # Re-create the space-delimited text. + text = remakeRefs(refs) + self.error(MessageId.REFPAGE_XREFS_COMMA, + "Found reference page markup, with an unexpected comma in the (space-delimited) xrefs attribute", + context=context, + replacement=text, + fix=(old_text, text)) + + # We could conditionally perform this creation, but the code complexity would increase substantially, + # for presumably minimal runtime improvement. + unique_refs = OrderedDict.fromkeys(refs) + if self.messageEnabled(MessageId.REFPAGE_XREF_DUPE) and len(unique_refs) != len(refs): + # TODO is it safe to auto-fix here? + old_text = text + text = remakeRefs(unique_refs.keys()) + self.warning(MessageId.REFPAGE_XREF_DUPE, + ["Reference page for {} contains at least one duplicate in its cross-references.".format( + self.entity), + "Look carefully to see if this is a copy and paste error and should be changed to a different but related entity:", + "auto-fix simply removes the duplicate."], + context=context, + replacement=text, + fix=(old_text, text)) + + if self.messageEnabled(MessageId.REFPAGE_SELF_XREF) and self.entity and self.entity in unique_refs: + # Not modifying unique_refs here because that would accidentally affect the whitespace auto-fix. + new_text = remakeRefs( + [x for x in unique_refs.keys() if x != self.entity]) + + # DON'T AUTOFIX HERE because these are likely copy-paste between related entities: + # e.g. a Create function and the associated CreateInfo struct. + self.warning(MessageId.REFPAGE_SELF_XREF, + [f"Reference page for {self.entity} included itself in its cross-references.", + "This is typically a copy and paste error, and the dupe should likely be changed to a different but related entity.", + "Not auto-fixing for this reason."], + context=context, + replacement=new_text,) + + # We didn't have another reason to replace the whole attribute value, + # so let's make sure it doesn't have any extra spaces + if self.messageEnabled(MessageId.REFPAGE_WHITESPACE) and xrefs_attrib.value == text: + old_text = text + text = remakeRefs(unique_refs.keys()) + if old_text != text: + self.warning(MessageId.REFPAGE_WHITESPACE, + [f"Cross-references for reference page for {self.entity} had non-minimal whitespace,", + "and no other enabled message has re-constructed this value already."], + context=context, + replacement=text, + fix=(old_text, text)) + + for entity in unique_refs.keys(): + self.checkRefPageXref(entity, context) + + @property + def allowEnumXrefs(self): + """Returns True if enums can be specified in the 'xrefs' attribute + of a refpage. + + May override. + """ + return False + + def checkRefPageXref(self, referenced_entity, line_context): + """Check a single cross-reference entry for a refpage. + + Called by self.checkRefPageXrefs(). + + Arguments: + referenced_entity -- The individual entity under consideration from the xrefs='...' string. + line_context -- A MessageContext referring to the entire line. + """ + data = self.checker.findEntity(referenced_entity) + context = line_context + match = re.search(r'\b{}\b'.format(referenced_entity), self.line) + if match: + context = self.storeMessageContext( + group=None, match=match) + + if data and data.category == "enumvalues" and not self.allowEnumXrefs: + msg = ["Found reference page markup, with an enum value listed: {}".format( + referenced_entity)] + self.error(MessageId.REFPAGE_XREFS, + msg, + context=context) + return + + if data: + # This is OK: we found it, and it's not an enum value + return + + msg = ["Found reference page markup, with an unrecognized entity listed: {}".format( + referenced_entity)] + + see_also = None + dataArray = self.checker.findEntityCaseInsensitive( + referenced_entity) + + if dataArray: + # We might have found the goof... + + if len(dataArray) == 1: + # Yep, found the goof - incorrect entity capitalization + data = dataArray[0] + new_entity = data.entity + self.error(MessageId.REFPAGE_XREFS, msg + [ + 'Apparently matching entity in category {} found by searching case-insensitively.'.format( + data.category), + AUTO_FIX_STRING], + replacement=new_entity, + fix=(referenced_entity, new_entity), + context=context) + return + + # Ugh, more than one resolution + msg.append( + 'More than one apparent match found by searching case-insensitively, cannot auto-fix.') + see_also = dataArray[:] + else: + # Probably not just a typo + msg.append( + 'If this is intentional, add the entity to EXTRA_DEFINES or EXTRA_REFPAGES in check_spec_links.py.') + + # Multiple or no resolutions found + self.error(MessageId.REFPAGE_XREFS, + msg, + see_also=see_also, + context=context) + + ### + # Message-related methods. + ### + + def warning(self, message_id, messageLines, context=None, group=None, + replacement=None, fix=None, see_also=None, frame=None): + """Log a warning for the file, if the message ID is enabled. + + Wrapper around self.diag() that automatically sets severity as well as frame. + + Arguments: + message_id -- A MessageId value. + messageLines -- A string or list of strings containing a human-readable error description. + + Optional, named arguments: + context -- A MessageContext. If None, will be constructed from self.match and group. + group -- The name of the regex group in self.match that contains the problem. Only used if context is None. + If needed and is None, self.group is used instead. + replacement -- The string, if any, that should be suggested as a replacement for the group in question. + Does not create an auto-fix: sometimes we want to show a possible fix but aren't confident enough + (or can't easily phrase a regex) to do it automatically. + fix -- A (old text, new text) pair if this error is auto-fixable safely. + see_also -- An optional array of other MessageContext locations relevant to this message. + frame -- The 'inspect' stack frame corresponding to the location that raised this message. + If None, will assume it is the direct caller of self.warning(). + """ + if not frame: + f = currentframe() + if f: + frame = f.f_back + self.diag(MessageType.WARNING, message_id, messageLines, group=group, + replacement=replacement, context=context, fix=fix, see_also=see_also, frame=frame) + + def error(self, message_id, messageLines, group=None, replacement=None, + context=None, fix=None, see_also=None, frame=None): + """Log an error for the file, if the message ID is enabled. + + Wrapper around self.diag() that automatically sets severity as well as frame. + + Arguments: + message_id -- A MessageId value. + messageLines -- A string or list of strings containing a human-readable error description. + + Optional, named arguments: + context -- A MessageContext. If None, will be constructed from self.match and group. + group -- The name of the regex group in self.match that contains the problem. Only used if context is None. + If needed and is None, self.group is used instead. + replacement -- The string, if any, that should be suggested as a replacement for the group in question. + Does not create an auto-fix: sometimes we want to show a possible fix but aren't confident enough + (or can't easily phrase a regex) to do it automatically. + fix -- A (old text, new text) pair if this error is auto-fixable safely. + see_also -- An optional array of other MessageContext locations relevant to this message. + frame -- The 'inspect' stack frame corresponding to the location that raised this message. + If None, will assume it is the direct caller of self.error(). + """ + if not frame: + f = currentframe() + if f: + frame = f.f_back + self.diag(MessageType.ERROR, message_id, messageLines, group=group, + replacement=replacement, context=context, fix=fix, see_also=see_also, frame=frame) + + def diag(self, severity, message_id, messageLines, context=None, group=None, + replacement=None, fix=None, see_also=None, frame=None): + """Log a diagnostic for the file, if the message ID is enabled. + + Also records the auto-fix, if applicable. + + Arguments: + severity -- A MessageType value. + message_id -- A MessageId value. + messageLines -- A string or list of strings containing a human-readable error description. + + Optional, named arguments: + context -- A MessageContext. If None, will be constructed from self.match and group. + group -- The name of the regex group in self.match that contains the problem. Only used if context is None. + If needed and is None, self.group is used instead. + replacement -- The string, if any, that should be suggested as a replacement for the group in question. + Does not create an auto-fix: sometimes we want to show a possible fix but aren't confident enough + (or can't easily phrase a regex) to do it automatically. + fix -- A (old text, new text) pair if this error is auto-fixable safely. + see_also -- An optional array of other MessageContext locations relevant to this message. + frame -- The 'inspect' stack frame corresponding to the location that raised this message. + If None, will assume it is the direct caller of self.diag(). + """ + if not self.messageEnabled(message_id): + self.logger.debug( + 'Discarding a %s message because it is disabled.', message_id) + return + + if isinstance(messageLines, str): + messageLines = [messageLines] + + self.logger.info('Recording a %s message: %s', + message_id, ' '.join(messageLines)) + + # Ensure all auto-fixes are marked as such. + if fix is not None and AUTO_FIX_STRING not in messageLines: + messageLines.append(AUTO_FIX_STRING) + + if not frame: + f = currentframe() + if f: + frame = f.f_back + if context is None: + message = Message(message_id=message_id, + message_type=severity, + message=messageLines, + context=self.storeMessageContext(group=group), + replacement=replacement, + see_also=see_also, + fix=fix, + frame=frame) + else: + message = Message(message_id=message_id, + message_type=severity, + message=messageLines, + context=context, + replacement=replacement, + see_also=see_also, + fix=fix, + frame=frame) + if fix is not None: + self.fixes.add(fix) + self.messages.append(message) + + def messageEnabled(self, message_id): + """Return true if the given message ID is enabled.""" + return message_id in self.enabled_messages + + ### + # Accessors for externally-interesting information + + def numDiagnostics(self): + """Count the total number of diagnostics (errors or warnings) for this file.""" + return len(self.messages) + + def numErrors(self): + """Count the total number of errors for this file.""" + return self.numMessagesOfType(MessageType.ERROR) + + def numMessagesOfType(self, message_type): + """Count the number of messages of a particular type (severity).""" + return len( + [msg for msg in self.messages if msg.message_type == message_type]) + + def hasFixes(self): + """Return True if any messages included auto-fix patterns.""" + return len(self.fixes) > 0 + + ### + # Assorted internal methods. + def printMessageCounts(self): + """Print a simple count of each MessageType of diagnostics.""" + for message_type in [MessageType.ERROR, MessageType.WARNING]: + count = self.numMessagesOfType(message_type) + if count > 0: + print(f'{count} {message_type}{_s_suffix(count)} generated.') + + def dumpInternals(self): + """Dump internal variables to screen, for debugging.""" + print('self.lineNum: ', self.lineNum) + print('self.line:', self.line) + print('self.prev_line_ref_page_tag: ', self.prev_line_ref_page_tag) + print('self.current_ref_page:', self.current_ref_page) + + def getMissingValiditySuppressions(self): + """Return an enumerable of entity names that we shouldn't warn about missing validity. + + May override. + """ + return [] + + def recordInclude(self, include_dict, generated_type=None): + """Store the current line as being the location of an include directive or equivalent. + + Reports duplicate include errors, as well as include/ref-page mismatch or missing ref-page, + by calling self.checkIncludeRefPageRelation() for "actual" includes (where generated_type is None). + + Arguments: + include_dict -- The include dictionary to update: one of self.apiIncludes or self.validityIncludes. + generated_type -- The type of include (e.g. 'api', 'valid', etc). By default, extracted from self.match. + """ + assert self.match + entity = self.match.group('entity_name') + if generated_type is None: + generated_type = self.match.group('generated_type') + + # Only checking the ref page relation if it's retrieved from regex. + # Otherwise it might be a manual anchor recorded as an include, + # etc. + self.checkIncludeRefPageRelation(entity, generated_type) + + if entity in include_dict: + self.error(MessageId.DUPLICATE_INCLUDE, + "Included {} docs for {} when they were already included.".format(generated_type, + entity), see_also=include_dict[entity]) + include_dict[entity].append(self.storeMessageContext()) + else: + include_dict[entity] = [self.storeMessageContext()] + + def getInnermostBlockEntry(self): + """Get the BlockEntry for the top block delim on our stack.""" + if not self.block_stack: + return None + return self.block_stack[-1] + + def getInnermostBlockDelimiter(self): + """Get the delimiter for the top block on our stack.""" + top = self.getInnermostBlockEntry() + if not top: + return None + return top.delimiter + + def pushBlock(self, block_type, refpage=None, context=None, delimiter=None): + """Push a new entry on the block stack.""" + if not delimiter: + self.logger.info("pushBlock: not given delimiter") + delimiter = self.line + if not context: + context = self.storeMessageContext() + + old_top_delim = self.getInnermostBlockDelimiter() + + self.block_stack.append(BlockEntry( + delimiter=delimiter, + context=context, + refpage=refpage, + block_type=block_type)) + + location = self.getBriefLocation(context) + self.logger.info( + "pushBlock: %s: Pushed %s delimiter %s, previous top was %s, now %d elements on the stack", + location, block_type.value, delimiter, old_top_delim, len(self.block_stack)) + + self.dumpBlockStack() + + def popBlock(self): + """Pop and return the top entry from the block stack.""" + old_top = self.block_stack.pop() + location = self.getBriefLocation(old_top.context) + self.logger.info( + "popBlock: %s: popping %s delimiter %s, now %d elements on the stack", + location, old_top.block_type.value, old_top.delimiter, len(self.block_stack)) + + self.dumpBlockStack() + + return old_top + + def dumpBlockStack(self): + self.logger.debug('Block stack, top first:') + for distFromTop, x in enumerate(reversed(self.block_stack)): + self.logger.debug(' - block_stack[%d]: Line %d: "%s" refpage=%s', + -1 - distFromTop, + x.context.lineNum, x.delimiter, x.refpage) + + def getBriefLocation(self, context): + """Format a context briefly - omitting the filename if it has newlines in it.""" + if '\n' in context.filename: + return f'input string line {context.lineNum}' + return f'{context.filename}:{context.lineNum}' + + ### + # Handlers for a variety of diagnostic-meriting conditions + # + # Split out for clarity and for allowing fine-grained override on a per-project basis. + ### + + def handleIncludeMissingRefPage(self, entity, generated_type): + """Report a message about an include outside of a ref-page block.""" + msg = [f"Found {generated_type} include for {entity} outside of a reference page block.", + "This is probably a missing reference page block."] + refpage = self.computeExpectedRefPageFromInclude(entity) + data = self.checker.findEntity(refpage) + if data: + msg.append('Expected ref page block might start like:') + msg.append(self.makeRefPageTag(refpage, data=data)) + else: + msg.append( + f"But, expected ref page entity name {refpage} isn't recognized...") + self.warning(MessageId.REFPAGE_MISSING, msg) + + def handleIncludeMismatchRefPage(self, entity, generated_type): + """Report a message about an include not matching its containing ref-page block.""" + assert self.current_ref_page + self.warning(MessageId.REFPAGE_MISMATCH, "Found {} include for {}, inside the reference page block of {}".format( + generated_type, entity, self.current_ref_page.entity)) + + def handleWrongMacro(self, msg, data): + """Report an appropriate message when we found that the macro used is incorrect. + + May be overridden depending on each API's behavior regarding macro misuse: + e.g. in some cases, it may be considered a MessageId.LEGACY warning rather than + a MessageId.WRONG_MACRO or MessageId.EXTENSION. + """ + message_type = MessageType.WARNING + message_id = MessageId.WRONG_MACRO + group = 'macro' + + if data.category == EXTENSION_CATEGORY: + # Ah, this is an extension + msg.append( + 'This is apparently an extension name, which should be marked up as a link.') + message_id = MessageId.EXTENSION + group = None # replace the whole thing + else: + # Non-extension, we found the macro though. + message_type = MessageType.ERROR + msg.append(AUTO_FIX_STRING) + self.diag(message_type, message_id, msg, + group=group, replacement=self.makeMacroMarkup(data=data), fix=self.makeFix(data=data)) + + def handleExpectedRefpageBlock(self): + """Handle expecting to see -- to start a refpage block, but not seeing that at all.""" + self.error(MessageId.REFPAGE_BLOCK, + ["Expected, but did not find, a line containing only -- following a reference page tag,", + "Pretending to insert one, for more readable messages."], + see_also=[self.prev_line_ref_page_tag]) + # Fake "in ref page" regardless, to avoid spurious extra errors. + self.processBlockDelimiter('--', BlockType.REF_PAGE_LIKE, + context=self.prev_line_ref_page_tag) + + ### + # Construct related values (typically named tuples) based on object state and supplied arguments. + # + # Results are typically supplied to another method call. + ### + + def storeMessageContext(self, group=None, match=None): + """Create message context from corresponding instance variables. + + Arguments: + group -- The regex group name, if any, identifying the part of the match to highlight. + match -- The regex match. If None, will use self.match. + """ + if match is None: + match = self.match + return MessageContext(filename=self.filename, + lineNum=self.lineNum, + line=self.line, + match=match, + group=group) + + def makeFix(self, newMacro=None, newEntity=None, data=None): + """Construct a fix pair for replacing the old macro:entity with new. + + Wrapper around self.makeSearch() and self.makeMacroMarkup(). + """ + return (self.makeSearch(), self.makeMacroMarkup( + newMacro, newEntity, data)) + + def makeSearch(self): + """Construct the string self.macro:self.entity, for use in the old text part of a fix pair.""" + return f'{self.macro}:{self.entity}' + + def makeMacroMarkup(self, newMacro=None, newEntity=None, data=None): + """Construct appropriate markup for referring to an entity. + + Typically constructs macro:entity, but can construct `<>` + (or equivalent) if the supplied entity is identified as an extension. + + Arguments: + newMacro -- The macro to use. Defaults to data.macro (if available), otherwise self.macro. + newEntity -- The entity to use. Defaults to data.entity (if available), otherwise self.entity. + data -- An EntityData value corresponding to this entity. If not provided, will be looked up by newEntity. + """ + if not newEntity: + if data: + newEntity = data.entity + else: + newEntity = self.entity + if not newMacro: + if data: + newMacro = data.macro + else: + newMacro = self.macro + if not data: + data = self.checker.findEntity(newEntity) + if data and data.category == EXTENSION_CATEGORY: + return self.makeExtensionLink(newEntity) + return f'{newMacro}:{newEntity}' + + def makeExtensionLink(self, newEntity=None): + """Create a correctly-formatted link to an extension. + + Result takes the form `<>` or whatever the Conventions define. + + Argument: + newEntity -- The extension name to link to. Defaults to self.entity. + """ + if not newEntity: + newEntity = self.entity + return self.checker.conventions().formatExtension(newEntity) + + def computeExpectedRefPageFromInclude(self, entity): + """Compute the expected ref page entity based on an include entity name.""" + # No-op in general. + return entity + + def makeRefPageTag(self, entity, data=None, + ref_type=None, desc='', xrefs=None): + """Construct a ref page tag string from attribute values.""" + if ref_type is None and data is not None: + ref_type = data.directory + if ref_type is None: + ref_type = "????" + return "[open,refpage='{}',type='{}',desc='{}',xrefs='{}']".format( + entity, ref_type, desc, ' '.join(xrefs or [])) diff --git a/libs/VulkanHeaders/spec_tools/main.py b/libs/VulkanHeaders/spec_tools/main.py new file mode 100644 index 0000000000..3ffacacc58 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/main.py @@ -0,0 +1,244 @@ +"""Provides a reusable command-line interface to a MacroChecker.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + + +import argparse +import logging +import re +from pathlib import Path + +from .shared import MessageId + + +def checkerMain(default_enabled_messages, make_macro_checker, + all_docs, available_messages=None): + """Perform the bulk of the work for a command-line interface to a MacroChecker. + + Arguments: + default_enabled_messages -- The MessageId values that should be enabled by default. + make_macro_checker -- A function that can be called with a set of enabled MessageId to create a + properly-configured MacroChecker. + all_docs -- A list of all spec documentation files. + available_messages -- a list of all MessageId values that can be generated for this project. + Defaults to every value. (e.g. some projects don't have MessageId.LEGACY) + """ + enabled_messages = set(default_enabled_messages) + if not available_messages: + available_messages = list(MessageId) + + disable_args = [] + enable_args = [] + + parser = argparse.ArgumentParser() + parser.add_argument( + "--scriptlocation", + help="Append the script location generated a message to the output.", + action="store_true") + parser.add_argument( + "--verbose", + "-v", + help="Output 'info'-level development logging messages.", + action="store_true") + parser.add_argument( + "--debug", + "-d", + help="Output 'debug'-level development logging messages (more verbose than -v).", + action="store_true") + parser.add_argument( + "-Werror", + "--warning_error", + help="Make warnings act as errors, exiting with non-zero error code", + action="store_true") + parser.add_argument( + "--include_warn", + help="List all expected but unseen include files, not just those that are referenced.", + action='store_true') + parser.add_argument( + "-Wmissing_refpages", + help="List all entities with expected but unseen ref page blocks. NOT included in -Wall!", + action='store_true') + parser.add_argument( + "--include_error", + help="Make expected but unseen include files cause exiting with non-zero error code", + action='store_true') + parser.add_argument( + "--broken_error", + help="Make missing include/anchor for linked-to entities cause exiting with non-zero error code. Weaker version of --include_error.", + action='store_true') + parser.add_argument( + "--dump_entities", + help="Just dump the parsed entity data to entities.json and exit.", + action='store_true') + parser.add_argument( + "--html", + help="Output messages to the named HTML file instead of stdout.") + parser.add_argument( + "file", + help="Only check the indicated file(s). By default, all chapters and extensions are checked.", + nargs="*") + parser.add_argument( + "--ignore_count", + type=int, + help="Ignore up to the given number of errors without exiting with a non-zero error code.") + parser.add_argument("-Wall", + help="Enable all warning categories.", + action='store_true') + + for message_id in MessageId: + enable_arg = message_id.enable_arg() + enable_args.append((message_id, enable_arg)) + + disable_arg = message_id.disable_arg() + disable_args.append((message_id, disable_arg)) + if message_id in enabled_messages: + parser.add_argument(f"-{disable_arg}", action="store_true", + help=f"Disable message category {str(message_id)}: {message_id.desc()}") + # Don't show the enable flag in help since it's enabled by default + parser.add_argument(f"-{enable_arg}", action="store_true", + help=argparse.SUPPRESS) + else: + parser.add_argument(f"-{enable_arg}", action="store_true", + help=f"Enable message category {str(message_id)}: {message_id.desc()}") + # Don't show the disable flag in help since it's disabled by + # default + parser.add_argument(f"-{disable_arg}", action="store_true", + help=argparse.SUPPRESS) + + args = parser.parse_args() + + arg_dict = vars(args) + for message_id, arg in enable_args: + if args.Wall or (arg in arg_dict and arg_dict[arg]): + enabled_messages.add(message_id) + + for message_id, arg in disable_args: + if arg in arg_dict and arg_dict[arg]: + enabled_messages.discard(message_id) + + if args.verbose: + logging.basicConfig(level='INFO') + + if args.debug: + logging.basicConfig(level='DEBUG') + + checker = make_macro_checker(enabled_messages) + + if args.dump_entities: + with open('entities.json', 'w', encoding='utf-8') as f: + f.write(checker.getEntityJson()) + exit(0) + + if args.file: + files = (str(Path(f).resolve()) for f in args.file) + else: + files = all_docs + + for fn in files: + checker.processFile(fn) + + if args.html: + from .html_printer import HTMLPrinter + printer = HTMLPrinter(args.html) + else: + from .console_printer import ConsolePrinter + printer = ConsolePrinter() + + if args.scriptlocation: + printer.show_script_location = True + + if args.file: + printer.output("Only checked specified files.") + for f in args.file: + printer.output(f) + else: + printer.output("Checked all chapters and extensions.") + + if args.warning_error: + numErrors = checker.numDiagnostics() + else: + numErrors = checker.numErrors() + + check_includes = args.include_warn + check_broken = not args.file + + if args.file and check_includes: + print('Note: forcing --include_warn off because only checking supplied files.') + check_includes = False + + printer.outputResults(checker, broken_links=(not args.file), + missing_includes=check_includes) + + if check_broken: + numErrors += len(checker.getBrokenLinks()) + + if args.file and args.include_error: + print('Note: forcing --include_error off because only checking supplied files.') + args.include_error = False + if args.include_error: + numErrors += len(checker.getMissingUnreferencedApiIncludes()) + + check_missing_refpages = args.Wmissing_refpages + if args.file and check_missing_refpages: + print('Note: forcing -Wmissing_refpages off because only checking supplied files.') + check_missing_refpages = False + + if check_missing_refpages: + missing = checker.getMissingRefPages() + if missing: + printer.output("Expected, but did not find, ref page blocks for the following {} entities: {}".format( + len(missing), + ', '.join(missing) + )) + if args.warning_error: + numErrors += len(missing) + + printer.close() + + if args.broken_error and not args.file: + numErrors += len(checker.getBrokenLinks()) + + if checker.hasFixes(): + fixFn = 'applyfixes.sh' + print(f'Saving shell script to apply fixes as {fixFn}') + with open(fixFn, 'w', encoding='utf-8') as f: + f.write('#!/bin/sh -e\n') + for fileChecker in checker.files: + wroteComment = False + for msg in fileChecker.messages: + if msg.fix is not None: + if not wroteComment: + f.write(f'\n# {fileChecker.filename}\n') + wroteComment = True + search, replace = msg.fix + f.write( + r"sed -i -r 's~\b{}\b~{}~g' {}".format( + re.escape(search), + replace, + fileChecker.filename)) + f.write('\n') + + print(f'Total number of errors with this run: {numErrors}') + + if args.ignore_count: + if numErrors > args.ignore_count: + # Exit with non-zero error code so that we "fail" CI, etc. + print('Exceeded specified limit of {}, so exiting with error'.format( + args.ignore_count)) + exit(1) + else: + print('At or below specified limit of {}, so exiting with success'.format( + args.ignore_count)) + exit(0) + + if numErrors: + # Exit with non-zero error code so that we "fail" CI, etc. + print('Exiting with error') + exit(1) + else: + print('Exiting with success') + exit(0) diff --git a/libs/VulkanHeaders/spec_tools/shared.py b/libs/VulkanHeaders/spec_tools/shared.py new file mode 100644 index 0000000000..565c261bdd --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/shared.py @@ -0,0 +1,256 @@ +"""Types, constants, and utility functions used by multiple sub-modules in spec_tools.""" + +# Copyright (c) 2018-2019 Collabora, Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Author(s): Rylie Pavlik + +import platform +from collections import namedtuple +from enum import Enum +from inspect import getframeinfo +from pathlib import Path +from sys import stdout + +# if we have termcolor and we know our stdout is a TTY, +# pull it in and use it. +if hasattr(stdout, 'isatty') and stdout.isatty(): + try: + from termcolor import colored as colored_impl + HAVE_COLOR = True + except ImportError: + HAVE_COLOR = False +elif platform.system() == 'Windows': + try: + from termcolor import colored as colored_impl + import colorama + colorama.init() + HAVE_COLOR = True + except ImportError: + HAVE_COLOR = False + +else: + HAVE_COLOR = False + + +def colored(s, color=None, attrs=None): + """Call termcolor.colored with same arguments if this is a tty and it is available.""" + if HAVE_COLOR: + return colored_impl(s, color, attrs=attrs) + return s + + +### +# Constants used in multiple places. +AUTO_FIX_STRING = 'Note: Auto-fix available.' +EXTENSION_CATEGORY = 'extension' +CATEGORIES_WITH_VALIDITY = set(('protos', 'structs')) +NON_EXISTENT_MACROS = set(('plink', 'ttext', 'dtext')) + +### +# MessageContext: All the information about where a message relates to. +MessageContext = namedtuple('MessageContext', + ['filename', 'lineNum', 'line', + 'match', 'group']) + + +def getInterestedRange(message_context): + """Return a (start, end) pair of character index for the match in a MessageContext.""" + if not message_context.match: + # whole line + return (0, len(message_context.line)) + return (message_context.match.start(), message_context.match.end()) + + +def getHighlightedRange(message_context): + """Return a (start, end) pair of character index for the highlighted range in a MessageContext.""" + if message_context.group is not None and message_context.match is not None: + return (message_context.match.start(message_context.group), + message_context.match.end(message_context.group)) + # no group (whole match) or no match (whole line) + return getInterestedRange(message_context) + + +def toNameAndLine(context, root_path=None): + """Convert MessageContext into a simple filename:line string.""" + my_fn = Path(context.filename) + if root_path: + my_fn = my_fn.relative_to(root_path) + return f'{str(my_fn)}:{context.lineNum}' + + +def generateInclude(dir_traverse, generated_type, category, entity): + """Create an include:: directive for generated api or validity from the various pieces.""" + return f'include::{dir_traverse}{generated_type}/{category}/{entity}.adoc[]' + + +# Data stored per entity (function, struct, enumerant type, enumerant, extension, etc.) +EntityData = namedtuple( + 'EntityData', ['entity', 'macro', 'elem', 'filename', 'category', 'directory']) + + +class MessageType(Enum): + """Type of a message.""" + + WARNING = 1 + ERROR = 2 + NOTE = 3 + + def __str__(self): + """Format a MessageType as a lowercase string.""" + return str(self.name).lower() + + def formattedWithColon(self): + """Format a MessageType as a colored, lowercase string followed by a colon.""" + if self == MessageType.WARNING: + return colored(f"{str(self)}:", 'magenta', attrs=['bold']) + if self == MessageType.ERROR: + return colored(f"{str(self)}:", 'red', attrs=['bold']) + return f"{str(self)}:" + + +class MessageId(Enum): + # Disable bogus pylint warnings in this enum + # pylint: disable=no-member + """Enumerates the varieties of messages that can be generated. + + Control over enabled messages with -Wbla or -Wno_bla is per-MessageId. + """ + + MISSING_TEXT = 1 + LEGACY = 2 + WRONG_MACRO = 3 + MISSING_MACRO = 4 + BAD_ENTITY = 5 + BAD_ENUMERANT = 6 + BAD_MACRO = 7 + UNRECOGNIZED_CONTEXT = 8 + UNKNOWN_MEMBER = 9 + DUPLICATE_INCLUDE = 10 + UNKNOWN_INCLUDE = 11 + API_VALIDITY_ORDER = 12 + UNDOCUMENTED_MEMBER = 13 + MEMBER_PNAME_MISSING = 14 + MISSING_VALIDITY_INCLUDE = 15 + MISSING_API_INCLUDE = 16 + MISUSED_TEXT = 17 + EXTENSION = 18 + REFPAGE_TAG = 19 + REFPAGE_MISSING_DESC = 20 + REFPAGE_XREFS = 21 + REFPAGE_XREFS_COMMA = 22 + REFPAGE_TYPE = 23 + REFPAGE_NAME = 24 + REFPAGE_BLOCK = 25 + REFPAGE_MISSING = 26 + REFPAGE_MISMATCH = 27 + REFPAGE_UNKNOWN_ATTRIB = 28 + REFPAGE_SELF_XREF = 29 + REFPAGE_XREF_DUPE = 30 + REFPAGE_WHITESPACE = 31 + REFPAGE_DUPLICATE = 32 + UNCLOSED_BLOCK = 33 + MISSING_INCLUDE_PATH_ATTRIBUTE = 34 + + def __str__(self): + """Format as a lowercase string.""" + return self.name.lower() + + def enable_arg(self): + """Return the corresponding Wbla string to make the 'enable this message' argument.""" + return f'W{self.name.lower()}' + + def disable_arg(self): + """Return the corresponding Wno_bla string to make the 'enable this message' argument.""" + return f'Wno_{self.name.lower()}' + + def desc(self): + """Return a brief description of the MessageId suitable for use in --help.""" + return _MESSAGE_DESCRIPTIONS[self] + + +_MESSAGE_DESCRIPTIONS = { + MessageId.MISSING_TEXT: "a *text: macro is expected but not found", + MessageId.LEGACY: "legacy usage of *name: macro when *link: is applicable", + MessageId.WRONG_MACRO: "wrong macro used for an entity", + MessageId.MISSING_MACRO: "a macro might be missing", + MessageId.BAD_ENTITY: "entity not recognized, etc.", + MessageId.BAD_ENUMERANT: "unrecognized enumerant value used in ename:", + MessageId.BAD_MACRO: "unrecognized macro used", + MessageId.UNRECOGNIZED_CONTEXT: "pname used with an unrecognized context", + MessageId.UNKNOWN_MEMBER: "pname used but member/argument by that name not found", + MessageId.DUPLICATE_INCLUDE: "duplicated include line", + MessageId.UNKNOWN_INCLUDE: "include line specified file we wouldn't expect to exists", + MessageId.API_VALIDITY_ORDER: "saw API include after validity include", + MessageId.UNDOCUMENTED_MEMBER: "saw an apparent struct/function documentation, but missing a member", + MessageId.MEMBER_PNAME_MISSING: "pname: missing from a 'scope' operator", + MessageId.MISSING_VALIDITY_INCLUDE: "missing validity include", + MessageId.MISSING_API_INCLUDE: "missing API include", + MessageId.MISUSED_TEXT: "a *text: macro is found but not expected", + MessageId.EXTENSION: "an extension name is incorrectly marked", + MessageId.REFPAGE_TAG: "a refpage tag is missing an expected field", + MessageId.REFPAGE_MISSING_DESC: "a refpage tag has an empty description", + MessageId.REFPAGE_XREFS: "an unrecognized entity is mentioned in xrefs of a refpage tag", + MessageId.REFPAGE_XREFS_COMMA: "a comma was founds in xrefs of a refpage tag, which is space-delimited", + MessageId.REFPAGE_TYPE: "a refpage tag has an incorrect type field", + MessageId.REFPAGE_NAME: "a refpage tag has an unrecognized entity name in its refpage field", + MessageId.REFPAGE_BLOCK: "a refpage block is not correctly opened or closed.", + MessageId.REFPAGE_MISSING: "an API include was found outside of a refpage block.", + MessageId.REFPAGE_MISMATCH: "an API or validity include was found in a non-matching refpage block.", + MessageId.REFPAGE_UNKNOWN_ATTRIB: "a refpage tag has an unrecognized attribute", + MessageId.REFPAGE_SELF_XREF: "a refpage tag has itself in the list of cross-references", + MessageId.REFPAGE_XREF_DUPE: "a refpage cross-references list has at least one duplicate", + MessageId.REFPAGE_WHITESPACE: "a refpage cross-references list has non-minimal whitespace", + MessageId.REFPAGE_DUPLICATE: "a refpage tag has been seen for a single entity for a second time", + MessageId.UNCLOSED_BLOCK: "one or more blocks remain unclosed at the end of a file", + MessageId.MISSING_INCLUDE_PATH_ATTRIBUTE: "include:: directives must begin with a recognized path attribute macro", +} + + +class Message(object): + """An Error, Warning, or Note with a MessageContext, MessageId, and message text. + + May optionally have a replacement, a see_also array, an auto-fix, + and a stack frame where the message was created. + """ + + def __init__(self, message_id, message_type, message, context, + replacement=None, see_also=None, fix=None, frame=None): + """Construct a Message. + + Typically called by MacroCheckerFile.diag(). + """ + self.message_id = message_id + + self.message_type = message_type + + if isinstance(message, str): + self.message = [message] + else: + self.message = message + + self.context = context + if context is not None and context.match is not None and context.group is not None: + if context.group not in context.match.groupdict(): + raise RuntimeError( + f'Group "{context.group}" does not exist in the match') + + self.replacement = replacement + + self.fix = fix + + if see_also is None: + self.see_also = None + elif isinstance(see_also, MessageContext): + self.see_also = [see_also] + else: + self.see_also = see_also + + self.script_location = None + if frame: + try: + frameinfo = getframeinfo(frame) + self.script_location = f"{frameinfo.filename}:{frameinfo.lineno}" + finally: + del frame diff --git a/libs/VulkanHeaders/spec_tools/util.py b/libs/VulkanHeaders/spec_tools/util.py new file mode 100644 index 0000000000..e50df9bd64 --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/util.py @@ -0,0 +1,58 @@ +"""Utility functions not closely tied to other spec_tools types.""" +# Copyright (c) 2018-2019 Collabora, Ltd. +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + + +def getElemName(elem, default=None): + """Get the name associated with an element, either a name child or name attribute.""" + name_elem = elem.find('name') + if name_elem is not None: + return name_elem.text + # Fallback if there is no child. + return elem.get('name', default) + + +def getElemType(elem, default=None): + """Get the type associated with an element, either a type child or type attribute.""" + type_elem = elem.find('type') + if type_elem is not None: + return type_elem.text + # Fallback if there is no child. + return elem.get('type', default) + + +def findFirstWithPredicate(collection, pred): + """Return the first element that satisfies the predicate, or None if none exist. + + NOTE: Some places where this is used might be better served by changing to a dictionary. + """ + for elt in collection: + if pred(elt): + return elt + return None + + +def findNamedElem(elems, name): + """Traverse a collection of elements with 'name' nodes or attributes, looking for and returning one with the right name. + + NOTE: Many places where this is used might be better served by changing to a dictionary. + """ + return findFirstWithPredicate(elems, lambda elem: getElemName(elem) == name) + + +def findTypedElem(elems, typename): + """Traverse a collection of elements with 'type' nodes or attributes, looking for and returning one with the right typename. + + NOTE: Many places where this is used might be better served by changing to a dictionary. + """ + return findFirstWithPredicate(elems, lambda elem: getElemType(elem) == typename) + + +def findNamedObject(collection, name): + """Traverse a collection of elements with 'name' attributes, looking for and returning one with the right name. + + NOTE: Many places where this is used might be better served by changing to a dictionary. + """ + return findFirstWithPredicate(collection, lambda elt: elt.name == name) diff --git a/libs/VulkanHeaders/spec_tools/validity.py b/libs/VulkanHeaders/spec_tools/validity.py new file mode 100644 index 0000000000..45dd2ff10b --- /dev/null +++ b/libs/VulkanHeaders/spec_tools/validity.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +import re + + +_A_VS_AN_RE = re.compile(r' a ([a-z]+:)?([aAeEiIoOxX]\w+\b)(?!:)') + +_STARTS_WITH_MACRO_RE = re.compile(r'^[a-z]+:.*') + +_VUID_ANCHOR_RE = re.compile(r'\[\[VUID-.*\]\]') + + +def _checkAnchorComponents(anchor): + """Raise an exception if any component of a VUID anchor name is illegal.""" + if anchor: + # Any other invalid things in an anchor name should be detected here. + if any((' ' in anchor_part for anchor_part in anchor)): + raise RuntimeError("Illegal component of a VUID anchor name!") + + +def _fix_a_vs_an(s): + """Fix usage (often generated) of the indefinite article 'a' when 'an' is appropriate. + + Explicitly excludes the markup macros.""" + return _A_VS_AN_RE.sub(r' an \1\2', s) + + +class ValidityCollection: + """Combines validity for a single entity.""" + + def __init__(self, entity_name=None, conventions=None, strict=True, verbose=False): + self.entity_name = entity_name + self.conventions = conventions + self.lines = [] + self.strict = strict + self.verbose = verbose + + def possiblyAddExtensionRequirement(self, extension_name, entity_preface): + """Add an extension-related validity statement if required. + + entity_preface is a string that goes between "must be enabled prior to " + and the name of the entity, and normally ends in a macro. + For instance, might be "calling flink:" for a function. + """ + if extension_name and not extension_name.startswith(self.conventions.api_version_prefix): + msg = 'The {} extension must: be enabled prior to {}{}'.format( + self.conventions.formatExtension(extension_name), entity_preface, self.entity_name) + self.addValidityEntry(msg, anchor=('extension', 'notenabled')) + + def addValidityEntry(self, msg, anchor=None): + """Add a validity entry, optionally with a VUID anchor. + + If any trailing arguments are supplied, + an anchor is generated by concatenating them with dashes + at the end of the VUID anchor name. + """ + if not msg: + raise RuntimeError("Tried to add a blank validity line!") + parts = ['*'] + _checkAnchorComponents(anchor) + if anchor: + if not self.entity_name: + raise RuntimeError('Cannot add a validity entry with an anchor to a collection that does not know its entity name.') + parts.append(f"[[{'-'.join(['VUID', self.entity_name] + list(anchor))}]]") + parts.append(msg) + combined = _fix_a_vs_an(' '.join(parts)) + if combined in self.lines: + raise RuntimeError("Duplicate validity added!") + self.lines.append(combined) + + def addText(self, msg): + """Add already formatted validity text.""" + if self.strict: + raise RuntimeError('addText called when collection in strict mode') + if not msg: + return + msg = msg.rstrip() + if not msg: + return + self.lines.append(msg) + + def _extend(self, lines): + lines = list(lines) + dupes = set(lines).intersection(self.lines) + if dupes: + raise RuntimeError("The two sets contain some shared entries! " + str(dupes)) + self.lines.extend(lines) + + def __iadd__(self, other): + """Perform += with a string, iterable, or ValidityCollection.""" + if other is None: + pass + elif isinstance(other, str): + if self.strict: + raise RuntimeError( + 'Collection += a string when collection in strict mode') + if not other: + # empty string + pass + elif other.startswith('*'): + # Handle already-formatted + self.addText(other) + else: + # Do the formatting ourselves. + self.addValidityEntry(other) + elif isinstance(other, ValidityEntry): + if other: + if other.verbose: + print(self.entity_name, 'Appending', str(other)) + self.addValidityEntry(str(other), anchor=other.anchor) + elif isinstance(other, ValidityCollection): + if self.entity_name == other.entity_name: + self._extend(other.lines) + else: + # Remove foreign anchors - this is presumably an alias + if other.verbose: + print(self.entity_name, + 'merging with validity for', + other.entity_name, + 'so removing VUID anchor on incoming entries') + self._extend(_VUID_ANCHOR_RE.sub('', s, 1) for s in other.lines) + else: + # Deal with other iterables. + self._extend(other) + + return self + + def __bool__(self): + """Is the collection non-empty?""" + empty = not self.lines + return not empty + + @property + def text(self): + """Access validity statements as a single string or None.""" + if not self.lines: + return None + return '\n'.join(self.lines) + '\n' + + def __str__(self): + """Access validity statements as a single string or empty string.""" + if not self: + return '' + return self.text + + def __repr__(self): + return f'' + + +class ValidityEntry: + """A single validity line in progress.""" + + def __init__(self, text=None, anchor=None): + """Prepare to add a validity entry, optionally with a VUID anchor. + + An anchor is generated by concatenating the elements of the anchor tuple with dashes + at the end of the VUID anchor name. + """ + _checkAnchorComponents(anchor) + if isinstance(anchor, str): + # anchor needs to be a tuple + anchor = (anchor,) + + # VUID does not allow special chars except ":" + if anchor is not None: + anchor = [(anchor_value.replace('->', '::').replace('.', '::')) for anchor_value in anchor] + + self.anchor = anchor + self.parts = [] + self.verbose = False + if text: + self.append(text) + + def append(self, part): + """Append a part of a string. + + If this is the first entry part and the part doesn't start + with a markup macro, the first character will be capitalized.""" + if not self.parts and not _STARTS_WITH_MACRO_RE.match(part): + self.parts.append(part[:1].upper()) + self.parts.append(part[1:]) + else: + self.parts.append(part) + if self.verbose: + print('ValidityEntry', id(self), 'after append:', str(self)) + + def drop_end(self, n): + """Remove up to n trailing characters from the string.""" + temp = str(self) + n = min(len(temp), n) + self.parts = [temp[:-n]] + + def __iadd__(self, other): + """Perform += with a string,""" + self.append(other) + return self + + def __bool__(self): + """Return true if we have something more than just an anchor.""" + empty = not self.parts + return not empty + + def __str__(self): + """Access validity statement as a single string or empty string.""" + if not self: + raise RuntimeError("No parts added?") + return ''.join(self.parts).strip() + + def __repr__(self): + parts = ['') + return ''.join(parts) diff --git a/libs/VulkanHeaders/vk.xml b/libs/VulkanHeaders/vk.xml new file mode 100644 index 0000000000..b425ea347d --- /dev/null +++ b/libs/VulkanHeaders/vk.xml @@ -0,0 +1,31806 @@ + + + +Copyright 2015-2025 The Khronos Group Inc. + +SPDX-License-Identifier: Apache-2.0 OR MIT + + + +This file, vk.xml, is the Vulkan API Registry. It is a critically important +and normative part of the Vulkan Specification, including a canonical +machine-readable definition of the API, parameter and member validation +language incorporated into the Specification and reference pages, and other +material which is registered by Khronos, such as tags used by extension and +layer authors. The authoritative public version of vk.xml is maintained in +the default branch (currently named main) of the Khronos Vulkan GitHub +project. The authoritative private version is maintained in the default +branch of the member gitlab server. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #include "vk_platform.h" + + WSI extensions + + + + + + + + + + + + + + In the current header structure, each platform's interfaces + are confined to a platform-specific header (vulkan_xlib.h, + vulkan_win32.h, etc.). These headers are not self-contained, + and should not include native headers (X11/Xlib.h, + windows.h, etc.). Code should either include vulkan.h after + defining the appropriate VK_USE_PLATFORM_platform + macros, or include the required native headers prior to + explicitly including the corresponding platform header. + + To accomplish this, the dependencies of native types require + native headers, but the XML defines the content for those + native headers as empty. The actual native header includes + can be restored by modifying the native header tags above + to #include the header file in the 'name' attribute. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#define VK_MAKE_VERSION(major, minor, patch) \ + ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22U) + +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) + +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + + #define VK_MAKE_API_VERSION(variant, major, minor, patch) \ + ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + #define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U) + #define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU) + #define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) + #define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + + // Vulkan SC variant number +#define VKSC_API_VARIANT 1 + + +//#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0 + // Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 + // Vulkan 1.1 version number +#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0 + // Vulkan 1.2 version number +#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)// Patch version should always be set to 0 + // Vulkan 1.3 version number +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 + // Vulkan 1.4 version number +#define VK_API_VERSION_1_4 VK_MAKE_API_VERSION(0, 1, 4, 0)// Patch version should always be set to 0 + // Vulkan SC 1.0 version number +#define VKSC_API_VERSION_1_0 VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, 0)// Patch version should always be set to 0 + + // Version of this file +#define VK_HEADER_VERSION 328 + // Complete version of this file +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 4, VK_HEADER_VERSION) + // Version of this file +#define VK_HEADER_VERSION 19 + // Complete version of this file +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, VK_HEADER_VERSION) + + +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* (object); + + +#ifndef VK_USE_64_BIT_PTR_DEFINES + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64) + #define VK_USE_64_BIT_PTR_DEFINES 1 + #else + #define VK_USE_64_BIT_PTR_DEFINES 0 + #endif +#endif + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) + #define VK_NULL_HANDLE nullptr + #else + #define VK_NULL_HANDLE ((void*)0) + #endif + #else + #define VK_NULL_HANDLE 0ULL + #endif +#endif +#ifndef VK_NULL_HANDLE + #define VK_NULL_HANDLE 0 +#endif + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; + #else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; + #endif +#endif + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *(object); + #else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t (object); + #endif +#endif + + struct ANativeWindow; + struct AHardwareBuffer; + #ifdef __OBJC__ +@class CAMetalLayer; +#else +typedef void CAMetalLayer; +#endif + #ifdef __OBJC__ +@protocol MTLDevice; +typedef __unsafe_unretained id<MTLDevice> MTLDevice_id; +#else +typedef void* MTLDevice_id; +#endif + #ifdef __OBJC__ +@protocol MTLCommandQueue; +typedef __unsafe_unretained id<MTLCommandQueue> MTLCommandQueue_id; +#else +typedef void* MTLCommandQueue_id; +#endif + #ifdef __OBJC__ +@protocol MTLBuffer; +typedef __unsafe_unretained id<MTLBuffer> MTLBuffer_id; +#else +typedef void* MTLBuffer_id; +#endif + #ifdef __OBJC__ +@protocol MTLTexture; +typedef __unsafe_unretained id<MTLTexture> MTLTexture_id; +#else +typedef void* MTLTexture_id; +#endif + #ifdef __OBJC__ +@protocol MTLSharedEvent; +typedef __unsafe_unretained id<MTLSharedEvent> MTLSharedEvent_id; +#else +typedef void* MTLSharedEvent_id; +#endif + typedef struct __IOSurface* IOSurfaceRef; + + typedef uint32_t VkSampleMask; + typedef uint32_t VkBool32; + typedef uint32_t VkFlags; + typedef uint64_t VkFlags64; + typedef uint64_t VkDeviceSize; + typedef uint64_t VkDeviceAddress; + + typedef struct NativeWindow OHNativeWindow; + + Basic C types, pulled in via vk_platform.h + + + + + + + + + + + + + + + + Bitmask types + typedef VkFlags VkFramebufferCreateFlags; + typedef VkFlags VkQueryPoolCreateFlags; + typedef VkFlags VkRenderPassCreateFlags; + typedef VkFlags VkSamplerCreateFlags; + typedef VkFlags VkPipelineLayoutCreateFlags; + typedef VkFlags VkPipelineCacheCreateFlags; + typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + typedef VkFlags VkPipelineDynamicStateCreateFlags; + typedef VkFlags VkPipelineColorBlendStateCreateFlags; + typedef VkFlags VkPipelineColorBlendStateCreateFlags; + typedef VkFlags VkPipelineMultisampleStateCreateFlags; + typedef VkFlags VkPipelineRasterizationStateCreateFlags; + typedef VkFlags VkPipelineViewportStateCreateFlags; + typedef VkFlags VkPipelineTessellationStateCreateFlags; + typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; + typedef VkFlags VkPipelineVertexInputStateCreateFlags; + typedef VkFlags VkPipelineShaderStageCreateFlags; + typedef VkFlags VkDescriptorSetLayoutCreateFlags; + typedef VkFlags VkBufferViewCreateFlags; + typedef VkFlags VkInstanceCreateFlags; + typedef VkFlags VkDeviceCreateFlags; + typedef VkFlags VkDeviceQueueCreateFlags; + typedef VkFlags VkQueueFlags; + typedef VkFlags VkMemoryPropertyFlags; + typedef VkFlags VkMemoryHeapFlags; + typedef VkFlags VkAccessFlags; + typedef VkFlags VkBufferUsageFlags; + typedef VkFlags VkBufferCreateFlags; + typedef VkFlags VkShaderStageFlags; + typedef VkFlags VkImageUsageFlags; + typedef VkFlags VkImageCreateFlags; + typedef VkFlags VkImageViewCreateFlags; + typedef VkFlags VkPipelineCreateFlags; + typedef VkFlags VkColorComponentFlags; + typedef VkFlags VkFenceCreateFlags; + typedef VkFlags VkSemaphoreCreateFlags; + typedef VkFlags VkFormatFeatureFlags; + typedef VkFlags VkQueryControlFlags; + typedef VkFlags VkQueryResultFlags; + typedef VkFlags VkShaderModuleCreateFlags; + typedef VkFlags VkEventCreateFlags; + typedef VkFlags VkCommandPoolCreateFlags; + typedef VkFlags VkCommandPoolResetFlags; + typedef VkFlags VkCommandBufferResetFlags; + typedef VkFlags VkCommandBufferUsageFlags; + typedef VkFlags VkQueryPipelineStatisticFlags; + typedef VkFlags VkMemoryMapFlags; + typedef VkFlags VkMemoryUnmapFlags; + + typedef VkFlags VkImageAspectFlags; + typedef VkFlags VkSparseMemoryBindFlags; + typedef VkFlags VkSparseImageFormatFlags; + typedef VkFlags VkSubpassDescriptionFlags; + typedef VkFlags VkPipelineStageFlags; + typedef VkFlags VkSampleCountFlags; + typedef VkFlags VkAttachmentDescriptionFlags; + typedef VkFlags VkStencilFaceFlags; + typedef VkFlags VkCullModeFlags; + typedef VkFlags VkDescriptorPoolCreateFlags; + typedef VkFlags VkDescriptorPoolResetFlags; + typedef VkFlags VkDependencyFlags; + typedef VkFlags VkSubgroupFeatureFlags; + typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV; + typedef VkFlags VkIndirectStateFlagsNV; + typedef VkFlags VkGeometryFlagsKHR; + + typedef VkFlags VkGeometryInstanceFlagsKHR; + + typedef VkFlags VkClusterAccelerationStructureGeometryFlagsNV; + typedef VkFlags VkClusterAccelerationStructureClusterFlagsNV; + typedef VkFlags VkClusterAccelerationStructureAddressResolutionFlagsNV; + typedef VkFlags VkBuildAccelerationStructureFlagsKHR; + + typedef VkFlags VkPrivateDataSlotCreateFlags; + + typedef VkFlags VkAccelerationStructureCreateFlagsKHR; + typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; + + typedef VkFlags VkPipelineCreationFeedbackFlags; + + typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR; + typedef VkFlags VkAcquireProfilingLockFlagsKHR; + typedef VkFlags VkSemaphoreWaitFlags; + + typedef VkFlags VkPipelineCompilerControlFlagsAMD; + typedef VkFlags VkShaderCorePropertiesFlagsAMD; + typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; + typedef VkFlags VkRefreshObjectFlagsKHR; + typedef VkFlags64 VkAccessFlags2; + + typedef VkFlags64 VkPipelineStageFlags2; + + typedef VkFlags VkAccelerationStructureMotionInfoFlagsNV; + typedef VkFlags VkAccelerationStructureMotionInstanceFlagsNV; + typedef VkFlags64 VkFormatFeatureFlags2; + + typedef VkFlags VkRenderingFlags; + typedef VkFlags64 VkMemoryDecompressionMethodFlagsNV; + + typedef VkFlags VkBuildMicromapFlagsEXT; + typedef VkFlags VkMicromapCreateFlagsEXT; + typedef VkFlags VkIndirectCommandsLayoutUsageFlagsEXT; + typedef VkFlags VkIndirectCommandsInputModeFlagsEXT; + typedef VkFlags VkDirectDriverLoadingFlagsLUNARG; + typedef VkFlags64 VkPipelineCreateFlags2; + + typedef VkFlags64 VkBufferUsageFlags2; + + typedef VkFlags VkAddressCopyFlagsKHR; + typedef VkFlags64 VkTensorCreateFlagsARM; + typedef VkFlags64 VkTensorUsageFlagsARM; + typedef VkFlags64 VkTensorViewCreateFlagsARM; + typedef VkFlags64 VkDataGraphPipelineSessionCreateFlagsARM; + typedef VkFlags64 VkDataGraphPipelineDispatchFlagsARM; + typedef VkFlags VkVideoEncodeRgbModelConversionFlagsVALVE; + typedef VkFlags VkVideoEncodeRgbRangeCompressionFlagsVALVE; + typedef VkFlags VkVideoEncodeRgbChromaOffsetFlagsVALVE; + + WSI extensions + typedef VkFlags VkCompositeAlphaFlagsKHR; + typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; + typedef VkFlags VkSurfaceTransformFlagsKHR; + typedef VkFlags VkSwapchainCreateFlagsKHR; + typedef VkFlags VkDisplayModeCreateFlagsKHR; + typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; + typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; + typedef VkFlags VkViSurfaceCreateFlagsNN; + typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; + typedef VkFlags VkWin32SurfaceCreateFlagsKHR; + typedef VkFlags VkXlibSurfaceCreateFlagsKHR; + typedef VkFlags VkXcbSurfaceCreateFlagsKHR; + typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT; + typedef VkFlags VkIOSSurfaceCreateFlagsMVK; + typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; + typedef VkFlags VkMetalSurfaceCreateFlagsEXT; + typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA; + typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP; + typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; + typedef VkFlags VkScreenSurfaceCreateFlagsQNX; + typedef VkFlags VkPeerMemoryFeatureFlags; + + typedef VkFlags VkMemoryAllocateFlags; + + typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; + + typedef VkFlags VkDebugReportFlagsEXT; + typedef VkFlags VkCommandPoolTrimFlags; + + typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; + typedef VkFlags VkClusterAccelerationStructureIndexFormatFlagsNV; + typedef VkFlags VkExternalMemoryFeatureFlagsNV; + typedef VkFlags VkExternalMemoryHandleTypeFlags; + + typedef VkFlags VkExternalMemoryFeatureFlags; + + typedef VkFlags VkExternalSemaphoreHandleTypeFlags; + + typedef VkFlags VkExternalSemaphoreFeatureFlags; + + typedef VkFlags VkSemaphoreImportFlags; + + typedef VkFlags VkExternalFenceHandleTypeFlags; + + typedef VkFlags VkExternalFenceFeatureFlags; + + typedef VkFlags VkFenceImportFlags; + + typedef VkFlags VkSurfaceCounterFlagsEXT; + typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; + typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; + typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; + typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; + typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV; + typedef VkFlags VkValidationCacheCreateFlagsEXT; + typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; + typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; + typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; + typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; + typedef VkFlags VkDeviceMemoryReportFlagsEXT; + typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; + typedef VkFlags VkDescriptorBindingFlags; + + typedef VkFlags VkConditionalRenderingFlagsEXT; + typedef VkFlags VkResolveModeFlags; + + typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT; + typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT; + typedef VkFlags VkSwapchainImageUsageFlagsANDROID; + typedef VkFlags VkToolPurposeFlags; + + typedef VkFlags VkSubmitFlags; + + typedef VkFlags VkImageFormatConstraintsFlagsFUCHSIA; + typedef VkFlags VkHostImageCopyFlags; + + typedef VkFlags VkPartitionedAccelerationStructureInstanceFlagsNV; + typedef VkFlags VkImageConstraintsInfoFlagsFUCHSIA; + typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; + typedef VkFlags VkImageCompressionFlagsEXT; + typedef VkFlags VkImageCompressionFixedRateFlagsEXT; + typedef VkFlags VkExportMetalObjectTypeFlagsEXT; + typedef VkFlags VkDeviceAddressBindingFlagsEXT; + typedef VkFlags VkOpticalFlowGridSizeFlagsNV; + typedef VkFlags VkOpticalFlowUsageFlagsNV; + typedef VkFlags VkOpticalFlowSessionCreateFlagsNV; + typedef VkFlags VkOpticalFlowExecuteFlagsNV; + typedef VkFlags VkFrameBoundaryFlagsEXT; + typedef VkFlags VkPresentScalingFlagsKHR; + + typedef VkFlags VkPresentGravityFlagsKHR; + + typedef VkFlags VkShaderCreateFlagsEXT; + typedef VkFlags VkTileShadingRenderPassFlagsQCOM; + typedef VkFlags64 VkPhysicalDeviceSchedulingControlsFlagsARM; + typedef VkFlags VkSurfaceCreateFlagsOHOS; + + Video Core extension + typedef VkFlags VkVideoCodecOperationFlagsKHR; + typedef VkFlags VkVideoCapabilityFlagsKHR; + typedef VkFlags VkVideoSessionCreateFlagsKHR; + typedef VkFlags VkVideoSessionParametersCreateFlagsKHR; + typedef VkFlags VkVideoBeginCodingFlagsKHR; + typedef VkFlags VkVideoEndCodingFlagsKHR; + typedef VkFlags VkVideoCodingControlFlagsKHR; + + Video Decode Core extension + typedef VkFlags VkVideoDecodeUsageFlagsKHR; + typedef VkFlags VkVideoDecodeCapabilityFlagsKHR; + typedef VkFlags VkVideoDecodeFlagsKHR; + + Video Decode H.264 extension + typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsKHR; + + Video Encode Core extension + typedef VkFlags VkVideoEncodeFlagsKHR; + typedef VkFlags VkVideoEncodeUsageFlagsKHR; + typedef VkFlags VkVideoEncodeContentFlagsKHR; + typedef VkFlags VkVideoEncodeCapabilityFlagsKHR; + typedef VkFlags VkVideoEncodeFeedbackFlagsKHR; + typedef VkFlags VkVideoEncodeRateControlFlagsKHR; + typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR; + typedef VkFlags VkVideoEncodeIntraRefreshModeFlagsKHR; + typedef VkFlags VkVideoChromaSubsamplingFlagsKHR; + typedef VkFlags VkVideoComponentBitDepthFlagsKHR; + + Video Encode H.264 extension + typedef VkFlags VkVideoEncodeH264CapabilityFlagsKHR; + typedef VkFlags VkVideoEncodeH264StdFlagsKHR; + typedef VkFlags VkVideoEncodeH264RateControlFlagsKHR; + + Video Encode H.265 extension + typedef VkFlags VkVideoEncodeH265CapabilityFlagsKHR; + typedef VkFlags VkVideoEncodeH265StdFlagsKHR; + typedef VkFlags VkVideoEncodeH265RateControlFlagsKHR; + typedef VkFlags VkVideoEncodeH265CtbSizeFlagsKHR; + typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsKHR; + + Video Encode AV1 extension + typedef VkFlags VkVideoEncodeAV1CapabilityFlagsKHR; + typedef VkFlags VkVideoEncodeAV1StdFlagsKHR; + typedef VkFlags VkVideoEncodeAV1RateControlFlagsKHR; + typedef VkFlags VkVideoEncodeAV1SuperblockSizeFlagsKHR; + + VK_KHR_maintenance8 + typedef VkFlags64 VkAccessFlags3KHR; + + Types which can be void pointers or class pointers, selected at compile time + VK_DEFINE_HANDLE(VkInstance) + VK_DEFINE_HANDLE(VkPhysicalDevice) + VK_DEFINE_HANDLE(VkDevice) + VK_DEFINE_HANDLE(VkQueue) + VK_DEFINE_HANDLE(VkCommandBuffer) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineBinaryKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectExecutionSetEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) + + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) + + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) + + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkOpticalFlowSessionNV) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkMicromapEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkTensorARM) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkTensorViewARM) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDataGraphPipelineSessionARM) + + WSI extensions + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) + + Video extensions + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR) + + VK_NV_external_sci_sync2 + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphoreSciSyncPoolNV) + + Types generated from corresponding enums tags below + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extensions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WSI extensions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Enumerated types in the header, but not used by the API + + + + + + + + Video Core extensions + + + + + + + + + + Video Decode extensions + + + + Video H.264 Decode extensions + + + Video H.265 Decode extensions + + Video Encode extensions + + + + + + + + + + Video H.264 Encode extensions + + + + + Video H.265 Encode extensions + + + + + + + Video AV1 Encode extensions + + + + + + + + VK_KHR_maintenance8 + + + VK_KHR_maintenance9 + + + The PFN_vk*Function types are used by VkAllocationCallbacks below + typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( + void* pUserData, + void* pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( + void* pUserData, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + typedef void (VKAPI_PTR *PFN_vkFreeFunction)( + void* pUserData, + void* pMemory); + + The PFN_vkVoidFunction type are used by VkGet*ProcAddr below + typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); + + The PFN_vkDebugReportCallbackEXT type are used by the DEBUG_REPORT extension + typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData); + + The PFN_vkDebugUtilsMessengerCallbackEXT type are used by the VK_EXT_debug_utils extension + typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData); + + The PFN_vkFaultCallbackFunction type is used by VKSC_VERSION_1_0 + typedef void (VKAPI_PTR *PFN_vkFaultCallbackFunction)( + VkBool32 unrecordedFaults, + uint32_t faultCount, + const VkFaultData* pFaults); + + The PFN_vkDeviceMemoryReportCallbackEXT type is used by the VK_EXT_device_memory_report extension + typedef void (VKAPI_PTR *PFN_vkDeviceMemoryReportCallbackEXT)( + const VkDeviceMemoryReportCallbackDataEXT* pCallbackData, + void* pUserData); + + The PFN_vkGetInstanceProcAddrLUNARG type is used by the + VkDirectDriverLoadingInfoLUNARG structure. + We cannot introduce an explicit dependency on the + equivalent PFN_vkGetInstanceProcAddr type, even though + it is implicitly generated in the C header, because + that results in multiple definitions. + typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddrLUNARG)( + VkInstance instance, const char* pName); + + Struct types + + VkStructureType sType + struct VkBaseOutStructure* pNext + + + VkStructureType sType + const struct VkBaseInStructure* pNext + + + int32_t x + int32_t y + + + int32_t x + int32_t y + int32_t z + + + uint32_t width + uint32_t height + + + uint32_t width + uint32_t height + uint32_t depth + + + float x + float y + float width + float height + float minDepth + float maxDepth + + + VkOffset2D offset + VkExtent2D extent + + + VkRect2D rect + uint32_t baseArrayLayer + uint32_t layerCount + + + VkComponentSwizzle r + VkComponentSwizzle g + VkComponentSwizzle b + VkComponentSwizzle a + + + uint32_t apiVersion + uint32_t driverVersion + uint32_t vendorID + uint32_t deviceID + VkPhysicalDeviceType deviceType + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] + uint8_t pipelineCacheUUID[VK_UUID_SIZE] + VkPhysicalDeviceLimits limits + VkPhysicalDeviceSparseProperties sparseProperties + + + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]extension name + uint32_t specVersionversion of the extension specification implemented + + + char layerName[VK_MAX_EXTENSION_NAME_SIZE]layer name + uint32_t specVersionversion of the layer specification implemented + uint32_t implementationVersionbuild or release version of the layer's library + char description[VK_MAX_DESCRIPTION_SIZE]Free-form description of the layer + + + VkStructureType sType + const void* pNext + const char* pApplicationName + uint32_t applicationVersion + const char* pEngineName + uint32_t engineVersion + uint32_t apiVersion + + + void* pUserData + PFN_vkAllocationFunction pfnAllocation + PFN_vkReallocationFunction pfnReallocation + PFN_vkFreeFunction pfnFree + PFN_vkInternalAllocationNotification pfnInternalAllocation + PFN_vkInternalFreeNotification pfnInternalFree + + + VkStructureType sType + const void* pNext + VkDeviceQueueCreateFlags flags + uint32_t queueFamilyIndex + uint32_t queueCount + const float* pQueuePriorities + + + VkStructureType sType + const void* pNext + VkDeviceCreateFlags flags + uint32_t queueCreateInfoCount + const VkDeviceQueueCreateInfo* pQueueCreateInfos + uint32_t enabledLayerCount + const char* const* ppEnabledLayerNamesOrdered list of layer names to be enabled + uint32_t enabledExtensionCount + const char* const* ppEnabledExtensionNames + const VkPhysicalDeviceFeatures* pEnabledFeatures + + + VkStructureType sType + const void* pNext + VkInstanceCreateFlags flags + const VkApplicationInfo* pApplicationInfo + uint32_t enabledLayerCount + const char* const* ppEnabledLayerNamesOrdered list of layer names to be enabled + uint32_t enabledExtensionCount + const char* const* ppEnabledExtensionNamesExtension names to be enabled + + + VkQueueFlags queueFlagsQueue flags + uint32_t queueCount + uint32_t timestampValidBits + VkExtent3D minImageTransferGranularityMinimum alignment requirement for image transfers + + + uint32_t memoryTypeCount + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES] + uint32_t memoryHeapCount + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS] + + + VkStructureType sType + const void* pNext + VkDeviceSize allocationSizeSize of memory allocation + uint32_t memoryTypeIndexIndex of the of the memory type to allocate from + + + VkDeviceSize sizeSpecified in bytes + VkDeviceSize alignmentSpecified in bytes + uint32_t memoryTypeBitsBitmask of the allowed memory type indices into memoryTypes[] for this object + + + VkImageAspectFlags aspectMask + VkExtent3D imageGranularity + VkSparseImageFormatFlags flags + + + VkSparseImageFormatProperties formatProperties + uint32_t imageMipTailFirstLod + VkDeviceSize imageMipTailSizeSpecified in bytes, must be a multiple of sparse block size in bytes / alignment + VkDeviceSize imageMipTailOffsetSpecified in bytes, must be a multiple of sparse block size in bytes / alignment + VkDeviceSize imageMipTailStrideSpecified in bytes, must be a multiple of sparse block size in bytes / alignment + + + VkMemoryPropertyFlags propertyFlagsMemory properties of this memory type + uint32_t heapIndexIndex of the memory heap allocations of this memory type are taken from + + + VkDeviceSize sizeAvailable memory in the heap + VkMemoryHeapFlags flagsFlags for the heap + + + VkStructureType sType + const void* pNext + VkDeviceMemory memoryMapped memory object + VkDeviceSize offsetOffset within the memory object where the range starts + VkDeviceSize sizeSize of the range within the memory object + + + VkFormatFeatureFlags linearTilingFeaturesFormat features in case of linear tiling + VkFormatFeatureFlags optimalTilingFeaturesFormat features in case of optimal tiling + VkFormatFeatureFlags bufferFeaturesFormat features supported by buffers + + + VkExtent3D maxExtentmax image dimensions for this resource type + uint32_t maxMipLevelsmax number of mipmap levels for this resource type + uint32_t maxArrayLayersmax array size for this resource type + VkSampleCountFlags sampleCountssupported sample counts for this resource type + VkDeviceSize maxResourceSizemax size (in bytes) of this resource type + + + VkBuffer bufferBuffer used for this descriptor slot. + VkDeviceSize offsetBase offset from buffer start in bytes to update in the descriptor set. + VkDeviceSize rangeSize in bytes of the buffer resource for this descriptor update. + + + VkSampler samplerSampler to write to the descriptor in case it is a SAMPLER or COMBINED_IMAGE_SAMPLER descriptor. Ignored otherwise. + VkImageView imageViewImage view to write to the descriptor in case it is a SAMPLED_IMAGE, STORAGE_IMAGE, COMBINED_IMAGE_SAMPLER, or INPUT_ATTACHMENT descriptor. Ignored otherwise. + VkImageLayout imageLayoutLayout the image is expected to be in when accessed using this descriptor (only used if imageView is not VK_NULL_HANDLE). + + + VkStructureType sType + const void* pNext + VkDescriptorSet dstSetDestination descriptor set + uint32_t dstBindingBinding within the destination descriptor set to write + uint32_t dstArrayElementArray element within the destination binding to write + uint32_t descriptorCountNumber of descriptors to write (determines the size of the array pointed by pDescriptors) + VkDescriptorType descriptorTypeDescriptor type to write (determines which members of the array pointed by pDescriptors are going to be used) + const VkDescriptorImageInfo* pImageInfoSampler, image view, and layout for SAMPLER, COMBINED_IMAGE_SAMPLER, {SAMPLED,STORAGE}_IMAGE, and INPUT_ATTACHMENT descriptor types. + const VkDescriptorBufferInfo* pBufferInfoRaw buffer, size, and offset for {UNIFORM,STORAGE}_BUFFER[_DYNAMIC] descriptor types. + const VkBufferView* pTexelBufferViewBuffer view to write to the descriptor for {UNIFORM,STORAGE}_TEXEL_BUFFER descriptor types. + + + VkStructureType sType + const void* pNext + VkDescriptorSet srcSetSource descriptor set + uint32_t srcBindingBinding within the source descriptor set to copy from + uint32_t srcArrayElementArray element within the source binding to copy from + VkDescriptorSet dstSetDestination descriptor set + uint32_t dstBindingBinding within the destination descriptor set to copy to + uint32_t dstArrayElementArray element within the destination binding to copy to + uint32_t descriptorCountNumber of descriptors to write (determines the size of the array pointed by pDescriptors) + + + VkStructureType sType + const void* pNext + VkBufferUsageFlags2 usage + + + + VkStructureType sType + const void* pNext + VkBufferCreateFlags flagsBuffer creation flags + VkDeviceSize sizeSpecified in bytes + VkBufferUsageFlags usageBuffer usage flags + VkSharingMode sharingMode + uint32_t queueFamilyIndexCount + const uint32_t* pQueueFamilyIndices + + + VkStructureType sType + const void* pNext + VkBufferViewCreateFlags flags + VkBuffer buffer + VkFormat formatOptionally specifies format of elements + VkDeviceSize offsetSpecified in bytes + VkDeviceSize rangeView size specified in bytes + + + VkImageAspectFlags aspectMask + uint32_t mipLevel + uint32_t arrayLayer + + + VkImageAspectFlags aspectMask + uint32_t mipLevel + uint32_t baseArrayLayer + uint32_t layerCount + + + VkImageAspectFlags aspectMask + uint32_t baseMipLevel + uint32_t levelCount + uint32_t baseArrayLayer + uint32_t layerCount + + + VkStructureType sType + const void* pNext + VkAccessFlags srcAccessMaskMemory accesses from the source of the dependency to synchronize + VkAccessFlags dstAccessMaskMemory accesses from the destination of the dependency to synchronize + + + VkStructureType sType + const void* pNext + VkAccessFlags srcAccessMaskMemory accesses from the source of the dependency to synchronize + VkAccessFlags dstAccessMaskMemory accesses from the destination of the dependency to synchronize + uint32_t srcQueueFamilyIndexQueue family to transition ownership from + uint32_t dstQueueFamilyIndexQueue family to transition ownership to + VkBuffer bufferBuffer to sync + VkDeviceSize offsetOffset within the buffer to sync + VkDeviceSize sizeAmount of bytes to sync + + + VkStructureType sType + const void* pNext + VkAccessFlags srcAccessMaskMemory accesses from the source of the dependency to synchronize + VkAccessFlags dstAccessMaskMemory accesses from the destination of the dependency to synchronize + VkImageLayout oldLayoutCurrent layout of the image + VkImageLayout newLayoutNew layout to transition the image to + uint32_t srcQueueFamilyIndexQueue family to transition ownership from + uint32_t dstQueueFamilyIndexQueue family to transition ownership to + VkImage imageImage to sync + VkImageSubresourceRange subresourceRangeSubresource range to sync + + + VkStructureType sType + const void* pNext + VkImageCreateFlags flagsImage creation flags + VkImageType imageType + VkFormat format + VkExtent3D extent + uint32_t mipLevels + uint32_t arrayLayers + VkSampleCountFlagBits samples + VkImageTiling tiling + VkImageUsageFlags usageImage usage flags + VkSharingMode sharingModeCross-queue-family sharing mode + uint32_t queueFamilyIndexCountNumber of queue families to share across + const uint32_t* pQueueFamilyIndicesArray of queue family indices to share across + VkImageLayout initialLayoutInitial image layout for all subresources + + + VkDeviceSize offsetSpecified in bytes + VkDeviceSize sizeSpecified in bytes + VkDeviceSize rowPitchSpecified in bytes + VkDeviceSize arrayPitchSpecified in bytes + VkDeviceSize depthPitchSpecified in bytes + + + VkStructureType sType + const void* pNext + VkImageViewCreateFlags flags + VkImage image + VkImageViewType viewType + VkFormat format + VkComponentMapping components + VkImageSubresourceRange subresourceRange + + + VkDeviceSize srcOffsetSpecified in bytes + VkDeviceSize dstOffsetSpecified in bytes + VkDeviceSize sizeSpecified in bytes + + + VkDeviceSize resourceOffsetSpecified in bytes + VkDeviceSize sizeSpecified in bytes + VkDeviceMemory memory + VkDeviceSize memoryOffsetSpecified in bytes + VkSparseMemoryBindFlags flags + + + VkImageSubresource subresource + VkOffset3D offset + VkExtent3D extent + VkDeviceMemory memory + VkDeviceSize memoryOffsetSpecified in bytes + VkSparseMemoryBindFlags flags + + + VkBuffer buffer + uint32_t bindCount + const VkSparseMemoryBind* pBinds + + + VkImage image + uint32_t bindCount + const VkSparseMemoryBind* pBinds + + + VkImage image + uint32_t bindCount + const VkSparseImageMemoryBind* pBinds + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreCount + const VkSemaphore* pWaitSemaphores + uint32_t bufferBindCount + const VkSparseBufferMemoryBindInfo* pBufferBinds + uint32_t imageOpaqueBindCount + const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds + uint32_t imageBindCount + const VkSparseImageMemoryBindInfo* pImageBinds + uint32_t signalSemaphoreCount + const VkSemaphore* pSignalSemaphores + + + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffsetSpecified in pixels for both compressed and uncompressed images + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffsetSpecified in pixels for both compressed and uncompressed images + VkExtent3D extentSpecified in pixels for both compressed and uncompressed images + + + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffsets[2]Specified in pixels for both compressed and uncompressed images + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffsets[2]Specified in pixels for both compressed and uncompressed images + + + VkDeviceSize bufferOffsetSpecified in bytes + uint32_t bufferRowLengthSpecified in texels + uint32_t bufferImageHeight + VkImageSubresourceLayers imageSubresource + VkOffset3D imageOffsetSpecified in pixels for both compressed and uncompressed images + VkExtent3D imageExtentSpecified in pixels for both compressed and uncompressed images + + + VkDeviceAddress address + VkDeviceSize size + VkDeviceSize stride + + + VkDeviceAddress srcAddress + VkDeviceAddress dstAddress + VkDeviceSize size + + + + VkStructureType sType + const void* pNext + VkAddressCopyFlagsKHR srcCopyFlags + VkAddressCopyFlagsKHR dstCopyFlags + uint32_t copyCount + VkStridedDeviceAddressRangeKHR copyAddressRange + + + VkDeviceAddress srcAddress + uint32_t bufferRowLength + uint32_t bufferImageHeight + VkImageSubresourceLayers imageSubresource + VkOffset3D imageOffset + VkExtent3D imageExtent + + + + VkStructureType sType + const void* pNext + VkAddressCopyFlagsKHR srcCopyFlags + uint32_t copyCount + VkStridedDeviceAddressRangeKHR copyAddressRange + VkImage dstImage + VkImageLayout dstImageLayout + const VkImageSubresourceLayers* pImageSubresources + + + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffset + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffset + VkExtent3D extent + + + VkStructureType sType + const void* pNextnoautovalidity because this structure can be either an explicit parameter, or passed in a pNext chain + VkShaderModuleCreateFlags flags + size_t codeSizeSpecified in bytes + const uint32_t* pCodeBinary code of size codeSize + + + uint32_t bindingBinding number for this entry + VkDescriptorType descriptorTypeType of the descriptors in this binding + uint32_t descriptorCountNumber of descriptors in this binding + VkShaderStageFlags stageFlagsShader stages this binding is visible to + const VkSampler* pImmutableSamplersImmutable samplers (used if descriptor type is SAMPLER or COMBINED_IMAGE_SAMPLER, is either NULL or contains count number of elements) + + + VkStructureType sType + const void* pNext + VkDescriptorSetLayoutCreateFlags flags + uint32_t bindingCountNumber of bindings in the descriptor set layout + const VkDescriptorSetLayoutBinding* pBindingsArray of descriptor set layout bindings + + + VkDescriptorType type + uint32_t descriptorCount + + + VkStructureType sType + const void* pNext + VkDescriptorPoolCreateFlags flags + uint32_t maxSets + uint32_t poolSizeCount + const VkDescriptorPoolSize* pPoolSizes + + + VkStructureType sType + const void* pNext + VkDescriptorPool descriptorPool + uint32_t descriptorSetCount + const VkDescriptorSetLayout* pSetLayouts + + + uint32_t constantIDThe SpecConstant ID specified in the BIL + uint32_t offsetOffset of the value in the data block + size_t sizeSize in bytes of the SpecConstant + + + uint32_t mapEntryCountNumber of entries in the map + const VkSpecializationMapEntry* pMapEntriesArray of map entries + size_t dataSizeSize in bytes of pData + const void* pDataPointer to SpecConstant data + + + VkStructureType sType + const void* pNext + VkPipelineShaderStageCreateFlags flags + VkShaderStageFlagBits stageShader stage + VkShaderModule moduleModule containing entry point + const char* pNameNull-terminated entry point name + const char* pNameNull-terminated entry point name + const VkSpecializationInfo* pSpecializationInfo + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags flagsPipeline creation flags + VkPipelineShaderStageCreateInfo stage + VkPipelineLayout layoutInterface layout of the pipeline + VkPipeline basePipelineHandleIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of + int32_t basePipelineIndexIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of + + + VkStructureType sType + const void* pNext + VkDeviceAddress deviceAddress + VkDeviceSize size + VkDeviceAddress pipelineDeviceAddressCaptureReplay + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags2 flags + + + + uint32_t bindingVertex buffer binding id + uint32_t strideDistance between vertices in bytes (0 = no advancement) + VkVertexInputRate inputRateThe rate at which the vertex data is consumed + + + uint32_t locationlocation of the shader vertex attrib + uint32_t bindingVertex buffer binding id + VkFormat formatformat of source data + uint32_t offsetOffset of first element in bytes from base of vertex + + + VkStructureType sType + const void* pNext + VkPipelineVertexInputStateCreateFlags flags + uint32_t vertexBindingDescriptionCountnumber of bindings + const VkVertexInputBindingDescription* pVertexBindingDescriptions + uint32_t vertexAttributeDescriptionCountnumber of attributes + const VkVertexInputAttributeDescription* pVertexAttributeDescriptions + + + VkStructureType sType + const void* pNext + VkPipelineInputAssemblyStateCreateFlags flags + VkPrimitiveTopology topology + VkBool32 primitiveRestartEnable + + + VkStructureType sType + const void* pNext + VkPipelineTessellationStateCreateFlags flags + uint32_t patchControlPoints + + + VkStructureType sType + const void* pNext + VkPipelineViewportStateCreateFlags flags + uint32_t viewportCount + const VkViewport* pViewports + uint32_t scissorCount + const VkRect2D* pScissors + + + VkStructureType sType + const void* pNext + VkPipelineRasterizationStateCreateFlags flags + VkBool32 depthClampEnable + VkBool32 rasterizerDiscardEnable + VkPolygonMode polygonModeoptional (GL45) + VkCullModeFlags cullMode + VkFrontFace frontFace + VkBool32 depthBiasEnable + float depthBiasConstantFactor + float depthBiasClamp + float depthBiasSlopeFactor + float lineWidth + + + VkStructureType sType + const void* pNext + VkPipelineMultisampleStateCreateFlags flags + VkSampleCountFlagBits rasterizationSamplesNumber of samples used for rasterization + VkBool32 sampleShadingEnableoptional (GL45) + float minSampleShadingoptional (GL45) + const VkSampleMask* pSampleMaskArray of sampleMask words + VkBool32 alphaToCoverageEnable + VkBool32 alphaToOneEnable + + + VkBool32 blendEnable + VkBlendFactor srcColorBlendFactor + VkBlendFactor dstColorBlendFactor + VkBlendOp colorBlendOp + VkBlendFactor srcAlphaBlendFactor + VkBlendFactor dstAlphaBlendFactor + VkBlendOp alphaBlendOp + VkColorComponentFlags colorWriteMask + + + VkStructureType sType + const void* pNext + VkPipelineColorBlendStateCreateFlags flags + VkBool32 logicOpEnable + VkLogicOp logicOp + uint32_t attachmentCount# of pAttachments + const VkPipelineColorBlendAttachmentState* pAttachments + float blendConstants[4] + + + VkStructureType sType + const void* pNext + VkPipelineDynamicStateCreateFlags flags + uint32_t dynamicStateCount + const VkDynamicState* pDynamicStates + + + VkStencilOp failOp + VkStencilOp passOp + VkStencilOp depthFailOp + VkCompareOp compareOp + uint32_t compareMask + uint32_t writeMask + uint32_t reference + + + VkStructureType sType + const void* pNext + VkPipelineDepthStencilStateCreateFlags flags + VkBool32 depthTestEnable + VkBool32 depthWriteEnable + VkCompareOp depthCompareOp + VkBool32 depthBoundsTestEnableoptional (depth_bounds_test) + VkBool32 stencilTestEnable + VkStencilOpState front + VkStencilOpState back + float minDepthBounds + float maxDepthBounds + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags flagsPipeline creation flags + uint32_t stageCount + const VkPipelineShaderStageCreateInfo* pStagesOne entry for each active shader stage + const VkPipelineShaderStageCreateInfo* pStagesOne entry for each active shader stage + const VkPipelineVertexInputStateCreateInfo* pVertexInputState + const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState + const VkPipelineTessellationStateCreateInfo* pTessellationState + const VkPipelineViewportStateCreateInfo* pViewportState + const VkPipelineRasterizationStateCreateInfo* pRasterizationState + const VkPipelineMultisampleStateCreateInfo* pMultisampleState + const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState + const VkPipelineColorBlendStateCreateInfo* pColorBlendState + const VkPipelineDynamicStateCreateInfo* pDynamicState + VkPipelineLayout layoutInterface layout of the pipeline + VkRenderPass renderPass + uint32_t subpass + VkPipeline basePipelineHandleIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of + int32_t basePipelineIndexIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of + + + VkStructureType sType + const void* pNext + VkPipelineCacheCreateFlags flags + size_t initialDataSizeSize of initial data to populate cache, in bytes + size_t initialDataSizeSize of initial data to populate cache, in bytes + const void* pInitialDataInitial data to populate cache + + + The fields in this structure are non-normative since structure packing is implementation-defined in C. The specification defines the normative layout. + uint32_t headerSize + VkPipelineCacheHeaderVersion headerVersion + uint32_t vendorID + uint32_t deviceID + uint8_t pipelineCacheUUID[VK_UUID_SIZE] + + + The fields in this structure are non-normative since structure packing is implementation-defined in C. The specification defines the normative layout. + uint64_t codeSize + uint64_t codeOffset + + + The fields in this structure are non-normative since structure packing is implementation-defined in C. The specification defines the normative layout. + uint8_t pipelineIdentifier[VK_UUID_SIZE] + uint64_t pipelineMemorySize + uint64_t jsonSize + uint64_t jsonOffset + uint32_t stageIndexCount + uint32_t stageIndexStride + uint64_t stageIndexOffset + + + The fields in this structure are non-normative since structure packing is implementation-defined in C. The specification defines the normative layout. + VkPipelineCacheHeaderVersionOne headerVersionOne + VkPipelineCacheValidationVersion validationVersion + uint32_t implementationData + uint32_t pipelineIndexCount + uint32_t pipelineIndexStride + uint64_t pipelineIndexOffset + + + VkShaderStageFlags stageFlagsWhich stages use the range + uint32_t offsetStart of the range, in bytes + uint32_t sizeSize of the range, in bytes + + + VkStructureType sType + const void* pNext + const VkPipelineBinaryKeysAndDataKHR* pKeysAndDataInfo + VkPipeline pipeline + const VkPipelineCreateInfoKHR* pPipelineCreateInfo + + + VkStructureType sType + const void* pNext + uint32_t pipelineBinaryCount + VkPipelineBinaryKHR* pPipelineBinaries + + + size_t dataSize + void* pData + + + uint32_t binaryCount + const VkPipelineBinaryKeyKHR* pPipelineBinaryKeys + const VkPipelineBinaryDataKHR* pPipelineBinaryData + + + VkStructureType sType + void* pNext + uint32_t keySize + uint8_t key[VK_MAX_PIPELINE_BINARY_KEY_SIZE_KHR] + + + VkStructureType sType + const void* pNext + uint32_t binaryCount + const VkPipelineBinaryKHR* pPipelineBinaries + + + VkStructureType sType + void* pNext + VkPipeline pipeline + + + VkStructureType sType + void* pNext + VkPipelineBinaryKHR pipelineBinary + + + VkStructureType sType + void* pNext + + + VkStructureType sType + const void* pNext + VkPipelineLayoutCreateFlags flags + uint32_t setLayoutCountNumber of descriptor sets interfaced by the pipeline + const VkDescriptorSetLayout* pSetLayoutsArray of setCount number of descriptor set layout objects defining the layout of the + uint32_t pushConstantRangeCountNumber of push-constant ranges used by the pipeline + const VkPushConstantRange* pPushConstantRangesArray of pushConstantRangeCount number of ranges used by various shader stages + + + VkStructureType sType + const void* pNext + VkSamplerCreateFlags flags + VkFilter magFilterFilter mode for magnification + VkFilter minFilterFilter mode for minifiation + VkSamplerMipmapMode mipmapModeMipmap selection mode + VkSamplerAddressMode addressModeU + VkSamplerAddressMode addressModeV + VkSamplerAddressMode addressModeW + float mipLodBias + VkBool32 anisotropyEnable + float maxAnisotropy + VkBool32 compareEnable + VkCompareOp compareOp + float minLod + float maxLod + VkBorderColor borderColor + VkBool32 unnormalizedCoordinates + + + VkStructureType sType + const void* pNext + VkCommandPoolCreateFlags flagsCommand pool creation flags + uint32_t queueFamilyIndex + + + VkStructureType sType + const void* pNext + VkCommandPool commandPool + VkCommandBufferLevel level + uint32_t commandBufferCount + + + VkStructureType sType + const void* pNext + VkRenderPass renderPassRender pass for secondary command buffers + uint32_t subpass + VkFramebuffer framebufferFramebuffer for secondary command buffers + VkBool32 occlusionQueryEnableWhether this secondary command buffer may be executed during an occlusion query + VkQueryControlFlags queryFlagsQuery flags used by this secondary command buffer, if executed during an occlusion query + VkQueryPipelineStatisticFlags pipelineStatisticsPipeline statistics that may be counted for this secondary command buffer + + + VkStructureType sType + const void* pNext + VkCommandBufferUsageFlags flagsCommand buffer usage flags + const VkCommandBufferInheritanceInfo* pInheritanceInfoPointer to inheritance info for secondary command buffers + + + VkStructureType sType + const void* pNext + VkRenderPass renderPass + VkFramebuffer framebuffer + VkRect2D renderArea + uint32_t clearValueCount + const VkClearValue* pClearValues + + + float float32[4] + int32_t int32[4] + uint32_t uint32[4] + + + float depth + uint32_t stencil + + + VkClearColorValue color + VkClearDepthStencilValue depthStencil + + + VkImageAspectFlags aspectMask + uint32_t colorAttachment + VkClearValue clearValue + + + VkAttachmentDescriptionFlags flags + VkFormat format + VkSampleCountFlagBits samples + VkAttachmentLoadOp loadOpLoad operation for color or depth data + VkAttachmentStoreOp storeOpStore operation for color or depth data + VkAttachmentLoadOp stencilLoadOpLoad operation for stencil data + VkAttachmentStoreOp stencilStoreOpStore operation for stencil data + VkImageLayout initialLayout + VkImageLayout finalLayout + + + uint32_t attachment + VkImageLayout layout + + + VkSubpassDescriptionFlags flags + VkPipelineBindPoint pipelineBindPointMust be VK_PIPELINE_BIND_POINT_GRAPHICS for now + uint32_t inputAttachmentCount + const VkAttachmentReference* pInputAttachments + uint32_t colorAttachmentCount + const VkAttachmentReference* pColorAttachments + const VkAttachmentReference* pResolveAttachments + const VkAttachmentReference* pDepthStencilAttachment + uint32_t preserveAttachmentCount + const uint32_t* pPreserveAttachments + + + uint32_t srcSubpass + uint32_t dstSubpass + VkPipelineStageFlags srcStageMask + VkPipelineStageFlags dstStageMask + VkAccessFlags srcAccessMaskMemory accesses from the source of the dependency to synchronize + VkAccessFlags dstAccessMaskMemory accesses from the destination of the dependency to synchronize + VkDependencyFlags dependencyFlags + + + VkStructureType sType + const void* pNext + VkRenderPassCreateFlags flags + uint32_t attachmentCount + const VkAttachmentDescription* pAttachments + uint32_t subpassCount + const VkSubpassDescription* pSubpasses + uint32_t dependencyCount + const VkSubpassDependency* pDependencies + + + VkStructureType sType + const void* pNext + VkEventCreateFlags flagsEvent creation flags + + + VkStructureType sType + const void* pNext + VkFenceCreateFlags flagsFence creation flags + + + VkBool32 robustBufferAccessout of bounds buffer accesses are well defined + VkBool32 fullDrawIndexUint32full 32-bit range of indices for indexed draw calls + VkBool32 imageCubeArrayimage views which are arrays of cube maps + VkBool32 independentBlendblending operations are controlled per-attachment + VkBool32 geometryShadergeometry stage + VkBool32 tessellationShadertessellation control and evaluation stage + VkBool32 sampleRateShadingper-sample shading and interpolation + VkBool32 dualSrcBlendblend operations which take two sources + VkBool32 logicOplogic operations + VkBool32 multiDrawIndirectmulti draw indirect + VkBool32 drawIndirectFirstInstanceindirect drawing can use non-zero firstInstance + VkBool32 depthClampdepth clamping + VkBool32 depthBiasClampdepth bias clamping + VkBool32 fillModeNonSolidpoint and wireframe fill modes + VkBool32 depthBoundsdepth bounds test + VkBool32 wideLineslines with width greater than 1 + VkBool32 largePointspoints with size greater than 1 + VkBool32 alphaToOnethe fragment alpha component can be forced to maximum representable alpha value + VkBool32 multiViewportviewport arrays + VkBool32 samplerAnisotropyanisotropic sampler filtering + VkBool32 textureCompressionETC2ETC texture compression formats + VkBool32 textureCompressionASTC_LDRASTC LDR texture compression formats + VkBool32 textureCompressionBCBC1-7 texture compressed formats + VkBool32 occlusionQueryPreciseprecise occlusion queries returning actual sample counts + VkBool32 pipelineStatisticsQuerypipeline statistics query + VkBool32 vertexPipelineStoresAndAtomicsstores and atomic ops on storage buffers and images are supported in vertex, tessellation, and geometry stages + VkBool32 fragmentStoresAndAtomicsstores and atomic ops on storage buffers and images are supported in the fragment stage + VkBool32 shaderTessellationAndGeometryPointSizetessellation and geometry stages can export point size + VkBool32 shaderImageGatherExtendedimage gather with runtime values and independent offsets + VkBool32 shaderStorageImageExtendedFormatsthe extended set of formats can be used for storage images + VkBool32 shaderStorageImageMultisamplemultisample images can be used for storage images + VkBool32 shaderStorageImageReadWithoutFormatread from storage image does not require format qualifier + VkBool32 shaderStorageImageWriteWithoutFormatwrite to storage image does not require format qualifier + VkBool32 shaderUniformBufferArrayDynamicIndexingarrays of uniform buffers can be accessed with dynamically uniform indices + VkBool32 shaderSampledImageArrayDynamicIndexingarrays of sampled images can be accessed with dynamically uniform indices + VkBool32 shaderStorageBufferArrayDynamicIndexingarrays of storage buffers can be accessed with dynamically uniform indices + VkBool32 shaderStorageImageArrayDynamicIndexingarrays of storage images can be accessed with dynamically uniform indices + VkBool32 shaderClipDistanceclip distance in shaders + VkBool32 shaderCullDistancecull distance in shaders + VkBool32 shaderFloat6464-bit floats (doubles) in shaders + VkBool32 shaderInt6464-bit integers in shaders + VkBool32 shaderInt1616-bit integers in shaders + VkBool32 shaderResourceResidencyshader can use texture operations that return resource residency information (requires sparseNonResident support) + VkBool32 shaderResourceMinLodshader can use texture operations that specify minimum resource LOD + VkBool32 sparseBindingSparse resources support: Resource memory can be managed at opaque page level rather than object level + VkBool32 sparseResidencyBufferSparse resources support: GPU can access partially resident buffers + VkBool32 sparseResidencyImage2DSparse resources support: GPU can access partially resident 2D (non-MSAA non-depth/stencil) images + VkBool32 sparseResidencyImage3DSparse resources support: GPU can access partially resident 3D images + VkBool32 sparseResidency2SamplesSparse resources support: GPU can access partially resident MSAA 2D images with 2 samples + VkBool32 sparseResidency4SamplesSparse resources support: GPU can access partially resident MSAA 2D images with 4 samples + VkBool32 sparseResidency8SamplesSparse resources support: GPU can access partially resident MSAA 2D images with 8 samples + VkBool32 sparseResidency16SamplesSparse resources support: GPU can access partially resident MSAA 2D images with 16 samples + VkBool32 sparseResidencyAliasedSparse resources support: GPU can correctly access data aliased into multiple locations (opt-in) + VkBool32 variableMultisampleRatemultisample rate must be the same for all pipelines in a subpass + VkBool32 inheritedQueriesQueries may be inherited from primary to secondary command buffers + + + VkBool32 residencyStandard2DBlockShapeSparse resources support: GPU will access all 2D (single sample) sparse resources using the standard sparse image block shapes (based on pixel format) + VkBool32 residencyStandard2DMultisampleBlockShapeSparse resources support: GPU will access all 2D (multisample) sparse resources using the standard sparse image block shapes (based on pixel format) + VkBool32 residencyStandard3DBlockShapeSparse resources support: GPU will access all 3D sparse resources using the standard sparse image block shapes (based on pixel format) + VkBool32 residencyAlignedMipSizeSparse resources support: Images with mip level dimensions that are NOT a multiple of the sparse image block dimensions will be placed in the mip tail + VkBool32 residencyNonResidentStrictSparse resources support: GPU can consistently access non-resident regions of a resource, all reads return as if data is 0, writes are discarded + + + resource maximum sizes + uint32_t maxImageDimension1Dmax 1D image dimension + uint32_t maxImageDimension2Dmax 2D image dimension + uint32_t maxImageDimension3Dmax 3D image dimension + uint32_t maxImageDimensionCubemax cube map image dimension + uint32_t maxImageArrayLayersmax layers for image arrays + uint32_t maxTexelBufferElementsmax texel buffer size (fstexels) + uint32_t maxUniformBufferRangemax uniform buffer range (bytes) + uint32_t maxStorageBufferRangemax storage buffer range (bytes) + uint32_t maxPushConstantsSizemax size of the push constants pool (bytes) + memory limits + uint32_t maxMemoryAllocationCountmax number of device memory allocations supported + uint32_t maxSamplerAllocationCountmax number of samplers that can be allocated on a device + VkDeviceSize bufferImageGranularityGranularity (in bytes) at which buffers and images can be bound to adjacent memory for simultaneous usage + VkDeviceSize sparseAddressSpaceSizeTotal address space available for sparse allocations (bytes) + descriptor set limits + uint32_t maxBoundDescriptorSetsmax number of descriptors sets that can be bound to a pipeline + uint32_t maxPerStageDescriptorSamplersmax number of samplers allowed per-stage in a descriptor set + uint32_t maxPerStageDescriptorUniformBuffersmax number of uniform buffers allowed per-stage in a descriptor set + uint32_t maxPerStageDescriptorStorageBuffersmax number of storage buffers allowed per-stage in a descriptor set + uint32_t maxPerStageDescriptorSampledImagesmax number of sampled images allowed per-stage in a descriptor set + uint32_t maxPerStageDescriptorStorageImagesmax number of storage images allowed per-stage in a descriptor set + uint32_t maxPerStageDescriptorInputAttachmentsmax number of input attachments allowed per-stage in a descriptor set + uint32_t maxPerStageResourcesmax number of resources allowed by a single stage + uint32_t maxDescriptorSetSamplersmax number of samplers allowed in all stages in a descriptor set + uint32_t maxDescriptorSetUniformBuffersmax number of uniform buffers allowed in all stages in a descriptor set + uint32_t maxDescriptorSetUniformBuffersDynamicmax number of dynamic uniform buffers allowed in all stages in a descriptor set + uint32_t maxDescriptorSetStorageBuffersmax number of storage buffers allowed in all stages in a descriptor set + uint32_t maxDescriptorSetStorageBuffersDynamicmax number of dynamic storage buffers allowed in all stages in a descriptor set + uint32_t maxDescriptorSetSampledImagesmax number of sampled images allowed in all stages in a descriptor set + uint32_t maxDescriptorSetStorageImagesmax number of storage images allowed in all stages in a descriptor set + uint32_t maxDescriptorSetInputAttachmentsmax number of input attachments allowed in all stages in a descriptor set + vertex stage limits + uint32_t maxVertexInputAttributesmax number of vertex input attribute slots + uint32_t maxVertexInputBindingsmax number of vertex input binding slots + uint32_t maxVertexInputAttributeOffsetmax vertex input attribute offset added to vertex buffer offset + uint32_t maxVertexInputBindingStridemax vertex input binding stride + uint32_t maxVertexOutputComponentsmax number of output components written by vertex shader + tessellation control stage limits + uint32_t maxTessellationGenerationLevelmax level supported by tessellation primitive generator + uint32_t maxTessellationPatchSizemax patch size (vertices) + uint32_t maxTessellationControlPerVertexInputComponentsmax number of input components per-vertex in TCS + uint32_t maxTessellationControlPerVertexOutputComponentsmax number of output components per-vertex in TCS + uint32_t maxTessellationControlPerPatchOutputComponentsmax number of output components per-patch in TCS + uint32_t maxTessellationControlTotalOutputComponentsmax total number of per-vertex and per-patch output components in TCS + tessellation evaluation stage limits + uint32_t maxTessellationEvaluationInputComponentsmax number of input components per vertex in TES + uint32_t maxTessellationEvaluationOutputComponentsmax number of output components per vertex in TES + geometry stage limits + uint32_t maxGeometryShaderInvocationsmax invocation count supported in geometry shader + uint32_t maxGeometryInputComponentsmax number of input components read in geometry stage + uint32_t maxGeometryOutputComponentsmax number of output components written in geometry stage + uint32_t maxGeometryOutputVerticesmax number of vertices that can be emitted in geometry stage + uint32_t maxGeometryTotalOutputComponentsmax total number of components (all vertices) written in geometry stage + fragment stage limits + uint32_t maxFragmentInputComponentsmax number of input components read in fragment stage + uint32_t maxFragmentOutputAttachmentsmax number of output attachments written in fragment stage + uint32_t maxFragmentDualSrcAttachmentsmax number of output attachments written when using dual source blending + uint32_t maxFragmentCombinedOutputResourcesmax total number of storage buffers, storage images and output buffers + compute stage limits + uint32_t maxComputeSharedMemorySizemax total storage size of work group local storage (bytes) + uint32_t maxComputeWorkGroupCount[3]max num of compute work groups that may be dispatched by a single command (x,y,z) + uint32_t maxComputeWorkGroupInvocationsmax total compute invocations in a single local work group + uint32_t maxComputeWorkGroupSize[3]max local size of a compute work group (x,y,z) + uint32_t subPixelPrecisionBitsnumber bits of subpixel precision in screen x and y + uint32_t subTexelPrecisionBitsnumber bits of precision for selecting texel weights + uint32_t mipmapPrecisionBitsnumber bits of precision for selecting mipmap weights + uint32_t maxDrawIndexedIndexValuemax index value for indexed draw calls (for 32-bit indices) + uint32_t maxDrawIndirectCountmax draw count for indirect drawing calls + float maxSamplerLodBiasmax absolute sampler LOD bias + float maxSamplerAnisotropymax degree of sampler anisotropy + uint32_t maxViewportsmax number of active viewports + uint32_t maxViewportDimensions[2]max viewport dimensions (x,y) + float viewportBoundsRange[2]viewport bounds range (min,max) + uint32_t viewportSubPixelBitsnumber bits of subpixel precision for viewport + size_t minMemoryMapAlignmentmin required alignment of pointers returned by MapMemory (bytes) + VkDeviceSize minTexelBufferOffsetAlignmentmin required alignment for texel buffer offsets (bytes) + VkDeviceSize minUniformBufferOffsetAlignmentmin required alignment for uniform buffer sizes and offsets (bytes) + VkDeviceSize minStorageBufferOffsetAlignmentmin required alignment for storage buffer offsets (bytes) + int32_t minTexelOffsetmin texel offset for OpTextureSampleOffset + uint32_t maxTexelOffsetmax texel offset for OpTextureSampleOffset + int32_t minTexelGatherOffsetmin texel offset for OpTextureGatherOffset + uint32_t maxTexelGatherOffsetmax texel offset for OpTextureGatherOffset + float minInterpolationOffsetfurthest negative offset for interpolateAtOffset + float maxInterpolationOffsetfurthest positive offset for interpolateAtOffset + uint32_t subPixelInterpolationOffsetBitsnumber of subpixel bits for interpolateAtOffset + uint32_t maxFramebufferWidthmax width for a framebuffer + uint32_t maxFramebufferHeightmax height for a framebuffer + uint32_t maxFramebufferLayersmax layer count for a layered framebuffer + VkSampleCountFlags framebufferColorSampleCountssupported color sample counts for a framebuffer + VkSampleCountFlags framebufferDepthSampleCountssupported depth sample counts for a framebuffer + VkSampleCountFlags framebufferStencilSampleCountssupported stencil sample counts for a framebuffer + VkSampleCountFlags framebufferNoAttachmentsSampleCountssupported sample counts for a subpass which uses no attachments + uint32_t maxColorAttachmentsmax number of color attachments per subpass + VkSampleCountFlags sampledImageColorSampleCountssupported color sample counts for a non-integer sampled image + VkSampleCountFlags sampledImageIntegerSampleCountssupported sample counts for an integer image + VkSampleCountFlags sampledImageDepthSampleCountssupported depth sample counts for a sampled image + VkSampleCountFlags sampledImageStencilSampleCountssupported stencil sample counts for a sampled image + VkSampleCountFlags storageImageSampleCountssupported sample counts for a storage image + uint32_t maxSampleMaskWordsmax number of sample mask words + VkBool32 timestampComputeAndGraphicstimestamps on graphics and compute queues + float timestampPeriodnumber of nanoseconds it takes for timestamp query value to increment by 1 + uint32_t maxClipDistancesmax number of clip distances + uint32_t maxCullDistancesmax number of cull distances + uint32_t maxCombinedClipAndCullDistancesmax combined number of user clipping + uint32_t discreteQueuePrioritiesdistinct queue priorities available + float pointSizeRange[2]range (min,max) of supported point sizes + float lineWidthRange[2]range (min,max) of supported line widths + float pointSizeGranularitygranularity of supported point sizes + float lineWidthGranularitygranularity of supported line widths + VkBool32 strictLinesline rasterization follows preferred rules + VkBool32 standardSampleLocationssupports standard sample locations for all supported sample counts + VkDeviceSize optimalBufferCopyOffsetAlignmentoptimal offset of buffer copies + VkDeviceSize optimalBufferCopyRowPitchAlignmentoptimal pitch of buffer copies + VkDeviceSize nonCoherentAtomSizeminimum size and alignment for non-coherent host-mapped device memory access + + + VkStructureType sType + const void* pNext + VkSemaphoreCreateFlags flagsSemaphore creation flags + + + VkStructureType sType + const void* pNext + VkQueryPoolCreateFlags flags + VkQueryType queryType + uint32_t queryCount + VkQueryPipelineStatisticFlags pipelineStatisticsOptional + + + VkStructureType sType + const void* pNext + VkFramebufferCreateFlags flags + VkRenderPass renderPass + uint32_t attachmentCount + const VkImageView* pAttachments + uint32_t width + uint32_t height + uint32_t layers + + + uint32_t vertexCount + uint32_t instanceCount + uint32_t firstVertex + uint32_t firstInstance + + + uint32_t indexCount + uint32_t instanceCount + uint32_t firstIndex + int32_t vertexOffset + uint32_t firstInstance + + + uint32_t x + uint32_t y + uint32_t z + + + uint32_t firstVertex + uint32_t vertexCount + + + uint32_t firstIndex + uint32_t indexCount + int32_t vertexOffset + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreCount + const VkSemaphore* pWaitSemaphores + const VkPipelineStageFlags* pWaitDstStageMask + uint32_t commandBufferCount + const VkCommandBuffer* pCommandBuffers + uint32_t signalSemaphoreCount + const VkSemaphore* pSignalSemaphores + + WSI extensions + + VkDisplayKHR displayHandle of the display object + const char* displayNameName of the display + VkExtent2D physicalDimensionsIn millimeters? + VkExtent2D physicalResolutionMax resolution for CRT? + VkSurfaceTransformFlagsKHR supportedTransformsone or more bits from VkSurfaceTransformFlagsKHR + VkBool32 planeReorderPossibleVK_TRUE if the overlay plane's z-order can be changed on this display. + VkBool32 persistentContentVK_TRUE if this is a "smart" display that supports self-refresh/internal buffering. + + + VkDisplayKHR currentDisplayDisplay the plane is currently associated with. Will be VK_NULL_HANDLE if the plane is not in use. + uint32_t currentStackIndexCurrent z-order of the plane. + + + VkExtent2D visibleRegionVisible scanout region. + uint32_t refreshRateNumber of times per second the display is updated. + + + VkDisplayModeKHR displayModeHandle of this display mode. + VkDisplayModeParametersKHR parametersThe parameters this mode uses. + + + VkStructureType sType + const void* pNext + VkDisplayModeCreateFlagsKHR flags + VkDisplayModeParametersKHR parametersThe parameters this mode uses. + + + VkDisplayPlaneAlphaFlagsKHR supportedAlphaTypes of alpha blending supported, if any. + VkOffset2D minSrcPositionDoes the plane have any position and extent restrictions? + VkOffset2D maxSrcPosition + VkExtent2D minSrcExtent + VkExtent2D maxSrcExtent + VkOffset2D minDstPosition + VkOffset2D maxDstPosition + VkExtent2D minDstExtent + VkExtent2D maxDstExtent + + + VkStructureType sType + const void* pNext + VkDisplaySurfaceCreateFlagsKHR flags + VkDisplayModeKHR displayModeThe mode to use when displaying this surface + uint32_t planeIndexThe plane on which this surface appears. Must be between 0 and the value returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR() in pPropertyCount. + uint32_t planeStackIndexThe z-order of the plane. + VkSurfaceTransformFlagBitsKHR transformTransform to apply to the images as part of the scanout operation + float globalAlphaGlobal alpha value. Must be between 0 and 1, inclusive. Ignored if alphaMode is not VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR + VkDisplayPlaneAlphaFlagBitsKHR alphaModeThe type of alpha blending to use. Must be one of the bits from VkDisplayPlaneCapabilitiesKHR::supportedAlpha for this display plane + VkExtent2D imageExtentsize of the images to use with this surface + + + VkStructureType sType + const void* pNext + VkDisplaySurfaceStereoTypeNV stereoTypeThe 3D stereo type to use when presenting this surface. + + + VkStructureType sType + const void* pNext + VkRect2D srcRectRectangle within the presentable image to read pixel data from when presenting to the display. + VkRect2D dstRectRectangle within the current display mode's visible region to display srcRectangle in. + VkBool32 persistentFor smart displays, use buffered mode. If the display properties member "persistentMode" is VK_FALSE, this member must always be VK_FALSE. + + + uint32_t minImageCountSupported minimum number of images for the surface + uint32_t maxImageCountSupported maximum number of images for the surface, 0 for unlimited + VkExtent2D currentExtentCurrent image width and height for the surface, (0, 0) if undefined + VkExtent2D minImageExtentSupported minimum image width and height for the surface + VkExtent2D maxImageExtentSupported maximum image width and height for the surface + uint32_t maxImageArrayLayersSupported maximum number of image layers for the surface + VkSurfaceTransformFlagsKHR supportedTransforms1 or more bits representing the transforms supported + VkSurfaceTransformFlagBitsKHR currentTransformThe surface's current transform relative to the device's natural orientation + VkCompositeAlphaFlagsKHR supportedCompositeAlpha1 or more bits representing the alpha compositing modes supported + VkImageUsageFlags supportedUsageFlagsSupported image usage flags for the surface + + + VkStructureType sType + const void* pNext + VkAndroidSurfaceCreateFlagsKHR flags + struct ANativeWindow* window + + + VkStructureType sType + const void* pNext + VkViSurfaceCreateFlagsNN flags + void* window + + + VkStructureType sType + const void* pNext + VkWaylandSurfaceCreateFlagsKHR flags + struct wl_display* display + struct wl_surface* surface + + + VkStructureType sType + const void* pNext + VkWin32SurfaceCreateFlagsKHR flags + HINSTANCE hinstance + HWND hwnd + + + VkStructureType sType + const void* pNext + VkXlibSurfaceCreateFlagsKHR flags + Display* dpy + Window window + + + VkStructureType sType + const void* pNext + VkXcbSurfaceCreateFlagsKHR flags + xcb_connection_t* connection + xcb_window_t window + + + VkStructureType sType + const void* pNext + VkDirectFBSurfaceCreateFlagsEXT flags + IDirectFB* dfb + IDirectFBSurface* surface + + + VkStructureType sType + const void* pNext + VkImagePipeSurfaceCreateFlagsFUCHSIA flags + zx_handle_t imagePipeHandle + + + VkStructureType sType + const void* pNext + VkStreamDescriptorSurfaceCreateFlagsGGP flags + GgpStreamDescriptor streamDescriptor + + + VkStructureType sType + const void* pNext + VkScreenSurfaceCreateFlagsQNX flags + struct _screen_context* context + struct _screen_window* window + + + VkFormat formatSupported pair of rendering format + VkColorSpaceKHR colorSpaceand color space for the surface + + + VkStructureType sType + const void* pNext + VkSwapchainCreateFlagsKHR flags + VkSurfaceKHR surfaceThe swapchain's target surface + uint32_t minImageCountMinimum number of presentation images the application needs + VkFormat imageFormatFormat of the presentation images + VkColorSpaceKHR imageColorSpaceColorspace of the presentation images + VkExtent2D imageExtentDimensions of the presentation images + uint32_t imageArrayLayersDetermines the number of views for multiview/stereo presentation + VkImageUsageFlags imageUsageBits indicating how the presentation images will be used + VkSharingMode imageSharingModeSharing mode used for the presentation images + uint32_t queueFamilyIndexCountNumber of queue families having access to the images in case of concurrent sharing mode + const uint32_t* pQueueFamilyIndicesArray of queue family indices having access to the images in case of concurrent sharing mode + VkSurfaceTransformFlagBitsKHR preTransformThe transform, relative to the device's natural orientation, applied to the image content prior to presentation + VkCompositeAlphaFlagBitsKHR compositeAlphaThe alpha blending mode used when compositing this surface with other surfaces in the window system + VkPresentModeKHR presentModeWhich presentation mode to use for presents on this swap chain + VkBool32 clippedSpecifies whether presentable images may be affected by window clip regions + VkSwapchainKHR oldSwapchainExisting swap chain to replace, if any + VkSwapchainKHR oldSwapchainExisting swap chain to replace, if any + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreCountNumber of semaphores to wait for before presenting + const VkSemaphore* pWaitSemaphoresSemaphores to wait for before presenting + uint32_t swapchainCountNumber of swapchains to present in this call + const VkSwapchainKHR* pSwapchainsSwapchains to present an image from + const uint32_t* pImageIndicesIndices of which presentable images to present + VkResult* pResultsOptional (i.e. if non-NULL) VkResult for each swapchain + + + VkStructureType sType + const void* pNext + VkDebugReportFlagsEXT flagsIndicates which events call this callback + PFN_vkDebugReportCallbackEXT pfnCallbackFunction pointer of a callback function + void* pUserDataData provided to callback function + + + VkStructureType sTypeMust be VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT + const void* pNext + uint32_t disabledValidationCheckCountNumber of validation checks to disable + const VkValidationCheckEXT* pDisabledValidationChecksValidation checks to disable + + + VkStructureType sTypeMust be VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT + const void* pNext + uint32_t enabledValidationFeatureCountNumber of validation features to enable + const VkValidationFeatureEnableEXT* pEnabledValidationFeaturesValidation features to enable + uint32_t disabledValidationFeatureCountNumber of validation features to disable + const VkValidationFeatureDisableEXT* pDisabledValidationFeaturesValidation features to disable + + + VkStructureType sTypeMust be VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT + const void* pNext + uint32_t settingCountNumber of settings to configure + const VkLayerSettingEXT* pSettingsValidation features to enable + + + const char* pLayerName + const char* pSettingName + VkLayerSettingTypeEXT typeThe type of the object + uint32_t valueCountNumber of values of the setting + const void* pValuesValues to pass for a setting + + + VkStructureType sType + const void* pNext + uint32_t vendorID + uint32_t deviceID + uint32_t key + uint64_t value + + + VkStructureType sType + const void* pNext + VkRasterizationOrderAMD rasterizationOrderRasterization order to use for the pipeline + + + VkStructureType sType + const void* pNext + VkDebugReportObjectTypeEXT objectTypeThe type of the object + uint64_t objectThe handle of the object, cast to uint64_t + const char* pObjectNameName to apply to the object + + + VkStructureType sType + const void* pNext + VkDebugReportObjectTypeEXT objectTypeThe type of the object + uint64_t objectThe handle of the object, cast to uint64_t + uint64_t tagNameThe name of the tag to set on the object + size_t tagSizeThe length in bytes of the tag data + const void* pTagTag data to attach to the object + + + VkStructureType sType + const void* pNext + const char* pMarkerNameName of the debug marker + float color[4]Optional color for debug marker + + + VkStructureType sType + const void* pNext + VkBool32 dedicatedAllocationWhether this image uses a dedicated allocation + + + VkStructureType sType + const void* pNext + VkBool32 dedicatedAllocationWhether this buffer uses a dedicated allocation + + + VkStructureType sType + const void* pNext + VkImage imageImage that this allocation will be bound to + VkBuffer bufferBuffer that this allocation will be bound to + + + VkImageFormatProperties imageFormatProperties + VkExternalMemoryFeatureFlagsNV externalMemoryFeatures + VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes + VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagsNV handleTypes + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagsNV handleTypes + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagsNV handleType + HANDLE handle + + + VkStructureType sType + const void* pNext + const SECURITY_ATTRIBUTES* pAttributes + DWORD dwAccess + + + VkStructureType sType + const void* pNext + NvSciBufAttrList pAttributes + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + NvSciBufObj handle + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + void* pNext + VkBool32 sciBufImport + VkBool32 sciBufExport + + + + VkStructureType sType + const void* pNext + uint32_t acquireCount + const VkDeviceMemory* pAcquireSyncs + const uint64_t* pAcquireKeys + const uint32_t* pAcquireTimeoutMilliseconds + uint32_t releaseCount + const VkDeviceMemory* pReleaseSyncs + const uint64_t* pReleaseKeys + + + VkStructureType sType + void* pNext + VkBool32 deviceGeneratedCommands + + + VkStructureType sType + void* pNext + VkBool32 deviceGeneratedCompute + VkBool32 deviceGeneratedComputePipelines + VkBool32 deviceGeneratedComputeCaptureReplay + + + VkStructureType sType + const void* pNext + uint32_t privateDataSlotRequestCount + + + + VkStructureType sType + const void* pNext + VkPrivateDataSlotCreateFlags flags + + + + VkStructureType sType + void* pNext + VkBool32 privateData + + + + VkStructureType sType + void* pNext + uint32_t maxGraphicsShaderGroupCount + uint32_t maxIndirectSequenceCount + uint32_t maxIndirectCommandsTokenCount + uint32_t maxIndirectCommandsStreamCount + uint32_t maxIndirectCommandsTokenOffset + uint32_t maxIndirectCommandsStreamStride + uint32_t minSequencesCountBufferOffsetAlignment + uint32_t minSequencesIndexBufferOffsetAlignment + uint32_t minIndirectCommandsBufferOffsetAlignment + + + VkStructureType sType + void* pNext + VkBool32 clusterAccelerationStructure + + + VkStructureType sType + void* pNext + uint32_t maxVerticesPerCluster + uint32_t maxTrianglesPerCluster + uint32_t clusterScratchByteAlignment + uint32_t clusterByteAlignment + uint32_t clusterTemplateByteAlignment + uint32_t clusterBottomLevelByteAlignment + uint32_t clusterTemplateBoundsByteAlignment + uint32_t maxClusterGeometryIndex + + + VkDeviceAddress startAddress + VkDeviceSize strideInBytesSpecified in bytes + + + VkStructureType sType + void* pNext + VkBool32 allowClusterAccelerationStructure + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + uint32_t geometryIndex:24 + uint32_t reserved:5 + uint32_t geometryFlags:3 + + + VkDeviceAddress srcAccelerationStructure + + + uint32_t clusterReferencesCount + uint32_t clusterReferencesStride + VkDeviceAddress clusterReferences + + + VkDeviceAddress clusterTemplateAddress + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + uint32_t clusterID + VkClusterAccelerationStructureClusterFlagsNV clusterFlags + uint32_t triangleCount:9 + uint32_t vertexCount:9 + uint32_t positionTruncateBitCount:6 + uint32_t indexType:4 + uint32_t opacityMicromapIndexType:4 + VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV baseGeometryIndexAndGeometryFlags + uint16_t indexBufferStride + uint16_t vertexBufferStride + uint16_t geometryIndexAndFlagsBufferStride + uint16_t opacityMicromapIndexBufferStride + VkDeviceAddress indexBuffer + VkDeviceAddress vertexBuffer + VkDeviceAddress geometryIndexAndFlagsBuffer + VkDeviceAddress opacityMicromapArray + VkDeviceAddress opacityMicromapIndexBuffer + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + uint32_t clusterID + VkClusterAccelerationStructureClusterFlagsNV clusterFlags + uint32_t triangleCount:9 + uint32_t vertexCount:9 + uint32_t positionTruncateBitCount:6 + uint32_t indexType:4 + uint32_t opacityMicromapIndexType:4 + VkClusterAccelerationStructureGeometryIndexAndGeometryFlagsNV baseGeometryIndexAndGeometryFlags + uint16_t indexBufferStride + uint16_t vertexBufferStride + uint16_t geometryIndexAndFlagsBufferStride + uint16_t opacityMicromapIndexBufferStride + VkDeviceAddress indexBuffer + VkDeviceAddress vertexBuffer + VkDeviceAddress geometryIndexAndFlagsBuffer + VkDeviceAddress opacityMicromapArray + VkDeviceAddress opacityMicromapIndexBuffer + VkDeviceAddress instantiationBoundingBoxLimit + + + uint32_t clusterIdOffset + uint32_t geometryIndexOffset:24 + uint32_t reserved:8 + VkDeviceAddress clusterTemplateAddress + VkStridedDeviceAddressNV vertexBuffer + + + VkStructureType sType + void* pNext + uint32_t maxTotalClusterCount + uint32_t maxClusterCountPerAccelerationStructure + + + VkStructureType sType + void* pNext + VkFormat vertexFormat + uint32_t maxGeometryIndexValue + uint32_t maxClusterUniqueGeometryCount + uint32_t maxClusterTriangleCount + uint32_t maxClusterVertexCount + uint32_t maxTotalTriangleCount + uint32_t maxTotalVertexCount + uint32_t minPositionTruncateBitCount + + + VkStructureType sType + void* pNext + VkClusterAccelerationStructureTypeNV type + VkBool32 noMoveOverlap + VkDeviceSize maxMovedBytes + + + VkClusterAccelerationStructureClustersBottomLevelInputNV* pClustersBottomLevel + VkClusterAccelerationStructureTriangleClusterInputNV* pTriangleClusters + VkClusterAccelerationStructureMoveObjectsInputNV* pMoveObjects + + + VkStructureType sType + void* pNext + uint32_t maxAccelerationStructureCount + VkBuildAccelerationStructureFlagsKHR flags + VkClusterAccelerationStructureOpTypeNV opType + VkClusterAccelerationStructureOpModeNV opMode + VkClusterAccelerationStructureOpInputNV opInput + + + VkStructureType sType + void* pNext + VkClusterAccelerationStructureInputInfoNV input + VkDeviceAddress dstImplicitData + VkDeviceAddress scratchData + VkStridedDeviceAddressRegionKHR dstAddressesArray + VkStridedDeviceAddressRegionKHR dstSizesArray + VkStridedDeviceAddressRegionKHR srcInfosArray + VkDeviceAddress srcInfosCount + VkClusterAccelerationStructureAddressResolutionFlagsNV addressResolutionFlags + + + VkStructureType sType + void* pNext + uint32_t maxMultiDrawCount + + + VkStructureType sType + const void* pNext + uint32_t stageCount + const VkPipelineShaderStageCreateInfo* pStages + const VkPipelineVertexInputStateCreateInfo* pVertexInputState + const VkPipelineTessellationStateCreateInfo* pTessellationState + + + VkStructureType sType + const void* pNext + uint32_t groupCount + const VkGraphicsShaderGroupCreateInfoNV* pGroups + uint32_t pipelineCount + const VkPipeline* pPipelines + + + uint32_t groupIndex + + + VkDeviceAddress bufferAddress + uint32_t size + VkIndexType indexType + + + VkDeviceAddress bufferAddress + uint32_t size + uint32_t stride + + + uint32_t data + + + VkBuffer buffer + VkDeviceSize offset + + + VkStructureType sType + const void* pNext + VkIndirectCommandsTokenTypeNV tokenType + uint32_t stream + uint32_t offset + uint32_t vertexBindingUnit + VkBool32 vertexDynamicStride + VkPipelineLayout pushconstantPipelineLayout + VkShaderStageFlags pushconstantShaderStageFlags + uint32_t pushconstantOffset + uint32_t pushconstantSize + VkIndirectStateFlagsNV indirectStateFlags + uint32_t indexTypeCount + const VkIndexType* pIndexTypes + const uint32_t* pIndexTypeValues + + + VkStructureType sType + const void* pNext + VkIndirectCommandsLayoutUsageFlagsNV flags + VkPipelineBindPoint pipelineBindPoint + uint32_t tokenCount + const VkIndirectCommandsLayoutTokenNV* pTokens + uint32_t streamCount + const uint32_t* pStreamStrides + + + VkStructureType sType + const void* pNext + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + VkIndirectCommandsLayoutNV indirectCommandsLayout + uint32_t streamCount + const VkIndirectCommandsStreamNV* pStreams + uint32_t sequencesCount + VkBuffer preprocessBuffer + VkDeviceSize preprocessOffset + VkDeviceSize preprocessSize + VkBuffer sequencesCountBuffer + VkDeviceSize sequencesCountOffset + VkBuffer sequencesIndexBuffer + VkDeviceSize sequencesIndexOffset + + + VkStructureType sType + const void* pNext + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + VkIndirectCommandsLayoutNV indirectCommandsLayout + uint32_t maxSequencesCount + + + VkStructureType sType + const void* pNext + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + + + VkDeviceAddress pipelineAddress + + + VkStructureType sType + void* pNext + VkPhysicalDeviceFeatures features + + + + VkStructureType sType + void* pNext + VkPhysicalDeviceProperties properties + + + + VkStructureType sType + void* pNext + VkFormatProperties formatProperties + + + + VkStructureType sType + void* pNext + VkImageFormatProperties imageFormatProperties + + + + VkStructureType sType + const void* pNext + VkFormat format + VkImageType type + VkImageTiling tiling + VkImageUsageFlags usage + VkImageCreateFlags flags + + + + VkStructureType sType + void* pNext + VkQueueFamilyProperties queueFamilyProperties + + + + VkStructureType sType + void* pNext + VkPhysicalDeviceMemoryProperties memoryProperties + + + + VkStructureType sType + void* pNext + VkSparseImageFormatProperties properties + + + + VkStructureType sType + const void* pNext + VkFormat format + VkImageType type + VkSampleCountFlagBits samples + VkImageUsageFlags usage + VkImageTiling tiling + + + + VkStructureType sType + void* pNext + uint32_t maxPushDescriptors + + + + uint8_t major + uint8_t minor + uint8_t subminor + uint8_t patch + + + + VkStructureType sType + void* pNext + VkDriverId driverID + char driverName[VK_MAX_DRIVER_NAME_SIZE] + char driverInfo[VK_MAX_DRIVER_INFO_SIZE] + VkConformanceVersion conformanceVersion + + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const VkPresentRegionKHR* pRegionsThe regions that have changed + + + uint32_t rectangleCountNumber of rectangles in pRectangles + const VkRectLayerKHR* pRectanglesArray of rectangles that have changed in a swapchain's image(s) + + + VkOffset2D offsetupper-left corner of a rectangle that has not changed, in pixels of a presentation images + VkExtent2D extentDimensions of a rectangle that has not changed, in pixels of a presentation images + uint32_t layerLayer of a swapchain's image(s), for stereoscopic-3D images + + + VkStructureType sType + void* pNext + VkBool32 variablePointersStorageBuffer + VkBool32 variablePointers + + + + + + VkExternalMemoryFeatureFlags externalMemoryFeatures + VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes + VkExternalMemoryHandleTypeFlags compatibleHandleTypes + + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + + + + VkStructureType sType + void* pNext + VkExternalMemoryProperties externalMemoryProperties + + + + VkStructureType sType + const void* pNext + VkBufferCreateFlags flags + VkBufferUsageFlags usage + VkExternalMemoryHandleTypeFlagBits handleType + + + + VkStructureType sType + void* pNext + VkExternalMemoryProperties externalMemoryProperties + + + + VkStructureType sType + void* pNext + uint8_t deviceUUID[VK_UUID_SIZE] + uint8_t driverUUID[VK_UUID_SIZE] + uint8_t deviceLUID[VK_LUID_SIZE] + uint32_t deviceNodeMask + VkBool32 deviceLUIDValid + + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlags handleTypes + + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlags handleTypes + + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlags handleTypes + + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + HANDLE handle + LPCWSTR name + + + VkStructureType sType + const void* pNext + const SECURITY_ATTRIBUTES* pAttributes + DWORD dwAccess + LPCWSTR name + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + zx_handle_t handle + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + int fd + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + uint32_t acquireCount + const VkDeviceMemory* pAcquireSyncs + const uint64_t* pAcquireKeys + const uint32_t* pAcquireTimeouts + uint32_t releaseCount + const VkDeviceMemory* pReleaseSyncs + const uint64_t* pReleaseKeys + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + void* handle + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkExternalSemaphoreHandleTypeFlagBits handleType + + + + VkStructureType sType + void* pNext + VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes + VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes + VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures + + + + VkStructureType sType + const void* pNext + VkExternalSemaphoreHandleTypeFlags handleTypes + + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkSemaphoreImportFlags flags + VkExternalSemaphoreHandleTypeFlagBits handleType + HANDLE handle + LPCWSTR name + + + VkStructureType sType + const void* pNext + const SECURITY_ATTRIBUTES* pAttributes + DWORD dwAccess + LPCWSTR name + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreValuesCount + const uint64_t* pWaitSemaphoreValues + uint32_t signalSemaphoreValuesCount + const uint64_t* pSignalSemaphoreValues + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkExternalSemaphoreHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkSemaphoreImportFlags flags + VkExternalSemaphoreHandleTypeFlagBits handleType + int fd + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkExternalSemaphoreHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkSemaphoreImportFlags flags + VkExternalSemaphoreHandleTypeFlagBits handleType + zx_handle_t zirconHandle + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkExternalSemaphoreHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkExternalFenceHandleTypeFlagBits handleType + + + + VkStructureType sType + void* pNext + VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes + VkExternalFenceHandleTypeFlags compatibleHandleTypes + VkExternalFenceFeatureFlags externalFenceFeatures + + + + VkStructureType sType + const void* pNext + VkExternalFenceHandleTypeFlags handleTypes + + + + VkStructureType sType + const void* pNext + VkFence fence + VkFenceImportFlags flags + VkExternalFenceHandleTypeFlagBits handleType + HANDLE handle + LPCWSTR name + + + VkStructureType sType + const void* pNext + const SECURITY_ATTRIBUTES* pAttributes + DWORD dwAccess + LPCWSTR name + + + VkStructureType sType + const void* pNext + VkFence fence + VkExternalFenceHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkFence fence + VkFenceImportFlags flags + VkExternalFenceHandleTypeFlagBits handleType + int fd + + + VkStructureType sType + const void* pNext + VkFence fence + VkExternalFenceHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + NvSciSyncAttrList pAttributes + + + VkStructureType sType + const void* pNext + VkFence fence + VkExternalFenceHandleTypeFlagBits handleType + void* handle + + + VkStructureType sType + const void* pNext + VkFence fence + VkExternalFenceHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + NvSciSyncAttrList pAttributes + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkExternalSemaphoreHandleTypeFlagBits handleType + void* handle + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkExternalSemaphoreHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkSciSyncClientTypeNV clientType + VkSciSyncPrimitiveTypeNV primitiveType + + + VkStructureType sType + void* pNext + VkBool32 sciSyncFence + VkBool32 sciSyncSemaphore + VkBool32 sciSyncImport + VkBool32 sciSyncExport + + + VkStructureType sType + void* pNext + VkBool32 sciSyncFence + VkBool32 sciSyncSemaphore2 + VkBool32 sciSyncImport + VkBool32 sciSyncExport + + + VkStructureType sType + const void* pNext + NvSciSyncObj handle + + + VkStructureType sType + const void* pNext + VkSemaphoreSciSyncPoolNV semaphorePool + const NvSciSyncFence* pFence + + + VkStructureType sType + const void* pNext + uint32_t semaphoreSciSyncPoolRequestCount + + + VkStructureType sType + void* pNext + VkBool32 multiviewMultiple views in a render pass + VkBool32 multiviewGeometryShaderMultiple views in a render pass w/ geometry shader + VkBool32 multiviewTessellationShaderMultiple views in a render pass w/ tessellation shader + + + + VkStructureType sType + void* pNext + uint32_t maxMultiviewViewCountmax number of views in a subpass + uint32_t maxMultiviewInstanceIndexmax instance index for a draw in a multiview subpass + + + + VkStructureType sType + const void* pNext + uint32_t subpassCount + const uint32_t* pViewMasks + uint32_t dependencyCount + const int32_t* pViewOffsets + uint32_t correlationMaskCount + const uint32_t* pCorrelationMasks + + + + VkStructureType sType + void* pNext + uint32_t minImageCountSupported minimum number of images for the surface + uint32_t maxImageCountSupported maximum number of images for the surface, 0 for unlimited + VkExtent2D currentExtentCurrent image width and height for the surface, (0, 0) if undefined + VkExtent2D minImageExtentSupported minimum image width and height for the surface + VkExtent2D maxImageExtentSupported maximum image width and height for the surface + uint32_t maxImageArrayLayersSupported maximum number of image layers for the surface + VkSurfaceTransformFlagsKHR supportedTransforms1 or more bits representing the transforms supported + VkSurfaceTransformFlagBitsKHR currentTransformThe surface's current transform relative to the device's natural orientation + VkCompositeAlphaFlagsKHR supportedCompositeAlpha1 or more bits representing the alpha compositing modes supported + VkImageUsageFlags supportedUsageFlagsSupported image usage flags for the surface + VkSurfaceCounterFlagsEXT supportedSurfaceCounters + + + VkStructureType sType + const void* pNext + VkDisplayPowerStateEXT powerState + + + VkStructureType sType + const void* pNext + VkDeviceEventTypeEXT deviceEvent + + + VkStructureType sType + const void* pNext + VkDisplayEventTypeEXT displayEvent + + + VkStructureType sType + const void* pNext + VkSurfaceCounterFlagsEXT surfaceCounters + + + VkStructureType sType + void* pNext + uint32_t physicalDeviceCount + VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE] + VkBool32 subsetAllocation + + + + VkStructureType sType + const void* pNext + VkMemoryAllocateFlags flags + uint32_t deviceMask + + + + VkStructureType sType + const void* pNext + VkBuffer buffer + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + + VkStructureType sType + const void* pNext + uint32_t deviceIndexCount + const uint32_t* pDeviceIndices + + + + VkStructureType sType + const void* pNext + VkImage image + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + + VkStructureType sType + const void* pNext + uint32_t deviceIndexCount + const uint32_t* pDeviceIndices + uint32_t splitInstanceBindRegionCount + const VkRect2D* pSplitInstanceBindRegions + + + + VkStructureType sType + const void* pNext + uint32_t deviceMask + uint32_t deviceRenderAreaCount + const VkRect2D* pDeviceRenderAreas + + + + VkStructureType sType + const void* pNext + uint32_t deviceMask + + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreCount + const uint32_t* pWaitSemaphoreDeviceIndices + uint32_t commandBufferCount + const uint32_t* pCommandBufferDeviceMasks + uint32_t signalSemaphoreCount + const uint32_t* pSignalSemaphoreDeviceIndices + + + + VkStructureType sType + const void* pNext + uint32_t resourceDeviceIndex + uint32_t memoryDeviceIndex + + + + VkStructureType sType + void* pNext + uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE] + VkDeviceGroupPresentModeFlagsKHR modes + + + VkStructureType sType + const void* pNext + VkSwapchainKHR swapchain + + + VkStructureType sType + const void* pNext + VkSwapchainKHR swapchain + uint32_t imageIndex + + + VkStructureType sType + const void* pNext + VkSwapchainKHR swapchain + uint64_t timeout + VkSemaphore semaphore + VkFence fence + uint32_t deviceMask + + + VkStructureType sType + const void* pNext + uint32_t swapchainCount + const uint32_t* pDeviceMasks + VkDeviceGroupPresentModeFlagBitsKHR mode + + + VkStructureType sType + const void* pNext + uint32_t physicalDeviceCount + const VkPhysicalDevice* pPhysicalDevices + + + + VkStructureType sType + const void* pNext + VkDeviceGroupPresentModeFlagsKHR modes + + + uint32_t dstBindingBinding within the destination descriptor set to write + uint32_t dstArrayElementArray element within the destination binding to write + uint32_t descriptorCountNumber of descriptors to write + VkDescriptorType descriptorTypeDescriptor type to write + size_t offsetOffset into pData where the descriptors to update are stored + size_t strideStride between two descriptors in pData when writing more than one descriptor + + + + VkStructureType sType + const void* pNext + VkDescriptorUpdateTemplateCreateFlags flags + uint32_t descriptorUpdateEntryCountNumber of descriptor update entries to use for the update template + const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntriesDescriptor update entries for the template + VkDescriptorUpdateTemplateType templateType + VkDescriptorSetLayout descriptorSetLayout + VkPipelineBindPoint pipelineBindPoint + VkPipelineLayout pipelineLayoutIf used for push descriptors, this is the only allowed layout + uint32_t set + + + + float x + float y + + + VkStructureType sType + void* pNext + VkBool32 presentIdPresent ID in VkPresentInfoKHR + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const uint64_t* pPresentIdsPresent ID values for each swapchain + + + VkStructureType sType + void* pNext + VkBool32 presentId2Present ID2 in VkPresentInfoKHR + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const uint64_t* pPresentIdsPresent ID values for each swapchain + + + VkStructureType sType + const void* pNext + uint64_t presentId + uint64_t timeout + + + VkStructureType sType + void* pNext + VkBool32 presentWaitvkWaitForPresentKHR is supported + + + VkStructureType sType + void* pNext + VkBool32 presentWait2vkWaitForPresent2KHR is supported + + + Display primary in chromaticity coordinates + VkStructureType sType + const void* pNext + From SMPTE 2086 + VkXYColorEXT displayPrimaryRedDisplay primary's Red + VkXYColorEXT displayPrimaryGreenDisplay primary's Green + VkXYColorEXT displayPrimaryBlueDisplay primary's Blue + VkXYColorEXT whitePointDisplay primary's Blue + float maxLuminanceDisplay maximum luminance + float minLuminanceDisplay minimum luminance + From CTA 861.3 + float maxContentLightLevelContent maximum luminance + float maxFrameAverageLightLevel + + + VkStructureType sType + const void* pNext + size_t dynamicMetadataSizeSpecified in bytes + const void* pDynamicMetadataBinary code of size dynamicMetadataSize + + + VkStructureType sType + void* pNext + VkBool32 localDimmingSupport + + + VkStructureType sType + const void* pNext + VkBool32 localDimmingEnable + + + uint64_t refreshDurationNumber of nanoseconds from the start of one refresh cycle to the next + + + uint32_t presentIDApplication-provided identifier, previously given to vkQueuePresentKHR + uint64_t desiredPresentTimeEarliest time an image should have been presented, previously given to vkQueuePresentKHR + uint64_t actualPresentTimeTime the image was actually displayed + uint64_t earliestPresentTimeEarliest time the image could have been displayed + uint64_t presentMarginHow early vkQueuePresentKHR was processed vs. how soon it needed to be and make earliestPresentTime + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const VkPresentTimeGOOGLE* pTimesThe earliest times to present images + + + uint32_t presentIDApplication-provided identifier + uint64_t desiredPresentTimeEarliest time an image should be presented + + + VkStructureType sType + const void* pNext + VkIOSSurfaceCreateFlagsMVK flags + const void* pView + + + VkStructureType sType + const void* pNext + VkMacOSSurfaceCreateFlagsMVK flags + const void* pView + + + VkStructureType sType + const void* pNext + VkMetalSurfaceCreateFlagsEXT flags + const CAMetalLayer* pLayer + + + float xcoeff + float ycoeff + + + VkStructureType sType + const void* pNext + VkBool32 viewportWScalingEnable + uint32_t viewportCount + const VkViewportWScalingNV* pViewportWScalings + + + VkViewportCoordinateSwizzleNV x + VkViewportCoordinateSwizzleNV y + VkViewportCoordinateSwizzleNV z + VkViewportCoordinateSwizzleNV w + + + VkStructureType sType + const void* pNext + VkPipelineViewportSwizzleStateCreateFlagsNV flags + uint32_t viewportCount + const VkViewportSwizzleNV* pViewportSwizzles + + + VkStructureType sType + void* pNext + uint32_t maxDiscardRectanglesmax number of active discard rectangles + + + VkStructureType sType + const void* pNext + VkPipelineDiscardRectangleStateCreateFlagsEXT flags + VkDiscardRectangleModeEXT discardRectangleMode + uint32_t discardRectangleCount + const VkRect2D* pDiscardRectangles + + + VkStructureType sType + void* pNext + VkBool32 perViewPositionAllComponents + + + uint32_t subpass + uint32_t inputAttachmentIndex + VkImageAspectFlags aspectMask + + + + VkStructureType sType + const void* pNext + uint32_t aspectReferenceCount + const VkInputAttachmentAspectReference* pAspectReferences + + + + VkStructureType sType + const void* pNext + VkSurfaceKHR surface + + + VkStructureType sType + void* pNext + VkSurfaceCapabilitiesKHR surfaceCapabilities + + + VkStructureType sType + void* pNext + VkSurfaceFormatKHR surfaceFormat + + + VkStructureType sType + void* pNext + VkDisplayPropertiesKHR displayProperties + + + VkStructureType sType + void* pNext + VkDisplayPlanePropertiesKHR displayPlaneProperties + + + VkStructureType sType + void* pNext + VkDisplayModePropertiesKHR displayModeProperties + + + VkStructureType sType + const void* pNext + VkBool32 hdmi3DSupportedWhether this mode supports HDMI 3D stereo rendering. + + + VkStructureType sType + const void* pNext + VkDisplayModeKHR mode + uint32_t planeIndex + + + VkStructureType sType + void* pNext + VkDisplayPlaneCapabilitiesKHR capabilities + + + VkStructureType sType + void* pNext + VkImageUsageFlags sharedPresentSupportedUsageFlagsSupported image usage flags if swapchain created using a shared present mode + + + VkStructureType sType + void* pNext + VkBool32 storageBuffer16BitAccess16-bit integer/floating-point variables supported in BufferBlock + VkBool32 uniformAndStorageBuffer16BitAccess16-bit integer/floating-point variables supported in BufferBlock and Block + VkBool32 storagePushConstant1616-bit integer/floating-point variables supported in PushConstant + VkBool32 storageInputOutput1616-bit integer/floating-point variables supported in shader inputs and outputs + + + + VkStructureType sType + void* pNext + uint32_t subgroupSizeThe size of a subgroup for this queue. + VkShaderStageFlags supportedStagesBitfield of what shader stages support subgroup operations + VkSubgroupFeatureFlags supportedOperationsBitfield of what subgroup operations are supported. + VkBool32 quadOperationsInAllStagesFlag to specify whether quad operations are available in all stages. + + + VkStructureType sType + void* pNext + VkBool32 shaderSubgroupExtendedTypesFlag to specify whether subgroup operations with extended types are supported + + + + VkStructureType sType + const void* pNext + VkBuffer buffer + + + + VkStructureType sType + const void* pNext + const VkBufferCreateInfo* pCreateInfo + + + + VkStructureType sType + const void* pNext + VkImage image + + + + VkStructureType sType + const void* pNext + VkImage image + + + + VkStructureType sType + const void* pNext + const VkImageCreateInfo* pCreateInfo + VkImageAspectFlagBits planeAspect + + + + VkStructureType sType + void* pNext + VkMemoryRequirements memoryRequirements + + + + VkStructureType sType + void* pNext + VkSparseImageMemoryRequirements memoryRequirements + + + + VkStructureType sType + void* pNext + VkPointClippingBehavior pointClippingBehavior + + + + VkStructureType sType + void* pNext + VkBool32 prefersDedicatedAllocation + VkBool32 requiresDedicatedAllocation + + + + VkStructureType sType + const void* pNext + VkImage imageImage that this allocation will be bound to + VkBuffer bufferBuffer that this allocation will be bound to + + + + VkStructureType sType + const void* pNext + VkImageUsageFlags usage + + + VkStructureType sType + const void* pNext + uint32_t sliceOffset + uint32_t sliceCount + + + + VkStructureType sType + const void* pNext + VkTessellationDomainOrigin domainOrigin + + + + VkStructureType sType + const void* pNext + VkSamplerYcbcrConversion conversion + + + + VkStructureType sType + const void* pNext + VkFormat format + VkSamplerYcbcrModelConversion ycbcrModel + VkSamplerYcbcrRange ycbcrRange + VkComponentMapping components + VkChromaLocation xChromaOffset + VkChromaLocation yChromaOffset + VkFilter chromaFilter + VkBool32 forceExplicitReconstruction + + + + VkStructureType sType + const void* pNext + VkImageAspectFlagBits planeAspect + + + + VkStructureType sType + const void* pNext + VkImageAspectFlagBits planeAspect + + + + VkStructureType sType + void* pNext + VkBool32 samplerYcbcrConversionSampler color conversion supported + + + + VkStructureType sType + void* pNext + uint32_t combinedImageSamplerDescriptorCount + + + + VkStructureType sType + void* pNext + VkBool32 supportsTextureGatherLODBiasAMD + + + VkStructureType sType + const void* pNext + VkBuffer buffer + VkDeviceSize offset + VkConditionalRenderingFlagsEXT flags + + + VkStructureType sType + const void* pNext + VkBool32 protectedSubmitSubmit protected command buffers + + + VkStructureType sType + void* pNext + VkBool32 protectedMemory + + + VkStructureType sType + void* pNext + VkBool32 protectedNoFault + + + VkStructureType sType + const void* pNext + VkDeviceQueueCreateFlags flags + uint32_t queueFamilyIndex + uint32_t queueIndex + + + VkStructureType sType + const void* pNext + VkPipelineCoverageToColorStateCreateFlagsNV flags + VkBool32 coverageToColorEnable + uint32_t coverageToColorLocation + + + VkStructureType sType + void* pNext + VkBool32 filterMinmaxSingleComponentFormats + VkBool32 filterMinmaxImageComponentMapping + + + + float x + float y + + + VkStructureType sType + const void* pNext + VkSampleCountFlagBits sampleLocationsPerPixel + VkExtent2D sampleLocationGridSize + uint32_t sampleLocationsCount + const VkSampleLocationEXT* pSampleLocations + + + uint32_t attachmentIndex + VkSampleLocationsInfoEXT sampleLocationsInfo + + + uint32_t subpassIndex + VkSampleLocationsInfoEXT sampleLocationsInfo + + + VkStructureType sType + const void* pNext + uint32_t attachmentInitialSampleLocationsCount + const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations + uint32_t postSubpassSampleLocationsCount + const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations + + + VkStructureType sType + const void* pNext + VkBool32 sampleLocationsEnable + VkSampleLocationsInfoEXT sampleLocationsInfo + + + VkStructureType sType + void* pNext + VkSampleCountFlags sampleLocationSampleCounts + VkExtent2D maxSampleLocationGridSize + float sampleLocationCoordinateRange[2] + uint32_t sampleLocationSubPixelBits + VkBool32 variableSampleLocations + + + VkStructureType sType + void* pNext + VkExtent2D maxSampleLocationGridSize + + + VkStructureType sType + const void* pNext + VkSamplerReductionMode reductionMode + + + + VkStructureType sType + void* pNext + VkBool32 advancedBlendCoherentOperations + + + VkStructureType sType + void* pNext + VkBool32 multiDraw + + + VkStructureType sType + void* pNext + uint32_t advancedBlendMaxColorAttachments + VkBool32 advancedBlendIndependentBlend + VkBool32 advancedBlendNonPremultipliedSrcColor + VkBool32 advancedBlendNonPremultipliedDstColor + VkBool32 advancedBlendCorrelatedOverlap + VkBool32 advancedBlendAllOperations + + + VkStructureType sType + const void* pNext + VkBool32 srcPremultiplied + VkBool32 dstPremultiplied + VkBlendOverlapEXT blendOverlap + + + VkStructureType sType + void* pNext + VkBool32 inlineUniformBlock + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind + + + + VkStructureType sType + void* pNext + uint32_t maxInlineUniformBlockSize + uint32_t maxPerStageDescriptorInlineUniformBlocks + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks + uint32_t maxDescriptorSetInlineUniformBlocks + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks + + + + VkStructureType sType + const void* pNext + uint32_t dataSize + const void* pData + + + + VkStructureType sType + const void* pNext + uint32_t maxInlineUniformBlockBindings + + + + VkStructureType sType + const void* pNext + VkPipelineCoverageModulationStateCreateFlagsNV flags + VkCoverageModulationModeNV coverageModulationMode + VkBool32 coverageModulationTableEnable + uint32_t coverageModulationTableCount + const float* pCoverageModulationTable + + + VkStructureType sType + const void* pNext + uint32_t viewFormatCount + const VkFormat* pViewFormats + + + + VkStructureType sType + const void* pNext + VkValidationCacheCreateFlagsEXT flags + size_t initialDataSize + const void* pInitialData + + + VkStructureType sType + const void* pNext + VkValidationCacheEXT validationCache + + + VkStructureType sType + void* pNext + uint32_t maxPerSetDescriptors + VkDeviceSize maxMemoryAllocationSize + + + + VkStructureType sType + void* pNext + VkBool32 maintenance4 + + + + VkStructureType sType + void* pNext + VkDeviceSize maxBufferSize + + + + VkStructureType sType + void* pNext + VkBool32 maintenance5 + + + + VkStructureType sType + void* pNext + VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting + VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting + VkBool32 depthStencilSwizzleOneSupport + VkBool32 polygonModePointSize + VkBool32 nonStrictSinglePixelWideLinesUseParallelogram + VkBool32 nonStrictWideLinesUseParallelogram + + + + VkStructureType sType + void* pNext + VkBool32 maintenance6 + + + + VkStructureType sType + void* pNext + VkBool32 blockTexelViewCompatibleMultipleLayers + uint32_t maxCombinedImageSamplerDescriptorCount + VkBool32 fragmentShadingRateClampCombinerInputs + + + + VkStructureType sType + void* pNext + VkBool32 maintenance7 + + + VkStructureType sType + void* pNext + VkBool32 robustFragmentShadingRateAttachmentAccess + VkBool32 separateDepthStencilAttachmentAccess + uint32_t maxDescriptorSetTotalUniformBuffersDynamic + uint32_t maxDescriptorSetTotalStorageBuffersDynamic + uint32_t maxDescriptorSetTotalBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindTotalBuffersDynamic + + + VkStructureType sType + void* pNext + uint32_t layeredApiCount + VkPhysicalDeviceLayeredApiPropertiesKHR* pLayeredApisOutput list of layered implementations underneath the physical device + + + VkStructureType sType + void* pNext + uint32_t vendorID + uint32_t deviceID + VkPhysicalDeviceLayeredApiKHR layeredAPI + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE] + + + VkStructureType sType + void* pNext + VkPhysicalDeviceProperties2 properties + + + VkStructureType sType + void* pNext + VkBool32 maintenance8 + + + VkStructureType sType + void* pNext + VkBool32 maintenance9 + + + VkStructureType sType + void* pNext + VkBool32 image2DViewOf3DSparse + VkDefaultVertexAttributeValueKHR defaultVertexAttributeValue + + + VkStructureType sType + void* pNext + uint32_t optimalImageTransferToQueueFamilies + + + VkStructureType sType + const void* pNext + uint32_t viewMask + uint32_t colorAttachmentCount + const VkFormat* pColorAttachmentFormats + VkFormat depthAttachmentFormat + VkFormat stencilAttachmentFormat + + + + VkStructureType sType + void* pNext + VkBool32 supported + + + + VkStructureType sType + void* pNext + VkBool32 shaderDrawParameters + + + + VkStructureType sType + void* pNext + VkBool32 shaderFloat1616-bit floats (halfs) in shaders + VkBool32 shaderInt88-bit integers in shaders + + + + + VkStructureType sType + void* pNext + VkShaderFloatControlsIndependence denormBehaviorIndependence + VkShaderFloatControlsIndependence roundingModeIndependence + VkBool32 shaderSignedZeroInfNanPreserveFloat16An implementation can preserve signed zero, nan, inf + VkBool32 shaderSignedZeroInfNanPreserveFloat32An implementation can preserve signed zero, nan, inf + VkBool32 shaderSignedZeroInfNanPreserveFloat64An implementation can preserve signed zero, nan, inf + VkBool32 shaderDenormPreserveFloat16An implementation can preserve denormals + VkBool32 shaderDenormPreserveFloat32An implementation can preserve denormals + VkBool32 shaderDenormPreserveFloat64An implementation can preserve denormals + VkBool32 shaderDenormFlushToZeroFloat16An implementation can flush to zero denormals + VkBool32 shaderDenormFlushToZeroFloat32An implementation can flush to zero denormals + VkBool32 shaderDenormFlushToZeroFloat64An implementation can flush to zero denormals + VkBool32 shaderRoundingModeRTEFloat16An implementation can support RTE + VkBool32 shaderRoundingModeRTEFloat32An implementation can support RTE + VkBool32 shaderRoundingModeRTEFloat64An implementation can support RTE + VkBool32 shaderRoundingModeRTZFloat16An implementation can support RTZ + VkBool32 shaderRoundingModeRTZFloat32An implementation can support RTZ + VkBool32 shaderRoundingModeRTZFloat64An implementation can support RTZ + + + + VkStructureType sType + void* pNext + VkBool32 hostQueryReset + + + + uint64_t consumer + uint64_t producer + + + VkStructureType sType + const void* pNext + const void* handle + int stride + int format + int usage + VkNativeBufferUsage2ANDROID usage2 + + + VkStructureType sType + const void* pNext + VkSwapchainImageUsageFlagsANDROID usage + + + VkStructureType sType + const void* pNext + VkBool32 sharedImage + + + uint32_t numUsedVgprs + uint32_t numUsedSgprs + uint32_t ldsSizePerLocalWorkGroup + size_t ldsUsageSizeInBytes + size_t scratchMemUsageInBytes + + + VkShaderStageFlags shaderStageMask + VkShaderResourceUsageAMD resourceUsage + uint32_t numPhysicalVgprs + uint32_t numPhysicalSgprs + uint32_t numAvailableVgprs + uint32_t numAvailableSgprs + uint32_t computeWorkGroupSize[3] + + + VkStructureType sType + const void* pNext + VkQueueGlobalPriority globalPriority + + + + + VkStructureType sType + void* pNext + VkBool32 globalPriorityQuery + + + + + VkStructureType sType + void* pNext + uint32_t priorityCount + VkQueueGlobalPriority priorities[VK_MAX_GLOBAL_PRIORITY_SIZE] + + + + + VkStructureType sType + const void* pNext + VkObjectType objectType + uint64_t objectHandle + const char* pObjectName + + + VkStructureType sType + const void* pNext + VkObjectType objectType + uint64_t objectHandle + uint64_t tagName + size_t tagSize + const void* pTag + + + VkStructureType sType + const void* pNext + const char* pLabelName + float color[4] + + + VkStructureType sType + const void* pNext + VkDebugUtilsMessengerCreateFlagsEXT flags + VkDebugUtilsMessageSeverityFlagsEXT messageSeverity + VkDebugUtilsMessageTypeFlagsEXT messageType + PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback + void* pUserData + + + VkStructureType sType + const void* pNext + VkDebugUtilsMessengerCallbackDataFlagsEXT flags + const char* pMessageIdName + int32_t messageIdNumber + const char* pMessage + uint32_t queueLabelCount + const VkDebugUtilsLabelEXT* pQueueLabels + uint32_t cmdBufLabelCount + const VkDebugUtilsLabelEXT* pCmdBufLabels + uint32_t objectCount + const VkDebugUtilsObjectNameInfoEXT* pObjects + + + VkStructureType sType + void* pNext + VkBool32 deviceMemoryReport + + + VkStructureType sType + const void* pNext + VkDeviceMemoryReportFlagsEXT flags + PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback + void* pUserData + + + VkStructureType sType + void* pNext + VkDeviceMemoryReportFlagsEXT flags + VkDeviceMemoryReportEventTypeEXT type + uint64_t memoryObjectId + VkDeviceSize size + VkObjectType objectType + uint64_t objectHandle + uint32_t heapIndex + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlagBits handleType + void* pHostPointer + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + + + VkStructureType sType + void* pNext + VkDeviceSize minImportedHostPointerAlignment + + + VkStructureType sType + void* pNext + float primitiveOverestimationSizeThe size in pixels the primitive is enlarged at each edge during conservative rasterization + float maxExtraPrimitiveOverestimationSizeThe maximum additional overestimation the client can specify in the pipeline state + float extraPrimitiveOverestimationSizeGranularityThe granularity of extra overestimation sizes the implementations supports between 0 and maxExtraOverestimationSize + VkBool32 primitiveUnderestimationtrue if the implementation supports conservative rasterization underestimation mode + VkBool32 conservativePointAndLineRasterizationtrue if conservative rasterization also applies to points and lines + VkBool32 degenerateTrianglesRasterizedtrue if degenerate triangles (those with zero area after snap) are rasterized + VkBool32 degenerateLinesRasterizedtrue if degenerate lines (those with zero length after snap) are rasterized + VkBool32 fullyCoveredFragmentShaderInputVariabletrue if the implementation supports the FullyCoveredEXT SPIR-V builtin fragment shader input variable + VkBool32 conservativeRasterizationPostDepthCoveragetrue if the implementation supports both conservative rasterization and post depth coverage sample coverage mask + + + VkStructureType sType + const void* pNext + VkTimeDomainKHR timeDomain + + + + VkStructureType sType + void* pNext + uint32_t shaderEngineCountnumber of shader engines + uint32_t shaderArraysPerEngineCountnumber of shader arrays + uint32_t computeUnitsPerShaderArraynumber of physical CUs per shader array + uint32_t simdPerComputeUnitnumber of SIMDs per compute unit + uint32_t wavefrontsPerSimdnumber of wavefront slots in each SIMD + uint32_t wavefrontSizemaximum number of threads per wavefront + uint32_t sgprsPerSimdnumber of physical SGPRs per SIMD + uint32_t minSgprAllocationminimum number of SGPRs that can be allocated by a wave + uint32_t maxSgprAllocationnumber of available SGPRs + uint32_t sgprAllocationGranularitySGPRs are allocated in groups of this size + uint32_t vgprsPerSimdnumber of physical VGPRs per SIMD + uint32_t minVgprAllocationminimum number of VGPRs that can be allocated by a wave + uint32_t maxVgprAllocationnumber of available VGPRs + uint32_t vgprAllocationGranularityVGPRs are allocated in groups of this size + + + VkStructureType sType + void* pNextPointer to next structure + VkShaderCorePropertiesFlagsAMD shaderCoreFeaturesfeatures supported by the shader core + uint32_t activeComputeUnitCountnumber of active compute units across all shader engines/arrays + + + VkStructureType sType + const void* pNext + VkPipelineRasterizationConservativeStateCreateFlagsEXT flagsReserved + VkConservativeRasterizationModeEXT conservativeRasterizationModeConservative rasterization mode + float extraPrimitiveOverestimationSizeExtra overestimation to add to the primitive + + + VkStructureType sType + void* pNext + VkBool32 shaderInputAttachmentArrayDynamicIndexing + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing + VkBool32 shaderUniformBufferArrayNonUniformIndexing + VkBool32 shaderSampledImageArrayNonUniformIndexing + VkBool32 shaderStorageBufferArrayNonUniformIndexing + VkBool32 shaderStorageImageArrayNonUniformIndexing + VkBool32 shaderInputAttachmentArrayNonUniformIndexing + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing + VkBool32 descriptorBindingUniformBufferUpdateAfterBind + VkBool32 descriptorBindingSampledImageUpdateAfterBind + VkBool32 descriptorBindingStorageImageUpdateAfterBind + VkBool32 descriptorBindingStorageBufferUpdateAfterBind + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind + VkBool32 descriptorBindingUpdateUnusedWhilePending + VkBool32 descriptorBindingPartiallyBound + VkBool32 descriptorBindingVariableDescriptorCount + VkBool32 runtimeDescriptorArray + + + + VkStructureType sType + void* pNext + uint32_t maxUpdateAfterBindDescriptorsInAllPools + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative + VkBool32 shaderSampledImageArrayNonUniformIndexingNative + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative + VkBool32 shaderStorageImageArrayNonUniformIndexingNative + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative + VkBool32 robustBufferAccessUpdateAfterBind + VkBool32 quadDivergentImplicitLod + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments + uint32_t maxPerStageUpdateAfterBindResources + uint32_t maxDescriptorSetUpdateAfterBindSamplers + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindSampledImages + uint32_t maxDescriptorSetUpdateAfterBindStorageImages + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments + + + + VkStructureType sType + const void* pNext + uint32_t bindingCount + const VkDescriptorBindingFlags* pBindingFlags + + + + VkStructureType sType + const void* pNext + uint32_t descriptorSetCount + const uint32_t* pDescriptorCounts + + + + VkStructureType sType + void* pNext + uint32_t maxVariableDescriptorCount + + + + VkStructureType sType + const void* pNext + VkAttachmentDescriptionFlags flags + VkFormat format + VkSampleCountFlagBits samples + VkAttachmentLoadOp loadOpLoad operation for color or depth data + VkAttachmentStoreOp storeOpStore operation for color or depth data + VkAttachmentLoadOp stencilLoadOpLoad operation for stencil data + VkAttachmentStoreOp stencilStoreOpStore operation for stencil data + VkImageLayout initialLayout + VkImageLayout finalLayout + + + + VkStructureType sType + const void* pNext + uint32_t attachment + VkImageLayout layout + VkImageAspectFlags aspectMask + + + + VkStructureType sType + const void* pNext + VkSubpassDescriptionFlags flags + VkPipelineBindPoint pipelineBindPoint + uint32_t viewMask + uint32_t inputAttachmentCount + const VkAttachmentReference2* pInputAttachments + uint32_t colorAttachmentCount + const VkAttachmentReference2* pColorAttachments + const VkAttachmentReference2* pResolveAttachments + const VkAttachmentReference2* pDepthStencilAttachment + uint32_t preserveAttachmentCount + const uint32_t* pPreserveAttachments + + + + VkStructureType sType + const void* pNext + uint32_t srcSubpass + uint32_t dstSubpass + VkPipelineStageFlags srcStageMask + VkPipelineStageFlags dstStageMask + VkAccessFlags srcAccessMask + VkAccessFlags dstAccessMask + VkDependencyFlags dependencyFlags + int32_t viewOffset + + + + VkStructureType sType + const void* pNext + VkRenderPassCreateFlags flags + uint32_t attachmentCount + const VkAttachmentDescription2* pAttachments + uint32_t subpassCount + const VkSubpassDescription2* pSubpasses + uint32_t dependencyCount + const VkSubpassDependency2* pDependencies + uint32_t correlatedViewMaskCount + const uint32_t* pCorrelatedViewMasks + + + + VkStructureType sType + const void* pNext + VkSubpassContents contents + + + + VkStructureType sType + const void* pNext + + + + VkStructureType sType + void* pNext + VkBool32 timelineSemaphore + + + + VkStructureType sType + void* pNext + uint64_t maxTimelineSemaphoreValueDifference + + + + VkStructureType sType + const void* pNext + VkSemaphoreType semaphoreType + uint64_t initialValue + + + + VkStructureType sType + const void* pNext + uint32_t waitSemaphoreValueCount + const uint64_t* pWaitSemaphoreValues + uint32_t signalSemaphoreValueCount + const uint64_t* pSignalSemaphoreValues + + + + VkStructureType sType + const void* pNext + VkSemaphoreWaitFlags flags + uint32_t semaphoreCount + const VkSemaphore* pSemaphores + const uint64_t* pValues + + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + uint64_t value + + + + uint32_t binding + uint32_t divisor + + + + + VkStructureType sType + const void* pNext + uint32_t vertexBindingDivisorCount + const VkVertexInputBindingDivisorDescription* pVertexBindingDivisors + + + + + VkStructureType sType + void* pNext + uint32_t maxVertexAttribDivisormax value of vertex attribute divisor + + + VkStructureType sType + void* pNext + uint32_t maxVertexAttribDivisormax value of vertex attribute divisor + VkBool32 supportsNonZeroFirstInstance + + + + VkStructureType sType + void* pNext + uint32_t pciDomain + uint32_t pciBus + uint32_t pciDevice + uint32_t pciFunction + + + VkStructureType sType + const void* pNext + struct AHardwareBuffer* buffer + + + VkStructureType sType + void* pNext + uint64_t androidHardwareBufferUsage + + + VkStructureType sType + void* pNext + VkDeviceSize allocationSize + uint32_t memoryTypeBits + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + + + VkStructureType sType + void* pNext + VkFormat format + uint64_t externalFormat + VkFormatFeatureFlags formatFeatures + VkComponentMapping samplerYcbcrConversionComponents + VkSamplerYcbcrModelConversion suggestedYcbcrModel + VkSamplerYcbcrRange suggestedYcbcrRange + VkChromaLocation suggestedXChromaOffset + VkChromaLocation suggestedYChromaOffset + + + VkStructureType sType + const void* pNext + VkBool32 conditionalRenderingEnableWhether this secondary command buffer may be executed during an active conditional rendering + + + VkStructureType sType + void* pNext + uint64_t externalFormat + + + VkStructureType sType + void* pNext + VkBool32 storageBuffer8BitAccess8-bit integer variables supported in StorageBuffer + VkBool32 uniformAndStorageBuffer8BitAccess8-bit integer variables supported in StorageBuffer and Uniform + VkBool32 storagePushConstant88-bit integer variables supported in PushConstant + + + + VkStructureType sType + void* pNext + VkBool32 conditionalRendering + VkBool32 inheritedConditionalRendering + + + VkStructureType sType + void* pNext + VkBool32 vulkanMemoryModel + VkBool32 vulkanMemoryModelDeviceScope + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains + + + + VkStructureType sType + void* pNext + VkBool32 shaderBufferInt64Atomics + VkBool32 shaderSharedInt64Atomics + + + + VkStructureType sType + void* pNext + VkBool32 shaderBufferFloat32Atomics + VkBool32 shaderBufferFloat32AtomicAdd + VkBool32 shaderBufferFloat64Atomics + VkBool32 shaderBufferFloat64AtomicAdd + VkBool32 shaderSharedFloat32Atomics + VkBool32 shaderSharedFloat32AtomicAdd + VkBool32 shaderSharedFloat64Atomics + VkBool32 shaderSharedFloat64AtomicAdd + VkBool32 shaderImageFloat32Atomics + VkBool32 shaderImageFloat32AtomicAdd + VkBool32 sparseImageFloat32Atomics + VkBool32 sparseImageFloat32AtomicAdd + + + VkStructureType sType + void* pNext + VkBool32 shaderBufferFloat16Atomics + VkBool32 shaderBufferFloat16AtomicAdd + VkBool32 shaderBufferFloat16AtomicMinMax + VkBool32 shaderBufferFloat32AtomicMinMax + VkBool32 shaderBufferFloat64AtomicMinMax + VkBool32 shaderSharedFloat16Atomics + VkBool32 shaderSharedFloat16AtomicAdd + VkBool32 shaderSharedFloat16AtomicMinMax + VkBool32 shaderSharedFloat32AtomicMinMax + VkBool32 shaderSharedFloat64AtomicMinMax + VkBool32 shaderImageFloat32AtomicMinMax + VkBool32 sparseImageFloat32AtomicMinMax + + + VkStructureType sType + void* pNext + VkBool32 vertexAttributeInstanceRateDivisor + VkBool32 vertexAttributeInstanceRateZeroDivisor + + + + + VkStructureType sType + void* pNext + VkPipelineStageFlags checkpointExecutionStageMask + + + VkStructureType sType + void* pNext + VkPipelineStageFlagBits stage + void* pCheckpointMarker + + + VkStructureType sType + void* pNext + VkResolveModeFlags supportedDepthResolveModessupported depth resolve modes + VkResolveModeFlags supportedStencilResolveModessupported stencil resolve modes + VkBool32 independentResolveNonedepth and stencil resolve modes can be set independently if one of them is none + VkBool32 independentResolvedepth and stencil resolve modes can be set independently + + + + VkStructureType sType + const void* pNext + VkResolveModeFlagBits depthResolveModedepth resolve mode + VkResolveModeFlagBits stencilResolveModestencil resolve mode + const VkAttachmentReference2* pDepthStencilResolveAttachmentdepth/stencil resolve attachment + + + + VkStructureType sType + const void* pNext + VkFormat decodeMode + + + VkStructureType sType + void* pNext + VkBool32 decodeModeSharedExponent + + + VkStructureType sType + void* pNext + VkBool32 transformFeedback + VkBool32 geometryStreams + + + VkStructureType sType + void* pNext + uint32_t maxTransformFeedbackStreams + uint32_t maxTransformFeedbackBuffers + VkDeviceSize maxTransformFeedbackBufferSize + uint32_t maxTransformFeedbackStreamDataSize + uint32_t maxTransformFeedbackBufferDataSize + uint32_t maxTransformFeedbackBufferDataStride + VkBool32 transformFeedbackQueries + VkBool32 transformFeedbackStreamsLinesTriangles + VkBool32 transformFeedbackRasterizationStreamSelect + VkBool32 transformFeedbackDraw + + + VkStructureType sType + const void* pNext + VkPipelineRasterizationStateStreamCreateFlagsEXT flags + uint32_t rasterizationStream + + + VkStructureType sType + void* pNext + VkBool32 representativeFragmentTest + + + VkStructureType sType + const void* pNext + VkBool32 representativeFragmentTestEnable + + + VkStructureType sType + void* pNext + VkBool32 exclusiveScissor + + + VkStructureType sType + const void* pNext + uint32_t exclusiveScissorCount + const VkRect2D* pExclusiveScissors + + + VkStructureType sType + void* pNext + VkBool32 cornerSampledImage + + + VkStructureType sType + void* pNext + VkBool32 computeDerivativeGroupQuads + VkBool32 computeDerivativeGroupLinear + + + + VkStructureType sType + void* pNext + VkBool32 meshAndTaskShaderDerivatives + + + + VkStructureType sType + void* pNext + VkBool32 imageFootprint + + + VkStructureType sType + void* pNext + VkBool32 dedicatedAllocationImageAliasing + + + VkStructureType sType + void* pNext + VkBool32 indirectMemoryCopy + VkBool32 indirectMemoryToImageCopy + + + VkStructureType sType + void* pNext + VkBool32 indirectCopy + + + VkStructureType sType + void* pNext + VkQueueFlags supportedQueuesBitmask of VkQueueFlagBits indicating the family of queues that support indirect copy + + + + VkStructureType sType + void* pNext + VkBool32 memoryDecompression + + + VkStructureType sType + void* pNext + VkMemoryDecompressionMethodFlagsNV decompressionMethods + uint64_t maxDecompressionIndirectCount + + + uint32_t shadingRatePaletteEntryCount + const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries + + + VkStructureType sType + const void* pNext + VkBool32 shadingRateImageEnable + uint32_t viewportCount + const VkShadingRatePaletteNV* pShadingRatePalettes + + + VkStructureType sType + void* pNext + VkBool32 shadingRateImage + VkBool32 shadingRateCoarseSampleOrder + + + VkStructureType sType + void* pNext + VkExtent2D shadingRateTexelSize + uint32_t shadingRatePaletteSize + uint32_t shadingRateMaxCoarseSamples + + + VkStructureType sType + void* pNext + VkBool32 invocationMask + + + uint32_t pixelX + uint32_t pixelY + uint32_t sample + + + VkShadingRatePaletteEntryNV shadingRate + uint32_t sampleCount + uint32_t sampleLocationCount + const VkCoarseSampleLocationNV* pSampleLocations + + + VkStructureType sType + const void* pNext + VkCoarseSampleOrderTypeNV sampleOrderType + uint32_t customSampleOrderCount + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders + + + VkStructureType sType + void* pNext + VkBool32 taskShader + VkBool32 meshShader + + + VkStructureType sType + void* pNext + uint32_t maxDrawMeshTasksCount + uint32_t maxTaskWorkGroupInvocations + uint32_t maxTaskWorkGroupSize[3] + uint32_t maxTaskTotalMemorySize + uint32_t maxTaskOutputCount + uint32_t maxMeshWorkGroupInvocations + uint32_t maxMeshWorkGroupSize[3] + uint32_t maxMeshTotalMemorySize + uint32_t maxMeshOutputVertices + uint32_t maxMeshOutputPrimitives + uint32_t maxMeshMultiviewViewCount + uint32_t meshOutputPerVertexGranularity + uint32_t meshOutputPerPrimitiveGranularity + + + uint32_t taskCount + uint32_t firstTask + + + VkStructureType sType + void* pNext + VkBool32 taskShader + VkBool32 meshShader + VkBool32 multiviewMeshShader + VkBool32 primitiveFragmentShadingRateMeshShader + VkBool32 meshShaderQueries + + + VkStructureType sType + void* pNext + uint32_t maxTaskWorkGroupTotalCount + uint32_t maxTaskWorkGroupCount[3] + uint32_t maxTaskWorkGroupInvocations + uint32_t maxTaskWorkGroupSize[3] + uint32_t maxTaskPayloadSize + uint32_t maxTaskSharedMemorySize + uint32_t maxTaskPayloadAndSharedMemorySize + uint32_t maxMeshWorkGroupTotalCount + uint32_t maxMeshWorkGroupCount[3] + uint32_t maxMeshWorkGroupInvocations + uint32_t maxMeshWorkGroupSize[3] + uint32_t maxMeshSharedMemorySize + uint32_t maxMeshPayloadAndSharedMemorySize + uint32_t maxMeshOutputMemorySize + uint32_t maxMeshPayloadAndOutputMemorySize + uint32_t maxMeshOutputComponents + uint32_t maxMeshOutputVertices + uint32_t maxMeshOutputPrimitives + uint32_t maxMeshOutputLayers + uint32_t maxMeshMultiviewViewCount + uint32_t meshOutputPerVertexGranularity + uint32_t meshOutputPerPrimitiveGranularity + uint32_t maxPreferredTaskWorkGroupInvocations + uint32_t maxPreferredMeshWorkGroupInvocations + VkBool32 prefersLocalInvocationVertexOutput + VkBool32 prefersLocalInvocationPrimitiveOutput + VkBool32 prefersCompactVertexOutput + VkBool32 prefersCompactPrimitiveOutput + + + uint32_t groupCountX + uint32_t groupCountY + uint32_t groupCountZ + + + VkStructureType sType + const void* pNext + VkRayTracingShaderGroupTypeKHR type + uint32_t generalShader + uint32_t closestHitShader + uint32_t anyHitShader + uint32_t intersectionShader + + + VkStructureType sType + const void* pNext + VkRayTracingShaderGroupTypeKHR type + uint32_t generalShader + uint32_t closestHitShader + uint32_t anyHitShader + uint32_t intersectionShader + const void* pShaderGroupCaptureReplayHandle + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags flagsPipeline creation flags + uint32_t stageCount + const VkPipelineShaderStageCreateInfo* pStagesOne entry for each active shader stage + uint32_t groupCount + const VkRayTracingShaderGroupCreateInfoNV* pGroups + uint32_t maxRecursionDepth + VkPipelineLayout layoutInterface layout of the pipeline + VkPipeline basePipelineHandleIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of + int32_t basePipelineIndexIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags flagsPipeline creation flags + uint32_t stageCount + const VkPipelineShaderStageCreateInfo* pStagesOne entry for each active shader stage + uint32_t groupCount + const VkRayTracingShaderGroupCreateInfoKHR* pGroups + uint32_t maxPipelineRayRecursionDepth + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo + const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface + const VkPipelineDynamicStateCreateInfo* pDynamicState + VkPipelineLayout layoutInterface layout of the pipeline + VkPipeline basePipelineHandleIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of + int32_t basePipelineIndexIf VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of + + + VkStructureType sType + const void* pNext + VkBuffer vertexData + VkDeviceSize vertexOffset + uint32_t vertexCount + VkDeviceSize vertexStride + VkFormat vertexFormat + VkBuffer indexData + VkDeviceSize indexOffset + uint32_t indexCount + VkIndexType indexType + VkBuffer transformDataOptional reference to array of floats representing a 3x4 row major affine transformation matrix. + VkDeviceSize transformOffset + + + VkStructureType sType + const void* pNext + VkBuffer aabbData + uint32_t numAABBs + uint32_t strideStride in bytes between AABBs + VkDeviceSize offsetOffset in bytes of the first AABB in aabbData + + + VkGeometryTrianglesNV triangles + VkGeometryAABBNV aabbs + + + VkStructureType sType + const void* pNext + VkGeometryTypeKHR geometryType + VkGeometryDataNV geometry + VkGeometryFlagsKHR flags + + + VkStructureType sType + const void* pNext + VkAccelerationStructureTypeNV type + VkBuildAccelerationStructureFlagsNV flags + uint32_t instanceCount + uint32_t geometryCount + const VkGeometryNV* pGeometries + + + VkStructureType sType + const void* pNext + VkDeviceSize compactedSize + VkAccelerationStructureInfoNV info + + + VkStructureType sType + const void* pNext + VkAccelerationStructureNV accelerationStructure + VkDeviceMemory memory + VkDeviceSize memoryOffset + uint32_t deviceIndexCount + const uint32_t* pDeviceIndices + + + VkStructureType sType + const void* pNext + uint32_t accelerationStructureCount + const VkAccelerationStructureKHR* pAccelerationStructures + + + VkStructureType sType + const void* pNext + uint32_t accelerationStructureCount + const VkAccelerationStructureNV* pAccelerationStructures + + + VkStructureType sType + const void* pNext + VkAccelerationStructureMemoryRequirementsTypeNV type + VkAccelerationStructureNV accelerationStructure + + + VkStructureType sType + void* pNext + VkBool32 accelerationStructure + VkBool32 accelerationStructureCaptureReplay + VkBool32 accelerationStructureIndirectBuild + VkBool32 accelerationStructureHostCommands + VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind + + + VkStructureType sType + void* pNext + VkBool32 rayTracingPipeline + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplay + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplayMixed + VkBool32 rayTracingPipelineTraceRaysIndirect + VkBool32 rayTraversalPrimitiveCulling + + + VkStructureType sType + void* pNext + VkBool32 rayQuery + + + VkStructureType sType + void* pNext + uint64_t maxGeometryCount + uint64_t maxInstanceCount + uint64_t maxPrimitiveCount + uint32_t maxPerStageDescriptorAccelerationStructures + uint32_t maxPerStageDescriptorUpdateAfterBindAccelerationStructures + uint32_t maxDescriptorSetAccelerationStructures + uint32_t maxDescriptorSetUpdateAfterBindAccelerationStructures + uint32_t minAccelerationStructureScratchOffsetAlignment + + + VkStructureType sType + void* pNext + uint32_t shaderGroupHandleSize + uint32_t maxRayRecursionDepth + uint32_t maxShaderGroupStride + uint32_t shaderGroupBaseAlignment + uint32_t shaderGroupHandleCaptureReplaySize + uint32_t maxRayDispatchInvocationCount + uint32_t shaderGroupHandleAlignment + uint32_t maxRayHitAttributeSize + + + VkStructureType sType + void* pNext + uint32_t shaderGroupHandleSize + uint32_t maxRecursionDepth + uint32_t maxShaderGroupStride + uint32_t shaderGroupBaseAlignment + uint64_t maxGeometryCount + uint64_t maxInstanceCount + uint64_t maxTriangleCount + uint32_t maxDescriptorSetAccelerationStructures + + + VkDeviceAddress deviceAddress + VkDeviceSize stride + VkDeviceSize size + + + uint32_t width + uint32_t height + uint32_t depth + + + VkDeviceAddress raygenShaderRecordAddress + VkDeviceSize raygenShaderRecordSize + VkDeviceAddress missShaderBindingTableAddress + VkDeviceSize missShaderBindingTableSize + VkDeviceSize missShaderBindingTableStride + VkDeviceAddress hitShaderBindingTableAddress + VkDeviceSize hitShaderBindingTableSize + VkDeviceSize hitShaderBindingTableStride + VkDeviceAddress callableShaderBindingTableAddress + VkDeviceSize callableShaderBindingTableSize + VkDeviceSize callableShaderBindingTableStride + uint32_t width + uint32_t height + uint32_t depth + + + VkStructureType sType + void* pNext + VkBool32 rayTracingMaintenance1 + VkBool32 rayTracingPipelineTraceRaysIndirect2 + + + VkStructureType sType + void* pNext + uint32_t drmFormatModifierCount + VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties + + + uint64_t drmFormatModifier + uint32_t drmFormatModifierPlaneCount + VkFormatFeatureFlags drmFormatModifierTilingFeatures + + + VkStructureType sType + const void* pNext + uint64_t drmFormatModifier + VkSharingMode sharingMode + uint32_t queueFamilyIndexCount + const uint32_t* pQueueFamilyIndices + + + VkStructureType sType + const void* pNext + uint32_t drmFormatModifierCount + const uint64_t* pDrmFormatModifiers + + + VkStructureType sType + const void* pNext + uint64_t drmFormatModifier + uint32_t drmFormatModifierPlaneCount + const VkSubresourceLayout* pPlaneLayouts + + + VkStructureType sType + void* pNext + uint64_t drmFormatModifier + + + VkStructureType sType + const void* pNext + VkImageUsageFlags stencilUsage + + + + VkStructureType sType + const void* pNext + VkMemoryOverallocationBehaviorAMD overallocationBehavior + + + VkStructureType sType + void* pNext + VkBool32 fragmentDensityMap + VkBool32 fragmentDensityMapDynamic + VkBool32 fragmentDensityMapNonSubsampledImages + + + VkStructureType sType + void* pNext + VkBool32 fragmentDensityMapDeferred + + + VkStructureType sType + void* pNext + VkBool32 fragmentDensityMapOffset + + + + VkStructureType sType + void* pNext + VkExtent2D minFragmentDensityTexelSize + VkExtent2D maxFragmentDensityTexelSize + VkBool32 fragmentDensityInvocations + + + VkStructureType sType + void* pNext + VkBool32 subsampledLoads + VkBool32 subsampledCoarseReconstructionEarlyAccess + uint32_t maxSubsampledArrayLayers + uint32_t maxDescriptorSetSubsampledSamplers + + + VkStructureType sType + void* pNext + VkExtent2D fragmentDensityOffsetGranularity + + + + VkStructureType sType + const void* pNext + VkAttachmentReference fragmentDensityMapAttachment + + + VkStructureType sType + const void* pNext + uint32_t fragmentDensityOffsetCount + const VkOffset2D* pFragmentDensityOffsets + + + + VkStructureType sType + void* pNext + VkBool32 scalarBlockLayout + + + + VkStructureType sType + const void* pNext + VkBool32 supportsProtectedRepresents if surface can be protected + + + VkStructureType sType + void* pNext + VkBool32 uniformBufferStandardLayout + + + + VkStructureType sType + void* pNext + VkBool32 depthClipEnable + + + VkStructureType sType + const void* pNext + VkPipelineRasterizationDepthClipStateCreateFlagsEXT flagsReserved + VkBool32 depthClipEnable + + + VkStructureType sType + void* pNext + VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS] + VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS] + + + VkStructureType sType + void* pNext + VkBool32 memoryPriority + + + VkStructureType sType + const void* pNext + float priority + + + VkStructureType sType + void* pNext + VkBool32 pageableDeviceLocalMemory + + + VkStructureType sType + void* pNext + VkBool32 bufferDeviceAddress + VkBool32 bufferDeviceAddressCaptureReplay + VkBool32 bufferDeviceAddressMultiDevice + + + + VkStructureType sType + void* pNext + VkBool32 bufferDeviceAddress + VkBool32 bufferDeviceAddressCaptureReplay + VkBool32 bufferDeviceAddressMultiDevice + + + + VkStructureType sType + const void* pNext + VkBuffer buffer + + + + + VkStructureType sType + const void* pNext + uint64_t opaqueCaptureAddress + + + + VkStructureType sType + const void* pNext + VkDeviceAddress deviceAddress + + + VkStructureType sType + void* pNext + VkImageViewType imageViewType + + + VkStructureType sType + void* pNext + VkBool32 filterCubicThe combinations of format, image type (and image view type if provided) can be filtered with VK_FILTER_CUBIC_EXT + VkBool32 filterCubicMinmaxThe combination of format, image type (and image view type if provided) can be filtered with VK_FILTER_CUBIC_EXT and ReductionMode of Min or Max + + + VkStructureType sType + void* pNext + VkBool32 imagelessFramebuffer + + + + VkStructureType sType + const void* pNext + uint32_t attachmentImageInfoCount + const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos + + + + VkStructureType sType + const void* pNext + VkImageCreateFlags flagsImage creation flags + VkImageUsageFlags usageImage usage flags + uint32_t width + uint32_t height + uint32_t layerCount + uint32_t viewFormatCount + const VkFormat* pViewFormats + + + + VkStructureType sType + const void* pNext + uint32_t attachmentCount + const VkImageView* pAttachments + + + + VkStructureType sType + void* pNext + VkBool32 textureCompressionASTC_HDR + + + + VkStructureType sType + void* pNext + VkBool32 cooperativeMatrix + VkBool32 cooperativeMatrixRobustBufferAccess + + + VkStructureType sType + void* pNext + VkShaderStageFlags cooperativeMatrixSupportedStages + + + VkStructureType sType + void* pNext + uint32_t MSize + uint32_t NSize + uint32_t KSize + VkComponentTypeNV AType + VkComponentTypeNV BType + VkComponentTypeNV CType + VkComponentTypeNV DType + VkScopeNV scope + + + VkStructureType sType + void* pNext + VkBool32 ycbcrImageArrays + + + VkStructureType sType + const void* pNext + VkImageView imageView + VkDescriptorType descriptorType + VkSampler sampler + + + VkStructureType sType + void* pNext + VkDeviceAddress deviceAddress + VkDeviceSize size + + + VkStructureType sType + const void* pNext + GgpFrameToken frameToken + + + VkPipelineCreationFeedbackFlags flags + uint64_t duration + + + + VkStructureType sType + const void* pNext + VkPipelineCreationFeedback* pPipelineCreationFeedbackOutput pipeline creation feedback. + uint32_t pipelineStageCreationFeedbackCount + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacksOne entry for each shader stage specified in the parent Vk*PipelineCreateInfo struct + + + + VkStructureType sType + void* pNext + VkFullScreenExclusiveEXT fullScreenExclusive + + + VkStructureType sType + const void* pNext + HMONITOR hmonitor + + + VkStructureType sType + void* pNext + VkBool32 fullScreenExclusiveSupported + + + VkStructureType sType + void* pNext + VkBool32 presentBarrier + + + VkStructureType sType + void* pNext + VkBool32 presentBarrierSupported + + + VkStructureType sType + void* pNext + VkBool32 presentBarrierEnable + + + VkStructureType sType + void* pNext + VkBool32 performanceCounterQueryPoolsperformance counters supported in query pools + VkBool32 performanceCounterMultipleQueryPoolsperformance counters from multiple query pools can be accessed in the same primary command buffer + + + VkStructureType sType + void* pNext + VkBool32 allowCommandBufferQueryCopiesFlag to specify whether performance queries are allowed to be used in vkCmdCopyQueryPoolResults + + + VkStructureType sType + void* pNext + VkPerformanceCounterUnitKHR unit + VkPerformanceCounterScopeKHR scope + VkPerformanceCounterStorageKHR storage + uint8_t uuid[VK_UUID_SIZE] + + + VkStructureType sType + void* pNext + VkPerformanceCounterDescriptionFlagsKHR flags + char name[VK_MAX_DESCRIPTION_SIZE] + char category[VK_MAX_DESCRIPTION_SIZE] + char description[VK_MAX_DESCRIPTION_SIZE] + + + VkStructureType sType + const void* pNext + uint32_t queueFamilyIndex + uint32_t counterIndexCount + const uint32_t* pCounterIndices + + + int32_t int32 + int64_t int64 + uint32_t uint32 + uint64_t uint64 + float float32 + double float64 + + + VkStructureType sType + const void* pNext + VkAcquireProfilingLockFlagsKHR flagsAcquire profiling lock flags + uint64_t timeout + + + VkStructureType sType + const void* pNext + uint32_t counterPassIndexIndex for which counter pass to submit + + + VkStructureType sType + const void* pNext + uint32_t maxPerformanceQueriesPerPoolMaximum number of VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR queries in a query pool + + + VkStructureType sType + const void* pNext + VkHeadlessSurfaceCreateFlagsEXT flags + + + VkStructureType sType + void* pNext + VkBool32 coverageReductionMode + + + VkStructureType sType + const void* pNext + VkPipelineCoverageReductionStateCreateFlagsNV flags + VkCoverageReductionModeNV coverageReductionMode + + + VkStructureType sType + void* pNext + VkCoverageReductionModeNV coverageReductionMode + VkSampleCountFlagBits rasterizationSamples + VkSampleCountFlags depthStencilSamples + VkSampleCountFlags colorSamples + + + VkStructureType sType + void* pNext + VkBool32 shaderIntegerFunctions2 + + + uint32_t value32 + uint64_t value64 + float valueFloat + VkBool32 valueBool + const char* valueString + + + VkPerformanceValueTypeINTEL type + VkPerformanceValueDataINTEL data + + + VkStructureType sType + const void* pNext + void* pUserData + + + VkStructureType sType + const void* pNext + VkQueryPoolSamplingModeINTEL performanceCountersSampling + + + + VkStructureType sType + const void* pNext + uint64_t marker + + + VkStructureType sType + const void* pNext + uint32_t marker + + + VkStructureType sType + const void* pNext + VkPerformanceOverrideTypeINTEL type + VkBool32 enable + uint64_t parameter + + + VkStructureType sType + const void* pNext + VkPerformanceConfigurationTypeINTEL type + + + VkStructureType sType + void* pNext + VkBool32 shaderSubgroupClock + VkBool32 shaderDeviceClock + + + VkStructureType sType + void* pNext + VkBool32 indexTypeUint8 + + + + + VkStructureType sType + void* pNext + uint32_t shaderSMCount + uint32_t shaderWarpsPerSM + + + VkStructureType sType + void* pNext + VkBool32 shaderSMBuiltins + + + VkStructureType sType + void* pNextPointer to next structure + VkBool32 fragmentShaderSampleInterlock + VkBool32 fragmentShaderPixelInterlock + VkBool32 fragmentShaderShadingRateInterlock + + + VkStructureType sType + void* pNext + VkBool32 separateDepthStencilLayouts + + + + VkStructureType sType + void* pNext + VkImageLayout stencilLayout + + + VkStructureType sType + void* pNext + VkBool32 primitiveTopologyListRestart + VkBool32 primitiveTopologyPatchListRestart + + + + VkStructureType sType + void* pNext + VkImageLayout stencilInitialLayout + VkImageLayout stencilFinalLayout + + + + VkStructureType sType + void* pNext + VkBool32 pipelineExecutableInfo + + + VkStructureType sType + const void* pNext + VkPipeline pipeline + + + + VkStructureType sType + void* pNext + VkShaderStageFlags stages + char name[VK_MAX_DESCRIPTION_SIZE] + char description[VK_MAX_DESCRIPTION_SIZE] + uint32_t subgroupSize + + + VkStructureType sType + const void* pNext + VkPipeline pipeline + uint32_t executableIndex + + + VkBool32 b32 + int64_t i64 + uint64_t u64 + double f64 + + + VkStructureType sType + void* pNext + char name[VK_MAX_DESCRIPTION_SIZE] + char description[VK_MAX_DESCRIPTION_SIZE] + VkPipelineExecutableStatisticFormatKHR format + VkPipelineExecutableStatisticValueKHR value + + + VkStructureType sType + void* pNext + char name[VK_MAX_DESCRIPTION_SIZE] + char description[VK_MAX_DESCRIPTION_SIZE] + VkBool32 isText + size_t dataSize + void* pData + + + VkStructureType sType + void* pNext + VkBool32 shaderDemoteToHelperInvocation + + + + VkStructureType sType + void* pNext + VkBool32 texelBufferAlignment + + + VkStructureType sType + void* pNext + VkDeviceSize storageTexelBufferOffsetAlignmentBytes + VkBool32 storageTexelBufferOffsetSingleTexelAlignment + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment + + + + VkStructureType sType + void* pNext + VkBool32 subgroupSizeControl + VkBool32 computeFullSubgroups + + + + VkStructureType sType + void* pNext + uint32_t minSubgroupSizeThe minimum subgroup size supported by this device + uint32_t maxSubgroupSizeThe maximum subgroup size supported by this device + uint32_t maxComputeWorkgroupSubgroupsThe maximum number of subgroups supported in a workgroup + VkShaderStageFlags requiredSubgroupSizeStagesThe shader stages that support specifying a subgroup size + + + + VkStructureType sType + const void* pNext + uint32_t requiredSubgroupSize + + + + + VkStructureType sType + void* pNext + VkRenderPass renderPass + uint32_t subpass + + + VkStructureType sType + void* pNext + uint32_t maxSubpassShadingWorkgroupSizeAspectRatio + + + VkStructureType sType + void* pNext + uint32_t maxWorkGroupCount[3] + uint32_t maxWorkGroupSize[3] + uint32_t maxOutputClusterCount + VkDeviceSize indirectBufferOffsetAlignment + + + VkStructureType sType + const void* pNext + uint64_t opaqueCaptureAddress + + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + + + + VkStructureType sType + void* pNext + VkBool32 rectangularLines + VkBool32 bresenhamLines + VkBool32 smoothLines + VkBool32 stippledRectangularLines + VkBool32 stippledBresenhamLines + VkBool32 stippledSmoothLines + + + + + VkStructureType sType + void* pNext + uint32_t lineSubPixelPrecisionBits + + + + + VkStructureType sType + const void* pNext + VkLineRasterizationMode lineRasterizationMode + VkBool32 stippledLineEnable + uint32_t lineStippleFactor + uint16_t lineStipplePattern + + + + + VkStructureType sType + void* pNext + VkBool32 pipelineCreationCacheControl + + + + VkStructureType sType + void* pNext + VkBool32 storageBuffer16BitAccess16-bit integer/floating-point variables supported in BufferBlock + VkBool32 uniformAndStorageBuffer16BitAccess16-bit integer/floating-point variables supported in BufferBlock and Block + VkBool32 storagePushConstant1616-bit integer/floating-point variables supported in PushConstant + VkBool32 storageInputOutput1616-bit integer/floating-point variables supported in shader inputs and outputs + VkBool32 multiviewMultiple views in a render pass + VkBool32 multiviewGeometryShaderMultiple views in a render pass w/ geometry shader + VkBool32 multiviewTessellationShaderMultiple views in a render pass w/ tessellation shader + VkBool32 variablePointersStorageBuffer + VkBool32 variablePointers + VkBool32 protectedMemory + VkBool32 samplerYcbcrConversionSampler color conversion supported + VkBool32 shaderDrawParameters + + + VkStructureType sType + void* pNext + uint8_t deviceUUID[VK_UUID_SIZE] + uint8_t driverUUID[VK_UUID_SIZE] + uint8_t deviceLUID[VK_LUID_SIZE] + uint32_t deviceNodeMask + VkBool32 deviceLUIDValid + uint32_t subgroupSizeThe size of a subgroup for this queue. + VkShaderStageFlags subgroupSupportedStagesBitfield of what shader stages support subgroup operations + VkSubgroupFeatureFlags subgroupSupportedOperationsBitfield of what subgroup operations are supported. + VkBool32 subgroupQuadOperationsInAllStagesFlag to specify whether quad operations are available in all stages. + VkPointClippingBehavior pointClippingBehavior + uint32_t maxMultiviewViewCountmax number of views in a subpass + uint32_t maxMultiviewInstanceIndexmax instance index for a draw in a multiview subpass + VkBool32 protectedNoFault + uint32_t maxPerSetDescriptors + VkDeviceSize maxMemoryAllocationSize + + + VkStructureType sType + void* pNext + VkBool32 samplerMirrorClampToEdge + VkBool32 drawIndirectCount + VkBool32 storageBuffer8BitAccess8-bit integer variables supported in StorageBuffer + VkBool32 uniformAndStorageBuffer8BitAccess8-bit integer variables supported in StorageBuffer and Uniform + VkBool32 storagePushConstant88-bit integer variables supported in PushConstant + VkBool32 shaderBufferInt64Atomics + VkBool32 shaderSharedInt64Atomics + VkBool32 shaderFloat1616-bit floats (halfs) in shaders + VkBool32 shaderInt88-bit integers in shaders + VkBool32 descriptorIndexing + VkBool32 shaderInputAttachmentArrayDynamicIndexing + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing + VkBool32 shaderUniformBufferArrayNonUniformIndexing + VkBool32 shaderSampledImageArrayNonUniformIndexing + VkBool32 shaderStorageBufferArrayNonUniformIndexing + VkBool32 shaderStorageImageArrayNonUniformIndexing + VkBool32 shaderInputAttachmentArrayNonUniformIndexing + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing + VkBool32 descriptorBindingUniformBufferUpdateAfterBind + VkBool32 descriptorBindingSampledImageUpdateAfterBind + VkBool32 descriptorBindingStorageImageUpdateAfterBind + VkBool32 descriptorBindingStorageBufferUpdateAfterBind + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind + VkBool32 descriptorBindingUpdateUnusedWhilePending + VkBool32 descriptorBindingPartiallyBound + VkBool32 descriptorBindingVariableDescriptorCount + VkBool32 runtimeDescriptorArray + VkBool32 samplerFilterMinmax + VkBool32 scalarBlockLayout + VkBool32 imagelessFramebuffer + VkBool32 uniformBufferStandardLayout + VkBool32 shaderSubgroupExtendedTypes + VkBool32 separateDepthStencilLayouts + VkBool32 hostQueryReset + VkBool32 timelineSemaphore + VkBool32 bufferDeviceAddress + VkBool32 bufferDeviceAddressCaptureReplay + VkBool32 bufferDeviceAddressMultiDevice + VkBool32 vulkanMemoryModel + VkBool32 vulkanMemoryModelDeviceScope + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains + VkBool32 shaderOutputViewportIndex + VkBool32 shaderOutputLayer + VkBool32 subgroupBroadcastDynamicId + + + VkStructureType sType + void* pNext + VkDriverId driverID + char driverName[VK_MAX_DRIVER_NAME_SIZE] + char driverInfo[VK_MAX_DRIVER_INFO_SIZE] + VkConformanceVersion conformanceVersion + VkShaderFloatControlsIndependence denormBehaviorIndependence + VkShaderFloatControlsIndependence roundingModeIndependence + VkBool32 shaderSignedZeroInfNanPreserveFloat16An implementation can preserve signed zero, nan, inf + VkBool32 shaderSignedZeroInfNanPreserveFloat32An implementation can preserve signed zero, nan, inf + VkBool32 shaderSignedZeroInfNanPreserveFloat64An implementation can preserve signed zero, nan, inf + VkBool32 shaderDenormPreserveFloat16An implementation can preserve denormals + VkBool32 shaderDenormPreserveFloat32An implementation can preserve denormals + VkBool32 shaderDenormPreserveFloat64An implementation can preserve denormals + VkBool32 shaderDenormFlushToZeroFloat16An implementation can flush to zero denormals + VkBool32 shaderDenormFlushToZeroFloat32An implementation can flush to zero denormals + VkBool32 shaderDenormFlushToZeroFloat64An implementation can flush to zero denormals + VkBool32 shaderRoundingModeRTEFloat16An implementation can support RTE + VkBool32 shaderRoundingModeRTEFloat32An implementation can support RTE + VkBool32 shaderRoundingModeRTEFloat64An implementation can support RTE + VkBool32 shaderRoundingModeRTZFloat16An implementation can support RTZ + VkBool32 shaderRoundingModeRTZFloat32An implementation can support RTZ + VkBool32 shaderRoundingModeRTZFloat64An implementation can support RTZ + uint32_t maxUpdateAfterBindDescriptorsInAllPools + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative + VkBool32 shaderSampledImageArrayNonUniformIndexingNative + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative + VkBool32 shaderStorageImageArrayNonUniformIndexingNative + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative + VkBool32 robustBufferAccessUpdateAfterBind + VkBool32 quadDivergentImplicitLod + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments + uint32_t maxPerStageUpdateAfterBindResources + uint32_t maxDescriptorSetUpdateAfterBindSamplers + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic + uint32_t maxDescriptorSetUpdateAfterBindSampledImages + uint32_t maxDescriptorSetUpdateAfterBindStorageImages + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments + VkResolveModeFlags supportedDepthResolveModessupported depth resolve modes + VkResolveModeFlags supportedStencilResolveModessupported stencil resolve modes + VkBool32 independentResolveNonedepth and stencil resolve modes can be set independently if one of them is none + VkBool32 independentResolvedepth and stencil resolve modes can be set independently + VkBool32 filterMinmaxSingleComponentFormats + VkBool32 filterMinmaxImageComponentMapping + uint64_t maxTimelineSemaphoreValueDifference + VkSampleCountFlags framebufferIntegerColorSampleCounts + + + VkStructureType sType + void* pNext + VkBool32 robustImageAccess + VkBool32 inlineUniformBlock + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind + VkBool32 pipelineCreationCacheControl + VkBool32 privateData + VkBool32 shaderDemoteToHelperInvocation + VkBool32 shaderTerminateInvocation + VkBool32 subgroupSizeControl + VkBool32 computeFullSubgroups + VkBool32 synchronization2 + VkBool32 textureCompressionASTC_HDR + VkBool32 shaderZeroInitializeWorkgroupMemory + VkBool32 dynamicRendering + VkBool32 shaderIntegerDotProduct + VkBool32 maintenance4 + + + VkStructureType sType + void* pNext + uint32_t minSubgroupSizeThe minimum subgroup size supported by this device + uint32_t maxSubgroupSizeThe maximum subgroup size supported by this device + uint32_t maxComputeWorkgroupSubgroupsThe maximum number of subgroups supported in a workgroup + VkShaderStageFlags requiredSubgroupSizeStagesThe shader stages that support specifying a subgroup size + uint32_t maxInlineUniformBlockSize + uint32_t maxPerStageDescriptorInlineUniformBlocks + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks + uint32_t maxDescriptorSetInlineUniformBlocks + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks + uint32_t maxInlineUniformTotalSize + VkBool32 integerDotProduct8BitUnsignedAccelerated + VkBool32 integerDotProduct8BitSignedAccelerated + VkBool32 integerDotProduct8BitMixedSignednessAccelerated + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated + VkBool32 integerDotProduct16BitUnsignedAccelerated + VkBool32 integerDotProduct16BitSignedAccelerated + VkBool32 integerDotProduct16BitMixedSignednessAccelerated + VkBool32 integerDotProduct32BitUnsignedAccelerated + VkBool32 integerDotProduct32BitSignedAccelerated + VkBool32 integerDotProduct32BitMixedSignednessAccelerated + VkBool32 integerDotProduct64BitUnsignedAccelerated + VkBool32 integerDotProduct64BitSignedAccelerated + VkBool32 integerDotProduct64BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated + VkDeviceSize storageTexelBufferOffsetAlignmentBytes + VkBool32 storageTexelBufferOffsetSingleTexelAlignment + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment + VkDeviceSize maxBufferSize + + + VkStructureType sType + void* pNext + VkBool32 globalPriorityQuery + VkBool32 shaderSubgroupRotate + VkBool32 shaderSubgroupRotateClustered + VkBool32 shaderFloatControls2 + VkBool32 shaderExpectAssume + VkBool32 rectangularLines + VkBool32 bresenhamLines + VkBool32 smoothLines + VkBool32 stippledRectangularLines + VkBool32 stippledBresenhamLines + VkBool32 stippledSmoothLines + VkBool32 vertexAttributeInstanceRateDivisor + VkBool32 vertexAttributeInstanceRateZeroDivisor + VkBool32 indexTypeUint8 + VkBool32 dynamicRenderingLocalRead + VkBool32 maintenance5 + VkBool32 maintenance6 + VkBool32 pipelineProtectedAccess + VkBool32 pipelineRobustness + VkBool32 hostImageCopy + VkBool32 pushDescriptor + + + VkStructureType sType + void* pNext + uint32_t lineSubPixelPrecisionBits + uint32_t maxVertexAttribDivisormax value of vertex attribute divisor + VkBool32 supportsNonZeroFirstInstance + uint32_t maxPushDescriptors + VkBool32 dynamicRenderingLocalReadDepthStencilAttachments + VkBool32 dynamicRenderingLocalReadMultisampledAttachments + VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting + VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting + VkBool32 depthStencilSwizzleOneSupport + VkBool32 polygonModePointSize + VkBool32 nonStrictSinglePixelWideLinesUseParallelogram + VkBool32 nonStrictWideLinesUseParallelogram + VkBool32 blockTexelViewCompatibleMultipleLayers + uint32_t maxCombinedImageSamplerDescriptorCount + VkBool32 fragmentShadingRateClampCombinerInputs + VkPipelineRobustnessBufferBehavior defaultRobustnessStorageBuffers + VkPipelineRobustnessBufferBehavior defaultRobustnessUniformBuffers + VkPipelineRobustnessBufferBehavior defaultRobustnessVertexInputs + VkPipelineRobustnessImageBehavior defaultRobustnessImages + uint32_t copySrcLayoutCount + VkImageLayout* pCopySrcLayouts + uint32_t copyDstLayoutCount + VkImageLayout* pCopyDstLayouts + uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE] + VkBool32 identicalMemoryTypeRequirements + + + VkStructureType sType + const void* pNext + VkPipelineCompilerControlFlagsAMD compilerControlFlags + + + VkStructureType sType + void* pNext + VkBool32 deviceCoherentMemory + + + VkStructureType sType + void* pNext + VkFaultLevel faultLevel + VkFaultType faultType + + + VkStructureType sType + const void* pNext + uint32_t faultCount + VkFaultData* pFaults + PFN_vkFaultCallbackFunction pfnFaultCallback + + + VkStructureType sType + void* pNext + char name[VK_MAX_EXTENSION_NAME_SIZE] + char version[VK_MAX_EXTENSION_NAME_SIZE] + VkToolPurposeFlags purposes + char description[VK_MAX_DESCRIPTION_SIZE] + char layer[VK_MAX_EXTENSION_NAME_SIZE] + + + + VkStructureType sType + const void* pNext + VkClearColorValue customBorderColor + VkFormat format + + + VkStructureType sType + void* pNext + uint32_t maxCustomBorderColorSamplers + + + VkStructureType sType + void* pNext + VkBool32 customBorderColors + VkBool32 customBorderColorWithoutFormat + + + VkStructureType sType + const void* pNext + VkComponentMapping components + VkBool32 srgb + + + VkStructureType sType + void* pNext + VkBool32 borderColorSwizzle + VkBool32 borderColorSwizzleFromImage + + + VkDeviceAddress deviceAddress + void* hostAddress + + + VkDeviceAddress deviceAddress + const void* hostAddress + + + VkDeviceAddress deviceAddress + const void* hostAddress + + + VkStructureType sType + const void* pNext + VkFormat vertexFormat + VkDeviceOrHostAddressConstKHR vertexData + VkDeviceSize vertexStride + uint32_t maxVertex + VkIndexType indexType + VkDeviceOrHostAddressConstKHR indexData + VkDeviceOrHostAddressConstKHR transformData + + + VkStructureType sType + const void* pNext + VkDeviceOrHostAddressConstKHR data + VkDeviceSize stride + + + VkStructureType sType + const void* pNext + VkBool32 arrayOfPointers + VkDeviceOrHostAddressConstKHR data + + + VkStructureType sType + const void* pNext + VkFormat vertexFormat + VkDeviceOrHostAddressConstKHR vertexData + VkDeviceSize vertexStride + VkFormat radiusFormat + VkDeviceOrHostAddressConstKHR radiusData + VkDeviceSize radiusStride + VkIndexType indexType + VkDeviceOrHostAddressConstKHR indexData + VkDeviceSize indexStride + VkRayTracingLssIndexingModeNV indexingMode + VkRayTracingLssPrimitiveEndCapsModeNV endCapsMode + + + VkStructureType sType + const void* pNext + VkFormat vertexFormat + VkDeviceOrHostAddressConstKHR vertexData + VkDeviceSize vertexStride + VkFormat radiusFormat + VkDeviceOrHostAddressConstKHR radiusData + VkDeviceSize radiusStride + VkIndexType indexType + VkDeviceOrHostAddressConstKHR indexData + VkDeviceSize indexStride + + + VkAccelerationStructureGeometryTrianglesDataKHR triangles + VkAccelerationStructureGeometryAabbsDataKHR aabbs + VkAccelerationStructureGeometryInstancesDataKHR instances + + + VkStructureType sType + const void* pNext + VkGeometryTypeKHR geometryType + VkAccelerationStructureGeometryDataKHR geometry + VkGeometryFlagsKHR flags + + + VkStructureType sType + const void* pNext + VkAccelerationStructureTypeKHR type + VkBuildAccelerationStructureFlagsKHR flags + VkBuildAccelerationStructureModeKHR mode + VkAccelerationStructureKHR srcAccelerationStructure + VkAccelerationStructureKHR dstAccelerationStructure + uint32_t geometryCount + const VkAccelerationStructureGeometryKHR* pGeometries + const VkAccelerationStructureGeometryKHR* const* ppGeometries + VkDeviceOrHostAddressKHR scratchData + + + uint32_t primitiveCount + uint32_t primitiveOffset + uint32_t firstVertex + uint32_t transformOffset + + + VkStructureType sType + const void* pNext + VkAccelerationStructureCreateFlagsKHR createFlags + VkBuffer buffer + VkDeviceSize offsetSpecified in bytes + VkDeviceSize size + VkAccelerationStructureTypeKHR type + VkDeviceAddress deviceAddress + + + float minX + float minY + float minZ + float maxX + float maxY + float maxZ + + + + float matrix[3][4] + + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + VkTransformMatrixKHR transform + uint32_t instanceCustomIndex:24 + uint32_t mask:8 + uint32_t instanceShaderBindingTableRecordOffset:24 + VkGeometryInstanceFlagsKHR flags:8 + uint64_t accelerationStructureReference + + + + VkStructureType sType + const void* pNext + VkAccelerationStructureKHR accelerationStructure + + + VkStructureType sType + const void* pNext + const uint8_t* pVersionData + + + VkStructureType sType + const void* pNext + VkAccelerationStructureKHR src + VkAccelerationStructureKHR dst + VkCopyAccelerationStructureModeKHR mode + + + VkStructureType sType + const void* pNext + VkAccelerationStructureKHR src + VkDeviceOrHostAddressKHR dst + VkCopyAccelerationStructureModeKHR mode + + + VkStructureType sType + const void* pNext + VkDeviceOrHostAddressConstKHR src + VkAccelerationStructureKHR dst + VkCopyAccelerationStructureModeKHR mode + + + VkStructureType sType + const void* pNext + uint32_t maxPipelineRayPayloadSize + uint32_t maxPipelineRayHitAttributeSize + + + VkStructureType sType + const void* pNext + uint32_t libraryCount + const VkPipeline* pLibraries + + + VkObjectType objectType + uint64_t objectHandle + VkRefreshObjectFlagsKHR flags + + + VkStructureType sType + const void* pNext + uint32_t objectCount + const VkRefreshObjectKHR* pObjects + + + VkStructureType sType + void* pNext + VkBool32 extendedDynamicState + + + VkStructureType sType + void* pNext + VkBool32 extendedDynamicState2 + VkBool32 extendedDynamicState2LogicOp + VkBool32 extendedDynamicState2PatchControlPoints + + + VkStructureType sType + void* pNext + VkBool32 extendedDynamicState3TessellationDomainOrigin + VkBool32 extendedDynamicState3DepthClampEnable + VkBool32 extendedDynamicState3PolygonMode + VkBool32 extendedDynamicState3RasterizationSamples + VkBool32 extendedDynamicState3SampleMask + VkBool32 extendedDynamicState3AlphaToCoverageEnable + VkBool32 extendedDynamicState3AlphaToOneEnable + VkBool32 extendedDynamicState3LogicOpEnable + VkBool32 extendedDynamicState3ColorBlendEnable + VkBool32 extendedDynamicState3ColorBlendEquation + VkBool32 extendedDynamicState3ColorWriteMask + VkBool32 extendedDynamicState3RasterizationStream + VkBool32 extendedDynamicState3ConservativeRasterizationMode + VkBool32 extendedDynamicState3ExtraPrimitiveOverestimationSize + VkBool32 extendedDynamicState3DepthClipEnable + VkBool32 extendedDynamicState3SampleLocationsEnable + VkBool32 extendedDynamicState3ColorBlendAdvanced + VkBool32 extendedDynamicState3ProvokingVertexMode + VkBool32 extendedDynamicState3LineRasterizationMode + VkBool32 extendedDynamicState3LineStippleEnable + VkBool32 extendedDynamicState3DepthClipNegativeOneToOne + VkBool32 extendedDynamicState3ViewportWScalingEnable + VkBool32 extendedDynamicState3ViewportSwizzle + VkBool32 extendedDynamicState3CoverageToColorEnable + VkBool32 extendedDynamicState3CoverageToColorLocation + VkBool32 extendedDynamicState3CoverageModulationMode + VkBool32 extendedDynamicState3CoverageModulationTableEnable + VkBool32 extendedDynamicState3CoverageModulationTable + VkBool32 extendedDynamicState3CoverageReductionMode + VkBool32 extendedDynamicState3RepresentativeFragmentTestEnable + VkBool32 extendedDynamicState3ShadingRateImageEnable + + + VkStructureType sType + void* pNext + VkBool32 dynamicPrimitiveTopologyUnrestricted + + + VkBlendFactor srcColorBlendFactor + VkBlendFactor dstColorBlendFactor + VkBlendOp colorBlendOp + VkBlendFactor srcAlphaBlendFactor + VkBlendFactor dstAlphaBlendFactor + VkBlendOp alphaBlendOp + + + VkBlendOp advancedBlendOp + VkBool32 srcPremultiplied + VkBool32 dstPremultiplied + VkBlendOverlapEXT blendOverlap + VkBool32 clampResults + + + VkStructureType sType + const void* pNextPointer to next structure + VkSurfaceTransformFlagBitsKHR transform + + + VkStructureType sType + const void* pNext + VkSurfaceTransformFlagBitsKHR transform + + + VkStructureType sType + const void* pNextPointer to next structure + VkSurfaceTransformFlagBitsKHR transform + VkRect2D renderArea + + + VkStructureType sType + void* pNext + VkBool32 partitionedAccelerationStructure + + + VkStructureType sType + void* pNext + uint32_t maxPartitionCount + + + VkPartitionedAccelerationStructureOpTypeNV opType + uint32_t argCount + VkStridedDeviceAddressNV argData + + + VkStructureType sType + void* pNext + VkBool32 enablePartitionTranslation + + + VkTransformMatrixKHR transform + float explicitAABB[6] + uint32_t instanceID + uint32_t instanceMask + uint32_t instanceContributionToHitGroupIndex + VkPartitionedAccelerationStructureInstanceFlagsNV instanceFlags + uint32_t instanceIndex + uint32_t partitionIndex + VkDeviceAddress accelerationStructure + + + uint32_t instanceIndex + uint32_t instanceContributionToHitGroupIndex + VkDeviceAddress accelerationStructure + + + uint32_t partitionIndex + float partitionTranslation[3] + + + VkStructureType sType + void* pNext + uint32_t accelerationStructureCount + const VkDeviceAddress* pAccelerationStructures + + + VkStructureType sType + void* pNext + VkBuildAccelerationStructureFlagsKHR flags + uint32_t instanceCount + uint32_t maxInstancePerPartitionCount + uint32_t partitionCount + uint32_t maxInstanceInGlobalPartitionCount + + + VkStructureType sType + void* pNext + VkPartitionedAccelerationStructureInstancesInputNV input + VkDeviceAddress srcAccelerationStructureData + VkDeviceAddress dstAccelerationStructureData + VkDeviceAddress scratchData + VkDeviceAddress srcInfos + VkDeviceAddress srcInfosCount + + + VkStructureType sType + void* pNext + VkBool32 diagnosticsConfig + + + VkStructureType sType + const void* pNext + VkDeviceDiagnosticsConfigFlagsNV flags + + + VkStructureType sType + const void* pNext + uint8_t pipelineIdentifier[VK_UUID_SIZE] + VkPipelineMatchControl matchControl + VkDeviceSize poolEntrySize + + + VkStructureType sType + void* pNext + VkBool32 shaderZeroInitializeWorkgroupMemory + + + + VkStructureType sType + void* pNext + VkBool32 shaderSubgroupUniformControlFlow + + + VkStructureType sType + void* pNext + VkBool32 robustBufferAccess2 + VkBool32 robustImageAccess2 + VkBool32 nullDescriptor + + + + VkStructureType sType + void* pNext + VkDeviceSize robustStorageBufferAccessSizeAlignment + VkDeviceSize robustUniformBufferAccessSizeAlignment + + + + VkStructureType sType + void* pNext + VkBool32 robustImageAccess + + + + VkStructureType sType + void* pNext + VkBool32 workgroupMemoryExplicitLayout + VkBool32 workgroupMemoryExplicitLayoutScalarBlockLayout + VkBool32 workgroupMemoryExplicitLayout8BitAccess + VkBool32 workgroupMemoryExplicitLayout16BitAccess + + + VkStructureType sType + void* pNext + VkBool32 constantAlphaColorBlendFactors + VkBool32 events + VkBool32 imageViewFormatReinterpretation + VkBool32 imageViewFormatSwizzle + VkBool32 imageView2DOn3DImage + VkBool32 multisampleArrayImage + VkBool32 mutableComparisonSamplers + VkBool32 pointPolygons + VkBool32 samplerMipLodBias + VkBool32 separateStencilMaskRef + VkBool32 shaderSampleRateInterpolationFunctions + VkBool32 tessellationIsolines + VkBool32 tessellationPointMode + VkBool32 triangleFans + VkBool32 vertexAttributeAccessBeyondStride + + + VkStructureType sType + void* pNext + uint32_t minVertexInputBindingStrideAlignment + + + VkStructureType sType + void* pNext + VkBool32 formatA4R4G4B4 + VkBool32 formatA4B4G4R4 + + + VkStructureType sType + void* pNext + VkBool32 subpassShading + + + VkStructureType sType + void* pNext + VkBool32 clustercullingShader + VkBool32 multiviewClusterCullingShader + + + VkStructureType sType + void* pNext + VkBool32 clusterShadingRate + + + VkStructureType sType + const void* pNext + VkDeviceSize srcOffsetSpecified in bytes + VkDeviceSize dstOffsetSpecified in bytes + VkDeviceSize sizeSpecified in bytes + + + + VkStructureType sType + const void* pNext + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffsetSpecified in pixels for both compressed and uncompressed images + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffsetSpecified in pixels for both compressed and uncompressed images + VkExtent3D extentSpecified in pixels for both compressed and uncompressed images + + + + VkStructureType sType + const void* pNext + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffsets[2]Specified in pixels for both compressed and uncompressed images + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffsets[2]Specified in pixels for both compressed and uncompressed images + + + + VkStructureType sType + const void* pNext + VkDeviceSize bufferOffsetSpecified in bytes + uint32_t bufferRowLengthSpecified in texels + uint32_t bufferImageHeight + VkImageSubresourceLayers imageSubresource + VkOffset3D imageOffsetSpecified in pixels for both compressed and uncompressed images + VkExtent3D imageExtentSpecified in pixels for both compressed and uncompressed images + + + + VkStructureType sType + const void* pNext + VkImageSubresourceLayers srcSubresource + VkOffset3D srcOffset + VkImageSubresourceLayers dstSubresource + VkOffset3D dstOffset + VkExtent3D extent + + + + VkStructureType sType + const void* pNext + VkBuffer srcBuffer + VkBuffer dstBuffer + uint32_t regionCount + const VkBufferCopy2* pRegions + + + + VkStructureType sType + const void* pNext + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageCopy2* pRegions + + + + VkStructureType sType + const void* pNext + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageBlit2* pRegions + VkFilter filter + + + + VkStructureType sType + const void* pNext + VkBuffer srcBuffer + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkBufferImageCopy2* pRegions + + + + VkStructureType sType + const void* pNext + VkImage srcImage + VkImageLayout srcImageLayout + VkBuffer dstBuffer + uint32_t regionCount + const VkBufferImageCopy2* pRegions + + + + VkStructureType sType + const void* pNext + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageResolve2* pRegions + + + + VkStructureType sType + void* pNext + VkBool32 shaderImageInt64Atomics + VkBool32 sparseImageInt64Atomics + + + VkStructureType sType + const void* pNext + const VkAttachmentReference2* pFragmentShadingRateAttachment + VkExtent2D shadingRateAttachmentTexelSize + + + VkStructureType sType + const void* pNext + VkExtent2D fragmentSize + VkFragmentShadingRateCombinerOpKHR combinerOps[2] + + + VkStructureType sType + void* pNext + VkBool32 pipelineFragmentShadingRate + VkBool32 primitiveFragmentShadingRate + VkBool32 attachmentFragmentShadingRate + + + VkStructureType sType + void* pNext + VkExtent2D minFragmentShadingRateAttachmentTexelSize + VkExtent2D maxFragmentShadingRateAttachmentTexelSize + uint32_t maxFragmentShadingRateAttachmentTexelSizeAspectRatio + VkBool32 primitiveFragmentShadingRateWithMultipleViewports + VkBool32 layeredShadingRateAttachments + VkBool32 fragmentShadingRateNonTrivialCombinerOps + VkExtent2D maxFragmentSize + uint32_t maxFragmentSizeAspectRatio + uint32_t maxFragmentShadingRateCoverageSamples + VkSampleCountFlagBits maxFragmentShadingRateRasterizationSamples + VkBool32 fragmentShadingRateWithShaderDepthStencilWrites + VkBool32 fragmentShadingRateWithSampleMask + VkBool32 fragmentShadingRateWithShaderSampleMask + VkBool32 fragmentShadingRateWithConservativeRasterization + VkBool32 fragmentShadingRateWithFragmentShaderInterlock + VkBool32 fragmentShadingRateWithCustomSampleLocations + VkBool32 fragmentShadingRateStrictMultiplyCombiner + + + VkStructureType sType + void* pNext + VkSampleCountFlags sampleCounts + VkExtent2D fragmentSize + + + VkStructureType sType + void* pNext + VkBool32 shaderTerminateInvocation + + + + VkStructureType sType + void* pNext + VkBool32 fragmentShadingRateEnums + VkBool32 supersampleFragmentShadingRates + VkBool32 noInvocationFragmentShadingRates + + + VkStructureType sType + void* pNext + VkSampleCountFlagBits maxFragmentShadingRateInvocationCount + + + VkStructureType sType + const void* pNext + VkFragmentShadingRateTypeNV shadingRateType + VkFragmentShadingRateNV shadingRate + VkFragmentShadingRateCombinerOpKHR combinerOps[2] + + + VkStructureType sType + const void* pNext + VkDeviceSize accelerationStructureSize + VkDeviceSize updateScratchSize + VkDeviceSize buildScratchSize + + + VkStructureType sType + void* pNext + VkBool32 image2DViewOf3D + VkBool32 sampler2DViewOf3D + + + VkStructureType sType + void* pNext + VkBool32 imageSlicedViewOf3D + + + VkStructureType sType + void* pNext + VkBool32 attachmentFeedbackLoopDynamicState + + + VkStructureType sType + void* pNext + VkBool32 legacyVertexAttributes + + + VkStructureType sType + void* pNext + VkBool32 nativeUnalignedPerformance + + + VkStructureType sType + void* pNext + VkBool32 mutableDescriptorType + + + + uint32_t descriptorTypeCount + const VkDescriptorType* pDescriptorTypes + + + + VkStructureType sType + const void* pNext + uint32_t mutableDescriptorTypeListCount + const VkMutableDescriptorTypeListEXT* pMutableDescriptorTypeLists + + + + VkStructureType sType + void* pNext + VkBool32 depthClipControl + + + VkStructureType sType + void* pNext + VkBool32 zeroInitializeDeviceMemory + + + VkStructureType sType + void* pNext + VkBool32 deviceGeneratedCommands + VkBool32 dynamicGeneratedPipelineLayout + + + VkStructureType sType + void* pNext + uint32_t maxIndirectPipelineCount + uint32_t maxIndirectShaderObjectCount + uint32_t maxIndirectSequenceCount + uint32_t maxIndirectCommandsTokenCount + uint32_t maxIndirectCommandsTokenOffset + uint32_t maxIndirectCommandsIndirectStride + VkIndirectCommandsInputModeFlagsEXT supportedIndirectCommandsInputModes + VkShaderStageFlags supportedIndirectCommandsShaderStages + VkShaderStageFlags supportedIndirectCommandsShaderStagesPipelineBinding + VkShaderStageFlags supportedIndirectCommandsShaderStagesShaderBinding + VkBool32 deviceGeneratedCommandsTransformFeedback + VkBool32 deviceGeneratedCommandsMultiDrawIndirectCount + + + VkStructureType sType + void* pNext + VkPipeline pipeline + + + VkStructureType sType + void* pNext + uint32_t shaderCount + const VkShaderEXT* pShaders + + + VkStructureType sType + const void* pNext + VkIndirectExecutionSetEXT indirectExecutionSet + VkIndirectCommandsLayoutEXT indirectCommandsLayout + uint32_t maxSequenceCount + uint32_t maxDrawCount + + + VkStructureType sType + const void* pNext + VkPipeline initialPipeline + uint32_t maxPipelineCount + + + VkStructureType sType + const void* pNext + uint32_t setLayoutCount + const VkDescriptorSetLayout* pSetLayouts + + + VkStructureType sType + const void* pNext + uint32_t shaderCount + const VkShaderEXT* pInitialShaders + const VkIndirectExecutionSetShaderLayoutInfoEXT* pSetLayoutInfos + uint32_t maxShaderCount + uint32_t pushConstantRangeCount + const VkPushConstantRange* pPushConstantRanges + + + const VkIndirectExecutionSetPipelineInfoEXT* pPipelineInfo + const VkIndirectExecutionSetShaderInfoEXT* pShaderInfo + + + VkStructureType sType + const void* pNext + VkIndirectExecutionSetInfoTypeEXT type + VkIndirectExecutionSetInfoEXT info + + + VkStructureType sType + const void* pNext + VkShaderStageFlags shaderStages + VkIndirectExecutionSetEXT indirectExecutionSet + VkIndirectCommandsLayoutEXT indirectCommandsLayout + VkDeviceAddress indirectAddress + VkDeviceSize indirectAddressSize + VkDeviceAddress preprocessAddress + VkDeviceSize preprocessSize + uint32_t maxSequenceCount + VkDeviceAddress sequenceCountAddress + uint32_t maxDrawCount + + + VkStructureType sType + const void* pNext + uint32_t index + VkPipeline pipeline + + + VkStructureType sType + const void* pNext + uint32_t index + VkShaderEXT shader + + + VkStructureType sType + const void* pNext + VkIndirectCommandsLayoutUsageFlagsEXT flags + VkShaderStageFlags shaderStages + uint32_t indirectStride + VkPipelineLayout pipelineLayout + uint32_t tokenCount + const VkIndirectCommandsLayoutTokenEXT* pTokens + + + VkStructureType sType + const void* pNext + VkIndirectCommandsTokenTypeEXT type + VkIndirectCommandsTokenDataEXT data + uint32_t offset + + + VkDeviceAddress bufferAddress + uint32_t stride + uint32_t commandCount + + + uint32_t vertexBindingUnit + + + VkDeviceAddress bufferAddress + uint32_t size + uint32_t stride + + + VkIndirectCommandsInputModeFlagBitsEXT mode + + + VkDeviceAddress bufferAddress + uint32_t size + VkIndexType indexType + + + VkPushConstantRange updateRange + + + VkIndirectExecutionSetInfoTypeEXT type + VkShaderStageFlags shaderStages + + + const VkIndirectCommandsPushConstantTokenEXT* pPushConstant + const VkIndirectCommandsVertexBufferTokenEXT* pVertexBuffer + const VkIndirectCommandsIndexBufferTokenEXT* pIndexBuffer + const VkIndirectCommandsExecutionSetTokenEXT* pExecutionSet + + + VkStructureType sType + const void* pNext + VkBool32 negativeOneToOne + + + VkStructureType sType + void* pNext + VkBool32 depthClampControl + + + VkStructureType sType + const void* pNext + VkDepthClampModeEXT depthClampMode + const VkDepthClampRangeEXT* pDepthClampRange + + + VkStructureType sType + void* pNext + VkBool32 vertexInputDynamicState + + + VkStructureType sType + void* pNext + VkBool32 externalMemoryRDMA + + + VkStructureType sType + void* pNext + VkBool32 shaderRelaxedExtendedInstruction + + + VkStructureType sType + void* pNext + uint32_t binding + uint32_t stride + VkVertexInputRate inputRate + uint32_t divisor + + + VkStructureType sType + void* pNext + uint32_t locationlocation of the shader vertex attrib + uint32_t bindingVertex buffer binding id + VkFormat formatformat of source data + uint32_t offsetOffset of first element in bytes from base of vertex + + + VkStructureType sType + void* pNext + VkBool32 colorWriteEnable + + + VkStructureType sType + const void* pNext + uint32_t attachmentCount# of pAttachments + const VkBool32* pColorWriteEnables + + + VkStructureType sType + const void* pNext + VkPipelineStageFlags2 srcStageMask + VkAccessFlags2 srcAccessMask + VkPipelineStageFlags2 dstStageMask + VkAccessFlags2 dstAccessMask + + + + VkStructureType sType + const void* pNext + VkPipelineStageFlags2 srcStageMask + VkAccessFlags2 srcAccessMask + VkPipelineStageFlags2 dstStageMask + VkAccessFlags2 dstAccessMask + VkImageLayout oldLayout + VkImageLayout newLayout + uint32_t srcQueueFamilyIndex + uint32_t dstQueueFamilyIndex + VkImage image + VkImageSubresourceRange subresourceRange + + + + VkStructureType sType + const void* pNext + VkPipelineStageFlags2 srcStageMask + VkAccessFlags2 srcAccessMask + VkPipelineStageFlags2 dstStageMask + VkAccessFlags2 dstAccessMask + uint32_t srcQueueFamilyIndex + uint32_t dstQueueFamilyIndex + VkBuffer buffer + VkDeviceSize offset + VkDeviceSize size + + + + VkStructureType sType + const void* pNext + VkAccessFlags3KHR srcAccessMask3 + VkAccessFlags3KHR dstAccessMask3 + + + VkStructureType sType + const void* pNext + VkDependencyFlags dependencyFlags + uint32_t memoryBarrierCount + const VkMemoryBarrier2* pMemoryBarriers + uint32_t bufferMemoryBarrierCount + const VkBufferMemoryBarrier2* pBufferMemoryBarriers + uint32_t imageMemoryBarrierCount + const VkImageMemoryBarrier2* pImageMemoryBarriers + + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + uint64_t value + VkPipelineStageFlags2 stageMask + uint32_t deviceIndex + + + + VkStructureType sType + const void* pNext + VkCommandBuffer commandBuffer + uint32_t deviceMask + + + + VkStructureType sType + const void* pNext + VkSubmitFlags flags + uint32_t waitSemaphoreInfoCount + const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos + uint32_t commandBufferInfoCount + const VkCommandBufferSubmitInfo* pCommandBufferInfos + uint32_t signalSemaphoreInfoCount + const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos + + + + VkStructureType sType + void* pNext + VkPipelineStageFlags2 checkpointExecutionStageMask + + + VkStructureType sType + void* pNext + VkPipelineStageFlags2 stage + void* pCheckpointMarker + + + VkStructureType sType + void* pNext + VkBool32 synchronization2 + + + + VkStructureType sType + void* pNext + VkBool32 unifiedImageLayouts + VkBool32 unifiedImageLayoutsVideo + + + VkStructureType sType + void* pNext + VkBool32 hostImageCopy + + + + VkStructureType sType + void* pNext + uint32_t copySrcLayoutCount + VkImageLayout* pCopySrcLayouts + uint32_t copyDstLayoutCount + VkImageLayout* pCopyDstLayouts + uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE] + VkBool32 identicalMemoryTypeRequirements + + + + VkStructureType sType + const void* pNext + const void* pHostPointer + uint32_t memoryRowLengthSpecified in texels + uint32_t memoryImageHeight + VkImageSubresourceLayers imageSubresource + VkOffset3D imageOffset + VkExtent3D imageExtent + + + + VkStructureType sType + const void* pNext + void* pHostPointer + uint32_t memoryRowLengthSpecified in texels + uint32_t memoryImageHeight + VkImageSubresourceLayers imageSubresource + VkOffset3D imageOffset + VkExtent3D imageExtent + + + + VkStructureType sType + const void* pNext + VkHostImageCopyFlags flags + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkMemoryToImageCopy* pRegions + + + + VkStructureType sType + const void* pNext + VkHostImageCopyFlags flags + VkImage srcImage + VkImageLayout srcImageLayout + uint32_t regionCount + const VkImageToMemoryCopy* pRegions + + + + VkStructureType sType + const void* pNext + VkHostImageCopyFlags flags + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageCopy2* pRegions + + + + VkStructureType sType + const void* pNext + VkImage image + VkImageLayout oldLayout + VkImageLayout newLayout + VkImageSubresourceRange subresourceRange + + + + VkStructureType sType + void* pNext + VkDeviceSize sizeSpecified in bytes + + + + VkStructureType sType + void* pNext + VkBool32 optimalDeviceAccessSpecifies if device access is optimal + VkBool32 identicalMemoryLayoutSpecifies if memory layout is identical + + + + VkStructureType sType + void* pNext + VkBool32 deviceNoDynamicHostAllocations + VkBool32 deviceDestroyFreesMemory + VkBool32 commandPoolMultipleCommandBuffersRecording + VkBool32 commandPoolResetCommandBuffer + VkBool32 commandBufferSimultaneousUse + VkBool32 secondaryCommandBufferNullOrImagelessFramebuffer + VkBool32 recycleDescriptorSetMemory + VkBool32 recyclePipelineMemory + uint32_t maxRenderPassSubpasses + uint32_t maxRenderPassDependencies + uint32_t maxSubpassInputAttachments + uint32_t maxSubpassPreserveAttachments + uint32_t maxFramebufferAttachments + uint32_t maxDescriptorSetLayoutBindings + uint32_t maxQueryFaultCount + uint32_t maxCallbackFaultCount + uint32_t maxCommandPoolCommandBuffers + VkDeviceSize maxCommandBufferSize + + + VkStructureType sType + const void* pNext + VkDeviceSize poolEntrySize + uint32_t poolEntryCount + + + VkStructureType sType + const void* pNext + uint32_t pipelineCacheCreateInfoCount + const VkPipelineCacheCreateInfo* pPipelineCacheCreateInfos + uint32_t pipelinePoolSizeCount + const VkPipelinePoolSize* pPipelinePoolSizes + uint32_t semaphoreRequestCount + uint32_t commandBufferRequestCount + uint32_t fenceRequestCount + uint32_t deviceMemoryRequestCount + uint32_t bufferRequestCount + uint32_t imageRequestCount + uint32_t eventRequestCount + uint32_t queryPoolRequestCount + uint32_t bufferViewRequestCount + uint32_t imageViewRequestCount + uint32_t layeredImageViewRequestCount + uint32_t pipelineCacheRequestCount + uint32_t pipelineLayoutRequestCount + uint32_t renderPassRequestCount + uint32_t graphicsPipelineRequestCount + uint32_t computePipelineRequestCount + uint32_t descriptorSetLayoutRequestCount + uint32_t samplerRequestCount + uint32_t descriptorPoolRequestCount + uint32_t descriptorSetRequestCount + uint32_t framebufferRequestCount + uint32_t commandPoolRequestCount + uint32_t samplerYcbcrConversionRequestCount + uint32_t surfaceRequestCount + uint32_t swapchainRequestCount + uint32_t displayModeRequestCount + uint32_t subpassDescriptionRequestCount + uint32_t attachmentDescriptionRequestCount + uint32_t descriptorSetLayoutBindingRequestCount + uint32_t descriptorSetLayoutBindingLimit + uint32_t maxImageViewMipLevels + uint32_t maxImageViewArrayLayers + uint32_t maxLayeredImageViewMipLevels + uint32_t maxOcclusionQueriesPerPool + uint32_t maxPipelineStatisticsQueriesPerPool + uint32_t maxTimestampQueriesPerPool + uint32_t maxImmutableSamplersPerDescriptorSetLayout + + + VkStructureType sType + const void* pNext + VkDeviceSize commandPoolReservedSize + uint32_t commandPoolMaxCommandBuffers + + + VkStructureType sType + void* pNext + VkDeviceSize commandPoolAllocated + VkDeviceSize commandPoolReservedSize + VkDeviceSize commandBufferAllocated + + + VkStructureType sType + void* pNext + VkBool32 shaderAtomicInstructions + + + VkStructureType sType + void* pNext + VkBool32 primitivesGeneratedQuery + VkBool32 primitivesGeneratedQueryWithRasterizerDiscard + VkBool32 primitivesGeneratedQueryWithNonZeroStreams + + + VkStructureType sType + void* pNext + VkBool32 legacyDithering + + + VkStructureType sType + void* pNext + VkBool32 multisampledRenderToSingleSampled + + + VkStructureType sType + void* pNext + VkBool32 presentId2Supported + + + VkStructureType sType + void* pNext + VkBool32 presentWait2Supported + + + VkStructureType sType + void* pNext + VkBool32 optimal + + + VkStructureType sType + const void* pNext + VkBool32 multisampledRenderToSingleSampledEnable + VkSampleCountFlagBits rasterizationSamples + + + VkStructureType sType + void* pNext + VkBool32 pipelineProtectedAccess + + + + VkStructureType sType + void* pNext + VkVideoCodecOperationFlagsKHR videoCodecOperations + + + VkStructureType sType + void* pNext + VkBool32 queryResultStatusSupport + + + VkStructureType sType + const void* pNext + uint32_t profileCount + const VkVideoProfileInfoKHR* pProfiles + + + VkStructureType sType + const void* pNext + VkImageUsageFlags imageUsage + + + VkStructureType sType + void* pNext + VkFormat format + VkComponentMapping componentMapping + VkImageCreateFlags imageCreateFlags + VkImageType imageType + VkImageTiling imageTiling + VkImageUsageFlags imageUsageFlags + + + VkStructureType sType + void* pNext + VkExtent2D maxQuantizationMapExtent + + + VkStructureType sType + void* pNext + int32_t minQpDelta + int32_t maxQpDelta + + + VkStructureType sType + void* pNext + int32_t minQpDelta + int32_t maxQpDelta + + + VkStructureType sType + void* pNext + int32_t minQIndexDelta + int32_t maxQIndexDelta + + + VkStructureType sType + void* pNext + VkExtent2D quantizationMapTexelSize + + + VkStructureType sType + void* pNext + VkVideoEncodeH265CtbSizeFlagsKHR compatibleCtbSizes + + + VkStructureType sType + void* pNext + VkVideoEncodeAV1SuperblockSizeFlagsKHR compatibleSuperblockSizes + + + VkStructureType sType + const void* pNext + VkVideoCodecOperationFlagBitsKHR videoCodecOperation + VkVideoChromaSubsamplingFlagsKHR chromaSubsampling + VkVideoComponentBitDepthFlagsKHR lumaBitDepth + VkVideoComponentBitDepthFlagsKHR chromaBitDepth + + + VkStructureType sType + void* pNext + VkVideoCapabilityFlagsKHR flags + VkDeviceSize minBitstreamBufferOffsetAlignment + VkDeviceSize minBitstreamBufferSizeAlignment + VkExtent2D pictureAccessGranularity + VkExtent2D minCodedExtent + VkExtent2D maxCodedExtent + uint32_t maxDpbSlots + uint32_t maxActiveReferencePictures + VkExtensionProperties stdHeaderVersion + + + VkStructureType sType + void* pNext + uint32_t memoryBindIndex + VkMemoryRequirements memoryRequirements + + + VkStructureType sType + const void* pNext + uint32_t memoryBindIndex + VkDeviceMemory memory + VkDeviceSize memoryOffset + VkDeviceSize memorySize + + + VkStructureType sType + const void* pNext + VkOffset2D codedOffsetThe offset to be used for the picture resource, currently only used in field mode + VkExtent2D codedExtentThe extent to be used for the picture resource + uint32_t baseArrayLayerThe first array layer to be accessed for the Decode or Encode Operations + VkImageView imageViewBindingThe ImageView binding of the resource + + + VkStructureType sType + const void* pNext + int32_t slotIndexThe reference slot index + const VkVideoPictureResourceInfoKHR* pPictureResourceThe reference picture resource + + + VkStructureType sType + void* pNext + VkVideoDecodeCapabilityFlagsKHR flags + + + VkStructureType sType + const void* pNext + VkVideoDecodeUsageFlagsKHR videoUsageHints + + + VkStructureType sType + const void* pNext + VkVideoDecodeFlagsKHR flags + VkBuffer srcBuffer + VkDeviceSize srcBufferOffset + VkDeviceSize srcBufferRange + VkVideoPictureResourceInfoKHR dstPictureResource + const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot + uint32_t referenceSlotCount + const VkVideoReferenceSlotInfoKHR* pReferenceSlots + + + VkStructureType sType + void* pNext + VkBool32 videoMaintenance1 + + + VkStructureType sType + void* pNext + VkBool32 videoMaintenance2 + + + VkStructureType sType + const void* pNext + VkQueryPool queryPool + uint32_t firstQuery + uint32_t queryCount + + Video Decode Codec Standard specific structures + #include "vk_video/vulkan_video_codec_h264std.h" + + + #include "vk_video/vulkan_video_codec_h264std_decode.h" + + + + VkStructureType sType + const void* pNext + StdVideoH264ProfileIdc stdProfileIdc + VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout + + + VkStructureType sType + void* pNext + StdVideoH264LevelIdc maxLevelIdc + VkOffset2D fieldOffsetGranularity + + + + + VkStructureType sType + const void* pNext + uint32_t stdSPSCount + const StdVideoH264SequenceParameterSet* pStdSPSs + uint32_t stdPPSCount + const StdVideoH264PictureParameterSet* pStdPPSsList of Picture Parameters associated with the spsStd, above + + + VkStructureType sType + const void* pNext + uint32_t maxStdSPSCount + uint32_t maxStdPPSCount + const VkVideoDecodeH264SessionParametersAddInfoKHR* pParametersAddInfo + + + VkStructureType sType + const void* pNext + const StdVideoH264SequenceParameterSet* pStdSPS + const StdVideoH264PictureParameterSet* pStdPPS + + + VkStructureType sType + const void* pNext + const StdVideoDecodeH264PictureInfo* pStdPictureInfo + uint32_t sliceCount + const uint32_t* pSliceOffsets + + + VkStructureType sType + const void* pNext + const StdVideoDecodeH264ReferenceInfo* pStdReferenceInfo + + #include "vk_video/vulkan_video_codec_h265std.h" + + + + + + #include "vk_video/vulkan_video_codec_h265std_decode.h" + + + + VkStructureType sType + const void* pNext + StdVideoH265ProfileIdc stdProfileIdc + + + VkStructureType sType + void* pNext + StdVideoH265LevelIdc maxLevelIdc + + + VkStructureType sType + const void* pNext + uint32_t stdVPSCount + const StdVideoH265VideoParameterSet* pStdVPSs + uint32_t stdSPSCount + const StdVideoH265SequenceParameterSet* pStdSPSs + uint32_t stdPPSCount + const StdVideoH265PictureParameterSet* pStdPPSsList of Picture Parameters associated with the spsStd, above + + + VkStructureType sType + const void* pNext + uint32_t maxStdVPSCount + uint32_t maxStdSPSCount + uint32_t maxStdPPSCount + const VkVideoDecodeH265SessionParametersAddInfoKHR* pParametersAddInfo + + + VkStructureType sType + const void* pNext + const StdVideoH265VideoParameterSet* pStdVPS + const StdVideoH265SequenceParameterSet* pStdSPS + const StdVideoH265PictureParameterSet* pStdPPS + + + VkStructureType sType + const void* pNext + const StdVideoDecodeH265PictureInfo* pStdPictureInfo + uint32_t sliceSegmentCount + const uint32_t* pSliceSegmentOffsets + + + VkStructureType sType + const void* pNext + const StdVideoDecodeH265ReferenceInfo* pStdReferenceInfo + + #include "vk_video/vulkan_video_codec_vp9std.h" + + + #include "vk_video/vulkan_video_codec_vp9std_decode.h" + + + VkStructureType sType + void* pNext + VkBool32 videoDecodeVP9 + + + VkStructureType sType + const void* pNext + StdVideoVP9Profile stdProfile + + + VkStructureType sType + void* pNext + StdVideoVP9Level maxLevel + + + VkStructureType sType + const void* pNext + const StdVideoDecodeVP9PictureInfo* pStdPictureInfo + int32_t referenceNameSlotIndices[VK_MAX_VIDEO_VP9_REFERENCES_PER_FRAME_KHR] + uint32_t uncompressedHeaderOffset + uint32_t compressedHeaderOffset + uint32_t tilesOffset + + #include "vk_video/vulkan_video_codec_av1std.h" + + + + #include "vk_video/vulkan_video_codec_av1std_decode.h" + + + + VkStructureType sType + const void* pNext + StdVideoAV1Profile stdProfile + VkBool32 filmGrainSupport + + + VkStructureType sType + void* pNext + StdVideoAV1Level maxLevel + + + VkStructureType sType + const void* pNext + const StdVideoAV1SequenceHeader* pStdSequenceHeader + + + VkStructureType sType + const void* pNext + const StdVideoAV1SequenceHeader* pStdSequenceHeader + + + VkStructureType sType + const void* pNext + const StdVideoDecodeAV1PictureInfo* pStdPictureInfo + int32_t referenceNameSlotIndices[VK_MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR] + uint32_t frameHeaderOffset + uint32_t tileCount + const uint32_t* pTileOffsets + const uint32_t* pTileSizes + + + VkStructureType sType + const void* pNext + const StdVideoDecodeAV1ReferenceInfo* pStdReferenceInfo + + + VkStructureType sType + const void* pNext + uint32_t queueFamilyIndex + VkVideoSessionCreateFlagsKHR flags + const VkVideoProfileInfoKHR* pVideoProfile + VkFormat pictureFormat + VkExtent2D maxCodedExtent + VkFormat referencePictureFormat + uint32_t maxDpbSlots + uint32_t maxActiveReferencePictures + const VkExtensionProperties* pStdHeaderVersion + + + VkStructureType sType + const void* pNext + VkVideoSessionParametersCreateFlagsKHR flags + VkVideoSessionParametersKHR videoSessionParametersTemplate + VkVideoSessionKHR videoSession + + + VkStructureType sType + const void* pNext + uint32_t updateSequenceCount + + + VkStructureType sType + const void* pNext + VkVideoSessionParametersKHR videoSessionParameters + + + VkStructureType sType + void* pNext + VkBool32 hasOverrides + + + VkStructureType sType + const void* pNext + VkVideoBeginCodingFlagsKHR flags + VkVideoSessionKHR videoSession + VkVideoSessionParametersKHR videoSessionParameters + uint32_t referenceSlotCount + const VkVideoReferenceSlotInfoKHR* pReferenceSlots + + + VkStructureType sType + const void* pNext + VkVideoEndCodingFlagsKHR flags + + + VkStructureType sType + const void* pNext + VkVideoCodingControlFlagsKHR flags + + + VkStructureType sType + const void* pNext + VkVideoEncodeUsageFlagsKHR videoUsageHints + VkVideoEncodeContentFlagsKHR videoContentHints + VkVideoEncodeTuningModeKHR tuningMode + + + VkStructureType sType + const void* pNext + VkVideoEncodeFlagsKHR flags + VkBuffer dstBuffer + VkDeviceSize dstBufferOffset + VkDeviceSize dstBufferRange + VkVideoPictureResourceInfoKHR srcPictureResource + const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot + uint32_t referenceSlotCount + const VkVideoReferenceSlotInfoKHR* pReferenceSlots + uint32_t precedingExternallyEncodedBytes + + + VkStructureType sType + const void* pNext + VkImageView quantizationMap + VkExtent2D quantizationMapExtent + + + VkStructureType sType + const void* pNext + VkExtent2D quantizationMapTexelSize + + + VkStructureType sType + void* pNext + VkBool32 videoEncodeQuantizationMap + + + VkStructureType sType + const void* pNext + VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags + + + VkStructureType sType + const void* pNext + uint32_t qualityLevel + + + VkStructureType sType + const void* pNext + const VkVideoProfileInfoKHR* pVideoProfile + uint32_t qualityLevel + + + VkStructureType sType + void* pNext + VkVideoEncodeRateControlModeFlagBitsKHR preferredRateControlMode + uint32_t preferredRateControlLayerCount + + + VkStructureType sType + const void* pNext + VkVideoEncodeRateControlFlagsKHR flags + VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode + uint32_t layerCount + const VkVideoEncodeRateControlLayerInfoKHR* pLayers + uint32_t virtualBufferSizeInMs + uint32_t initialVirtualBufferSizeInMs + + + VkStructureType sType + const void* pNext + uint64_t averageBitrate + uint64_t maxBitrate + uint32_t frameRateNumerator + uint32_t frameRateDenominator + + + VkStructureType sType + void* pNext + VkVideoEncodeCapabilityFlagsKHR flags + VkVideoEncodeRateControlModeFlagsKHR rateControlModes + uint32_t maxRateControlLayers + uint64_t maxBitrate + uint32_t maxQualityLevels + VkExtent2D encodeInputPictureGranularity + VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags + + + VkStructureType sType + void* pNext + VkVideoEncodeH264CapabilityFlagsKHR flags + StdVideoH264LevelIdc maxLevelIdc + uint32_t maxSliceCount + uint32_t maxPPictureL0ReferenceCount + uint32_t maxBPictureL0ReferenceCount + uint32_t maxL1ReferenceCount + uint32_t maxTemporalLayerCount + VkBool32 expectDyadicTemporalLayerPattern + int32_t minQp + int32_t maxQp + VkBool32 prefersGopRemainingFrames + VkBool32 requiresGopRemainingFrames + VkVideoEncodeH264StdFlagsKHR stdSyntaxFlags + + + VkStructureType sType + void* pNext + VkVideoEncodeH264RateControlFlagsKHR preferredRateControlFlags + uint32_t preferredGopFrameCount + uint32_t preferredIdrPeriod + uint32_t preferredConsecutiveBFrameCount + uint32_t preferredTemporalLayerCount + VkVideoEncodeH264QpKHR preferredConstantQp + uint32_t preferredMaxL0ReferenceCount + uint32_t preferredMaxL1ReferenceCount + VkBool32 preferredStdEntropyCodingModeFlag + + #include "vk_video/vulkan_video_codec_h264std_encode.h" + + + + + VkStructureType sType + const void* pNext + VkBool32 useMaxLevelIdc + StdVideoH264LevelIdc maxLevelIdc + + + VkStructureType sType + const void* pNext + uint32_t stdSPSCount + const StdVideoH264SequenceParameterSet* pStdSPSs + uint32_t stdPPSCount + const StdVideoH264PictureParameterSet* pStdPPSsList of Picture Parameters associated with the spsStd, above + + + VkStructureType sType + const void* pNext + uint32_t maxStdSPSCount + uint32_t maxStdPPSCount + const VkVideoEncodeH264SessionParametersAddInfoKHR* pParametersAddInfo + + + VkStructureType sType + const void* pNext + VkBool32 writeStdSPS + VkBool32 writeStdPPS + uint32_t stdSPSId + uint32_t stdPPSId + + + VkStructureType sType + void* pNext + VkBool32 hasStdSPSOverrides + VkBool32 hasStdPPSOverrides + + + VkStructureType sType + const void* pNext + const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo + + + VkStructureType sType + const void* pNext + uint32_t naluSliceEntryCount + const VkVideoEncodeH264NaluSliceInfoKHR* pNaluSliceEntries + const StdVideoEncodeH264PictureInfo* pStdPictureInfo + VkBool32 generatePrefixNalu + + + VkStructureType sType + const void* pNext + StdVideoH264ProfileIdc stdProfileIdc + + + VkStructureType sType + const void* pNext + int32_t constantQp + const StdVideoEncodeH264SliceHeader* pStdSliceHeader + + + VkStructureType sType + const void* pNext + VkVideoEncodeH264RateControlFlagsKHR flags + uint32_t gopFrameCount + uint32_t idrPeriod + uint32_t consecutiveBFrameCount + uint32_t temporalLayerCount + + + int32_t qpI + int32_t qpP + int32_t qpB + + + uint32_t frameISize + uint32_t framePSize + uint32_t frameBSize + + + VkStructureType sType + const void* pNext + VkBool32 useGopRemainingFrames + uint32_t gopRemainingI + uint32_t gopRemainingP + uint32_t gopRemainingB + + + VkStructureType sType + const void* pNext + VkBool32 useMinQp + VkVideoEncodeH264QpKHR minQp + VkBool32 useMaxQp + VkVideoEncodeH264QpKHR maxQp + VkBool32 useMaxFrameSize + VkVideoEncodeH264FrameSizeKHR maxFrameSize + + + VkStructureType sType + void* pNext + VkVideoEncodeH265CapabilityFlagsKHR flags + StdVideoH265LevelIdc maxLevelIdc + uint32_t maxSliceSegmentCount + VkExtent2D maxTiles + VkVideoEncodeH265CtbSizeFlagsKHR ctbSizes + VkVideoEncodeH265TransformBlockSizeFlagsKHR transformBlockSizes + uint32_t maxPPictureL0ReferenceCount + uint32_t maxBPictureL0ReferenceCount + uint32_t maxL1ReferenceCount + uint32_t maxSubLayerCount + VkBool32 expectDyadicTemporalSubLayerPattern + int32_t minQp + int32_t maxQp + VkBool32 prefersGopRemainingFrames + VkBool32 requiresGopRemainingFrames + VkVideoEncodeH265StdFlagsKHR stdSyntaxFlags + + + VkStructureType sType + void* pNext + VkVideoEncodeH265RateControlFlagsKHR preferredRateControlFlags + uint32_t preferredGopFrameCount + uint32_t preferredIdrPeriod + uint32_t preferredConsecutiveBFrameCount + uint32_t preferredSubLayerCount + VkVideoEncodeH265QpKHR preferredConstantQp + uint32_t preferredMaxL0ReferenceCount + uint32_t preferredMaxL1ReferenceCount + + #include "vk_video/vulkan_video_codec_h265std_encode.h" + + + + + VkStructureType sType + const void* pNext + VkBool32 useMaxLevelIdc + StdVideoH265LevelIdc maxLevelIdc + + + VkStructureType sType + const void* pNext + uint32_t stdVPSCount + const StdVideoH265VideoParameterSet* pStdVPSs + uint32_t stdSPSCount + const StdVideoH265SequenceParameterSet* pStdSPSs + uint32_t stdPPSCount + const StdVideoH265PictureParameterSet* pStdPPSsList of Picture Parameters associated with the spsStd, above + + + VkStructureType sType + const void* pNext + uint32_t maxStdVPSCount + uint32_t maxStdSPSCount + uint32_t maxStdPPSCount + const VkVideoEncodeH265SessionParametersAddInfoKHR* pParametersAddInfo + + + VkStructureType sType + const void* pNext + VkBool32 writeStdVPS + VkBool32 writeStdSPS + VkBool32 writeStdPPS + uint32_t stdVPSId + uint32_t stdSPSId + uint32_t stdPPSId + + + VkStructureType sType + void* pNext + VkBool32 hasStdVPSOverrides + VkBool32 hasStdSPSOverrides + VkBool32 hasStdPPSOverrides + + + VkStructureType sType + const void* pNext + uint32_t naluSliceSegmentEntryCount + const VkVideoEncodeH265NaluSliceSegmentInfoKHR* pNaluSliceSegmentEntries + const StdVideoEncodeH265PictureInfo* pStdPictureInfo + + + VkStructureType sType + const void* pNext + int32_t constantQp + const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader + + + VkStructureType sType + const void* pNext + VkVideoEncodeH265RateControlFlagsKHR flags + uint32_t gopFrameCount + uint32_t idrPeriod + uint32_t consecutiveBFrameCount + uint32_t subLayerCount + + + int32_t qpI + int32_t qpP + int32_t qpB + + + uint32_t frameISize + uint32_t framePSize + uint32_t frameBSize + + + VkStructureType sType + const void* pNext + VkBool32 useGopRemainingFrames + uint32_t gopRemainingI + uint32_t gopRemainingP + uint32_t gopRemainingB + + + VkStructureType sType + const void* pNext + VkBool32 useMinQp + VkVideoEncodeH265QpKHR minQp + VkBool32 useMaxQp + VkVideoEncodeH265QpKHR maxQp + VkBool32 useMaxFrameSize + VkVideoEncodeH265FrameSizeKHR maxFrameSize + + + VkStructureType sType + const void* pNext + StdVideoH265ProfileIdc stdProfileIdc + + + VkStructureType sType + const void* pNext + const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo + + + VkStructureType sType + void* pNext + VkVideoEncodeAV1CapabilityFlagsKHR flags + StdVideoAV1Level maxLevel + VkExtent2D codedPictureAlignment + VkExtent2D maxTiles + VkExtent2D minTileSize + VkExtent2D maxTileSize + VkVideoEncodeAV1SuperblockSizeFlagsKHR superblockSizes + uint32_t maxSingleReferenceCount + uint32_t singleReferenceNameMask + uint32_t maxUnidirectionalCompoundReferenceCount + uint32_t maxUnidirectionalCompoundGroup1ReferenceCount + uint32_t unidirectionalCompoundReferenceNameMask + uint32_t maxBidirectionalCompoundReferenceCount + uint32_t maxBidirectionalCompoundGroup1ReferenceCount + uint32_t maxBidirectionalCompoundGroup2ReferenceCount + uint32_t bidirectionalCompoundReferenceNameMask + uint32_t maxTemporalLayerCount + uint32_t maxSpatialLayerCount + uint32_t maxOperatingPoints + uint32_t minQIndex + uint32_t maxQIndex + VkBool32 prefersGopRemainingFrames + VkBool32 requiresGopRemainingFrames + VkVideoEncodeAV1StdFlagsKHR stdSyntaxFlags + + + VkStructureType sType + void* pNext + VkVideoEncodeAV1RateControlFlagsKHR preferredRateControlFlags + uint32_t preferredGopFrameCount + uint32_t preferredKeyFramePeriod + uint32_t preferredConsecutiveBipredictiveFrameCount + uint32_t preferredTemporalLayerCount + VkVideoEncodeAV1QIndexKHR preferredConstantQIndex + uint32_t preferredMaxSingleReferenceCount + uint32_t preferredSingleReferenceNameMask + uint32_t preferredMaxUnidirectionalCompoundReferenceCount + uint32_t preferredMaxUnidirectionalCompoundGroup1ReferenceCount + uint32_t preferredUnidirectionalCompoundReferenceNameMask + uint32_t preferredMaxBidirectionalCompoundReferenceCount + uint32_t preferredMaxBidirectionalCompoundGroup1ReferenceCount + uint32_t preferredMaxBidirectionalCompoundGroup2ReferenceCount + uint32_t preferredBidirectionalCompoundReferenceNameMask + + #include "vk_video/vulkan_video_codec_av1std_encode.h" + + + + + + + VkStructureType sType + void* pNext + VkBool32 videoEncodeAV1 + + + VkStructureType sType + const void* pNext + VkBool32 useMaxLevel + StdVideoAV1Level maxLevel + + + VkStructureType sType + const void* pNext + const StdVideoAV1SequenceHeader* pStdSequenceHeader + const StdVideoEncodeAV1DecoderModelInfo* pStdDecoderModelInfo + uint32_t stdOperatingPointCount + const StdVideoEncodeAV1OperatingPointInfo* pStdOperatingPoints + + + VkStructureType sType + const void* pNext + const StdVideoEncodeAV1ReferenceInfo* pStdReferenceInfo + + + VkStructureType sType + const void* pNext + VkVideoEncodeAV1PredictionModeKHR predictionMode + VkVideoEncodeAV1RateControlGroupKHR rateControlGroup + uint32_t constantQIndex + const StdVideoEncodeAV1PictureInfo* pStdPictureInfo + int32_t referenceNameSlotIndices[VK_MAX_VIDEO_AV1_REFERENCES_PER_FRAME_KHR] + VkBool32 primaryReferenceCdfOnly + VkBool32 generateObuExtensionHeader + + + VkStructureType sType + const void* pNext + StdVideoAV1Profile stdProfile + + + VkStructureType sType + const void* pNext + VkVideoEncodeAV1RateControlFlagsKHR flags + uint32_t gopFrameCount + uint32_t keyFramePeriod + uint32_t consecutiveBipredictiveFrameCount + uint32_t temporalLayerCount + + + uint32_t intraQIndex + uint32_t predictiveQIndex + uint32_t bipredictiveQIndex + + + uint32_t intraFrameSize + uint32_t predictiveFrameSize + uint32_t bipredictiveFrameSize + + + VkStructureType sType + const void* pNext + VkBool32 useGopRemainingFrames + uint32_t gopRemainingIntra + uint32_t gopRemainingPredictive + uint32_t gopRemainingBipredictive + + + VkStructureType sType + const void* pNext + VkBool32 useMinQIndex + VkVideoEncodeAV1QIndexKHR minQIndex + VkBool32 useMaxQIndex + VkVideoEncodeAV1QIndexKHR maxQIndex + VkBool32 useMaxFrameSize + VkVideoEncodeAV1FrameSizeKHR maxFrameSize + + + VkStructureType sType + void* pNext + VkBool32 inheritedViewportScissor2D + + + VkStructureType sType + const void* pNext + VkBool32 viewportScissor2D + uint32_t viewportDepthCount + const VkViewport* pViewportDepths + + + VkStructureType sType + void* pNext + VkBool32 ycbcr2plane444Formats + + + VkStructureType sType + void* pNext + VkBool32 provokingVertexLast + VkBool32 transformFeedbackPreservesProvokingVertex + + + VkStructureType sType + void* pNext + VkBool32 provokingVertexModePerPipeline + VkBool32 transformFeedbackPreservesTriangleFanProvokingVertex + + + VkStructureType sType + const void* pNext + VkProvokingVertexModeEXT provokingVertexMode + + + VkStructureType sType + void* pNext + VkVideoEncodeIntraRefreshModeFlagsKHR intraRefreshModes + uint32_t maxIntraRefreshCycleDuration + uint32_t maxIntraRefreshActiveReferencePictures + VkBool32 partitionIndependentIntraRefreshRegions + VkBool32 nonRectangularIntraRefreshRegions + + + VkStructureType sType + const void* pNext + VkVideoEncodeIntraRefreshModeFlagBitsKHR intraRefreshMode + + + VkStructureType sType + const void* pNext + uint32_t intraRefreshCycleDuration + uint32_t intraRefreshIndex + + + VkStructureType sType + const void* pNext + uint32_t dirtyIntraRefreshRegions + + + VkStructureType sType + void* pNext + VkBool32 videoEncodeIntraRefresh + + + VkStructureType sType + const void* pNext + size_t dataSize + const void* pData + + + VkStructureType sType + const void* pNext + VkBool32 use64bitTexturing + + + VkStructureType sType + const void* pNext + VkCuModuleNVX module + const char* pName + + + VkStructureType sType + const void* pNext + VkCuFunctionNVX function + uint32_t gridDimX + uint32_t gridDimY + uint32_t gridDimZ + uint32_t blockDimX + uint32_t blockDimY + uint32_t blockDimZ + uint32_t sharedMemBytes + size_t paramCount + const void* const * pParams + size_t extraCount + const void* const * pExtras + + + VkStructureType sType + void* pNext + VkBool32 descriptorBuffer + VkBool32 descriptorBufferCaptureReplay + VkBool32 descriptorBufferImageLayoutIgnored + VkBool32 descriptorBufferPushDescriptors + + + VkStructureType sType + void* pNext + VkBool32 combinedImageSamplerDescriptorSingleArray + VkBool32 bufferlessPushDescriptors + VkBool32 allowSamplerImageViewPostSubmitCreation + VkDeviceSize descriptorBufferOffsetAlignment + uint32_t maxDescriptorBufferBindings + uint32_t maxResourceDescriptorBufferBindings + uint32_t maxSamplerDescriptorBufferBindings + uint32_t maxEmbeddedImmutableSamplerBindings + uint32_t maxEmbeddedImmutableSamplers + size_t bufferCaptureReplayDescriptorDataSize + size_t imageCaptureReplayDescriptorDataSize + size_t imageViewCaptureReplayDescriptorDataSize + size_t samplerCaptureReplayDescriptorDataSize + size_t accelerationStructureCaptureReplayDescriptorDataSize + size_t samplerDescriptorSize + size_t combinedImageSamplerDescriptorSize + size_t sampledImageDescriptorSize + size_t storageImageDescriptorSize + size_t uniformTexelBufferDescriptorSize + size_t robustUniformTexelBufferDescriptorSize + size_t storageTexelBufferDescriptorSize + size_t robustStorageTexelBufferDescriptorSize + size_t uniformBufferDescriptorSize + size_t robustUniformBufferDescriptorSize + size_t storageBufferDescriptorSize + size_t robustStorageBufferDescriptorSize + size_t inputAttachmentDescriptorSize + size_t accelerationStructureDescriptorSize + VkDeviceSize maxSamplerDescriptorBufferRange + VkDeviceSize maxResourceDescriptorBufferRange + VkDeviceSize samplerDescriptorBufferAddressSpaceSize + VkDeviceSize resourceDescriptorBufferAddressSpaceSize + VkDeviceSize descriptorBufferAddressSpaceSize + + + VkStructureType sType + void* pNext + size_t combinedImageSamplerDensityMapDescriptorSize + + + VkStructureType sType + void* pNext + VkDeviceAddress address + VkDeviceSize range + VkFormat format + + + VkStructureType sType + const void* pNext + VkDeviceAddress address + VkBufferUsageFlags usage + + + VkStructureType sType + const void* pNext + VkBuffer buffer + + + const VkSampler* pSampler + const VkDescriptorImageInfo* pCombinedImageSampler + const VkDescriptorImageInfo* pInputAttachmentImage + const VkDescriptorImageInfo* pSampledImage + const VkDescriptorImageInfo* pStorageImage + const VkDescriptorAddressInfoEXT* pUniformTexelBuffer + const VkDescriptorAddressInfoEXT* pStorageTexelBuffer + const VkDescriptorAddressInfoEXT* pUniformBuffer + const VkDescriptorAddressInfoEXT* pStorageBuffer + VkDeviceAddress accelerationStructure + + + VkStructureType sType + const void* pNext + VkDescriptorType type + VkDescriptorDataEXT data + + + VkStructureType sType + const void* pNext + VkBuffer buffer + + + VkStructureType sType + const void* pNext + VkImage image + + + VkStructureType sType + const void* pNext + VkImageView imageView + + + VkStructureType sType + const void* pNext + VkSampler sampler + + + VkStructureType sType + const void* pNext + VkAccelerationStructureKHR accelerationStructure + VkAccelerationStructureNV accelerationStructureNV + + + VkStructureType sType + const void* pNext + const void* opaqueCaptureDescriptorData + + + VkStructureType sType + void* pNext + VkBool32 shaderIntegerDotProduct + + + + VkStructureType sType + void* pNext + VkBool32 integerDotProduct8BitUnsignedAccelerated + VkBool32 integerDotProduct8BitSignedAccelerated + VkBool32 integerDotProduct8BitMixedSignednessAccelerated + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated + VkBool32 integerDotProduct16BitUnsignedAccelerated + VkBool32 integerDotProduct16BitSignedAccelerated + VkBool32 integerDotProduct16BitMixedSignednessAccelerated + VkBool32 integerDotProduct32BitUnsignedAccelerated + VkBool32 integerDotProduct32BitSignedAccelerated + VkBool32 integerDotProduct32BitMixedSignednessAccelerated + VkBool32 integerDotProduct64BitUnsignedAccelerated + VkBool32 integerDotProduct64BitSignedAccelerated + VkBool32 integerDotProduct64BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated + + + + VkStructureType sType + void* pNext + VkBool32 hasPrimary + VkBool32 hasRender + int64_t primaryMajor + int64_t primaryMinor + int64_t renderMajor + int64_t renderMinor + + + VkStructureType sType + void* pNext + VkBool32 fragmentShaderBarycentric + + + VkStructureType sType + void* pNext + VkBool32 triStripVertexOrderIndependentOfProvokingVertex + + + VkStructureType sType + void* pNext + VkBool32 rayTracingMotionBlur + VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect + + + VkStructureType sType + void* pNext + VkBool32 rayTracingValidation + + + VkStructureType sType + void* pNext + VkBool32 spheres + VkBool32 linearSweptSpheres + + + + VkStructureType sType + const void* pNext + VkDeviceOrHostAddressConstKHR vertexData + + + VkStructureType sType + const void* pNext + uint32_t maxInstances + VkAccelerationStructureMotionInfoFlagsNV flags + + + float sx + float a + float b + float pvx + float sy + float c + float pvy + float sz + float pvz + float qx + float qy + float qz + float qw + float tx + float ty + float tz + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + VkSRTDataNV transformT0 + VkSRTDataNV transformT1 + uint32_t instanceCustomIndex:24 + uint32_t mask:8 + uint32_t instanceShaderBindingTableRecordOffset:24 + VkGeometryInstanceFlagsKHR flags:8 + uint64_t accelerationStructureReference + + + The bitfields in this structure are non-normative since bitfield ordering is implementation-defined in C. The specification defines the normative layout. + VkTransformMatrixKHR transformT0 + VkTransformMatrixKHR transformT1 + uint32_t instanceCustomIndex:24 + uint32_t mask:8 + uint32_t instanceShaderBindingTableRecordOffset:24 + VkGeometryInstanceFlagsKHR flags:8 + uint64_t accelerationStructureReference + + + VkAccelerationStructureInstanceKHR staticInstance + VkAccelerationStructureMatrixMotionInstanceNV matrixMotionInstance + VkAccelerationStructureSRTMotionInstanceNV srtMotionInstance + + + VkAccelerationStructureMotionInstanceTypeNV type + VkAccelerationStructureMotionInstanceFlagsNV flags + VkAccelerationStructureMotionInstanceDataNV data + + typedef void* VkRemoteAddressNV; + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkBufferCollectionFUCHSIA collection + uint32_t index + + + VkStructureType sType + const void* pNext + VkBufferCollectionFUCHSIA collection + uint32_t index + + + VkStructureType sType + const void* pNext + VkBufferCollectionFUCHSIA collection + uint32_t index + + + VkStructureType sType + const void* pNext + zx_handle_t collectionToken + + + VkStructureType sType + void* pNext + uint32_t memoryTypeBits + uint32_t bufferCount + uint32_t createInfoIndex + uint64_t sysmemPixelFormat + VkFormatFeatureFlags formatFeatures + VkSysmemColorSpaceFUCHSIA sysmemColorSpaceIndex + VkComponentMapping samplerYcbcrConversionComponents + VkSamplerYcbcrModelConversion suggestedYcbcrModel + VkSamplerYcbcrRange suggestedYcbcrRange + VkChromaLocation suggestedXChromaOffset + VkChromaLocation suggestedYChromaOffset + + + VkStructureType sType + const void* pNext + VkBufferCreateInfo createInfo + VkFormatFeatureFlags requiredFormatFeatures + VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints + + + VkStructureType sType + const void* pNext + uint32_t colorSpace + + + VkStructureType sType + const void* pNext + VkImageCreateInfo imageCreateInfo + VkFormatFeatureFlags requiredFormatFeatures + VkImageFormatConstraintsFlagsFUCHSIA flags + uint64_t sysmemPixelFormat + uint32_t colorSpaceCount + const VkSysmemColorSpaceFUCHSIA* pColorSpaces + + + VkStructureType sType + const void* pNext + uint32_t formatConstraintsCount + const VkImageFormatConstraintsInfoFUCHSIA* pFormatConstraints + VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints + VkImageConstraintsInfoFlagsFUCHSIA flags + + + VkStructureType sType + const void* pNext + uint32_t minBufferCount + uint32_t maxBufferCount + uint32_t minBufferCountForCamping + uint32_t minBufferCountForDedicatedSlack + uint32_t minBufferCountForSharedSlack + + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaModuleNV) + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaFunctionNV) + + VkStructureType sType + const void* pNext + size_t dataSize + const void* pData + + + VkStructureType sType + const void* pNext + VkCudaModuleNV module + const char* pName + + + VkStructureType sType + const void* pNext + VkCudaFunctionNV function + uint32_t gridDimX + uint32_t gridDimY + uint32_t gridDimZ + uint32_t blockDimX + uint32_t blockDimY + uint32_t blockDimZ + uint32_t sharedMemBytes + size_t paramCount + const void* const * pParams + size_t extraCount + const void* const * pExtras + + + VkStructureType sType + void* pNext + VkBool32 formatRgba10x6WithoutYCbCrSampler + + + VkStructureType sType + void* pNext + VkFormatFeatureFlags2 linearTilingFeatures + VkFormatFeatureFlags2 optimalTilingFeatures + VkFormatFeatureFlags2 bufferFeatures + + + + VkStructureType sType + void* pNext + uint32_t drmFormatModifierCount + VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties + + + uint64_t drmFormatModifier + uint32_t drmFormatModifierPlaneCount + VkFormatFeatureFlags2 drmFormatModifierTilingFeatures + + + VkStructureType sType + void* pNext + VkFormat format + uint64_t externalFormat + VkFormatFeatureFlags2 formatFeatures + VkComponentMapping samplerYcbcrConversionComponents + VkSamplerYcbcrModelConversion suggestedYcbcrModel + VkSamplerYcbcrRange suggestedYcbcrRange + VkChromaLocation suggestedXChromaOffset + VkChromaLocation suggestedYChromaOffset + + + VkStructureType sType + const void* pNext + uint32_t viewMask + uint32_t colorAttachmentCount + const VkFormat* pColorAttachmentFormats + VkFormat depthAttachmentFormat + VkFormat stencilAttachmentFormat + + + + VkStructureType sType + const void* pNext + VkRenderingFlags flags + VkRect2D renderArea + uint32_t layerCount + uint32_t viewMask + uint32_t colorAttachmentCount + const VkRenderingAttachmentInfo* pColorAttachments + const VkRenderingAttachmentInfo* pDepthAttachment + const VkRenderingAttachmentInfo* pStencilAttachment + + + + VkStructureType sType + const void* pNext + + + VkStructureType sType + const void* pNext + VkImageView imageView + VkImageLayout imageLayout + VkResolveModeFlagBits resolveMode + VkImageView resolveImageView + VkImageLayout resolveImageLayout + VkAttachmentLoadOp loadOp + VkAttachmentStoreOp storeOp + VkClearValue clearValue + + + + VkStructureType sType + const void* pNext + VkImageView imageView + VkImageLayout imageLayout + VkExtent2D shadingRateAttachmentTexelSize + + + VkStructureType sType + const void* pNext + VkImageView imageView + VkImageLayout imageLayout + + + VkStructureType sType + void* pNext + VkBool32 dynamicRendering + + + + VkStructureType sType + const void* pNext + VkRenderingFlags flags + uint32_t viewMask + uint32_t colorAttachmentCount + uint32_t colorAttachmentCount + const VkFormat* pColorAttachmentFormats + VkFormat depthAttachmentFormat + VkFormat stencilAttachmentFormat + VkSampleCountFlagBits rasterizationSamples + + + + VkStructureType sType + const void* pNext + uint32_t colorAttachmentCount + const VkSampleCountFlagBits* pColorAttachmentSamples + VkSampleCountFlagBits depthStencilAttachmentSamples + + + + VkStructureType sType + const void* pNext + VkBool32 perViewAttributes + VkBool32 perViewAttributesPositionXOnly + + + VkStructureType sType + void* pNext + VkBool32 minLod + + + VkStructureType sType + const void* pNext + float minLod + + + VkStructureType sType + void* pNext + VkBool32 rasterizationOrderColorAttachmentAccess + VkBool32 rasterizationOrderDepthAttachmentAccess + VkBool32 rasterizationOrderStencilAttachmentAccess + + + + VkStructureType sType + void* pNext + VkBool32 linearColorAttachment + + + VkStructureType sType + void* pNext + VkBool32 graphicsPipelineLibrary + + + VkStructureType sType + void* pNext + VkBool32 pipelineBinaries + + + VkStructureType sType + const void* pNext + VkBool32 disableInternalCache + + + VkStructureType sType + void* pNext + VkBool32 pipelineBinaryInternalCache + VkBool32 pipelineBinaryInternalCacheControl + VkBool32 pipelineBinaryPrefersInternalCache + VkBool32 pipelineBinaryPrecompiledInternalCache + VkBool32 pipelineBinaryCompressedData + + + VkStructureType sType + void* pNext + VkBool32 graphicsPipelineLibraryFastLinking + VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration + + + VkStructureType sType + const void* pNext + VkGraphicsPipelineLibraryFlagsEXT flags + + + VkStructureType sType + void* pNext + VkBool32 descriptorSetHostMapping + + + VkStructureType sType + const void* pNext + VkDescriptorSetLayout descriptorSetLayout + uint32_t binding + + + VkStructureType sType + void* pNext + size_t descriptorOffset + uint32_t descriptorSize + + + VkStructureType sType + void* pNext + VkBool32 nestedCommandBuffer + VkBool32 nestedCommandBufferRendering + VkBool32 nestedCommandBufferSimultaneousUse + + + VkStructureType sType + void* pNext + uint32_t maxCommandBufferNestingLevel + + + VkStructureType sType + void* pNext + VkBool32 shaderModuleIdentifier + + + VkStructureType sType + void* pNext + uint8_t shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE] + + + VkStructureType sType + const void* pNext + uint32_t identifierSize + const uint8_t* pIdentifier + + + VkStructureType sType + void* pNext + uint32_t identifierSize + uint8_t identifier[VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT] + + + VkStructureType sType + const void* pNext + VkImageCompressionFlagsEXT flags + uint32_t compressionControlPlaneCount + VkImageCompressionFixedRateFlagsEXT* pFixedRateFlags + + + VkStructureType sType + void* pNext + VkBool32 imageCompressionControl + + + VkStructureType sType + void* pNext + VkImageCompressionFlagsEXT imageCompressionFlags + VkImageCompressionFixedRateFlagsEXT imageCompressionFixedRateFlags + + + VkStructureType sType + void* pNext + VkBool32 imageCompressionControlSwapchain + + + VkStructureType sType + void* pNext + VkImageSubresource imageSubresource + + + + + VkStructureType sType + void* pNext + VkSubresourceLayout subresourceLayout + + + + + VkStructureType sType + const void* pNext + VkBool32 disallowMerging + + + uint32_t postMergeSubpassCount + + + VkStructureType sType + const void* pNext + VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback + + + VkSubpassMergeStatusEXT subpassMergeStatus + char description[VK_MAX_DESCRIPTION_SIZE] + uint32_t postMergeIndex + + + VkStructureType sType + const void* pNext + VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback + + + VkStructureType sType + void* pNext + VkBool32 subpassMergeFeedback + + + VkStructureType sType + const void* pNext + VkMicromapTypeEXT type + VkBuildMicromapFlagsEXT flags + VkBuildMicromapModeEXT mode + VkMicromapEXT dstMicromap + uint32_t usageCountsCount + const VkMicromapUsageEXT* pUsageCounts + const VkMicromapUsageEXT* const* ppUsageCounts + VkDeviceOrHostAddressConstKHR data + VkDeviceOrHostAddressKHR scratchData + VkDeviceOrHostAddressConstKHR triangleArray + VkDeviceSize triangleArrayStride + + + VkStructureType sType + const void* pNext + VkMicromapCreateFlagsEXT createFlags + VkBuffer buffer + VkDeviceSize offsetSpecified in bytes + VkDeviceSize size + VkMicromapTypeEXT type + VkDeviceAddress deviceAddress + + + VkStructureType sType + const void* pNext + const uint8_t* pVersionData + + + VkStructureType sType + const void* pNext + VkMicromapEXT src + VkMicromapEXT dst + VkCopyMicromapModeEXT mode + + + VkStructureType sType + const void* pNext + VkMicromapEXT src + VkDeviceOrHostAddressKHR dst + VkCopyMicromapModeEXT mode + + + VkStructureType sType + const void* pNext + VkDeviceOrHostAddressConstKHR src + VkMicromapEXT dst + VkCopyMicromapModeEXT mode + + + VkStructureType sType + const void* pNext + VkDeviceSize micromapSize + VkDeviceSize buildScratchSize + VkBool32 discardable + + + uint32_t count + uint32_t subdivisionLevel + uint32_t formatInterpretation depends on parent type + + + uint32_t dataOffsetSpecified in bytes + uint16_t subdivisionLevel + uint16_t format + + + VkStructureType sType + void* pNext + VkBool32 micromap + VkBool32 micromapCaptureReplay + VkBool32 micromapHostCommands + + + VkStructureType sType + void* pNext + uint32_t maxOpacity2StateSubdivisionLevel + uint32_t maxOpacity4StateSubdivisionLevel + + + VkStructureType sType + void* pNext + VkIndexType indexType + VkDeviceOrHostAddressConstKHR indexBuffer + VkDeviceSize indexStride + uint32_t baseTriangle + uint32_t usageCountsCount + const VkMicromapUsageEXT* pUsageCounts + const VkMicromapUsageEXT* const* ppUsageCounts + VkMicromapEXT micromap + + + VkStructureType sType + void* pNext + VkBool32 displacementMicromap + + + VkStructureType sType + void* pNext + uint32_t maxDisplacementMicromapSubdivisionLevel + + + VkStructureType sType + void* pNext + + VkFormat displacementBiasAndScaleFormat + VkFormat displacementVectorFormat + + VkDeviceOrHostAddressConstKHR displacementBiasAndScaleBuffer + VkDeviceSize displacementBiasAndScaleStride + VkDeviceOrHostAddressConstKHR displacementVectorBuffer + VkDeviceSize displacementVectorStride + VkDeviceOrHostAddressConstKHR displacedMicromapPrimitiveFlags + VkDeviceSize displacedMicromapPrimitiveFlagsStride + VkIndexType indexType + VkDeviceOrHostAddressConstKHR indexBuffer + VkDeviceSize indexStride + + uint32_t baseTriangle + + uint32_t usageCountsCount + const VkMicromapUsageEXT* pUsageCounts + const VkMicromapUsageEXT* const* ppUsageCounts + + VkMicromapEXT micromap + + + VkStructureType sType + void* pNext + uint8_t pipelineIdentifier[VK_UUID_SIZE] + + + VkStructureType sType + void* pNext + VkBool32 pipelinePropertiesIdentifier + + + VkStructureType sType + void* pNext + VkBool32 shaderEarlyAndLateFragmentTests + + + VkStructureType sType + const void* pNext + VkBool32 acquireUnmodifiedMemory + + + VkStructureType sType + const void* pNext + VkExportMetalObjectTypeFlagBitsEXT exportObjectType + + + VkStructureType sType + const void* pNext + + + VkStructureType sType + const void* pNext + MTLDevice_id mtlDevice + + + VkStructureType sType + const void* pNext + VkQueue queue + MTLCommandQueue_id mtlCommandQueue + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + MTLBuffer_id mtlBuffer + + + VkStructureType sType + const void* pNext + MTLBuffer_id mtlBuffer + + + VkStructureType sType + const void* pNext + VkImage image + VkImageView imageView + VkBufferView bufferView + VkImageAspectFlagBits plane + MTLTexture_id mtlTexture + + + VkStructureType sType + const void* pNext + VkImageAspectFlagBits plane + MTLTexture_id mtlTexture + + + VkStructureType sType + const void* pNext + VkImage image + IOSurfaceRef ioSurface + + + VkStructureType sType + const void* pNext + IOSurfaceRef ioSurface + + + VkStructureType sType + const void* pNext + VkSemaphore semaphore + VkEvent event + MTLSharedEvent_id mtlSharedEvent + + + VkStructureType sType + const void* pNext + MTLSharedEvent_id mtlSharedEvent + + + VkStructureType sType + void* pNext + VkBool32 nonSeamlessCubeMap + + + VkStructureType sType + void* pNext + VkBool32 pipelineRobustness + + + + VkStructureType sType + const void* pNext + VkPipelineRobustnessBufferBehavior storageBuffers + VkPipelineRobustnessBufferBehavior uniformBuffers + VkPipelineRobustnessBufferBehavior vertexInputs + VkPipelineRobustnessImageBehavior images + + + + VkStructureType sType + void* pNext + VkPipelineRobustnessBufferBehavior defaultRobustnessStorageBuffers + VkPipelineRobustnessBufferBehavior defaultRobustnessUniformBuffers + VkPipelineRobustnessBufferBehavior defaultRobustnessVertexInputs + VkPipelineRobustnessImageBehavior defaultRobustnessImages + + + + VkStructureType sType + const void* pNext + VkOffset2D filterCenter + VkExtent2D filterSize + uint32_t numPhases + + + VkStructureType sType + void* pNext + VkBool32 textureSampleWeighted + VkBool32 textureBoxFilter + VkBool32 textureBlockMatch + + + VkStructureType sType + void* pNext + uint32_t maxWeightFilterPhases + VkExtent2D maxWeightFilterDimension + VkExtent2D maxBlockMatchRegion + VkExtent2D maxBoxFilterBlockSize + + + VkStructureType sType + void* pNext + VkBool32 tileProperties + + + VkStructureType sType + void* pNext + VkExtent3D tileSize + VkExtent2D apronSize + VkOffset2D origin + + + VkStructureType sType + const void* pNext + VkDeviceMemory memory + + + VkStructureType sType + void* pNext + VkBool32 amigoProfiling + + + VkStructureType sType + const void* pNext + uint64_t firstDrawTimestamp + uint64_t swapBufferTimestamp + + + VkStructureType sType + void* pNext + VkBool32 attachmentFeedbackLoopLayout + + + + VkStructureType sType + const void* pNext + VkBool32 feedbackLoopEnable + + + VkStructureType sType + void* pNext + VkBool32 reportAddressBinding + + + VkStructureType sType + void* pNext + VkDeviceAddressBindingFlagsEXT flags + VkDeviceAddress baseAddress + VkDeviceSize size + VkDeviceAddressBindingTypeEXT bindingType + + + VkStructureType sType + void* pNext + VkBool32 opticalFlow + + + VkStructureType sType + void* pNext + VkOpticalFlowGridSizeFlagsNV supportedOutputGridSizes + VkOpticalFlowGridSizeFlagsNV supportedHintGridSizes + VkBool32 hintSupported + VkBool32 costSupported + VkBool32 bidirectionalFlowSupported + VkBool32 globalFlowSupported + uint32_t minWidth + uint32_t minHeight + uint32_t maxWidth + uint32_t maxHeight + uint32_t maxNumRegionsOfInterest + + + VkStructureType sType + const void* pNext + VkOpticalFlowUsageFlagsNV usage + + + VkStructureType sType + const void* pNext + VkFormat format + + + VkStructureType sType + void* pNext + uint32_t width + uint32_t height + VkFormat imageFormat + VkFormat flowVectorFormat + VkFormat costFormat + VkOpticalFlowGridSizeFlagsNV outputGridSize + VkOpticalFlowGridSizeFlagsNV hintGridSize + VkOpticalFlowPerformanceLevelNV performanceLevel + VkOpticalFlowSessionCreateFlagsNV flags + + NV internal use only + VkStructureType sType + void* pNext + uint32_t id + uint32_t size + const void* pPrivateData + + + VkStructureType sType + void* pNext + VkOpticalFlowExecuteFlagsNV flags + uint32_t regionCount + const VkRect2D* pRegions + + + VkStructureType sType + void* pNext + VkBool32 deviceFault + VkBool32 deviceFaultVendorBinary + + + VkDeviceFaultAddressTypeEXT addressType + VkDeviceAddress reportedAddress + VkDeviceSize addressPrecision + + + char description[VK_MAX_DESCRIPTION_SIZE]Free-form description of the fault + uint64_t vendorFaultCode + uint64_t vendorFaultData + + + VkStructureType sType + void* pNext + uint32_t addressInfoCount + uint32_t vendorInfoCount + VkDeviceSize vendorBinarySizeSpecified in bytes + + + VkStructureType sType + void* pNext + char description[VK_MAX_DESCRIPTION_SIZE]Free-form description of the fault + VkDeviceFaultAddressInfoEXT* pAddressInfos + VkDeviceFaultVendorInfoEXT* pVendorInfos + void* pVendorBinaryData + + + The fields in this structure are non-normative since structure packing is implementation-defined in C. The specification defines the normative layout. + uint32_t headerSize + VkDeviceFaultVendorBinaryHeaderVersionEXT headerVersion + uint32_t vendorID + uint32_t deviceID + uint32_t driverVersion + uint8_t pipelineCacheUUID[VK_UUID_SIZE] + uint32_t applicationNameOffset + uint32_t applicationVersion + uint32_t engineNameOffset + uint32_t engineVersion + uint32_t apiVersion + + + VkStructureType sType + void* pNext + VkBool32 pipelineLibraryGroupHandles + + + VkStructureType sType + const void* pNext + float depthBiasConstantFactor + float depthBiasClamp + float depthBiasSlopeFactor + + + VkStructureType sType + const void* pNext + VkDepthBiasRepresentationEXT depthBiasRepresentation + VkBool32 depthBiasExact + + + VkDeviceAddress srcAddress + VkDeviceAddress dstAddress + VkDeviceSize compressedSizeSpecified in bytes + VkDeviceSize decompressedSizeSpecified in bytes + VkMemoryDecompressionMethodFlagsNV decompressionMethod + + + VkStructureType sType + void* pNext + uint64_t shaderCoreMask + uint32_t shaderCoreCount + uint32_t shaderWarpsPerCore + + + VkStructureType sType + void* pNext + VkBool32 shaderCoreBuiltins + + + VkStructureType sType + const void* pNext + VkFrameBoundaryFlagsEXT flags + uint64_t frameID + uint32_t imageCount + const VkImage* pImages + uint32_t bufferCount + const VkBuffer* pBuffers + uint64_t tagName + size_t tagSize + const void* pTag + + + VkStructureType sType + void* pNext + VkBool32 frameBoundary + + + VkStructureType sType + void* pNext + VkBool32 dynamicRenderingUnusedAttachments + + + VkStructureType sType + void* pNext + VkPresentModeKHR presentMode + + + + VkStructureType sType + void* pNext + VkPresentScalingFlagsKHR supportedPresentScaling + VkPresentGravityFlagsKHR supportedPresentGravityX + VkPresentGravityFlagsKHR supportedPresentGravityY + VkExtent2D minScaledImageExtentSupported minimum image width and height for the surface when scaling is used + VkExtent2D maxScaledImageExtentSupported maximum image width and height for the surface when scaling is used + + + + VkStructureType sType + void* pNext + uint32_t presentModeCount + VkPresentModeKHR* pPresentModesOutput list of present modes compatible with the one specified in VkSurfacePresentModeKHR + + + + VkStructureType sType + void* pNext + VkBool32 swapchainMaintenance1 + + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const VkFence* pFencesFence to signal for each swapchain + + + + VkStructureType sType + const void* pNext + uint32_t presentModeCountLength of the pPresentModes array + const VkPresentModeKHR* pPresentModesPresentation modes which will be usable with this swapchain + + + + VkStructureType sType + const void* pNext + uint32_t swapchainCountCopy of VkPresentInfoKHR::swapchainCount + const VkPresentModeKHR* pPresentModesPresentation mode for each swapchain + + + + VkStructureType sType + const void* pNext + VkPresentScalingFlagsKHR scalingBehavior + VkPresentGravityFlagsKHR presentGravityX + VkPresentGravityFlagsKHR presentGravityY + + + + VkStructureType sType + const void* pNext + VkSwapchainKHR swapchainSwapchain for which images are being released + uint32_t imageIndexCountNumber of indices to release + const uint32_t* pImageIndicesIndices of which presentable images to release + + + + VkStructureType sType + void* pNext + VkBool32 depthBiasControl + VkBool32 leastRepresentableValueForceUnormRepresentation + VkBool32 floatRepresentation + VkBool32 depthBiasExact + + + VkStructureType sType + void* pNext + VkBool32 rayTracingInvocationReorder + + + VkStructureType sType + void* pNext + VkRayTracingInvocationReorderModeNV rayTracingInvocationReorderReorderingHint + + + VkStructureType sType + void* pNext + VkBool32 extendedSparseAddressSpace + + + VkStructureType sType + void* pNext + VkDeviceSize extendedSparseAddressSpaceSizeTotal address space available for extended sparse allocations (bytes) + VkImageUsageFlags extendedSparseImageUsageFlagsBitfield of which image usages are supported for extended sparse allocations + VkBufferUsageFlags extendedSparseBufferUsageFlagsBitfield of which buffer usages are supported for extended sparse allocations + + + VkStructureType sType + void* pNext + VkDirectDriverLoadingFlagsLUNARG flags + PFN_vkGetInstanceProcAddrLUNARG pfnGetInstanceProcAddr + + + VkStructureType sType + const void* pNext + VkDirectDriverLoadingModeLUNARG mode + uint32_t driverCount + const VkDirectDriverLoadingInfoLUNARG* pDrivers + + + VkStructureType sType + void* pNext + VkBool32 multiviewPerViewViewports + + + VkStructureType sType + void* pNext + VkBool32 rayTracingPositionFetch + + + VkStructureType sType + const void* pNext + const VkImageCreateInfo* pCreateInfo + const VkImageSubresource2* pSubresource + + + + VkStructureType sType + void* pNext + uint32_t pixelRate + uint32_t texelRate + uint32_t fmaRate + + + VkStructureType sType + void* pNext + VkBool32 multiviewPerViewRenderAreas + + + VkStructureType sType + const void* pNext + uint32_t perViewRenderAreaCount + const VkRect2D* pPerViewRenderAreas + + + VkStructureType sType + const void* pNext + void* pQueriedLowLatencyData + + + VkStructureType sType + const void* pNext + VkMemoryMapFlags flags + VkDeviceMemory memory + VkDeviceSize offset + VkDeviceSize size + + + + VkStructureType sType + const void* pNext + VkMemoryUnmapFlags flags + VkDeviceMemory memory + + + + VkStructureType sType + void* pNext + VkBool32 shaderObject + + + VkStructureType sType + void* pNext + uint8_t shaderBinaryUUID[VK_UUID_SIZE] + uint32_t shaderBinaryVersion + + + VkStructureType sType + const void* pNext + VkShaderCreateFlagsEXT flags + VkShaderStageFlagBits stage + VkShaderStageFlags nextStage + VkShaderCodeTypeEXT codeType + size_t codeSize + const void* pCode + const char* pName + uint32_t setLayoutCount + const VkDescriptorSetLayout* pSetLayouts + uint32_t pushConstantRangeCount + const VkPushConstantRange* pPushConstantRanges + const VkSpecializationInfo* pSpecializationInfo + + + VkStructureType sType + void* pNext + VkBool32 shaderTileImageColorReadAccess + VkBool32 shaderTileImageDepthReadAccess + VkBool32 shaderTileImageStencilReadAccess + + + VkStructureType sType + void* pNext + VkBool32 shaderTileImageCoherentReadAccelerated + VkBool32 shaderTileImageReadSampleFromPixelRateInvocation + VkBool32 shaderTileImageReadFromHelperInvocation + + + VkStructureType sType + const void* pNext + struct _screen_buffer* buffer + + + VkStructureType sType + void* pNext + VkDeviceSize allocationSize + uint32_t memoryTypeBits + + + VkStructureType sType + void* pNext + VkFormat format + uint64_t externalFormat + uint64_t screenUsage + VkFormatFeatureFlags formatFeatures + VkComponentMapping samplerYcbcrConversionComponents + VkSamplerYcbcrModelConversion suggestedYcbcrModel + VkSamplerYcbcrRange suggestedYcbcrRange + VkChromaLocation suggestedXChromaOffset + VkChromaLocation suggestedYChromaOffset + + + VkStructureType sType + void* pNext + uint64_t externalFormat + + + VkStructureType sType + void* pNext + VkBool32 screenBufferImport + + + VkStructureType sType + void* pNext + VkBool32 cooperativeMatrix + VkBool32 cooperativeMatrixRobustBufferAccess + + + VkStructureType sType + void* pNext + uint32_t MSize + uint32_t NSize + uint32_t KSize + VkComponentTypeKHR AType + VkComponentTypeKHR BType + VkComponentTypeKHR CType + VkComponentTypeKHR ResultType + VkBool32 saturatingAccumulation + VkScopeKHR scope + + + VkStructureType sType + void* pNext + VkShaderStageFlags cooperativeMatrixSupportedStages + + + VkStructureType sType + void* pNext + uint32_t maxExecutionGraphDepth + uint32_t maxExecutionGraphShaderOutputNodes + uint32_t maxExecutionGraphShaderPayloadSize + uint32_t maxExecutionGraphShaderPayloadCount + uint32_t executionGraphDispatchAddressAlignment + uint32_t maxExecutionGraphWorkgroupCount[3] + uint32_t maxExecutionGraphWorkgroups + + + VkStructureType sType + void* pNext + VkBool32 shaderEnqueue + VkBool32 shaderMeshEnqueue + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags flags + uint32_t stageCount + const VkPipelineShaderStageCreateInfo* pStages + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo + VkPipelineLayout layout + VkPipeline basePipelineHandle + int32_t basePipelineIndex + + + VkStructureType sType + const void* pNext + const char* pName + uint32_t index + + + VkStructureType sType + void* pNext + VkDeviceSize minSize + VkDeviceSize maxSize + VkDeviceSize sizeGranularity + + + uint32_t nodeIndex + uint32_t payloadCount + VkDeviceOrHostAddressConstAMDX payloads + uint64_t payloadStride + + + uint32_t count + VkDeviceOrHostAddressConstAMDX infos + uint64_t stride + + + VkStructureType sType + void* pNext + VkBool32 antiLag + + + VkStructureType sType + const void* pNext + VkAntiLagModeAMD mode + uint32_t maxFPS + const VkAntiLagPresentationInfoAMD* pPresentationInfo + + + VkStructureType sType + void* pNext + VkAntiLagStageAMD stage + uint64_t frameIndex + + + VkStructureType sType + const void* pNext + VkResult* pResult + + + VkStructureType sType + void* pNext + VkBool32 tileMemoryHeap + + + VkStructureType sType + void* pNext + VkBool32 queueSubmitBoundary + VkBool32 tileBufferTransfers + + + VkStructureType sType + const void* pNext + VkDeviceSize size + + + VkStructureType sType + void* pNext + VkDeviceSize size + VkDeviceSize alignment + + + + VkStructureType sType + const void* pNext + VkShaderStageFlags stageFlags + VkPipelineLayout layout + uint32_t firstSet + uint32_t descriptorSetCount + const VkDescriptorSet* pDescriptorSets + uint32_t dynamicOffsetCount + const uint32_t* pDynamicOffsets + + + + VkStructureType sType + const void* pNext + VkPipelineLayout layout + VkShaderStageFlags stageFlags + uint32_t offset + uint32_t size + const void* pValues + + + + VkStructureType sType + const void* pNext + VkShaderStageFlags stageFlags + VkPipelineLayout layout + uint32_t set + uint32_t descriptorWriteCount + const VkWriteDescriptorSet* pDescriptorWrites + + + + VkStructureType sType + const void* pNext + VkDescriptorUpdateTemplate descriptorUpdateTemplate + VkPipelineLayout layout + uint32_t set + const void* pData + + + + VkStructureType sType + const void* pNext + VkShaderStageFlags stageFlags + VkPipelineLayout layout + uint32_t firstSet + uint32_t setCount + const uint32_t* pBufferIndices + const VkDeviceSize* pOffsets + + + VkStructureType sType + const void* pNext + VkShaderStageFlags stageFlags + VkPipelineLayout layout + uint32_t set + + + VkStructureType sType + void* pNext + VkBool32 cubicRangeClamp + + + VkStructureType sType + void* pNext + VkBool32 ycbcrDegamma + + + VkStructureType sType + void* pNext + VkBool32 enableYDegamma + VkBool32 enableCbCrDegamma + + + VkStructureType sType + void* pNext + VkBool32 selectableCubicWeights + + + VkStructureType sType + const void* pNext + VkCubicFilterWeightsQCOM cubicWeights + + + VkStructureType sType + const void* pNext + VkCubicFilterWeightsQCOM cubicWeights + + + VkStructureType sType + void* pNext + VkBool32 textureBlockMatch2 + + + VkStructureType sType + void* pNext + VkExtent2D maxBlockMatchWindow + + + VkStructureType sType + const void* pNext + VkExtent2D windowExtent + VkBlockMatchWindowCompareModeQCOM windowCompareMode + + + VkStructureType sType + void* pNext + VkBool32 descriptorPoolOverallocation + + + VkStructureType sType + void* pNext + VkLayeredDriverUnderlyingApiMSFT underlyingAPI + + + VkStructureType sType + void* pNext + VkBool32 perStageDescriptorSet + VkBool32 dynamicPipelineLayout + + + VkStructureType sType + void* pNext + VkBool32 externalFormatResolve + + + VkStructureType sType + void* pNext + VkBool32 nullColorAttachmentWithExternalFormatResolve + VkChromaLocation externalFormatResolveChromaOffsetX + VkChromaLocation externalFormatResolveChromaOffsetY + + + VkStructureType sType + void* pNext + VkFormat colorAttachmentFormat + + + VkStructureType sType + const void* pNext + VkBool32 lowLatencyMode + VkBool32 lowLatencyBoost + uint32_t minimumIntervalUs + + + VkStructureType sType + const void* pNext + VkSemaphore signalSemaphore + uint64_t value + + + VkStructureType sType + const void* pNext + uint64_t presentID + VkLatencyMarkerNV marker + + + VkStructureType sType + const void* pNext + uint32_t timingCount + VkLatencyTimingsFrameReportNV* pTimings + + + VkStructureType sType + const void* pNext + uint64_t presentID + uint64_t inputSampleTimeUs + uint64_t simStartTimeUs + uint64_t simEndTimeUs + uint64_t renderSubmitStartTimeUs + uint64_t renderSubmitEndTimeUs + uint64_t presentStartTimeUs + uint64_t presentEndTimeUs + uint64_t driverStartTimeUs + uint64_t driverEndTimeUs + uint64_t osRenderQueueStartTimeUs + uint64_t osRenderQueueEndTimeUs + uint64_t gpuRenderStartTimeUs + uint64_t gpuRenderEndTimeUs + + + VkStructureType sType + const void* pNext + VkOutOfBandQueueTypeNV queueType + + + VkStructureType sType + const void* pNext + uint64_t presentID + + + VkStructureType sType + const void* pNext + VkBool32 latencyModeEnable + + + VkStructureType sType + const void* pNext + uint32_t presentModeCount + VkPresentModeKHR* pPresentModes + + + VkStructureType sType + void* pNext + VkBool32 cudaKernelLaunchFeatures + + + VkStructureType sType + void* pNext + uint32_t computeCapabilityMinor + uint32_t computeCapabilityMajor + + + VkStructureType sType + void* pNext + uint32_t shaderCoreCount + + + VkStructureType sType + void* pNext + VkBool32 schedulingControls + + + VkStructureType sType + void* pNext + VkPhysicalDeviceSchedulingControlsFlagsARM schedulingControlsFlags + + + VkStructureType sType + void* pNext + VkBool32 relaxedLineRasterization + + + VkStructureType sType + void* pNext + VkBool32 renderPassStriped + + + VkStructureType sType + void* pNext + VkExtent2D renderPassStripeGranularity + uint32_t maxRenderPassStripes + + + VkStructureType sType + const void* pNext + VkRect2D stripeArea + + + VkStructureType sType + const void* pNext + uint32_t stripeInfoCount + const VkRenderPassStripeInfoARM* pStripeInfos + + + VkStructureType sType + const void* pNext + uint32_t stripeSemaphoreInfoCount + const VkSemaphoreSubmitInfo* pStripeSemaphoreInfos + + + VkStructureType sType + void* pNext + VkBool32 pipelineOpacityMicromap + + + VkStructureType sType + void* pNext + VkBool32 shaderMaximalReconvergence + + + VkStructureType sType + void* pNext + VkBool32 shaderSubgroupRotate + VkBool32 shaderSubgroupRotateClustered + + + + VkStructureType sType + void* pNext + VkBool32 shaderExpectAssume + + + + VkStructureType sType + void* pNext + VkBool32 shaderFloatControls2 + + + + VkStructureType sType + void* pNext + VkBool32 dynamicRenderingLocalRead + + + + VkStructureType sType + const void* pNext + uint32_t colorAttachmentCount + const uint32_t* pColorAttachmentLocations + + + + VkStructureType sType + const void* pNext + uint32_t colorAttachmentCount + const uint32_t* pColorAttachmentInputIndices + const uint32_t* pDepthInputAttachmentIndex + const uint32_t* pStencilInputAttachmentIndex + + + + VkStructureType sType + void* pNext + VkBool32 shaderQuadControl + + + VkStructureType sType + void* pNext + VkBool32 shaderFloat16VectorAtomics + + + VkStructureType sType + void* pNext + VkBool32 memoryMapPlaced + VkBool32 memoryMapRangePlaced + VkBool32 memoryUnmapReserve + + + VkStructureType sType + void* pNext + VkDeviceSize minPlacedMemoryMapAlignment + + + VkStructureType sType + const void* pNext + void* pPlacedAddress + + + VkStructureType sType + void* pNext + VkBool32 shaderBFloat16Type + VkBool32 shaderBFloat16DotProduct + VkBool32 shaderBFloat16CooperativeMatrix + + + VkStructureType sType + void* pNext + VkBool32 shaderRawAccessChains + + + VkStructureType sType + void* pNext + VkBool32 commandBufferInheritance + + + VkStructureType sType + void* pNext + VkBool32 imageAlignmentControl + + + VkStructureType sType + void* pNext + uint32_t supportedImageAlignmentMask + + + VkStructureType sType + const void* pNext + uint32_t maximumRequestedAlignment + + + VkStructureType sType + void* pNext + VkBool32 shaderReplicatedComposites + + + + VkStructureType sType + void* pNext + VkBool32 presentModeFifoLatestReady + + + float minDepthClamp + float maxDepthClamp + + + VkStructureType sType + void* pNext + VkBool32 cooperativeMatrixWorkgroupScope + VkBool32 cooperativeMatrixFlexibleDimensions + VkBool32 cooperativeMatrixReductions + VkBool32 cooperativeMatrixConversions + VkBool32 cooperativeMatrixPerElementOperations + VkBool32 cooperativeMatrixTensorAddressing + VkBool32 cooperativeMatrixBlockLoads + + + VkStructureType sType + void* pNext + uint32_t cooperativeMatrixWorkgroupScopeMaxWorkgroupSize + uint32_t cooperativeMatrixFlexibleDimensionsMaxDimension + uint32_t cooperativeMatrixWorkgroupScopeReservedSharedMemory + + + VkStructureType sType + void* pNext + uint32_t MGranularity + uint32_t NGranularity + uint32_t KGranularity + VkComponentTypeKHR AType + VkComponentTypeKHR BType + VkComponentTypeKHR CType + VkComponentTypeKHR ResultType + VkBool32 saturatingAccumulation + VkScopeKHR scope + uint32_t workgroupInvocations + + + VkStructureType sType + void* pNext + VkBool32 hdrVivid + + + VkStructureType sType + void* pNext + VkBool32 vertexAttributeRobustness + + + VkStructureType sType + void* pNext + VkBool32 denseGeometryFormat + + + VkStructureType sType + const void* pNext + VkDeviceOrHostAddressConstKHR compressedData + VkDeviceSize dataSize + uint32_t numTriangles + uint32_t numVertices + uint32_t maxPrimitiveIndex + uint32_t maxGeometryIndex + VkCompressedTriangleFormatAMDX format + + + VkStructureType sType + void* pNext + VkBool32 depthClampZeroOne + + + VkStructureType sType + void* pNext + VkBool32 cooperativeVector + VkBool32 cooperativeVectorTraining + + + VkStructureType sType + void* pNext + VkComponentTypeKHR inputType + VkComponentTypeKHR inputInterpretation + VkComponentTypeKHR matrixInterpretation + VkComponentTypeKHR biasInterpretation + VkComponentTypeKHR resultType + VkBool32 transpose + + + VkStructureType sType + void* pNext + VkShaderStageFlags cooperativeVectorSupportedStages + VkBool32 cooperativeVectorTrainingFloat16Accumulation + VkBool32 cooperativeVectorTrainingFloat32Accumulation + uint32_t maxCooperativeVectorComponents + + + VkStructureType sType + const void* pNext + size_t srcSize + VkDeviceOrHostAddressConstKHR srcData + size_t* pDstSize + VkDeviceOrHostAddressKHR dstData + VkComponentTypeKHR srcComponentType + VkComponentTypeKHR dstComponentType + uint32_t numRows + uint32_t numColumns + VkCooperativeVectorMatrixLayoutNV srcLayout + size_t srcStride + VkCooperativeVectorMatrixLayoutNV dstLayout + size_t dstStride + + + VkStructureType sType + void* pNext + VkBool32 tileShading + VkBool32 tileShadingFragmentStage + VkBool32 tileShadingColorAttachments + VkBool32 tileShadingDepthAttachments + VkBool32 tileShadingStencilAttachments + VkBool32 tileShadingInputAttachments + VkBool32 tileShadingSampledAttachments + VkBool32 tileShadingPerTileDraw + VkBool32 tileShadingPerTileDispatch + VkBool32 tileShadingDispatchTile + VkBool32 tileShadingApron + VkBool32 tileShadingAnisotropicApron + VkBool32 tileShadingAtomicOps + VkBool32 tileShadingImageProcessing + + + VkStructureType sType + void* pNext + uint32_t maxApronSize + VkBool32 preferNonCoherent + VkExtent2D tileGranularity + VkExtent2D maxTileShadingRate + + + VkStructureType sType + const void* pNext + VkTileShadingRenderPassFlagsQCOM flags + VkExtent2D tileApronSize + + + VkStructureType sType + const void* pNext + + + VkStructureType sType + const void* pNext + + + VkStructureType sType + const void* pNext + + + VkStructureType sType + void* pNext + uint32_t maxFragmentDensityMapLayers + + + VkStructureType sType + void* pNext + VkBool32 fragmentDensityMapLayered + + + VkStructureType sType + const void* pNext + uint32_t maxFragmentDensityMapLayers + + + VkStructureType sType + const void* pNext + uint32_t numFramesPerBatch + uint32_t presentConfigFeedback + + + VkStructureType sType + void* pNext + VkBool32 presentMetering + + + VkStructureType sType + const void* pNext + uint32_t reservedExternalQueues + + + VkStructureType sType + const void* pNext + VkQueue preferredQueue + + + VkStructureType sType + const void* pNext + uint32_t deviceIndex + + + VkStructureType sType + void* pNext + uint32_t externalDataSize + uint32_t maxExternalQueues + + VK_DEFINE_HANDLE(VkExternalComputeQueueNV) + + VkStructureType sType + void* pNext + VkBool32 formatPack + + + VkStructureType sType + const void* pNext + VkTensorTilingARM tiling + VkFormat format + uint32_t dimensionCount + const int64_t* pDimensions + const int64_t* pStrides + VkTensorUsageFlagsARM usage + + + VkStructureType sType + const void* pNext + VkTensorCreateFlagsARM flags + const VkTensorDescriptionARM* pDescription + VkSharingMode sharingMode + uint32_t queueFamilyIndexCount + const uint32_t* pQueueFamilyIndices + + + VkStructureType sType + const void* pNext + VkTensorViewCreateFlagsARM flags + VkTensorARM tensor + VkFormat format + + + VkStructureType sType + const void* pNext + VkTensorARM tensor + + + VkStructureType sType + const void* pNext + VkTensorARM tensor + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + VkStructureType sType + const void* pNext + uint32_t tensorViewCount + const VkTensorViewARM* pTensorViews + + + VkStructureType sType + const void* pNext + VkFormatFeatureFlags2 optimalTilingTensorFeatures + VkFormatFeatureFlags2 linearTilingTensorFeatures + + + VkStructureType sType + void* pNext + uint32_t maxTensorDimensionCount + uint64_t maxTensorElements + uint64_t maxPerDimensionTensorElements + int64_t maxTensorStride + uint64_t maxTensorSize + uint32_t maxTensorShaderAccessArrayLength + uint32_t maxTensorShaderAccessSize + uint32_t maxDescriptorSetStorageTensors + uint32_t maxPerStageDescriptorSetStorageTensors + uint32_t maxDescriptorSetUpdateAfterBindStorageTensors + uint32_t maxPerStageDescriptorUpdateAfterBindStorageTensors + VkBool32 shaderStorageTensorArrayNonUniformIndexingNative + VkShaderStageFlags shaderTensorSupportedStages + + + VkStructureType sType + const void* pNext + VkPipelineStageFlags2 srcStageMask + VkAccessFlags2 srcAccessMask + VkPipelineStageFlags2 dstStageMask + VkAccessFlags2 dstAccessMask + uint32_t srcQueueFamilyIndex + uint32_t dstQueueFamilyIndex + VkTensorARM tensor + + + VkStructureType sType + const void* pNext + uint32_t tensorMemoryBarrierCount + const VkTensorMemoryBarrierARM* pTensorMemoryBarriers + + + VkStructureType sType + void* pNext + VkBool32 tensorNonPacked + VkBool32 shaderTensorAccess + VkBool32 shaderStorageTensorArrayDynamicIndexing + VkBool32 shaderStorageTensorArrayNonUniformIndexing + VkBool32 descriptorBindingStorageTensorUpdateAfterBind + VkBool32 tensors + + + VkStructureType sType + const void* pNext + const VkTensorCreateInfoARM* pCreateInfo + + + VkStructureType sType + const void* pNext + VkTensorARM srcTensor + VkTensorARM dstTensor + uint32_t regionCount + const VkTensorCopyARM* pRegions + + + VkStructureType sType + const void* pNext + uint32_t dimensionCount + const uint64_t* pSrcOffset + const uint64_t* pDstOffset + const uint64_t* pExtent + + + VkStructureType sType + const void* pNext + VkTensorARM tensorTensor that this allocation will be bound to + + + VkStructureType sType + void* pNext + size_t tensorCaptureReplayDescriptorDataSize + size_t tensorViewCaptureReplayDescriptorDataSize + size_t tensorDescriptorSize + + + VkStructureType sType + void* pNext + VkBool32 descriptorBufferTensorDescriptors + + + VkStructureType sType + const void* pNext + VkTensorARM tensor + + + VkStructureType sType + const void* pNext + VkTensorViewARM tensorView + + + VkStructureType sType + const void* pNext + VkTensorViewARM tensorView + + + VkStructureType sType + const void* pNext + uint32_t tensorCount + const VkTensorARM* pTensors + + + VkStructureType sType + const void* pNext + VkTensorCreateFlagsARM flags + const VkTensorDescriptionARM* pDescription + VkExternalMemoryHandleTypeFlagBits handleType + + + VkStructureType sType + const void* pNext + VkExternalMemoryProperties externalMemoryProperties + + + VkStructureType sType + const void* pNext + VkExternalMemoryHandleTypeFlags handleTypes + + + VkStructureType sType + void* pNext + VkBool32 shaderFloat8 + VkBool32 shaderFloat8CooperativeMatrix + + + VkStructureType sType + const void* pNext + VkSurfaceCreateFlagsOHOS flags + OHNativeWindow* window + + + VkStructureType sType + void* pNext + VkBool32 dataGraph + VkBool32 dataGraphUpdateAfterBind + VkBool32 dataGraphSpecializationConstants + VkBool32 dataGraphDescriptorBuffer + VkBool32 dataGraphShaderModule + + + VkStructureType sType + const void* pNext + uint32_t dimension + uint32_t zeroCount + uint32_t groupSize + + + VkStructureType sType + const void* pNext + uint32_t id + const void* pConstantData + + + VkStructureType sType + const void* pNext + uint32_t descriptorSet + uint32_t binding + uint32_t arrayElement + + + VkStructureType sType + const void* pNext + const char* pVendorOptions + + + VkStructureType sType + const void* pNext + VkPipelineCreateFlags2KHR flags + VkPipelineLayout layout + uint32_t resourceInfoCount + const VkDataGraphPipelineResourceInfoARM* pResourceInfos + + + VkStructureType sType + const void* pNext + VkShaderModule module + const char* pName + const VkSpecializationInfo* pSpecializationInfo + uint32_t constantCount + const VkDataGraphPipelineConstantARM* pConstants + + + VkStructureType sType + const void* pNext + VkDataGraphPipelineSessionCreateFlagsARM flags + VkPipeline dataGraphPipeline + + + VkStructureType sType + const void* pNext + VkDataGraphPipelineSessionARM session + + + VkStructureType sType + const void* pNext + VkDataGraphPipelineSessionBindPointARM bindPoint + VkDataGraphPipelineSessionBindPointTypeARM bindPointType + uint32_t numObjects + + + VkStructureType sType + const void* pNext + VkDataGraphPipelineSessionARM session + VkDataGraphPipelineSessionBindPointARM bindPoint + uint32_t objectIndex + + + VkStructureType sType + const void* pNext + VkDataGraphPipelineSessionARM session + VkDataGraphPipelineSessionBindPointARM bindPoint + uint32_t objectIndex + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + VkStructureType sType + const void* pNext + VkPipeline dataGraphPipeline + + + VkStructureType sType + const void* pNext + VkDataGraphPipelinePropertyARM property + VkBool32 isText + size_t dataSize + void* pData + + + VkStructureType sType + const void* pNext + uint32_t identifierSize + const uint8_t* pIdentifier + + + VkStructureType sType + void* pNext + VkDataGraphPipelineDispatchFlagsARM flags + + + VkPhysicalDeviceDataGraphProcessingEngineTypeARM type + VkBool32 isForeign + + + VkPhysicalDeviceDataGraphOperationTypeARM operationType + char name[VK_MAX_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_SET_NAME_SIZE_ARM] + uint32_t version + + + VkStructureType sType + const void* pNext + VkPhysicalDeviceDataGraphProcessingEngineARM engine + VkPhysicalDeviceDataGraphOperationSupportARM operation + + + VkStructureType sType + const void* pNext + uint32_t queueFamilyIndex + VkPhysicalDeviceDataGraphProcessingEngineTypeARM engineType + + + VkStructureType sType + const void* pNext + VkExternalSemaphoreHandleTypeFlags foreignSemaphoreHandleTypes + VkExternalMemoryHandleTypeFlags foreignMemoryHandleTypes + + + VkStructureType sType + const void* pNext + uint32_t processingEngineCount + VkPhysicalDeviceDataGraphProcessingEngineARM* pProcessingEngines + + + VkStructureType sType + void* pNext + VkBool32 pipelineCacheIncrementalMode + + + VkStructureType sType + void* pNext + VkBool32 shaderUntypedPointers + + + VkStructureType sType + void* pNext + VkBool32 videoEncodeRgbConversion + + + VkStructureType sType + void* pNext + VkVideoEncodeRgbModelConversionFlagsVALVE rgbModels + VkVideoEncodeRgbRangeCompressionFlagsVALVE rgbRanges + VkVideoEncodeRgbChromaOffsetFlagsVALVE xChromaOffsets + VkVideoEncodeRgbChromaOffsetFlagsVALVE yChromaOffsets + + + VkStructureType sType + const void* pNext + VkBool32 performEncodeRgbConversion + + + VkStructureType sType + const void* pNext + VkVideoEncodeRgbModelConversionFlagBitsVALVE rgbModel + VkVideoEncodeRgbRangeCompressionFlagBitsVALVE rgbRange + VkVideoEncodeRgbChromaOffsetFlagBitsVALVE xChromaOffset + VkVideoEncodeRgbChromaOffsetFlagBitsVALVE yChromaOffset + + + + + Vulkan enumerant (token) definitions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Unlike OpenGL, most tokens in Vulkan are actual typed enumerants in + their own numeric namespaces. The "name" attribute is the C enum + type name, and is pulled in from a type tag definition above + (slightly clunky, but retains the type / enum distinction). "type" + attributes of "enum" or "bitmask" indicate that these values should + be generated inside an appropriate definition. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + value="4" reserved for VK_KHR_sampler_mirror_clamp_to_edge + enum VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; do not + alias! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Return codes (positive values) + + + + + + + Error codes (negative values) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Flags + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WSI Extensions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NVX_device_generated_commands formerly used these enum values, but that extension has been removed + value 31 / name VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT + value 32 / name VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Vendor IDs are now represented as enums instead of the old + <vendorids> tag, allowing them to be included in the + API headers. + + + + + + + + + + + + Driver IDs are now represented as enums instead of the old + <driverids> tag, allowing them to be included in the + API headers. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bitpos 17-31 are specified by extensions to the original VkAccessFlagBits enum + + + + + + + + + + + + + + + + + + + + + + + + + bitpos 17-31 are specified by extensions to the original VkPipelineStageFlagBits enum + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bitpos 13 is an extension interaction with VK_EXT_filter_cubic" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VkResult vkCreateInstance + const VkInstanceCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkInstance* pInstance + + + void vkDestroyInstance + VkInstance instance + const VkAllocationCallbacks* pAllocator + + all sname:VkPhysicalDevice objects enumerated from pname:instance + + + + VkResult vkEnumeratePhysicalDevices + VkInstance instance + uint32_t* pPhysicalDeviceCount + VkPhysicalDevice* pPhysicalDevices + + + PFN_vkVoidFunction vkGetDeviceProcAddr + VkDevice device + const char* pName + + + PFN_vkVoidFunction vkGetInstanceProcAddr + VkInstance instance + const char* pName + + + void vkGetPhysicalDeviceProperties + VkPhysicalDevice physicalDevice + VkPhysicalDeviceProperties* pProperties + + + void vkGetPhysicalDeviceQueueFamilyProperties + VkPhysicalDevice physicalDevice + uint32_t* pQueueFamilyPropertyCount + VkQueueFamilyProperties* pQueueFamilyProperties + + + void vkGetPhysicalDeviceMemoryProperties + VkPhysicalDevice physicalDevice + VkPhysicalDeviceMemoryProperties* pMemoryProperties + + + void vkGetPhysicalDeviceFeatures + VkPhysicalDevice physicalDevice + VkPhysicalDeviceFeatures* pFeatures + + + void vkGetPhysicalDeviceFormatProperties + VkPhysicalDevice physicalDevice + VkFormat format + VkFormatProperties* pFormatProperties + + + VkResult vkGetPhysicalDeviceImageFormatProperties + VkPhysicalDevice physicalDevice + VkFormat format + VkImageType type + VkImageTiling tiling + VkImageUsageFlags usage + VkImageCreateFlags flags + VkImageFormatProperties* pImageFormatProperties + + + VkResult vkCreateDevice + VkPhysicalDevice physicalDevice + const VkDeviceCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDevice* pDevice + + + VkResult vkCreateDevice + VkPhysicalDevice physicalDevice + const VkDeviceCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDevice* pDevice + + + void vkDestroyDevice + VkDevice device + const VkAllocationCallbacks* pAllocator + + all sname:VkQueue objects created from pname:device + + + + VkResult vkEnumerateInstanceVersion + uint32_t* pApiVersion + + + VkResult vkEnumerateInstanceLayerProperties + uint32_t* pPropertyCount + VkLayerProperties* pProperties + + + VkResult vkEnumerateInstanceExtensionProperties + const char* pLayerName + uint32_t* pPropertyCount + VkExtensionProperties* pProperties + + + VkResult vkEnumerateDeviceLayerProperties + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkLayerProperties* pProperties + + + VkResult vkEnumerateDeviceLayerProperties + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkLayerProperties* pProperties + + + VkResult vkEnumerateDeviceExtensionProperties + VkPhysicalDevice physicalDevice + const char* pLayerName + uint32_t* pPropertyCount + VkExtensionProperties* pProperties + + + void vkGetDeviceQueue + VkDevice device + uint32_t queueFamilyIndex + uint32_t queueIndex + VkQueue* pQueue + + + VkResult vkQueueSubmit + VkQueue queue + uint32_t submitCount + const VkSubmitInfo* pSubmits + VkFence fence + + + VkResult vkQueueWaitIdle + VkQueue queue + + + VkResult vkDeviceWaitIdle + VkDevice device + + all sname:VkQueue objects created from pname:device + + + + VkResult vkAllocateMemory + VkDevice device + const VkMemoryAllocateInfo* pAllocateInfo + const VkAllocationCallbacks* pAllocator + VkDeviceMemory* pMemory + + + void vkFreeMemory + VkDevice device + VkDeviceMemory memory + const VkAllocationCallbacks* pAllocator + + + VkResult vkMapMemory + VkDevice device + VkDeviceMemory memory + VkDeviceSize offset + VkDeviceSize size + VkMemoryMapFlags flags + void** ppData + + + void vkUnmapMemory + VkDevice device + VkDeviceMemory memory + + + VkResult vkFlushMappedMemoryRanges + VkDevice device + uint32_t memoryRangeCount + const VkMappedMemoryRange* pMemoryRanges + + + VkResult vkInvalidateMappedMemoryRanges + VkDevice device + uint32_t memoryRangeCount + const VkMappedMemoryRange* pMemoryRanges + + + void vkGetDeviceMemoryCommitment + VkDevice device + VkDeviceMemory memory + VkDeviceSize* pCommittedMemoryInBytes + + + void vkGetBufferMemoryRequirements + VkDevice device + VkBuffer buffer + VkMemoryRequirements* pMemoryRequirements + + + VkResult vkBindBufferMemory + VkDevice device + VkBuffer buffer + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + void vkGetImageMemoryRequirements + VkDevice device + VkImage image + VkMemoryRequirements* pMemoryRequirements + + + VkResult vkBindImageMemory + VkDevice device + VkImage image + VkDeviceMemory memory + VkDeviceSize memoryOffset + + + void vkGetImageSparseMemoryRequirements + VkDevice device + VkImage image + uint32_t* pSparseMemoryRequirementCount + VkSparseImageMemoryRequirements* pSparseMemoryRequirements + + + void vkGetPhysicalDeviceSparseImageFormatProperties + VkPhysicalDevice physicalDevice + VkFormat format + VkImageType type + VkSampleCountFlagBits samples + VkImageUsageFlags usage + VkImageTiling tiling + uint32_t* pPropertyCount + VkSparseImageFormatProperties* pProperties + + + VkResult vkQueueBindSparse + VkQueue queue + uint32_t bindInfoCount + const VkBindSparseInfo* pBindInfo + VkFence fence + + + VkResult vkCreateFence + VkDevice device + const VkFenceCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkFence* pFence + + + void vkDestroyFence + VkDevice device + VkFence fence + const VkAllocationCallbacks* pAllocator + + + VkResult vkResetFences + VkDevice device + uint32_t fenceCount + const VkFence* pFences + + + VkResult vkGetFenceStatus + VkDevice device + VkFence fence + + + VkResult vkWaitForFences + VkDevice device + uint32_t fenceCount + const VkFence* pFences + VkBool32 waitAll + uint64_t timeout + + + VkResult vkCreateSemaphore + VkDevice device + const VkSemaphoreCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSemaphore* pSemaphore + + + void vkDestroySemaphore + VkDevice device + VkSemaphore semaphore + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateEvent + VkDevice device + const VkEventCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkEvent* pEvent + + + void vkDestroyEvent + VkDevice device + VkEvent event + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetEventStatus + VkDevice device + VkEvent event + + + VkResult vkSetEvent + VkDevice device + VkEvent event + + + VkResult vkResetEvent + VkDevice device + VkEvent event + + + VkResult vkCreateQueryPool + VkDevice device + const VkQueryPoolCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkQueryPool* pQueryPool + + + void vkDestroyQueryPool + VkDevice device + VkQueryPool queryPool + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetQueryPoolResults + VkDevice device + VkQueryPool queryPool + uint32_t firstQuery + uint32_t queryCount + size_t dataSize + void* pData + VkDeviceSize stride + VkQueryResultFlags flags + + + void vkResetQueryPool + VkDevice device + VkQueryPool queryPool + uint32_t firstQuery + uint32_t queryCount + + + + VkResult vkCreateBuffer + VkDevice device + const VkBufferCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkBuffer* pBuffer + + + void vkDestroyBuffer + VkDevice device + VkBuffer buffer + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateBufferView + VkDevice device + const VkBufferViewCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkBufferView* pView + + + void vkDestroyBufferView + VkDevice device + VkBufferView bufferView + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateImage + VkDevice device + const VkImageCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkImage* pImage + + + void vkDestroyImage + VkDevice device + VkImage image + const VkAllocationCallbacks* pAllocator + + + void vkGetImageSubresourceLayout + VkDevice device + VkImage image + const VkImageSubresource* pSubresource + VkSubresourceLayout* pLayout + + + VkResult vkCreateImageView + VkDevice device + const VkImageViewCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkImageView* pView + + + void vkDestroyImageView + VkDevice device + VkImageView imageView + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateShaderModule + VkDevice device + const VkShaderModuleCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkShaderModule* pShaderModule + + + void vkDestroyShaderModule + VkDevice device + VkShaderModule shaderModule + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreatePipelineCache + VkDevice device + const VkPipelineCacheCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkPipelineCache* pPipelineCache + + + VkResult vkCreatePipelineCache + VkDevice device + const VkPipelineCacheCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkPipelineCache* pPipelineCache + + + void vkDestroyPipelineCache + VkDevice device + VkPipelineCache pipelineCache + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetPipelineCacheData + VkDevice device + VkPipelineCache pipelineCache + size_t* pDataSize + void* pData + + + VkResult vkMergePipelineCaches + VkDevice device + VkPipelineCache dstCache + uint32_t srcCacheCount + const VkPipelineCache* pSrcCaches + + + VkResult vkCreatePipelineBinariesKHR + VkDevice device + const VkPipelineBinaryCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkPipelineBinaryHandlesInfoKHR* pBinaries + + + void vkDestroyPipelineBinaryKHR + VkDevice device + VkPipelineBinaryKHR pipelineBinary + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetPipelineKeyKHR + VkDevice device + const VkPipelineCreateInfoKHR* pPipelineCreateInfo + VkPipelineBinaryKeyKHR* pPipelineKey + + + VkResult vkGetPipelineBinaryDataKHR + VkDevice device + const VkPipelineBinaryDataInfoKHR* pInfo + VkPipelineBinaryKeyKHR* pPipelineBinaryKey + size_t* pPipelineBinaryDataSize + void* pPipelineBinaryData + + + VkResult vkReleaseCapturedPipelineDataKHR + VkDevice device + const VkReleaseCapturedPipelineDataInfoKHR* pInfo + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateGraphicsPipelines + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkGraphicsPipelineCreateInfo* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateGraphicsPipelines + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkGraphicsPipelineCreateInfo* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateComputePipelines + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkComputePipelineCreateInfo* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateComputePipelines + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkComputePipelineCreateInfo* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI + VkDevice device + VkRenderPass renderpass + VkExtent2D* pMaxWorkgroupSize + + + void vkDestroyPipeline + VkDevice device + VkPipeline pipeline + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreatePipelineLayout + VkDevice device + const VkPipelineLayoutCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkPipelineLayout* pPipelineLayout + + + void vkDestroyPipelineLayout + VkDevice device + VkPipelineLayout pipelineLayout + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateSampler + VkDevice device + const VkSamplerCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSampler* pSampler + + + void vkDestroySampler + VkDevice device + VkSampler sampler + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateDescriptorSetLayout + VkDevice device + const VkDescriptorSetLayoutCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDescriptorSetLayout* pSetLayout + + + void vkDestroyDescriptorSetLayout + VkDevice device + VkDescriptorSetLayout descriptorSetLayout + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateDescriptorPool + VkDevice device + const VkDescriptorPoolCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDescriptorPool* pDescriptorPool + + + void vkDestroyDescriptorPool + VkDevice device + VkDescriptorPool descriptorPool + const VkAllocationCallbacks* pAllocator + + + VkResult vkResetDescriptorPool + VkDevice device + VkDescriptorPool descriptorPool + VkDescriptorPoolResetFlags flags + + any sname:VkDescriptorSet objects allocated from pname:descriptorPool + + + + VkResult vkAllocateDescriptorSets + VkDevice device + const VkDescriptorSetAllocateInfo* pAllocateInfo + VkDescriptorSet* pDescriptorSets + + + VkResult vkFreeDescriptorSets + VkDevice device + VkDescriptorPool descriptorPool + uint32_t descriptorSetCount + const VkDescriptorSet* pDescriptorSets + + + void vkUpdateDescriptorSets + VkDevice device + uint32_t descriptorWriteCount + const VkWriteDescriptorSet* pDescriptorWrites + uint32_t descriptorCopyCount + const VkCopyDescriptorSet* pDescriptorCopies + + + VkResult vkCreateFramebuffer + VkDevice device + const VkFramebufferCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkFramebuffer* pFramebuffer + + + void vkDestroyFramebuffer + VkDevice device + VkFramebuffer framebuffer + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateRenderPass + VkDevice device + const VkRenderPassCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkRenderPass* pRenderPass + + + void vkDestroyRenderPass + VkDevice device + VkRenderPass renderPass + const VkAllocationCallbacks* pAllocator + + + void vkGetRenderAreaGranularity + VkDevice device + VkRenderPass renderPass + VkExtent2D* pGranularity + + + void vkGetRenderingAreaGranularity + VkDevice device + const VkRenderingAreaInfo* pRenderingAreaInfo + VkExtent2D* pGranularity + + + + VkResult vkCreateCommandPool + VkDevice device + const VkCommandPoolCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkCommandPool* pCommandPool + + + void vkDestroyCommandPool + VkDevice device + VkCommandPool commandPool + const VkAllocationCallbacks* pAllocator + + + VkResult vkResetCommandPool + VkDevice device + VkCommandPool commandPool + VkCommandPoolResetFlags flags + + + VkResult vkAllocateCommandBuffers + VkDevice device + const VkCommandBufferAllocateInfo* pAllocateInfo + VkCommandBuffer* pCommandBuffers + + + void vkFreeCommandBuffers + VkDevice device + VkCommandPool commandPool + uint32_t commandBufferCount + const VkCommandBuffer* pCommandBuffers + + + VkResult vkBeginCommandBuffer + VkCommandBuffer commandBuffer + const VkCommandBufferBeginInfo* pBeginInfo + + the sname:VkCommandPool that pname:commandBuffer was allocated from + + + + VkResult vkEndCommandBuffer + VkCommandBuffer commandBuffer + + the sname:VkCommandPool that pname:commandBuffer was allocated from + + + + VkResult vkResetCommandBuffer + VkCommandBuffer commandBuffer + VkCommandBufferResetFlags flags + + the sname:VkCommandPool that pname:commandBuffer was allocated from + + + + void vkCmdBindPipeline + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + + + void vkCmdSetAttachmentFeedbackLoopEnableEXT + VkCommandBuffer commandBuffer + VkImageAspectFlags aspectMask + + + void vkCmdSetViewport + VkCommandBuffer commandBuffer + uint32_t firstViewport + uint32_t viewportCount + const VkViewport* pViewports + + + void vkCmdSetScissor + VkCommandBuffer commandBuffer + uint32_t firstScissor + uint32_t scissorCount + const VkRect2D* pScissors + + + void vkCmdSetLineWidth + VkCommandBuffer commandBuffer + float lineWidth + + + void vkCmdSetDepthBias + VkCommandBuffer commandBuffer + float depthBiasConstantFactor + float depthBiasClamp + float depthBiasSlopeFactor + + + void vkCmdSetBlendConstants + VkCommandBuffer commandBuffer + const float blendConstants[4] + + + void vkCmdSetDepthBounds + VkCommandBuffer commandBuffer + float minDepthBounds + float maxDepthBounds + + + void vkCmdSetStencilCompareMask + VkCommandBuffer commandBuffer + VkStencilFaceFlags faceMask + uint32_t compareMask + + + void vkCmdSetStencilWriteMask + VkCommandBuffer commandBuffer + VkStencilFaceFlags faceMask + uint32_t writeMask + + + void vkCmdSetStencilReference + VkCommandBuffer commandBuffer + VkStencilFaceFlags faceMask + uint32_t reference + + + void vkCmdBindDescriptorSets + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipelineLayout layout + uint32_t firstSet + uint32_t descriptorSetCount + const VkDescriptorSet* pDescriptorSets + uint32_t dynamicOffsetCount + const uint32_t* pDynamicOffsets + + + void vkCmdBindIndexBuffer + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkIndexType indexType + + + void vkCmdBindVertexBuffers + VkCommandBuffer commandBuffer + uint32_t firstBinding + uint32_t bindingCount + const VkBuffer* pBuffers + const VkDeviceSize* pOffsets + + + void vkCmdDraw + VkCommandBuffer commandBuffer + uint32_t vertexCount + uint32_t instanceCount + uint32_t firstVertex + uint32_t firstInstance + + + void vkCmdDrawIndexed + VkCommandBuffer commandBuffer + uint32_t indexCount + uint32_t instanceCount + uint32_t firstIndex + int32_t vertexOffset + uint32_t firstInstance + + + void vkCmdDrawMultiEXT + VkCommandBuffer commandBuffer + uint32_t drawCount + const VkMultiDrawInfoEXT* pVertexInfo + uint32_t instanceCount + uint32_t firstInstance + uint32_t stride + + + void vkCmdDrawMultiIndexedEXT + VkCommandBuffer commandBuffer + uint32_t drawCount + const VkMultiDrawIndexedInfoEXT* pIndexInfo + uint32_t instanceCount + uint32_t firstInstance + uint32_t stride + const int32_t* pVertexOffset + + + void vkCmdDrawIndirect + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + uint32_t drawCount + uint32_t stride + + + void vkCmdDrawIndexedIndirect + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + uint32_t drawCount + uint32_t stride + + + void vkCmdDispatch + VkCommandBuffer commandBuffer + uint32_t groupCountX + uint32_t groupCountY + uint32_t groupCountZ + + + void vkCmdDispatchIndirect + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + + + void vkCmdSubpassShadingHUAWEI + VkCommandBuffer commandBuffer + + + void vkCmdDrawClusterHUAWEI + VkCommandBuffer commandBuffer + uint32_t groupCountX + uint32_t groupCountY + uint32_t groupCountZ + + + void vkCmdDrawClusterIndirectHUAWEI + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + + + void vkCmdUpdatePipelineIndirectBufferNV + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + + + void vkCmdCopyBuffer + VkCommandBuffer commandBuffer + VkBuffer srcBuffer + VkBuffer dstBuffer + uint32_t regionCount + const VkBufferCopy* pRegions + + + void vkCmdCopyImage + VkCommandBuffer commandBuffer + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageCopy* pRegions + + + void vkCmdBlitImage + VkCommandBuffer commandBuffer + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageBlit* pRegions + VkFilter filter + + + void vkCmdCopyBufferToImage + VkCommandBuffer commandBuffer + VkBuffer srcBuffer + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkBufferImageCopy* pRegions + + + void vkCmdCopyImageToBuffer + VkCommandBuffer commandBuffer + VkImage srcImage + VkImageLayout srcImageLayout + VkBuffer dstBuffer + uint32_t regionCount + const VkBufferImageCopy* pRegions + + + void vkCmdCopyMemoryIndirectNV + VkCommandBuffer commandBuffer + VkDeviceAddress copyBufferAddress + uint32_t copyCount + uint32_t stride + + + void vkCmdCopyMemoryIndirectKHR + VkCommandBuffer commandBuffer + const VkCopyMemoryIndirectInfoKHR* pCopyMemoryIndirectInfo + + + void vkCmdCopyMemoryToImageIndirectNV + VkCommandBuffer commandBuffer + VkDeviceAddress copyBufferAddress + uint32_t copyCount + uint32_t stride + VkImage dstImage + VkImageLayout dstImageLayout + const VkImageSubresourceLayers* pImageSubresources + + + void vkCmdCopyMemoryToImageIndirectKHR + VkCommandBuffer commandBuffer + const VkCopyMemoryToImageIndirectInfoKHR* pCopyMemoryToImageIndirectInfo + + + void vkCmdUpdateBuffer + VkCommandBuffer commandBuffer + VkBuffer dstBuffer + VkDeviceSize dstOffset + VkDeviceSize dataSize + const void* pData + + + void vkCmdFillBuffer + VkCommandBuffer commandBuffer + VkBuffer dstBuffer + VkDeviceSize dstOffset + VkDeviceSize size + uint32_t data + + + void vkCmdClearColorImage + VkCommandBuffer commandBuffer + VkImage image + VkImageLayout imageLayout + const VkClearColorValue* pColor + uint32_t rangeCount + const VkImageSubresourceRange* pRanges + + + void vkCmdClearDepthStencilImage + VkCommandBuffer commandBuffer + VkImage image + VkImageLayout imageLayout + const VkClearDepthStencilValue* pDepthStencil + uint32_t rangeCount + const VkImageSubresourceRange* pRanges + + + void vkCmdClearAttachments + VkCommandBuffer commandBuffer + uint32_t attachmentCount + const VkClearAttachment* pAttachments + uint32_t rectCount + const VkClearRect* pRects + + + void vkCmdResolveImage + VkCommandBuffer commandBuffer + VkImage srcImage + VkImageLayout srcImageLayout + VkImage dstImage + VkImageLayout dstImageLayout + uint32_t regionCount + const VkImageResolve* pRegions + + + void vkCmdSetEvent + VkCommandBuffer commandBuffer + VkEvent event + VkPipelineStageFlags stageMask + + + void vkCmdResetEvent + VkCommandBuffer commandBuffer + VkEvent event + VkPipelineStageFlags stageMask + + + void vkCmdWaitEvents + VkCommandBuffer commandBuffer + uint32_t eventCount + const VkEvent* pEvents + VkPipelineStageFlags srcStageMask + VkPipelineStageFlags dstStageMask + uint32_t memoryBarrierCount + const VkMemoryBarrier* pMemoryBarriers + uint32_t bufferMemoryBarrierCount + const VkBufferMemoryBarrier* pBufferMemoryBarriers + uint32_t imageMemoryBarrierCount + const VkImageMemoryBarrier* pImageMemoryBarriers + + + void vkCmdPipelineBarrier + VkCommandBuffer commandBuffer + VkPipelineStageFlags srcStageMask + VkPipelineStageFlags dstStageMask + VkDependencyFlags dependencyFlags + uint32_t memoryBarrierCount + const VkMemoryBarrier* pMemoryBarriers + uint32_t bufferMemoryBarrierCount + const VkBufferMemoryBarrier* pBufferMemoryBarriers + uint32_t imageMemoryBarrierCount + const VkImageMemoryBarrier* pImageMemoryBarriers + + + void vkCmdBeginQuery + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t query + VkQueryControlFlags flags + + + void vkCmdEndQuery + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t query + + + void vkCmdBeginConditionalRenderingEXT + VkCommandBuffer commandBuffer + const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin + + + void vkCmdEndConditionalRenderingEXT + VkCommandBuffer commandBuffer + + + void vkCmdResetQueryPool + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t firstQuery + uint32_t queryCount + + + void vkCmdWriteTimestamp + VkCommandBuffer commandBuffer + VkPipelineStageFlagBits pipelineStage + VkQueryPool queryPool + uint32_t query + + + void vkCmdCopyQueryPoolResults + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t firstQuery + uint32_t queryCount + VkBuffer dstBuffer + VkDeviceSize dstOffset + VkDeviceSize stride + VkQueryResultFlags flags + + + void vkCmdPushConstants + VkCommandBuffer commandBuffer + VkPipelineLayout layout + VkShaderStageFlags stageFlags + uint32_t offset + uint32_t size + const void* pValues + + + void vkCmdBeginRenderPass + VkCommandBuffer commandBuffer + const VkRenderPassBeginInfo* pRenderPassBegin + VkSubpassContents contents + + + void vkCmdNextSubpass + VkCommandBuffer commandBuffer + VkSubpassContents contents + + + void vkCmdEndRenderPass + VkCommandBuffer commandBuffer + + + void vkCmdExecuteCommands + VkCommandBuffer commandBuffer + uint32_t commandBufferCount + const VkCommandBuffer* pCommandBuffers + + + VkResult vkCreateAndroidSurfaceKHR + VkInstance instance + const VkAndroidSurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateSurfaceOHOS + VkInstance instance + const VkSurfaceCreateInfoOHOS* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkGetPhysicalDeviceDisplayPropertiesKHR + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkDisplayPropertiesKHR* pProperties + + + VkResult vkGetPhysicalDeviceDisplayPlanePropertiesKHR + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkDisplayPlanePropertiesKHR* pProperties + + + VkResult vkGetDisplayPlaneSupportedDisplaysKHR + VkPhysicalDevice physicalDevice + uint32_t planeIndex + uint32_t* pDisplayCount + VkDisplayKHR* pDisplays + + + VkResult vkGetDisplayModePropertiesKHR + VkPhysicalDevice physicalDevice + VkDisplayKHR display + uint32_t* pPropertyCount + VkDisplayModePropertiesKHR* pProperties + + + VkResult vkCreateDisplayModeKHR + VkPhysicalDevice physicalDevice + VkDisplayKHR display + const VkDisplayModeCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDisplayModeKHR* pMode + + + VkResult vkGetDisplayPlaneCapabilitiesKHR + VkPhysicalDevice physicalDevice + VkDisplayModeKHR mode + uint32_t planeIndex + VkDisplayPlaneCapabilitiesKHR* pCapabilities + + + VkResult vkCreateDisplayPlaneSurfaceKHR + VkInstance instance + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateSharedSwapchainsKHR + VkDevice device + uint32_t swapchainCount + const VkSwapchainCreateInfoKHR* pCreateInfos + const VkSwapchainCreateInfoKHR* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkSwapchainKHR* pSwapchains + + + void vkDestroySurfaceKHR + VkInstance instance + VkSurfaceKHR surface + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetPhysicalDeviceSurfaceSupportKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + VkSurfaceKHR surface + VkBool32* pSupported + + + VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR + VkPhysicalDevice physicalDevice + VkSurfaceKHR surface + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities + + + VkResult vkGetPhysicalDeviceSurfaceFormatsKHR + VkPhysicalDevice physicalDevice + VkSurfaceKHR surface + uint32_t* pSurfaceFormatCount + VkSurfaceFormatKHR* pSurfaceFormats + + + VkResult vkGetPhysicalDeviceSurfacePresentModesKHR + VkPhysicalDevice physicalDevice + VkSurfaceKHR surface + uint32_t* pPresentModeCount + VkPresentModeKHR* pPresentModes + + + VkResult vkCreateSwapchainKHR + VkDevice device + const VkSwapchainCreateInfoKHR* pCreateInfo + const VkSwapchainCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSwapchainKHR* pSwapchain + + + void vkDestroySwapchainKHR + VkDevice device + VkSwapchainKHR swapchain + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetSwapchainImagesKHR + VkDevice device + VkSwapchainKHR swapchain + uint32_t* pSwapchainImageCount + VkImage* pSwapchainImages + + + VkResult vkAcquireNextImageKHR + VkDevice device + VkSwapchainKHR swapchain + uint64_t timeout + VkSemaphore semaphore + VkFence fence + uint32_t* pImageIndex + + + VkResult vkQueuePresentKHR + VkQueue queue + const VkPresentInfoKHR* pPresentInfo + + + VkResult vkCreateViSurfaceNN + VkInstance instance + const VkViSurfaceCreateInfoNN* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateWaylandSurfaceKHR + VkInstance instance + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceWaylandPresentationSupportKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + struct wl_display* display + + + VkResult vkCreateWin32SurfaceKHR + VkInstance instance + const VkWin32SurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + + + VkResult vkCreateXlibSurfaceKHR + VkInstance instance + const VkXlibSurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceXlibPresentationSupportKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + Display* dpy + VisualID visualID + + + VkResult vkCreateXcbSurfaceKHR + VkInstance instance + const VkXcbSurfaceCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceXcbPresentationSupportKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + xcb_connection_t* connection + xcb_visualid_t visual_id + + + VkResult vkCreateDirectFBSurfaceEXT + VkInstance instance + const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceDirectFBPresentationSupportEXT + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + IDirectFB* dfb + + + VkResult vkCreateImagePipeSurfaceFUCHSIA + VkInstance instance + const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateStreamDescriptorSurfaceGGP + VkInstance instance + const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateScreenSurfaceQNX + VkInstance instance + const VkScreenSurfaceCreateInfoQNX* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkBool32 vkGetPhysicalDeviceScreenPresentationSupportQNX + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + struct _screen_window* window + + + VkResult vkCreateDebugReportCallbackEXT + VkInstance instance + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDebugReportCallbackEXT* pCallback + + + void vkDestroyDebugReportCallbackEXT + VkInstance instance + VkDebugReportCallbackEXT callback + const VkAllocationCallbacks* pAllocator + + + void vkDebugReportMessageEXT + VkInstance instance + VkDebugReportFlagsEXT flags + VkDebugReportObjectTypeEXT objectType + uint64_t object + size_t location + int32_t messageCode + const char* pLayerPrefix + const char* pMessage + + + VkResult vkDebugMarkerSetObjectNameEXT + VkDevice device + const VkDebugMarkerObjectNameInfoEXT* pNameInfo + + + VkResult vkDebugMarkerSetObjectTagEXT + VkDevice device + const VkDebugMarkerObjectTagInfoEXT* pTagInfo + + + void vkCmdDebugMarkerBeginEXT + VkCommandBuffer commandBuffer + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo + + + void vkCmdDebugMarkerEndEXT + VkCommandBuffer commandBuffer + + + void vkCmdDebugMarkerInsertEXT + VkCommandBuffer commandBuffer + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo + + + VkResult vkGetPhysicalDeviceExternalImageFormatPropertiesNV + VkPhysicalDevice physicalDevice + VkFormat format + VkImageType type + VkImageTiling tiling + VkImageUsageFlags usage + VkImageCreateFlags flags + VkExternalMemoryHandleTypeFlagsNV externalHandleType + VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties + + + VkResult vkGetMemoryWin32HandleNV + VkDevice device + VkDeviceMemory memory + VkExternalMemoryHandleTypeFlagsNV handleType + HANDLE* pHandle + + + void vkCmdExecuteGeneratedCommandsNV + VkCommandBuffer commandBuffer + VkBool32 isPreprocessed + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo + + + void vkCmdPreprocessGeneratedCommandsNV + VkCommandBuffer commandBuffer + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo + + + void vkCmdBindPipelineShaderGroupNV + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipeline pipeline + uint32_t groupIndex + + + void vkGetGeneratedCommandsMemoryRequirementsNV + VkDevice device + const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + VkResult vkCreateIndirectCommandsLayoutNV + VkDevice device + const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkIndirectCommandsLayoutNV* pIndirectCommandsLayout + + + void vkDestroyIndirectCommandsLayoutNV + VkDevice device + VkIndirectCommandsLayoutNV indirectCommandsLayout + const VkAllocationCallbacks* pAllocator + + + void vkCmdExecuteGeneratedCommandsEXT + VkCommandBuffer commandBuffer + VkBool32 isPreprocessed + const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo + + + void vkCmdPreprocessGeneratedCommandsEXT + VkCommandBuffer commandBuffer + const VkGeneratedCommandsInfoEXT* pGeneratedCommandsInfo + VkCommandBuffer stateCommandBuffer + + + void vkGetGeneratedCommandsMemoryRequirementsEXT + VkDevice device + const VkGeneratedCommandsMemoryRequirementsInfoEXT* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + VkResult vkCreateIndirectCommandsLayoutEXT + VkDevice device + const VkIndirectCommandsLayoutCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkIndirectCommandsLayoutEXT* pIndirectCommandsLayout + + + void vkDestroyIndirectCommandsLayoutEXT + VkDevice device + VkIndirectCommandsLayoutEXT indirectCommandsLayout + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateIndirectExecutionSetEXT + VkDevice device + const VkIndirectExecutionSetCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkIndirectExecutionSetEXT* pIndirectExecutionSet + + + void vkDestroyIndirectExecutionSetEXT + VkDevice device + VkIndirectExecutionSetEXT indirectExecutionSet + const VkAllocationCallbacks* pAllocator + + + void vkUpdateIndirectExecutionSetPipelineEXT + VkDevice device + VkIndirectExecutionSetEXT indirectExecutionSet + uint32_t executionSetWriteCount + const VkWriteIndirectExecutionSetPipelineEXT* pExecutionSetWrites + + + void vkUpdateIndirectExecutionSetShaderEXT + VkDevice device + VkIndirectExecutionSetEXT indirectExecutionSet + uint32_t executionSetWriteCount + const VkWriteIndirectExecutionSetShaderEXT* pExecutionSetWrites + + + void vkGetPhysicalDeviceFeatures2 + VkPhysicalDevice physicalDevice + VkPhysicalDeviceFeatures2* pFeatures + + + + void vkGetPhysicalDeviceProperties2 + VkPhysicalDevice physicalDevice + VkPhysicalDeviceProperties2* pProperties + + + + void vkGetPhysicalDeviceFormatProperties2 + VkPhysicalDevice physicalDevice + VkFormat format + VkFormatProperties2* pFormatProperties + + + + VkResult vkGetPhysicalDeviceImageFormatProperties2 + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo + VkImageFormatProperties2* pImageFormatProperties + + + + void vkGetPhysicalDeviceQueueFamilyProperties2 + VkPhysicalDevice physicalDevice + uint32_t* pQueueFamilyPropertyCount + VkQueueFamilyProperties2* pQueueFamilyProperties + + + + void vkGetPhysicalDeviceMemoryProperties2 + VkPhysicalDevice physicalDevice + VkPhysicalDeviceMemoryProperties2* pMemoryProperties + + + + void vkGetPhysicalDeviceSparseImageFormatProperties2 + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo + uint32_t* pPropertyCount + VkSparseImageFormatProperties2* pProperties + + + + void vkCmdPushDescriptorSet + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipelineLayout layout + uint32_t set + uint32_t descriptorWriteCount + const VkWriteDescriptorSet* pDescriptorWrites + + + + void vkTrimCommandPool + VkDevice device + VkCommandPool commandPool + VkCommandPoolTrimFlags flags + + + + void vkGetPhysicalDeviceExternalBufferProperties + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo + VkExternalBufferProperties* pExternalBufferProperties + + + + VkResult vkGetMemoryWin32HandleKHR + VkDevice device + const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo + HANDLE* pHandle + + + VkResult vkGetMemoryWin32HandlePropertiesKHR + VkDevice device + VkExternalMemoryHandleTypeFlagBits handleType + HANDLE handle + VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties + + + VkResult vkGetMemoryFdKHR + VkDevice device + const VkMemoryGetFdInfoKHR* pGetFdInfo + int* pFd + + + VkResult vkGetMemoryFdPropertiesKHR + VkDevice device + VkExternalMemoryHandleTypeFlagBits handleType + int fd + VkMemoryFdPropertiesKHR* pMemoryFdProperties + + + VkResult vkGetMemoryZirconHandleFUCHSIA + VkDevice device + const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo + zx_handle_t* pZirconHandle + + + VkResult vkGetMemoryZirconHandlePropertiesFUCHSIA + VkDevice device + VkExternalMemoryHandleTypeFlagBits handleType + zx_handle_t zirconHandle + VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties + + + VkResult vkGetMemoryRemoteAddressNV + VkDevice device + const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo + VkRemoteAddressNV* pAddress + + + VkResult vkGetMemorySciBufNV + VkDevice device + const VkMemoryGetSciBufInfoNV* pGetSciBufInfo + NvSciBufObj* pHandle + + + VkResult vkGetPhysicalDeviceExternalMemorySciBufPropertiesNV + VkPhysicalDevice physicalDevice + VkExternalMemoryHandleTypeFlagBits handleType + NvSciBufObj handle + VkMemorySciBufPropertiesNV* pMemorySciBufProperties + + + VkResult vkGetPhysicalDeviceSciBufAttributesNV + VkPhysicalDevice physicalDevice + NvSciBufAttrList pAttributes + + + void vkGetPhysicalDeviceExternalSemaphoreProperties + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo + VkExternalSemaphoreProperties* pExternalSemaphoreProperties + + + + VkResult vkGetSemaphoreWin32HandleKHR + VkDevice device + const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo + HANDLE* pHandle + + + VkResult vkImportSemaphoreWin32HandleKHR + VkDevice device + const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo + + + VkResult vkGetSemaphoreFdKHR + VkDevice device + const VkSemaphoreGetFdInfoKHR* pGetFdInfo + int* pFd + + + VkResult vkImportSemaphoreFdKHR + VkDevice device + const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo + + + VkResult vkGetSemaphoreZirconHandleFUCHSIA + VkDevice device + const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo + zx_handle_t* pZirconHandle + + + VkResult vkImportSemaphoreZirconHandleFUCHSIA + VkDevice device + const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo + + + void vkGetPhysicalDeviceExternalFenceProperties + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo + VkExternalFenceProperties* pExternalFenceProperties + + + + VkResult vkGetFenceWin32HandleKHR + VkDevice device + const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo + HANDLE* pHandle + + + VkResult vkImportFenceWin32HandleKHR + VkDevice device + const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo + + + VkResult vkGetFenceFdKHR + VkDevice device + const VkFenceGetFdInfoKHR* pGetFdInfo + int* pFd + + + VkResult vkImportFenceFdKHR + VkDevice device + const VkImportFenceFdInfoKHR* pImportFenceFdInfo + + + VkResult vkGetFenceSciSyncFenceNV + VkDevice device + const VkFenceGetSciSyncInfoNV* pGetSciSyncHandleInfo + void* pHandle + + + VkResult vkGetFenceSciSyncObjNV + VkDevice device + const VkFenceGetSciSyncInfoNV* pGetSciSyncHandleInfo + void* pHandle + + + VkResult vkImportFenceSciSyncFenceNV + VkDevice device + const VkImportFenceSciSyncInfoNV* pImportFenceSciSyncInfo + + + VkResult vkImportFenceSciSyncObjNV + VkDevice device + const VkImportFenceSciSyncInfoNV* pImportFenceSciSyncInfo + + + VkResult vkGetSemaphoreSciSyncObjNV + VkDevice device + const VkSemaphoreGetSciSyncInfoNV* pGetSciSyncInfo + void* pHandle + + + VkResult vkImportSemaphoreSciSyncObjNV + VkDevice device + const VkImportSemaphoreSciSyncInfoNV* pImportSemaphoreSciSyncInfo + + + VkResult vkGetPhysicalDeviceSciSyncAttributesNV + VkPhysicalDevice physicalDevice + const VkSciSyncAttributesInfoNV* pSciSyncAttributesInfo + NvSciSyncAttrList pAttributes + + + VkResult vkCreateSemaphoreSciSyncPoolNV + VkDevice device + const VkSemaphoreSciSyncPoolCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSemaphoreSciSyncPoolNV* pSemaphorePool + + + void vkDestroySemaphoreSciSyncPoolNV + VkDevice device + VkSemaphoreSciSyncPoolNV semaphorePool + const VkAllocationCallbacks* pAllocator + + + VkResult vkReleaseDisplayEXT + VkPhysicalDevice physicalDevice + VkDisplayKHR display + + + VkResult vkAcquireXlibDisplayEXT + VkPhysicalDevice physicalDevice + Display* dpy + VkDisplayKHR display + + + VkResult vkGetRandROutputDisplayEXT + VkPhysicalDevice physicalDevice + Display* dpy + RROutput rrOutput + VkDisplayKHR* pDisplay + + + VkResult vkAcquireWinrtDisplayNV + VkPhysicalDevice physicalDevice + VkDisplayKHR display + + + VkResult vkGetWinrtDisplayNV + VkPhysicalDevice physicalDevice + uint32_t deviceRelativeId + VkDisplayKHR* pDisplay + + + VkResult vkDisplayPowerControlEXT + VkDevice device + VkDisplayKHR display + const VkDisplayPowerInfoEXT* pDisplayPowerInfo + + + VkResult vkRegisterDeviceEventEXT + VkDevice device + const VkDeviceEventInfoEXT* pDeviceEventInfo + const VkAllocationCallbacks* pAllocator + VkFence* pFence + + + VkResult vkRegisterDisplayEventEXT + VkDevice device + VkDisplayKHR display + const VkDisplayEventInfoEXT* pDisplayEventInfo + const VkAllocationCallbacks* pAllocator + VkFence* pFence + + + VkResult vkGetSwapchainCounterEXT + VkDevice device + VkSwapchainKHR swapchain + VkSurfaceCounterFlagBitsEXT counter + uint64_t* pCounterValue + + + VkResult vkGetPhysicalDeviceSurfaceCapabilities2EXT + VkPhysicalDevice physicalDevice + VkSurfaceKHR surface + VkSurfaceCapabilities2EXT* pSurfaceCapabilities + + + VkResult vkEnumeratePhysicalDeviceGroups + VkInstance instance + uint32_t* pPhysicalDeviceGroupCount + VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties + + + + void vkGetDeviceGroupPeerMemoryFeatures + VkDevice device + uint32_t heapIndex + uint32_t localDeviceIndex + uint32_t remoteDeviceIndex + VkPeerMemoryFeatureFlags* pPeerMemoryFeatures + + + + VkResult vkBindBufferMemory2 + VkDevice device + uint32_t bindInfoCount + const VkBindBufferMemoryInfo* pBindInfos + + + + VkResult vkBindImageMemory2 + VkDevice device + uint32_t bindInfoCount + const VkBindImageMemoryInfo* pBindInfos + + + + void vkCmdSetDeviceMask + VkCommandBuffer commandBuffer + uint32_t deviceMask + + + + VkResult vkGetDeviceGroupPresentCapabilitiesKHR + VkDevice device + VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities + + + VkResult vkGetDeviceGroupSurfacePresentModesKHR + VkDevice device + VkSurfaceKHR surface + VkDeviceGroupPresentModeFlagsKHR* pModes + + + VkResult vkAcquireNextImage2KHR + VkDevice device + const VkAcquireNextImageInfoKHR* pAcquireInfo + uint32_t* pImageIndex + + + void vkCmdDispatchBase + VkCommandBuffer commandBuffer + uint32_t baseGroupX + uint32_t baseGroupY + uint32_t baseGroupZ + uint32_t groupCountX + uint32_t groupCountY + uint32_t groupCountZ + + + + VkResult vkGetPhysicalDevicePresentRectanglesKHR + VkPhysicalDevice physicalDevice + VkSurfaceKHR surface + uint32_t* pRectCount + VkRect2D* pRects + + + VkResult vkCreateDescriptorUpdateTemplate + VkDevice device + const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate + + + + void vkDestroyDescriptorUpdateTemplate + VkDevice device + VkDescriptorUpdateTemplate descriptorUpdateTemplate + const VkAllocationCallbacks* pAllocator + + + + void vkUpdateDescriptorSetWithTemplate + VkDevice device + VkDescriptorSet descriptorSet + VkDescriptorUpdateTemplate descriptorUpdateTemplate + const void* pData + + + + void vkCmdPushDescriptorSetWithTemplate + VkCommandBuffer commandBuffer + VkDescriptorUpdateTemplate descriptorUpdateTemplate + VkPipelineLayout layout + uint32_t set + const void* pData + + + + void vkSetHdrMetadataEXT + VkDevice device + uint32_t swapchainCount + const VkSwapchainKHR* pSwapchains + const VkHdrMetadataEXT* pMetadata + + + VkResult vkGetSwapchainStatusKHR + VkDevice device + VkSwapchainKHR swapchain + + + VkResult vkGetRefreshCycleDurationGOOGLE + VkDevice device + VkSwapchainKHR swapchain + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties + + + VkResult vkGetPastPresentationTimingGOOGLE + VkDevice device + VkSwapchainKHR swapchain + uint32_t* pPresentationTimingCount + VkPastPresentationTimingGOOGLE* pPresentationTimings + + + VkResult vkCreateIOSSurfaceMVK + VkInstance instance + const VkIOSSurfaceCreateInfoMVK* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateMacOSSurfaceMVK + VkInstance instance + const VkMacOSSurfaceCreateInfoMVK* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkCreateMetalSurfaceEXT + VkInstance instance + const VkMetalSurfaceCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + void vkCmdSetViewportWScalingNV + VkCommandBuffer commandBuffer + uint32_t firstViewport + uint32_t viewportCount + const VkViewportWScalingNV* pViewportWScalings + + + void vkCmdSetDiscardRectangleEXT + VkCommandBuffer commandBuffer + uint32_t firstDiscardRectangle + uint32_t discardRectangleCount + const VkRect2D* pDiscardRectangles + + + void vkCmdSetDiscardRectangleEnableEXT + VkCommandBuffer commandBuffer + VkBool32 discardRectangleEnable + + + void vkCmdSetDiscardRectangleModeEXT + VkCommandBuffer commandBuffer + VkDiscardRectangleModeEXT discardRectangleMode + + + void vkCmdSetSampleLocationsEXT + VkCommandBuffer commandBuffer + const VkSampleLocationsInfoEXT* pSampleLocationsInfo + + + void vkGetPhysicalDeviceMultisamplePropertiesEXT + VkPhysicalDevice physicalDevice + VkSampleCountFlagBits samples + VkMultisamplePropertiesEXT* pMultisampleProperties + + + VkResult vkGetPhysicalDeviceSurfaceCapabilities2KHR + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo + VkSurfaceCapabilities2KHR* pSurfaceCapabilities + + + VkResult vkGetPhysicalDeviceSurfaceFormats2KHR + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo + uint32_t* pSurfaceFormatCount + VkSurfaceFormat2KHR* pSurfaceFormats + + + VkResult vkGetPhysicalDeviceDisplayProperties2KHR + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkDisplayProperties2KHR* pProperties + + + VkResult vkGetPhysicalDeviceDisplayPlaneProperties2KHR + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkDisplayPlaneProperties2KHR* pProperties + + + VkResult vkGetDisplayModeProperties2KHR + VkPhysicalDevice physicalDevice + VkDisplayKHR display + uint32_t* pPropertyCount + VkDisplayModeProperties2KHR* pProperties + + + VkResult vkGetDisplayPlaneCapabilities2KHR + VkPhysicalDevice physicalDevice + const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo + VkDisplayPlaneCapabilities2KHR* pCapabilities + + + void vkGetBufferMemoryRequirements2 + VkDevice device + const VkBufferMemoryRequirementsInfo2* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + + void vkGetImageMemoryRequirements2 + VkDevice device + const VkImageMemoryRequirementsInfo2* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + + void vkGetImageSparseMemoryRequirements2 + VkDevice device + const VkImageSparseMemoryRequirementsInfo2* pInfo + uint32_t* pSparseMemoryRequirementCount + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements + + + + void vkGetDeviceBufferMemoryRequirements + VkDevice device + const VkDeviceBufferMemoryRequirements* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + + void vkGetDeviceImageMemoryRequirements + VkDevice device + const VkDeviceImageMemoryRequirements* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + + void vkGetDeviceImageSparseMemoryRequirements + VkDevice device + const VkDeviceImageMemoryRequirements* pInfo + uint32_t* pSparseMemoryRequirementCount + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements + + + + VkResult vkCreateSamplerYcbcrConversion + VkDevice device + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSamplerYcbcrConversion* pYcbcrConversion + + + + void vkDestroySamplerYcbcrConversion + VkDevice device + VkSamplerYcbcrConversion ycbcrConversion + const VkAllocationCallbacks* pAllocator + + + + void vkGetDeviceQueue2 + VkDevice device + const VkDeviceQueueInfo2* pQueueInfo + VkQueue* pQueue + + + VkResult vkCreateValidationCacheEXT + VkDevice device + const VkValidationCacheCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkValidationCacheEXT* pValidationCache + + + void vkDestroyValidationCacheEXT + VkDevice device + VkValidationCacheEXT validationCache + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetValidationCacheDataEXT + VkDevice device + VkValidationCacheEXT validationCache + size_t* pDataSize + void* pData + + + VkResult vkMergeValidationCachesEXT + VkDevice device + VkValidationCacheEXT dstCache + uint32_t srcCacheCount + const VkValidationCacheEXT* pSrcCaches + + + void vkGetDescriptorSetLayoutSupport + VkDevice device + const VkDescriptorSetLayoutCreateInfo* pCreateInfo + VkDescriptorSetLayoutSupport* pSupport + + + + VkResult vkGetSwapchainGrallocUsageANDROID + VkDevice device + VkFormat format + VkImageUsageFlags imageUsage + int* grallocUsage + + + VkResult vkGetSwapchainGrallocUsage2ANDROID + VkDevice device + VkFormat format + VkImageUsageFlags imageUsage + VkSwapchainImageUsageFlagsANDROID swapchainImageUsage + uint64_t* grallocConsumerUsage + uint64_t* grallocProducerUsage + + + VkResult vkAcquireImageANDROID + VkDevice device + VkImage image + int nativeFenceFd + VkSemaphore semaphore + VkFence fence + + + VkResult vkQueueSignalReleaseImageANDROID + VkQueue queue + uint32_t waitSemaphoreCount + const VkSemaphore* pWaitSemaphores + VkImage image + int* pNativeFenceFd + + + VkResult vkGetShaderInfoAMD + VkDevice device + VkPipeline pipeline + VkShaderStageFlagBits shaderStage + VkShaderInfoTypeAMD infoType + size_t* pInfoSize + void* pInfo + + + void vkSetLocalDimmingAMD + VkDevice device + VkSwapchainKHR swapChain + VkBool32 localDimmingEnable + + + VkResult vkGetPhysicalDeviceCalibrateableTimeDomainsKHR + VkPhysicalDevice physicalDevice + uint32_t* pTimeDomainCount + VkTimeDomainKHR* pTimeDomains + + + + VkResult vkGetCalibratedTimestampsKHR + VkDevice device + uint32_t timestampCount + const VkCalibratedTimestampInfoKHR* pTimestampInfos + uint64_t* pTimestamps + uint64_t* pMaxDeviation + + + + VkResult vkSetDebugUtilsObjectNameEXT + VkDevice device + const VkDebugUtilsObjectNameInfoEXT* pNameInfo + + + VkResult vkSetDebugUtilsObjectTagEXT + VkDevice device + const VkDebugUtilsObjectTagInfoEXT* pTagInfo + + + void vkQueueBeginDebugUtilsLabelEXT + VkQueue queue + const VkDebugUtilsLabelEXT* pLabelInfo + + + void vkQueueEndDebugUtilsLabelEXT + VkQueue queue + + + void vkQueueInsertDebugUtilsLabelEXT + VkQueue queue + const VkDebugUtilsLabelEXT* pLabelInfo + + + void vkCmdBeginDebugUtilsLabelEXT + VkCommandBuffer commandBuffer + const VkDebugUtilsLabelEXT* pLabelInfo + + + void vkCmdEndDebugUtilsLabelEXT + VkCommandBuffer commandBuffer + + + void vkCmdInsertDebugUtilsLabelEXT + VkCommandBuffer commandBuffer + const VkDebugUtilsLabelEXT* pLabelInfo + + + VkResult vkCreateDebugUtilsMessengerEXT + VkInstance instance + const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDebugUtilsMessengerEXT* pMessenger + + + void vkDestroyDebugUtilsMessengerEXT + VkInstance instance + VkDebugUtilsMessengerEXT messenger + const VkAllocationCallbacks* pAllocator + + + void vkSubmitDebugUtilsMessageEXT + VkInstance instance + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity + VkDebugUtilsMessageTypeFlagsEXT messageTypes + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData + + + VkResult vkGetMemoryHostPointerPropertiesEXT + VkDevice device + VkExternalMemoryHandleTypeFlagBits handleType + const void* pHostPointer + VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties + + + void vkCmdWriteBufferMarkerAMD + VkCommandBuffer commandBuffer + VkPipelineStageFlagBits pipelineStage + VkBuffer dstBuffer + VkDeviceSize dstOffset + uint32_t marker + + + VkResult vkCreateRenderPass2 + VkDevice device + const VkRenderPassCreateInfo2* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkRenderPass* pRenderPass + + + + void vkCmdBeginRenderPass2 + VkCommandBuffer commandBuffer + const VkRenderPassBeginInfo* pRenderPassBegin + const VkSubpassBeginInfo* pSubpassBeginInfo + + + + void vkCmdNextSubpass2 + VkCommandBuffer commandBuffer + const VkSubpassBeginInfo* pSubpassBeginInfo + const VkSubpassEndInfo* pSubpassEndInfo + + + + void vkCmdEndRenderPass2 + VkCommandBuffer commandBuffer + const VkSubpassEndInfo* pSubpassEndInfo + + + + VkResult vkGetSemaphoreCounterValue + VkDevice device + VkSemaphore semaphore + uint64_t* pValue + + + + VkResult vkWaitSemaphores + VkDevice device + const VkSemaphoreWaitInfo* pWaitInfo + uint64_t timeout + + + + VkResult vkSignalSemaphore + VkDevice device + const VkSemaphoreSignalInfo* pSignalInfo + + + + VkResult vkGetAndroidHardwareBufferPropertiesANDROID + VkDevice device + const struct AHardwareBuffer* buffer + VkAndroidHardwareBufferPropertiesANDROID* pProperties + + + VkResult vkGetMemoryAndroidHardwareBufferANDROID + VkDevice device + const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo + struct AHardwareBuffer** pBuffer + + + void vkCmdDrawIndirectCount + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkBuffer countBuffer + VkDeviceSize countBufferOffset + uint32_t maxDrawCount + uint32_t stride + + + + + void vkCmdDrawIndexedIndirectCount + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkBuffer countBuffer + VkDeviceSize countBufferOffset + uint32_t maxDrawCount + uint32_t stride + + + + + void vkCmdSetCheckpointNV + VkCommandBuffer commandBuffer + const void* pCheckpointMarker + + + void vkGetQueueCheckpointDataNV + VkQueue queue + uint32_t* pCheckpointDataCount + VkCheckpointDataNV* pCheckpointData + + + void vkCmdBindTransformFeedbackBuffersEXT + VkCommandBuffer commandBuffer + uint32_t firstBinding + uint32_t bindingCount + const VkBuffer* pBuffers + const VkDeviceSize* pOffsets + const VkDeviceSize* pSizes + + + void vkCmdBeginTransformFeedbackEXT + VkCommandBuffer commandBuffer + uint32_t firstCounterBuffer + uint32_t counterBufferCount + const VkBuffer* pCounterBuffers + const VkDeviceSize* pCounterBufferOffsets + + + void vkCmdEndTransformFeedbackEXT + VkCommandBuffer commandBuffer + uint32_t firstCounterBuffer + uint32_t counterBufferCount + const VkBuffer* pCounterBuffers + const VkDeviceSize* pCounterBufferOffsets + + + void vkCmdBeginQueryIndexedEXT + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t query + VkQueryControlFlags flags + uint32_t index + + + void vkCmdEndQueryIndexedEXT + VkCommandBuffer commandBuffer + VkQueryPool queryPool + uint32_t query + uint32_t index + + + void vkCmdDrawIndirectByteCountEXT + VkCommandBuffer commandBuffer + uint32_t instanceCount + uint32_t firstInstance + VkBuffer counterBuffer + VkDeviceSize counterBufferOffset + uint32_t counterOffset + uint32_t vertexStride + + + void vkCmdSetExclusiveScissorNV + VkCommandBuffer commandBuffer + uint32_t firstExclusiveScissor + uint32_t exclusiveScissorCount + const VkRect2D* pExclusiveScissors + + + void vkCmdSetExclusiveScissorEnableNV + VkCommandBuffer commandBuffer + uint32_t firstExclusiveScissor + uint32_t exclusiveScissorCount + const VkBool32* pExclusiveScissorEnables + + + void vkCmdBindShadingRateImageNV + VkCommandBuffer commandBuffer + VkImageView imageView + VkImageLayout imageLayout + + + void vkCmdSetViewportShadingRatePaletteNV + VkCommandBuffer commandBuffer + uint32_t firstViewport + uint32_t viewportCount + const VkShadingRatePaletteNV* pShadingRatePalettes + + + void vkCmdSetCoarseSampleOrderNV + VkCommandBuffer commandBuffer + VkCoarseSampleOrderTypeNV sampleOrderType + uint32_t customSampleOrderCount + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders + + + void vkCmdDrawMeshTasksNV + VkCommandBuffer commandBuffer + uint32_t taskCount + uint32_t firstTask + + + void vkCmdDrawMeshTasksIndirectNV + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + uint32_t drawCount + uint32_t stride + + + void vkCmdDrawMeshTasksIndirectCountNV + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkBuffer countBuffer + VkDeviceSize countBufferOffset + uint32_t maxDrawCount + uint32_t stride + + + void vkCmdDrawMeshTasksEXT + VkCommandBuffer commandBuffer + uint32_t groupCountX + uint32_t groupCountY + uint32_t groupCountZ + + + void vkCmdDrawMeshTasksIndirectEXT + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + uint32_t drawCount + uint32_t stride + + + void vkCmdDrawMeshTasksIndirectCountEXT + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkBuffer countBuffer + VkDeviceSize countBufferOffset + uint32_t maxDrawCount + uint32_t stride + + + VkResult vkCompileDeferredNV + VkDevice device + VkPipeline pipeline + uint32_t shader + + + VkResult vkCreateAccelerationStructureNV + VkDevice device + const VkAccelerationStructureCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkAccelerationStructureNV* pAccelerationStructure + + + void vkCmdBindInvocationMaskHUAWEI + VkCommandBuffer commandBuffer + VkImageView imageView + VkImageLayout imageLayout + + + void vkDestroyAccelerationStructureKHR + VkDevice device + VkAccelerationStructureKHR accelerationStructure + const VkAllocationCallbacks* pAllocator + + + void vkDestroyAccelerationStructureNV + VkDevice device + VkAccelerationStructureNV accelerationStructure + const VkAllocationCallbacks* pAllocator + + + void vkGetAccelerationStructureMemoryRequirementsNV + VkDevice device + const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo + VkMemoryRequirements2KHR* pMemoryRequirements + + + VkResult vkBindAccelerationStructureMemoryNV + VkDevice device + uint32_t bindInfoCount + const VkBindAccelerationStructureMemoryInfoNV* pBindInfos + + + void vkCmdCopyAccelerationStructureNV + VkCommandBuffer commandBuffer + VkAccelerationStructureNV dst + VkAccelerationStructureNV src + VkCopyAccelerationStructureModeKHR mode + + + void vkCmdCopyAccelerationStructureKHR + VkCommandBuffer commandBuffer + const VkCopyAccelerationStructureInfoKHR* pInfo + + + VkResult vkCopyAccelerationStructureKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyAccelerationStructureInfoKHR* pInfo + + + void vkCmdCopyAccelerationStructureToMemoryKHR + VkCommandBuffer commandBuffer + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo + + + VkResult vkCopyAccelerationStructureToMemoryKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo + + + void vkCmdCopyMemoryToAccelerationStructureKHR + VkCommandBuffer commandBuffer + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo + + + VkResult vkCopyMemoryToAccelerationStructureKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo + + + void vkCmdWriteAccelerationStructuresPropertiesKHR + VkCommandBuffer commandBuffer + uint32_t accelerationStructureCount + const VkAccelerationStructureKHR* pAccelerationStructures + VkQueryType queryType + VkQueryPool queryPool + uint32_t firstQuery + + + void vkCmdWriteAccelerationStructuresPropertiesNV + VkCommandBuffer commandBuffer + uint32_t accelerationStructureCount + const VkAccelerationStructureNV* pAccelerationStructures + VkQueryType queryType + VkQueryPool queryPool + uint32_t firstQuery + + + void vkCmdBuildAccelerationStructureNV + VkCommandBuffer commandBuffer + const VkAccelerationStructureInfoNV* pInfo + VkBuffer instanceData + VkDeviceSize instanceOffset + VkBool32 update + VkAccelerationStructureNV dst + VkAccelerationStructureNV src + VkBuffer scratch + VkDeviceSize scratchOffset + + + VkResult vkWriteAccelerationStructuresPropertiesKHR + VkDevice device + uint32_t accelerationStructureCount + const VkAccelerationStructureKHR* pAccelerationStructures + VkQueryType queryType + size_t dataSize + void* pData + size_t stride + + + void vkCmdTraceRaysKHR + VkCommandBuffer commandBuffer + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable + uint32_t width + uint32_t height + uint32_t depth + + + void vkCmdTraceRaysNV + VkCommandBuffer commandBuffer + VkBuffer raygenShaderBindingTableBuffer + VkDeviceSize raygenShaderBindingOffset + VkBuffer missShaderBindingTableBuffer + VkDeviceSize missShaderBindingOffset + VkDeviceSize missShaderBindingStride + VkBuffer hitShaderBindingTableBuffer + VkDeviceSize hitShaderBindingOffset + VkDeviceSize hitShaderBindingStride + VkBuffer callableShaderBindingTableBuffer + VkDeviceSize callableShaderBindingOffset + VkDeviceSize callableShaderBindingStride + uint32_t width + uint32_t height + uint32_t depth + + + VkResult vkGetRayTracingShaderGroupHandlesKHR + VkDevice device + VkPipeline pipeline + uint32_t firstGroup + uint32_t groupCount + size_t dataSize + void* pData + + + + VkResult vkGetRayTracingCaptureReplayShaderGroupHandlesKHR + VkDevice device + VkPipeline pipeline + uint32_t firstGroup + uint32_t groupCount + size_t dataSize + void* pData + + + VkResult vkGetAccelerationStructureHandleNV + VkDevice device + VkAccelerationStructureNV accelerationStructure + size_t dataSize + void* pData + + + VkResult vkCreateRayTracingPipelinesNV + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkRayTracingPipelineCreateInfoNV* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateRayTracingPipelinesNV + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkRayTracingPipelineCreateInfoNV* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateRayTracingPipelinesKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkRayTracingPipelineCreateInfoKHR* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateRayTracingPipelinesKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkRayTracingPipelineCreateInfoKHR* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkGetPhysicalDeviceCooperativeMatrixPropertiesNV + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkCooperativeMatrixPropertiesNV* pProperties + + + void vkCmdTraceRaysIndirectKHR + VkCommandBuffer commandBuffer + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable + VkDeviceAddress indirectDeviceAddress + + + void vkCmdTraceRaysIndirect2KHR + VkCommandBuffer commandBuffer + VkDeviceAddress indirectDeviceAddress + + + void vkGetClusterAccelerationStructureBuildSizesNV + VkDevice device + const VkClusterAccelerationStructureInputInfoNV* pInfo + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo + + + void vkCmdBuildClusterAccelerationStructureIndirectNV + VkCommandBuffer commandBuffer + const VkClusterAccelerationStructureCommandsInfoNV* pCommandInfos + + + void vkGetDeviceAccelerationStructureCompatibilityKHR + VkDevice device + const VkAccelerationStructureVersionInfoKHR* pVersionInfo + VkAccelerationStructureCompatibilityKHR* pCompatibility + + + VkDeviceSize vkGetRayTracingShaderGroupStackSizeKHR + VkDevice device + VkPipeline pipeline + uint32_t group + VkShaderGroupShaderKHR groupShader + + + void vkCmdSetRayTracingPipelineStackSizeKHR + VkCommandBuffer commandBuffer + uint32_t pipelineStackSize + + + uint32_t vkGetImageViewHandleNVX + VkDevice device + const VkImageViewHandleInfoNVX* pInfo + + + uint64_t vkGetImageViewHandle64NVX + VkDevice device + const VkImageViewHandleInfoNVX* pInfo + + + VkResult vkGetImageViewAddressNVX + VkDevice device + VkImageView imageView + VkImageViewAddressPropertiesNVX* pProperties + + + VkResult vkGetPhysicalDeviceSurfacePresentModes2EXT + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo + uint32_t* pPresentModeCount + VkPresentModeKHR* pPresentModes + + + VkResult vkGetDeviceGroupSurfacePresentModes2EXT + VkDevice device + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo + VkDeviceGroupPresentModeFlagsKHR* pModes + + + VkResult vkAcquireFullScreenExclusiveModeEXT + VkDevice device + VkSwapchainKHR swapchain + + + VkResult vkReleaseFullScreenExclusiveModeEXT + VkDevice device + VkSwapchainKHR swapchain + + + VkResult vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + uint32_t* pCounterCount + VkPerformanceCounterKHR* pCounters + VkPerformanceCounterDescriptionKHR* pCounterDescriptions + + + void vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR + VkPhysicalDevice physicalDevice + const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo + uint32_t* pNumPasses + + + VkResult vkAcquireProfilingLockKHR + VkDevice device + const VkAcquireProfilingLockInfoKHR* pInfo + + + void vkReleaseProfilingLockKHR + VkDevice device + + + VkResult vkGetImageDrmFormatModifierPropertiesEXT + VkDevice device + VkImage image + VkImageDrmFormatModifierPropertiesEXT* pProperties + + + uint64_t vkGetBufferOpaqueCaptureAddress + VkDevice device + const VkBufferDeviceAddressInfo* pInfo + + + + VkDeviceAddress vkGetBufferDeviceAddress + VkDevice device + const VkBufferDeviceAddressInfo* pInfo + + + + + VkResult vkCreateHeadlessSurfaceEXT + VkInstance instance + const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkSurfaceKHR* pSurface + + + VkResult vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV + VkPhysicalDevice physicalDevice + uint32_t* pCombinationCount + VkFramebufferMixedSamplesCombinationNV* pCombinations + + + VkResult vkInitializePerformanceApiINTEL + VkDevice device + const VkInitializePerformanceApiInfoINTEL* pInitializeInfo + + + void vkUninitializePerformanceApiINTEL + VkDevice device + + + VkResult vkCmdSetPerformanceMarkerINTEL + VkCommandBuffer commandBuffer + const VkPerformanceMarkerInfoINTEL* pMarkerInfo + + + VkResult vkCmdSetPerformanceStreamMarkerINTEL + VkCommandBuffer commandBuffer + const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo + + + VkResult vkCmdSetPerformanceOverrideINTEL + VkCommandBuffer commandBuffer + const VkPerformanceOverrideInfoINTEL* pOverrideInfo + + + VkResult vkAcquirePerformanceConfigurationINTEL + VkDevice device + const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo + VkPerformanceConfigurationINTEL* pConfiguration + + + VkResult vkReleasePerformanceConfigurationINTEL + VkDevice device + VkPerformanceConfigurationINTEL configuration + + + VkResult vkQueueSetPerformanceConfigurationINTEL + VkQueue queue + VkPerformanceConfigurationINTEL configuration + + + VkResult vkGetPerformanceParameterINTEL + VkDevice device + VkPerformanceParameterTypeINTEL parameter + VkPerformanceValueINTEL* pValue + + + uint64_t vkGetDeviceMemoryOpaqueCaptureAddress + VkDevice device + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo + + + + VkResult vkGetPipelineExecutablePropertiesKHR + VkDevice device + const VkPipelineInfoKHR* pPipelineInfo + uint32_t* pExecutableCount + VkPipelineExecutablePropertiesKHR* pProperties + + + VkResult vkGetPipelineExecutableStatisticsKHR + VkDevice device + const VkPipelineExecutableInfoKHR* pExecutableInfo + uint32_t* pStatisticCount + VkPipelineExecutableStatisticKHR* pStatistics + + + VkResult vkGetPipelineExecutableInternalRepresentationsKHR + VkDevice device + const VkPipelineExecutableInfoKHR* pExecutableInfo + uint32_t* pInternalRepresentationCount + VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations + + + void vkCmdSetLineStipple + VkCommandBuffer commandBuffer + uint32_t lineStippleFactor + uint16_t lineStipplePattern + + + + + VkResult vkGetFaultData + VkDevice device + VkFaultQueryBehavior faultQueryBehavior + VkBool32* pUnrecordedFaults + uint32_t* pFaultCount + VkFaultData* pFaults + + + VkResult vkGetPhysicalDeviceToolProperties + VkPhysicalDevice physicalDevice + uint32_t* pToolCount + VkPhysicalDeviceToolProperties* pToolProperties + + + + VkResult vkCreateAccelerationStructureKHR + VkDevice device + const VkAccelerationStructureCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkAccelerationStructureKHR* pAccelerationStructure + + + void vkCmdBuildAccelerationStructuresKHR + VkCommandBuffer commandBuffer + uint32_t infoCount + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos + + + void vkCmdBuildAccelerationStructuresIndirectKHR + VkCommandBuffer commandBuffer + uint32_t infoCount + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos + const VkDeviceAddress* pIndirectDeviceAddresses + const uint32_t* pIndirectStrides + const uint32_t* const* ppMaxPrimitiveCounts + + + VkResult vkBuildAccelerationStructuresKHR + VkDevice device + VkDeferredOperationKHR deferredOperation + uint32_t infoCount + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos + + + VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR + VkDevice device + const VkAccelerationStructureDeviceAddressInfoKHR* pInfo + + + VkResult vkCreateDeferredOperationKHR + VkDevice device + const VkAllocationCallbacks* pAllocator + VkDeferredOperationKHR* pDeferredOperation + + + void vkDestroyDeferredOperationKHR + VkDevice device + VkDeferredOperationKHR operation + const VkAllocationCallbacks* pAllocator + + + uint32_t vkGetDeferredOperationMaxConcurrencyKHR + VkDevice device + VkDeferredOperationKHR operation + + + VkResult vkGetDeferredOperationResultKHR + VkDevice device + VkDeferredOperationKHR operation + + + VkResult vkDeferredOperationJoinKHR + VkDevice device + VkDeferredOperationKHR operation + + + void vkGetPipelineIndirectMemoryRequirementsNV + VkDevice device + const VkComputePipelineCreateInfo* pCreateInfo + VkMemoryRequirements2* pMemoryRequirements + + + VkDeviceAddress vkGetPipelineIndirectDeviceAddressNV + VkDevice device + const VkPipelineIndirectDeviceAddressInfoNV* pInfo + + + void vkAntiLagUpdateAMD + VkDevice device + const VkAntiLagDataAMD* pData + + + void vkCmdSetCullMode + VkCommandBuffer commandBuffer + VkCullModeFlags cullMode + + + + void vkCmdSetFrontFace + VkCommandBuffer commandBuffer + VkFrontFace frontFace + + + + void vkCmdSetPrimitiveTopology + VkCommandBuffer commandBuffer + VkPrimitiveTopology primitiveTopology + + + + void vkCmdSetViewportWithCount + VkCommandBuffer commandBuffer + uint32_t viewportCount + const VkViewport* pViewports + + + + void vkCmdSetScissorWithCount + VkCommandBuffer commandBuffer + uint32_t scissorCount + const VkRect2D* pScissors + + + + void vkCmdBindIndexBuffer2 + VkCommandBuffer commandBuffer + VkBuffer buffer + VkDeviceSize offset + VkDeviceSize size + VkIndexType indexType + + + + void vkCmdBindVertexBuffers2 + VkCommandBuffer commandBuffer + uint32_t firstBinding + uint32_t bindingCount + const VkBuffer* pBuffers + const VkDeviceSize* pOffsets + const VkDeviceSize* pSizes + const VkDeviceSize* pStrides + + + + void vkCmdSetDepthTestEnable + VkCommandBuffer commandBuffer + VkBool32 depthTestEnable + + + + void vkCmdSetDepthWriteEnable + VkCommandBuffer commandBuffer + VkBool32 depthWriteEnable + + + + void vkCmdSetDepthCompareOp + VkCommandBuffer commandBuffer + VkCompareOp depthCompareOp + + + + void vkCmdSetDepthBoundsTestEnable + VkCommandBuffer commandBuffer + VkBool32 depthBoundsTestEnable + + + + void vkCmdSetStencilTestEnable + VkCommandBuffer commandBuffer + VkBool32 stencilTestEnable + + + + void vkCmdSetStencilOp + VkCommandBuffer commandBuffer + VkStencilFaceFlags faceMask + VkStencilOp failOp + VkStencilOp passOp + VkStencilOp depthFailOp + VkCompareOp compareOp + + + + void vkCmdSetPatchControlPointsEXT + VkCommandBuffer commandBuffer + uint32_t patchControlPoints + + + void vkCmdSetRasterizerDiscardEnable + VkCommandBuffer commandBuffer + VkBool32 rasterizerDiscardEnable + + + + void vkCmdSetDepthBiasEnable + VkCommandBuffer commandBuffer + VkBool32 depthBiasEnable + + + + void vkCmdSetLogicOpEXT + VkCommandBuffer commandBuffer + VkLogicOp logicOp + + + void vkCmdSetPrimitiveRestartEnable + VkCommandBuffer commandBuffer + VkBool32 primitiveRestartEnable + + + + void vkCmdSetTessellationDomainOriginEXT + VkCommandBuffer commandBuffer + VkTessellationDomainOrigin domainOrigin + + + void vkCmdSetDepthClampEnableEXT + VkCommandBuffer commandBuffer + VkBool32 depthClampEnable + + + void vkCmdSetPolygonModeEXT + VkCommandBuffer commandBuffer + VkPolygonMode polygonMode + + + void vkCmdSetRasterizationSamplesEXT + VkCommandBuffer commandBuffer + VkSampleCountFlagBits rasterizationSamples + + + void vkCmdSetSampleMaskEXT + VkCommandBuffer commandBuffer + VkSampleCountFlagBits samples + const VkSampleMask* pSampleMask + + + void vkCmdSetAlphaToCoverageEnableEXT + VkCommandBuffer commandBuffer + VkBool32 alphaToCoverageEnable + + + void vkCmdSetAlphaToOneEnableEXT + VkCommandBuffer commandBuffer + VkBool32 alphaToOneEnable + + + void vkCmdSetLogicOpEnableEXT + VkCommandBuffer commandBuffer + VkBool32 logicOpEnable + + + void vkCmdSetColorBlendEnableEXT + VkCommandBuffer commandBuffer + uint32_t firstAttachment + uint32_t attachmentCount + const VkBool32* pColorBlendEnables + + + void vkCmdSetColorBlendEquationEXT + VkCommandBuffer commandBuffer + uint32_t firstAttachment + uint32_t attachmentCount + const VkColorBlendEquationEXT* pColorBlendEquations + + + void vkCmdSetColorWriteMaskEXT + VkCommandBuffer commandBuffer + uint32_t firstAttachment + uint32_t attachmentCount + const VkColorComponentFlags* pColorWriteMasks + + + void vkCmdSetRasterizationStreamEXT + VkCommandBuffer commandBuffer + uint32_t rasterizationStream + + + void vkCmdSetConservativeRasterizationModeEXT + VkCommandBuffer commandBuffer + VkConservativeRasterizationModeEXT conservativeRasterizationMode + + + void vkCmdSetExtraPrimitiveOverestimationSizeEXT + VkCommandBuffer commandBuffer + float extraPrimitiveOverestimationSize + + + void vkCmdSetDepthClipEnableEXT + VkCommandBuffer commandBuffer + VkBool32 depthClipEnable + + + void vkCmdSetSampleLocationsEnableEXT + VkCommandBuffer commandBuffer + VkBool32 sampleLocationsEnable + + + void vkCmdSetColorBlendAdvancedEXT + VkCommandBuffer commandBuffer + uint32_t firstAttachment + uint32_t attachmentCount + const VkColorBlendAdvancedEXT* pColorBlendAdvanced + + + void vkCmdSetProvokingVertexModeEXT + VkCommandBuffer commandBuffer + VkProvokingVertexModeEXT provokingVertexMode + + + void vkCmdSetLineRasterizationModeEXT + VkCommandBuffer commandBuffer + VkLineRasterizationModeEXT lineRasterizationMode + + + void vkCmdSetLineStippleEnableEXT + VkCommandBuffer commandBuffer + VkBool32 stippledLineEnable + + + void vkCmdSetDepthClipNegativeOneToOneEXT + VkCommandBuffer commandBuffer + VkBool32 negativeOneToOne + + + void vkCmdSetViewportWScalingEnableNV + VkCommandBuffer commandBuffer + VkBool32 viewportWScalingEnable + + + void vkCmdSetViewportSwizzleNV + VkCommandBuffer commandBuffer + uint32_t firstViewport + uint32_t viewportCount + const VkViewportSwizzleNV* pViewportSwizzles + + + void vkCmdSetCoverageToColorEnableNV + VkCommandBuffer commandBuffer + VkBool32 coverageToColorEnable + + + void vkCmdSetCoverageToColorLocationNV + VkCommandBuffer commandBuffer + uint32_t coverageToColorLocation + + + void vkCmdSetCoverageModulationModeNV + VkCommandBuffer commandBuffer + VkCoverageModulationModeNV coverageModulationMode + + + void vkCmdSetCoverageModulationTableEnableNV + VkCommandBuffer commandBuffer + VkBool32 coverageModulationTableEnable + + + void vkCmdSetCoverageModulationTableNV + VkCommandBuffer commandBuffer + uint32_t coverageModulationTableCount + const float* pCoverageModulationTable + + + void vkCmdSetShadingRateImageEnableNV + VkCommandBuffer commandBuffer + VkBool32 shadingRateImageEnable + + + void vkCmdSetCoverageReductionModeNV + VkCommandBuffer commandBuffer + VkCoverageReductionModeNV coverageReductionMode + + + void vkCmdSetRepresentativeFragmentTestEnableNV + VkCommandBuffer commandBuffer + VkBool32 representativeFragmentTestEnable + + + VkResult vkCreatePrivateDataSlot + VkDevice device + const VkPrivateDataSlotCreateInfo* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkPrivateDataSlot* pPrivateDataSlot + + + + void vkDestroyPrivateDataSlot + VkDevice device + VkPrivateDataSlot privateDataSlot + const VkAllocationCallbacks* pAllocator + + + + VkResult vkSetPrivateData + VkDevice device + VkObjectType objectType + uint64_t objectHandle + VkPrivateDataSlot privateDataSlot + uint64_t data + + + + void vkGetPrivateData + VkDevice device + VkObjectType objectType + uint64_t objectHandle + VkPrivateDataSlot privateDataSlot + uint64_t* pData + + + + void vkCmdCopyBuffer2 + VkCommandBuffer commandBuffer + const VkCopyBufferInfo2* pCopyBufferInfo + + + + void vkCmdCopyImage2 + VkCommandBuffer commandBuffer + const VkCopyImageInfo2* pCopyImageInfo + + + + void vkCmdBlitImage2 + VkCommandBuffer commandBuffer + const VkBlitImageInfo2* pBlitImageInfo + + + + void vkCmdCopyBufferToImage2 + VkCommandBuffer commandBuffer + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo + + + + void vkCmdCopyImageToBuffer2 + VkCommandBuffer commandBuffer + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo + + + + void vkCmdResolveImage2 + VkCommandBuffer commandBuffer + const VkResolveImageInfo2* pResolveImageInfo + + + + void vkCmdRefreshObjectsKHR + VkCommandBuffer commandBuffer + const VkRefreshObjectListKHR* pRefreshObjects + + + VkResult vkGetPhysicalDeviceRefreshableObjectTypesKHR + VkPhysicalDevice physicalDevice + uint32_t* pRefreshableObjectTypeCount + VkObjectType* pRefreshableObjectTypes + + + void vkCmdSetFragmentShadingRateKHR + VkCommandBuffer commandBuffer + const VkExtent2D* pFragmentSize + const VkFragmentShadingRateCombinerOpKHR combinerOps[2] + + + VkResult vkGetPhysicalDeviceFragmentShadingRatesKHR + VkPhysicalDevice physicalDevice + uint32_t* pFragmentShadingRateCount + VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates + + + void vkCmdSetFragmentShadingRateEnumNV + VkCommandBuffer commandBuffer + VkFragmentShadingRateNV shadingRate + const VkFragmentShadingRateCombinerOpKHR combinerOps[2] + + + void vkGetAccelerationStructureBuildSizesKHR + VkDevice device + VkAccelerationStructureBuildTypeKHR buildType + const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo + const uint32_t* pMaxPrimitiveCounts + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo + + + void vkCmdSetVertexInputEXT + VkCommandBuffer commandBuffer + uint32_t vertexBindingDescriptionCount + const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions + uint32_t vertexAttributeDescriptionCount + const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions + + + void vkCmdSetColorWriteEnableEXT + VkCommandBuffer commandBuffer + uint32_t attachmentCount + const VkBool32* pColorWriteEnables + + + void vkCmdSetEvent2 + VkCommandBuffer commandBuffer + VkEvent event + const VkDependencyInfo* pDependencyInfo + + + + void vkCmdResetEvent2 + VkCommandBuffer commandBuffer + VkEvent event + VkPipelineStageFlags2 stageMask + + + + void vkCmdWaitEvents2 + VkCommandBuffer commandBuffer + uint32_t eventCount + const VkEvent* pEvents + const VkDependencyInfo* pDependencyInfos + + + + void vkCmdPipelineBarrier2 + VkCommandBuffer commandBuffer + const VkDependencyInfo* pDependencyInfo + + + + VkResult vkQueueSubmit2 + VkQueue queue + uint32_t submitCount + const VkSubmitInfo2* pSubmits + VkFence fence + + + + void vkCmdWriteTimestamp2 + VkCommandBuffer commandBuffer + VkPipelineStageFlags2 stage + VkQueryPool queryPool + uint32_t query + + + + void vkCmdWriteBufferMarker2AMD + VkCommandBuffer commandBuffer + VkPipelineStageFlags2 stage + VkBuffer dstBuffer + VkDeviceSize dstOffset + uint32_t marker + + + void vkGetQueueCheckpointData2NV + VkQueue queue + uint32_t* pCheckpointDataCount + VkCheckpointData2NV* pCheckpointData + + + VkResult vkCopyMemoryToImage + VkDevice device + const VkCopyMemoryToImageInfo* pCopyMemoryToImageInfo + + + + VkResult vkCopyImageToMemory + VkDevice device + const VkCopyImageToMemoryInfo* pCopyImageToMemoryInfo + + + + VkResult vkCopyImageToImage + VkDevice device + const VkCopyImageToImageInfo* pCopyImageToImageInfo + + + + VkResult vkTransitionImageLayout + VkDevice device + uint32_t transitionCount + const VkHostImageLayoutTransitionInfo* pTransitions + + + + void vkGetCommandPoolMemoryConsumption + VkDevice device + VkCommandPool commandPool + VkCommandBuffer commandBuffer + VkCommandPoolMemoryConsumption* pConsumption + + + VkResult vkGetPhysicalDeviceVideoCapabilitiesKHR + VkPhysicalDevice physicalDevice + const VkVideoProfileInfoKHR* pVideoProfile + VkVideoCapabilitiesKHR* pCapabilities + + + VkResult vkGetPhysicalDeviceVideoFormatPropertiesKHR + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo + uint32_t* pVideoFormatPropertyCount + VkVideoFormatPropertiesKHR* pVideoFormatProperties + + + VkResult vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo + VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties + + + VkResult vkCreateVideoSessionKHR + VkDevice device + const VkVideoSessionCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkVideoSessionKHR* pVideoSession + + + void vkDestroyVideoSessionKHR + VkDevice device + VkVideoSessionKHR videoSession + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateVideoSessionParametersKHR + VkDevice device + const VkVideoSessionParametersCreateInfoKHR* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkVideoSessionParametersKHR* pVideoSessionParameters + + + VkResult vkUpdateVideoSessionParametersKHR + VkDevice device + VkVideoSessionParametersKHR videoSessionParameters + const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo + + + VkResult vkGetEncodedVideoSessionParametersKHR + VkDevice device + const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo + VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo + size_t* pDataSize + void* pData + + + void vkDestroyVideoSessionParametersKHR + VkDevice device + VkVideoSessionParametersKHR videoSessionParameters + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetVideoSessionMemoryRequirementsKHR + VkDevice device + VkVideoSessionKHR videoSession + uint32_t* pMemoryRequirementsCount + VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements + + + VkResult vkBindVideoSessionMemoryKHR + VkDevice device + VkVideoSessionKHR videoSession + uint32_t bindSessionMemoryInfoCount + const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos + + + void vkCmdDecodeVideoKHR + VkCommandBuffer commandBuffer + const VkVideoDecodeInfoKHR* pDecodeInfo + + + void vkCmdBeginVideoCodingKHR + VkCommandBuffer commandBuffer + const VkVideoBeginCodingInfoKHR* pBeginInfo + + + void vkCmdControlVideoCodingKHR + VkCommandBuffer commandBuffer + const VkVideoCodingControlInfoKHR* pCodingControlInfo + + + void vkCmdEndVideoCodingKHR + VkCommandBuffer commandBuffer + const VkVideoEndCodingInfoKHR* pEndCodingInfo + + + void vkCmdEncodeVideoKHR + VkCommandBuffer commandBuffer + const VkVideoEncodeInfoKHR* pEncodeInfo + + + void vkCmdDecompressMemoryNV + VkCommandBuffer commandBuffer + uint32_t decompressRegionCount + const VkDecompressMemoryRegionNV* pDecompressMemoryRegions + + + void vkCmdDecompressMemoryIndirectCountNV + VkCommandBuffer commandBuffer + VkDeviceAddress indirectCommandsAddress + VkDeviceAddress indirectCommandsCountAddress + uint32_t stride + + + void vkGetPartitionedAccelerationStructuresBuildSizesNV + VkDevice device + const VkPartitionedAccelerationStructureInstancesInputNV* pInfo + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo + + + void vkCmdBuildPartitionedAccelerationStructuresNV + VkCommandBuffer commandBuffer + const VkBuildPartitionedAccelerationStructureInfoNV* pBuildInfo + + + VkResult vkCreateCuModuleNVX + VkDevice device + const VkCuModuleCreateInfoNVX* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkCuModuleNVX* pModule + + + VkResult vkCreateCuFunctionNVX + VkDevice device + const VkCuFunctionCreateInfoNVX* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkCuFunctionNVX* pFunction + + + void vkDestroyCuModuleNVX + VkDevice device + VkCuModuleNVX module + const VkAllocationCallbacks* pAllocator + + + void vkDestroyCuFunctionNVX + VkDevice device + VkCuFunctionNVX function + const VkAllocationCallbacks* pAllocator + + + void vkCmdCuLaunchKernelNVX + VkCommandBuffer commandBuffer + const VkCuLaunchInfoNVX* pLaunchInfo + + + void vkGetDescriptorSetLayoutSizeEXT + VkDevice device + VkDescriptorSetLayout layout + VkDeviceSize* pLayoutSizeInBytes + + + void vkGetDescriptorSetLayoutBindingOffsetEXT + VkDevice device + VkDescriptorSetLayout layout + uint32_t binding + VkDeviceSize* pOffset + + + void vkGetDescriptorEXT + VkDevice device + const VkDescriptorGetInfoEXT* pDescriptorInfo + size_t dataSize + void* pDescriptor + + + void vkCmdBindDescriptorBuffersEXT + VkCommandBuffer commandBuffer + uint32_t bufferCount + const VkDescriptorBufferBindingInfoEXT* pBindingInfos + + + void vkCmdSetDescriptorBufferOffsetsEXT + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipelineLayout layout + uint32_t firstSet + uint32_t setCount + const uint32_t* pBufferIndices + const VkDeviceSize* pOffsets + + + void vkCmdBindDescriptorBufferEmbeddedSamplersEXT + VkCommandBuffer commandBuffer + VkPipelineBindPoint pipelineBindPoint + VkPipelineLayout layout + uint32_t set + + + VkResult vkGetBufferOpaqueCaptureDescriptorDataEXT + VkDevice device + const VkBufferCaptureDescriptorDataInfoEXT* pInfo + void* pData + + + VkResult vkGetImageOpaqueCaptureDescriptorDataEXT + VkDevice device + const VkImageCaptureDescriptorDataInfoEXT* pInfo + void* pData + + + VkResult vkGetImageViewOpaqueCaptureDescriptorDataEXT + VkDevice device + const VkImageViewCaptureDescriptorDataInfoEXT* pInfo + void* pData + + + VkResult vkGetSamplerOpaqueCaptureDescriptorDataEXT + VkDevice device + const VkSamplerCaptureDescriptorDataInfoEXT* pInfo + void* pData + + + VkResult vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT + VkDevice device + const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo + void* pData + + + void vkSetDeviceMemoryPriorityEXT + VkDevice device + VkDeviceMemory memory + float priority + + + VkResult vkAcquireDrmDisplayEXT + VkPhysicalDevice physicalDevice + int32_t drmFd + VkDisplayKHR display + + + VkResult vkGetDrmDisplayEXT + VkPhysicalDevice physicalDevice + int32_t drmFd + uint32_t connectorId + VkDisplayKHR* display + + + VkResult vkWaitForPresent2KHR + VkDevice device + VkSwapchainKHR swapchain + const VkPresentWait2InfoKHR* pPresentWait2Info + + + VkResult vkWaitForPresentKHR + VkDevice device + VkSwapchainKHR swapchain + uint64_t presentId + uint64_t timeout + + + VkResult vkCreateBufferCollectionFUCHSIA + VkDevice device + const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkBufferCollectionFUCHSIA* pCollection + + + VkResult vkSetBufferCollectionBufferConstraintsFUCHSIA + VkDevice device + VkBufferCollectionFUCHSIA collection + const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo + + + VkResult vkSetBufferCollectionImageConstraintsFUCHSIA + VkDevice device + VkBufferCollectionFUCHSIA collection + const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo + + + void vkDestroyBufferCollectionFUCHSIA + VkDevice device + VkBufferCollectionFUCHSIA collection + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetBufferCollectionPropertiesFUCHSIA + VkDevice device + VkBufferCollectionFUCHSIA collection + VkBufferCollectionPropertiesFUCHSIA* pProperties + + + VkResult vkCreateCudaModuleNV + VkDevice device + const VkCudaModuleCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkCudaModuleNV* pModule + + + VkResult vkGetCudaModuleCacheNV + VkDevice device + VkCudaModuleNV module + size_t* pCacheSize + void* pCacheData + + + VkResult vkCreateCudaFunctionNV + VkDevice device + const VkCudaFunctionCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkCudaFunctionNV* pFunction + + + void vkDestroyCudaModuleNV + VkDevice device + VkCudaModuleNV module + const VkAllocationCallbacks* pAllocator + + + void vkDestroyCudaFunctionNV + VkDevice device + VkCudaFunctionNV function + const VkAllocationCallbacks* pAllocator + + + void vkCmdCudaLaunchKernelNV + VkCommandBuffer commandBuffer + const VkCudaLaunchInfoNV* pLaunchInfo + + + void vkCmdBeginRendering + VkCommandBuffer commandBuffer + const VkRenderingInfo* pRenderingInfo + + + + void vkCmdEndRendering + VkCommandBuffer commandBuffer + + + void vkCmdEndRendering2EXT + VkCommandBuffer commandBuffer + const VkRenderingEndInfoEXT* pRenderingEndInfo + + + + void vkGetDescriptorSetLayoutHostMappingInfoVALVE + VkDevice device + const VkDescriptorSetBindingReferenceVALVE* pBindingReference + VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping + + + void vkGetDescriptorSetHostMappingVALVE + VkDevice device + VkDescriptorSet descriptorSet + void** ppData + + + VkResult vkCreateMicromapEXT + VkDevice device + const VkMicromapCreateInfoEXT* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkMicromapEXT* pMicromap + + + void vkCmdBuildMicromapsEXT + VkCommandBuffer commandBuffer + uint32_t infoCount + const VkMicromapBuildInfoEXT* pInfos + + + VkResult vkBuildMicromapsEXT + VkDevice device + VkDeferredOperationKHR deferredOperation + uint32_t infoCount + const VkMicromapBuildInfoEXT* pInfos + + + void vkDestroyMicromapEXT + VkDevice device + VkMicromapEXT micromap + const VkAllocationCallbacks* pAllocator + + + void vkCmdCopyMicromapEXT + VkCommandBuffer commandBuffer + const VkCopyMicromapInfoEXT* pInfo + + + VkResult vkCopyMicromapEXT + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyMicromapInfoEXT* pInfo + + + void vkCmdCopyMicromapToMemoryEXT + VkCommandBuffer commandBuffer + const VkCopyMicromapToMemoryInfoEXT* pInfo + + + VkResult vkCopyMicromapToMemoryEXT + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyMicromapToMemoryInfoEXT* pInfo + + + void vkCmdCopyMemoryToMicromapEXT + VkCommandBuffer commandBuffer + const VkCopyMemoryToMicromapInfoEXT* pInfo + + + VkResult vkCopyMemoryToMicromapEXT + VkDevice device + VkDeferredOperationKHR deferredOperation + const VkCopyMemoryToMicromapInfoEXT* pInfo + + + void vkCmdWriteMicromapsPropertiesEXT + VkCommandBuffer commandBuffer + uint32_t micromapCount + const VkMicromapEXT* pMicromaps + VkQueryType queryType + VkQueryPool queryPool + uint32_t firstQuery + + + VkResult vkWriteMicromapsPropertiesEXT + VkDevice device + uint32_t micromapCount + const VkMicromapEXT* pMicromaps + VkQueryType queryType + size_t dataSize + void* pData + size_t stride + + + void vkGetDeviceMicromapCompatibilityEXT + VkDevice device + const VkMicromapVersionInfoEXT* pVersionInfo + VkAccelerationStructureCompatibilityKHR* pCompatibility + + + void vkGetMicromapBuildSizesEXT + VkDevice device + VkAccelerationStructureBuildTypeKHR buildType + const VkMicromapBuildInfoEXT* pBuildInfo + VkMicromapBuildSizesInfoEXT* pSizeInfo + + + void vkGetShaderModuleIdentifierEXT + VkDevice device + VkShaderModule shaderModule + VkShaderModuleIdentifierEXT* pIdentifier + + + void vkGetShaderModuleCreateInfoIdentifierEXT + VkDevice device + const VkShaderModuleCreateInfo* pCreateInfo + VkShaderModuleIdentifierEXT* pIdentifier + + + void vkGetImageSubresourceLayout2 + VkDevice device + VkImage image + const VkImageSubresource2* pSubresource + VkSubresourceLayout2* pLayout + + + + + VkResult vkGetPipelinePropertiesEXT + VkDevice device + const VkPipelineInfoEXT* pPipelineInfo + VkBaseOutStructure* pPipelineProperties + + + void vkExportMetalObjectsEXT + VkDevice device + VkExportMetalObjectsInfoEXT* pMetalObjectsInfo + + + void vkCmdBindTileMemoryQCOM + VkCommandBuffer commandBuffer + const VkTileMemoryBindInfoQCOM* pTileMemoryBindInfo + + + VkResult vkGetFramebufferTilePropertiesQCOM + VkDevice device + VkFramebuffer framebuffer + uint32_t* pPropertiesCount + VkTilePropertiesQCOM* pProperties + + + VkResult vkGetDynamicRenderingTilePropertiesQCOM + VkDevice device + const VkRenderingInfo* pRenderingInfo + VkTilePropertiesQCOM* pProperties + + + VkResult vkGetPhysicalDeviceOpticalFlowImageFormatsNV + VkPhysicalDevice physicalDevice + const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo + uint32_t* pFormatCount + VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties + + + VkResult vkCreateOpticalFlowSessionNV + VkDevice device + const VkOpticalFlowSessionCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkOpticalFlowSessionNV* pSession + + + void vkDestroyOpticalFlowSessionNV + VkDevice device + VkOpticalFlowSessionNV session + const VkAllocationCallbacks* pAllocator + + + VkResult vkBindOpticalFlowSessionImageNV + VkDevice device + VkOpticalFlowSessionNV session + VkOpticalFlowSessionBindingPointNV bindingPoint + VkImageView view + VkImageLayout layout + + + void vkCmdOpticalFlowExecuteNV + VkCommandBuffer commandBuffer + VkOpticalFlowSessionNV session + const VkOpticalFlowExecuteInfoNV* pExecuteInfo + + + VkResult vkGetDeviceFaultInfoEXT + VkDevice device + VkDeviceFaultCountsEXT* pFaultCounts + VkDeviceFaultInfoEXT* pFaultInfo + + + void vkCmdSetDepthBias2EXT + VkCommandBuffer commandBuffer + const VkDepthBiasInfoEXT* pDepthBiasInfo + + + VkResult vkReleaseSwapchainImagesKHR + VkDevice device + const VkReleaseSwapchainImagesInfoKHR* pReleaseInfo + + + + void vkGetDeviceImageSubresourceLayout + VkDevice device + const VkDeviceImageSubresourceInfo* pInfo + VkSubresourceLayout2* pLayout + + + + VkResult vkMapMemory2 + VkDevice device + const VkMemoryMapInfo* pMemoryMapInfo + void** ppData + + + + VkResult vkUnmapMemory2 + VkDevice device + const VkMemoryUnmapInfo* pMemoryUnmapInfo + + + + VkResult vkCreateShadersEXT + VkDevice device + uint32_t createInfoCount + const VkShaderCreateInfoEXT* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkShaderEXT* pShaders + + + void vkDestroyShaderEXT + VkDevice device + VkShaderEXT shader + const VkAllocationCallbacks* pAllocator + + + VkResult vkGetShaderBinaryDataEXT + VkDevice device + VkShaderEXT shader + size_t* pDataSize + void* pData + + + void vkCmdBindShadersEXT + VkCommandBuffer commandBuffer + uint32_t stageCount + const VkShaderStageFlagBits* pStages + const VkShaderEXT* pShaders + + + VkResult vkGetScreenBufferPropertiesQNX + VkDevice device + const struct _screen_buffer* buffer + VkScreenBufferPropertiesQNX* pProperties + + + VkResult vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkCooperativeMatrixPropertiesKHR* pProperties + + + VkResult vkGetExecutionGraphPipelineScratchSizeAMDX + VkDevice device + VkPipeline executionGraph + VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo + + + VkResult vkGetExecutionGraphPipelineNodeIndexAMDX + VkDevice device + VkPipeline executionGraph + const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo + uint32_t* pNodeIndex + + + VkResult vkCreateExecutionGraphPipelinesAMDX + VkDevice device + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + void vkCmdInitializeGraphScratchMemoryAMDX + VkCommandBuffer commandBuffer + VkPipeline executionGraph + VkDeviceAddress scratch + VkDeviceSize scratchSize + + + void vkCmdDispatchGraphAMDX + VkCommandBuffer commandBuffer + VkDeviceAddress scratch + VkDeviceSize scratchSize + const VkDispatchGraphCountInfoAMDX* pCountInfo + + + void vkCmdDispatchGraphIndirectAMDX + VkCommandBuffer commandBuffer + VkDeviceAddress scratch + VkDeviceSize scratchSize + const VkDispatchGraphCountInfoAMDX* pCountInfo + + + void vkCmdDispatchGraphIndirectCountAMDX + VkCommandBuffer commandBuffer + VkDeviceAddress scratch + VkDeviceSize scratchSize + VkDeviceAddress countInfo + + + void vkCmdBindDescriptorSets2 + VkCommandBuffer commandBuffer + const VkBindDescriptorSetsInfo* pBindDescriptorSetsInfo + + + + void vkCmdPushConstants2 + VkCommandBuffer commandBuffer + const VkPushConstantsInfo* pPushConstantsInfo + + + + void vkCmdPushDescriptorSet2 + VkCommandBuffer commandBuffer + const VkPushDescriptorSetInfo* pPushDescriptorSetInfo + + + + void vkCmdPushDescriptorSetWithTemplate2 + VkCommandBuffer commandBuffer + const VkPushDescriptorSetWithTemplateInfo* pPushDescriptorSetWithTemplateInfo + + + + void vkCmdSetDescriptorBufferOffsets2EXT + VkCommandBuffer commandBuffer + const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo + + + void vkCmdBindDescriptorBufferEmbeddedSamplers2EXT + VkCommandBuffer commandBuffer + const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo + + + VkResult vkSetLatencySleepModeNV + VkDevice device + VkSwapchainKHR swapchain + const VkLatencySleepModeInfoNV* pSleepModeInfo + + + VkResult vkLatencySleepNV + VkDevice device + VkSwapchainKHR swapchain + const VkLatencySleepInfoNV* pSleepInfo + + + void vkSetLatencyMarkerNV + VkDevice device + VkSwapchainKHR swapchain + const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo + + + void vkGetLatencyTimingsNV + VkDevice device + VkSwapchainKHR swapchain + VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo + + + void vkQueueNotifyOutOfBandNV + VkQueue queue + const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo + + + void vkCmdSetRenderingAttachmentLocations + VkCommandBuffer commandBuffer + const VkRenderingAttachmentLocationInfo* pLocationInfo + + + + void vkCmdSetRenderingInputAttachmentIndices + VkCommandBuffer commandBuffer + const VkRenderingInputAttachmentIndexInfo* pInputAttachmentIndexInfo + + + + void vkCmdSetDepthClampRangeEXT + VkCommandBuffer commandBuffer + VkDepthClampModeEXT depthClampMode + const VkDepthClampRangeEXT* pDepthClampRange + + + VkResult vkGetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkCooperativeMatrixFlexibleDimensionsPropertiesNV* pProperties + + + VkResult vkGetMemoryMetalHandleEXT + VkDevice device + const VkMemoryGetMetalHandleInfoEXT* pGetMetalHandleInfo + void** pHandle + + + VkResult vkGetMemoryMetalHandlePropertiesEXT + VkDevice device + VkExternalMemoryHandleTypeFlagBits handleType + const void* pHandle + VkMemoryMetalHandlePropertiesEXT* pMemoryMetalHandleProperties + + + VkResult vkGetPhysicalDeviceCooperativeVectorPropertiesNV + VkPhysicalDevice physicalDevice + uint32_t* pPropertyCount + VkCooperativeVectorPropertiesNV* pProperties + + + VkResult vkConvertCooperativeVectorMatrixNV + VkDevice device + const VkConvertCooperativeVectorMatrixInfoNV* pInfo + + + void vkCmdConvertCooperativeVectorMatrixNV + VkCommandBuffer commandBuffer + uint32_t infoCount + const VkConvertCooperativeVectorMatrixInfoNV* pInfos + + + void vkCmdDispatchTileQCOM + VkCommandBuffer commandBuffer + const VkDispatchTileInfoQCOM* pDispatchTileInfo + + + void vkCmdBeginPerTileExecutionQCOM + VkCommandBuffer commandBuffer + const VkPerTileBeginInfoQCOM* pPerTileBeginInfo + + + void vkCmdEndPerTileExecutionQCOM + VkCommandBuffer commandBuffer + const VkPerTileEndInfoQCOM* pPerTileEndInfo + + + VkResult vkCreateExternalComputeQueueNV + VkDevice device + const VkExternalComputeQueueCreateInfoNV* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkExternalComputeQueueNV* pExternalQueue + + + void vkDestroyExternalComputeQueueNV + VkDevice device + VkExternalComputeQueueNV externalQueue + const VkAllocationCallbacks* pAllocator + + + void vkGetExternalComputeQueueDataNV + VkExternalComputeQueueNV externalQueue + VkExternalComputeQueueDataParamsNV* params + void* pData + + + VkResult vkCreateTensorARM + VkDevice device + const VkTensorCreateInfoARM* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkTensorARM* pTensor + + + void vkDestroyTensorARM + VkDevice device + VkTensorARM tensor + const VkAllocationCallbacks* pAllocator + + + VkResult vkCreateTensorViewARM + VkDevice device + const VkTensorViewCreateInfoARM* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkTensorViewARM* pView + + + void vkDestroyTensorViewARM + VkDevice device + VkTensorViewARM tensorView + const VkAllocationCallbacks* pAllocator + + + void vkGetTensorMemoryRequirementsARM + VkDevice device + const VkTensorMemoryRequirementsInfoARM* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + VkResult vkBindTensorMemoryARM + VkDevice device + uint32_t bindInfoCount + const VkBindTensorMemoryInfoARM* pBindInfos + + + void vkGetDeviceTensorMemoryRequirementsARM + VkDevice device + const VkDeviceTensorMemoryRequirementsARM* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + void vkCmdCopyTensorARM + VkCommandBuffer commandBuffer + const VkCopyTensorInfoARM* pCopyTensorInfo + + + VkResult vkGetTensorOpaqueCaptureDescriptorDataARM + VkDevice device + const VkTensorCaptureDescriptorDataInfoARM* pInfo + void* pData + + + VkResult vkGetTensorViewOpaqueCaptureDescriptorDataARM + VkDevice device + const VkTensorViewCaptureDescriptorDataInfoARM* pInfo + void* pData + + + void vkGetPhysicalDeviceExternalTensorPropertiesARM + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceExternalTensorInfoARM* pExternalTensorInfo + VkExternalTensorPropertiesARM* pExternalTensorProperties + + + VkResult vkCreateDataGraphPipelinesARM + VkDevice device + VkDeferredOperationKHR deferredOperation + VkPipelineCache pipelineCache + uint32_t createInfoCount + const VkDataGraphPipelineCreateInfoARM* pCreateInfos + const VkAllocationCallbacks* pAllocator + VkPipeline* pPipelines + + + VkResult vkCreateDataGraphPipelineSessionARM + VkDevice device + const VkDataGraphPipelineSessionCreateInfoARM* pCreateInfo + const VkAllocationCallbacks* pAllocator + VkDataGraphPipelineSessionARM* pSession + + + VkResult vkGetDataGraphPipelineSessionBindPointRequirementsARM + VkDevice device + const VkDataGraphPipelineSessionBindPointRequirementsInfoARM* pInfo + uint32_t* pBindPointRequirementCount + VkDataGraphPipelineSessionBindPointRequirementARM* pBindPointRequirements + + + void vkGetDataGraphPipelineSessionMemoryRequirementsARM + VkDevice device + const VkDataGraphPipelineSessionMemoryRequirementsInfoARM* pInfo + VkMemoryRequirements2* pMemoryRequirements + + + VkResult vkBindDataGraphPipelineSessionMemoryARM + VkDevice device + uint32_t bindInfoCount + const VkBindDataGraphPipelineSessionMemoryInfoARM* pBindInfos + + + void vkDestroyDataGraphPipelineSessionARM + VkDevice device + VkDataGraphPipelineSessionARM session + const VkAllocationCallbacks* pAllocator + + + void vkCmdDispatchDataGraphARM + VkCommandBuffer commandBuffer + VkDataGraphPipelineSessionARM session + const VkDataGraphPipelineDispatchInfoARM* pInfo + + + VkResult vkGetDataGraphPipelineAvailablePropertiesARM + VkDevice device + const VkDataGraphPipelineInfoARM* pPipelineInfo + uint32_t* pPropertiesCount + VkDataGraphPipelinePropertyARM* pProperties + + + VkResult vkGetDataGraphPipelinePropertiesARM + VkDevice device + const VkDataGraphPipelineInfoARM* pPipelineInfo + uint32_t propertiesCount + VkDataGraphPipelinePropertyQueryResultARM* pProperties + + + VkResult vkGetPhysicalDeviceQueueFamilyDataGraphPropertiesARM + VkPhysicalDevice physicalDevice + uint32_t queueFamilyIndex + uint32_t* pQueueFamilyDataGraphPropertyCount + VkQueueFamilyDataGraphPropertiesARM* pQueueFamilyDataGraphProperties + + + void vkGetPhysicalDeviceQueueFamilyDataGraphProcessingEnginePropertiesARM + VkPhysicalDevice physicalDevice + const VkPhysicalDeviceQueueFamilyDataGraphProcessingEngineInfoARM* pQueueFamilyDataGraphProcessingEngineInfo + VkQueueFamilyDataGraphProcessingEnginePropertiesARM* pQueueFamilyDataGraphProcessingEngineProperties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + offset 1 reserved for the old VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHX enum + offset 2 reserved for the old VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHX enum + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Additional dependent types / tokens extending enumerants, not explicitly mentioned + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Additional dependent types / tokens extending enumerants, not explicitly mentioned + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This duplicates definitions in VK_KHR_device_group below + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VK_ANDROID_native_buffer is used between the Android Vulkan loader and drivers to implement the WSI extensions. It is not exposed to applications and uses types that are not part of Android's stable public API, so it is left disabled to keep it out of the standard Vulkan headers. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This duplicates definitions in other extensions, below + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + enum offset=0 was mistakenly used for the 1.1 core enum + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES + (value=1000094000). Fortunately, no conflict resulted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This extension requires buffer_device_address functionality. + VK_EXT_buffer_device_address is also acceptable, but since it is deprecated the KHR version is preferred. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + These enums are present only to inform downstream + consumers like KTX2. There is no actual Vulkan extension + corresponding to the enums. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT and + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT + were not promoted to Vulkan 1.3. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VkPhysicalDevice4444FormatsFeaturesEXT and + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT + were not promoted to Vulkan 1.3. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NV internal use only + + + + + + + + + + + + + + + + + + + + + + + + + + + NV internal use only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fragment shader stage is added by the VK_EXT_shader_tile_image extension + + + + + + + Fragment shader stage is added by the VK_EXT_shader_tile_image extension + + + + + + + + + + + + + + + + + + + TODO/Suggestion. Introduce 'synclist' (could be a different name) element + that specifies the list of stages, accesses, etc. This list can be used by + 'syncaccess' or 'syncstage' elements. For example, 'syncsupport' in addition to the + 'stage' attribute can support 'list' attribute to reference 'synclist'. + We can have the lists defined for ALL stages and it can be shared between MEMORY_READ + and MEMORY_WRITE accesses. Similarly, ALL shader stages list is often used. This proposal + is a way to fix duplication problem. When new stage is added multiple places needs to be + updated. It is potential source of bugs. The expectation such setup will produce more + robust system and also more simple structure to review and validate. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT + VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR + VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT + VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT + VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT + VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT + VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT + VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT + VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT + VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR + VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT + VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT + + + VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT + VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT + VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT + VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR + VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT + VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT + VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT + + + VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT + VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT + VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT + + + VK_PIPELINE_STAGE_2_COPY_INDIRECT_BIT_KHR + VK_PIPELINE_STAGE_2_TRANSFER_BIT + + + VK_PIPELINE_STAGE_2_HOST_BIT + + + VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI + + + VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_EXT + + + VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR + + + VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR + + + VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT + + + VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT + VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR + + + VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR + + + VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR + + + VK_PIPELINE_STAGE_2_OPTICAL_FLOW_BIT_NV + + + VK_PIPELINE_STAGE_2_CONVERT_COOPERATIVE_VECTOR_MATRIX_BIT_NV + + + VK_PIPELINE_STAGE_2_DATA_GRAPH_BIT_ARM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/VulkanHeaders/vkconventions.py b/libs/VulkanHeaders/vkconventions.py new file mode 100644 index 0000000000..ccde698cee --- /dev/null +++ b/libs/VulkanHeaders/vkconventions.py @@ -0,0 +1,314 @@ +#!/usr/bin/env python3 -i +# +# Copyright 2013-2025 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +# Working-group-specific style conventions, +# used in generation. + +import re +import os + +from spec_tools.conventions import ConventionsBase + +# Modified from default implementation - see category_requires_validation() below +CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask')) + +# Tokenize into "words" for structure types, approximately per spec "Implicit Valid Usage" section 2.7.2 +# This first set is for things we recognize explicitly as words, +# as exceptions to the general regex. +# Ideally these would be listed in the spec as exceptions, as OpenXR does. +SPECIAL_WORDS = set(( + '16Bit', # VkPhysicalDevice16BitStorageFeatures + '2D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT + '3D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT + '8Bit', # VkPhysicalDevice8BitStorageFeaturesKHR + 'AABB', # VkGeometryAABBNV + 'ASTC', # VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT + 'D3D12', # VkD3D12FenceSubmitInfoKHR + 'Float16', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR + 'Bfloat16', # VkPhysicalDeviceShaderBfloat16FeaturesKHR + 'Float8', # VkPhysicalDeviceShaderFloat8FeaturesEXT + 'ImagePipe', # VkImagePipeSurfaceCreateInfoFUCHSIA + 'Int64', # VkPhysicalDeviceShaderAtomicInt64FeaturesKHR + 'Int8', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR + 'MacOS', # VkMacOSSurfaceCreateInfoMVK + 'RGBA10X6', # VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT + 'Uint8', # VkPhysicalDeviceIndexTypeUint8FeaturesEXT + 'Win32', # VkWin32SurfaceCreateInfoKHR +)) +# A regex to match any of the SPECIAL_WORDS +EXCEPTION_PATTERN = r'(?P{})'.format( + '|'.join(f'({re.escape(w)})' for w in SPECIAL_WORDS)) +MAIN_RE = re.compile( + # the negative lookahead is to prevent the all-caps pattern from being too greedy. + r'({}|([0-9]+)|([A-Z][a-z]+)|([A-Z][A-Z]*(?![a-z])))'.format(EXCEPTION_PATTERN)) + + +class VulkanConventions(ConventionsBase): + @property + def null(self): + """Preferred spelling of NULL.""" + return '`NULL`' + + def formatVersion(self, name, apivariant, major, minor): + """Mark up an API version name as a link in the spec.""" + version = f'{major}.{minor}' + if apivariant == 'VKSC': + # Vulkan SC has a different anchor pattern for version appendices + if version == '1.0': + return 'Vulkan SC 1.0' + else: + return f'<>' + else: + return f'<>' + + def formatExtension(self, name): + """Mark up an extension name as a link in the spec.""" + return f'apiext:{name}' + + @property + def struct_macro(self): + """Get the appropriate format macro for a structure. + + Primarily affects generated valid usage statements. + """ + + return 'slink:' + + @property + def constFlagBits(self): + """Returns True if static const flag bits should be generated, False if an enumerated type should be generated.""" + return False + + @property + def structtype_member_name(self): + """Return name of the structure type member""" + return 'sType' + + @property + def nextpointer_member_name(self): + """Return name of the structure pointer chain member""" + return 'pNext' + + @property + def valid_pointer_prefix(self): + """Return prefix to pointers which must themselves be valid""" + return 'valid' + + def is_structure_type_member(self, paramtype, paramname): + """Determine if member type and name match the structure type member.""" + return paramtype == 'VkStructureType' and paramname == self.structtype_member_name + + def is_nextpointer_member(self, paramtype, paramname): + """Determine if member type and name match the next pointer chain member.""" + return paramtype == 'void' and paramname == self.nextpointer_member_name + + def generate_structure_type_from_name(self, structname): + """Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO""" + + structure_type_parts = [] + # Tokenize into "words" + for elem in MAIN_RE.findall(structname): + word = elem[0] + if word == 'Vk': + structure_type_parts.append('VK_STRUCTURE_TYPE') + else: + structure_type_parts.append(word.upper()) + name = '_'.join(structure_type_parts) + + # The simple-minded rules need modification for some structure names + subpats = [ + [ r'_H_(26[45])_', r'_H\1_' ], + [ r'_VP_9_', r'_VP9_' ], + [ r'_AV_1_', r'_AV1_' ], + [ r'_VULKAN_([0-9])([0-9])_', r'_VULKAN_\1_\2_' ], + [ r'_VULKAN_SC_([0-9])([0-9])_',r'_VULKAN_SC_\1_\2_' ], + [ r'_DIRECT_FB_', r'_DIRECTFB_' ], + [ r'_VULKAN_SC_10', r'_VULKAN_SC_1_0' ], + + ] + + for subpat in subpats: + name = re.sub(subpat[0], subpat[1], name) + return name + + @property + def warning_comment(self): + """Return warning comment to be placed in header of generated Asciidoctor files""" + return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry' + + @property + def file_suffix(self): + """Return suffix of generated Asciidoctor files""" + return '.adoc' + + def api_name(self, spectype='api'): + """Return API or specification name for citations in ref pages.ref + pages should link to for + + spectype is the spec this refpage is for: 'api' is the Vulkan API + Specification. Defaults to 'api'. If an unrecognized spectype is + given, returns None. + """ + if spectype == 'api' or spectype is None: + return 'Vulkan' + else: + return None + + @property + def api_prefix(self): + """Return API token prefix""" + return 'VK_' + + @property + def write_contacts(self): + """Return whether contact list should be written to extension appendices""" + return True + + @property + def write_refpage_include(self): + """Return whether refpage include should be written to extension appendices""" + return True + + @property + def member_used_for_unique_vuid(self): + """Return the member name used in the VUID-...-...-unique ID.""" + return self.structtype_member_name + + def is_externsync_command(self, protoname): + """Returns True if the protoname element is an API command requiring + external synchronization + """ + return protoname is not None and 'vkCmd' in protoname + + def is_api_name(self, name): + """Returns True if name is in the reserved API namespace. + For Vulkan, these are names with a case-insensitive 'vk' prefix, or + a 'PFN_vk' function pointer type prefix. + """ + return name[0:2].lower() == 'vk' or name.startswith('PFN_vk') + + def specURL(self, spectype='api'): + """Return public registry URL which ref pages should link to for the + current all-extensions HTML specification, so xrefs in the + asciidoc source that are not to ref pages can link into it + instead. N.b. this may need to change on a per-refpage basis if + there are multiple documents involved. + """ + return 'https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html' + + @property + def xml_api_name(self): + """Return the name used in the default API XML registry for the default API""" + return 'vulkan' + + @property + def registry_path(self): + """Return relpath to the default API XML registry in this project.""" + return 'xml/vk.xml' + + @property + def specification_path(self): + """Return relpath to the Asciidoctor specification sources in this project.""" + return '{generated}/meta' + + @property + def special_use_section_anchor(self): + """Return asciidoctor anchor name in the API Specification of the + section describing extension special uses in detail.""" + return 'extendingvulkan-compatibility-specialuse' + + @property + def extension_index_prefixes(self): + """Return a list of extension prefixes used to group extension refpages.""" + return ['VK_KHR', 'VK_EXT', 'VK'] + + @property + def unified_flag_refpages(self): + """Return True if Flags/FlagBits refpages are unified, False if + they are separate. + """ + return False + + @property + def spec_reflow_path(self): + """Return the path to the spec source folder to reflow""" + return os.getcwd() + + @property + def spec_no_reflow_dirs(self): + """Return a set of directories not to automatically descend into + when reflowing spec text + """ + return ('scripts', 'style') + + @property + def zero(self): + return '`0`' + + def category_requires_validation(self, category): + """Return True if the given type 'category' always requires validation. + + Overridden because Vulkan does not require "valid" text for basetype + in the spec right now.""" + return category in CATEGORIES_REQUIRING_VALIDATION + + @property + def should_skip_checking_codes(self): + """Return True if more than the basic validation of return codes should + be skipped for a command. + + Vulkan mostly relies on the validation layers rather than API + builtin error checking, so these checks are not appropriate. + + For example, passing in a VkFormat parameter will not potentially + generate a VK_ERROR_FORMAT_NOT_SUPPORTED code.""" + + return True + + def extension_file_path(self, name): + """Return file path to an extension appendix relative to a directory + containing all such appendices. + - name - extension name""" + + return f'{name}{self.file_suffix}' + + def valid_flag_bit(self, bitpos): + """Return True if bitpos is an allowed numeric bit position for + an API flag bit. + + Vulkan uses 32 bit Vk*Flags types, and assumes C compilers may + cause Vk*FlagBits values with bit 31 set to result in a 64 bit + enumerated type, so disallows such flags.""" + return bitpos >= 0 and bitpos < 31 + + @property + def extra_refpage_headers(self): + """Return any extra text to add to refpage headers.""" + return 'include::{config}/attribs.adoc[]' + + @property + def extra_refpage_body(self): + """Return any extra text (following the title) for generated + reference pages.""" + return 'include::{generated}/specattribs.adoc[]' + + +class VulkanSCConventions(VulkanConventions): + + def specURL(self, spectype='api'): + """Return public registry URL which ref pages should link to for the + current all-extensions HTML specification, so xrefs in the + asciidoc source that are not to ref pages can link into it + instead. N.b. this may need to change on a per-refpage basis if + there are multiple documents involved. + """ + return 'https://registry.khronos.org/vulkansc/specs/1.0-extensions/html/vkspec.html' + + @property + def xml_api_name(self): + """Return the name used in the default API XML registry for the default API""" + return 'vulkansc' + From a80ab6d66a794a61202dcdac32810ea64bc1501e Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 5 Oct 2025 15:10:58 +0300 Subject: [PATCH 18/19] VulkanHeaders generator: generate sType as const with default value Also add a script to generate all the headers we need along with function loading. --- libs/VulkanHeaders/GenerateAll.py | 82 ++++++++++++++++++++++ libs/VulkanHeaders/Globals.py | 44 ++++++++++++ libs/VulkanHeaders/Vulkan.cpp | 4 ++ libs/VulkanHeaders/Vulkan.h | 14 ++++ libs/VulkanHeaders/VulkanLoadFunctions.cpp | 43 ++++++++++++ libs/VulkanHeaders/generator.py | 41 +++++++++++ libs/VulkanHeaders/genvk.py | 10 ++- libs/VulkanHeaders/reg.py | 69 +++++++++++++++++- 8 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 libs/VulkanHeaders/GenerateAll.py create mode 100644 libs/VulkanHeaders/Globals.py create mode 100644 libs/VulkanHeaders/Vulkan.cpp create mode 100644 libs/VulkanHeaders/Vulkan.h create mode 100644 libs/VulkanHeaders/VulkanLoadFunctions.cpp diff --git a/libs/VulkanHeaders/GenerateAll.py b/libs/VulkanHeaders/GenerateAll.py new file mode 100644 index 0000000000..3a0ee94d61 --- /dev/null +++ b/libs/VulkanHeaders/GenerateAll.py @@ -0,0 +1,82 @@ +# =========================================================================== +# +# Daemon BSD Source Code +# Copyright (c) 2025 Daemon Developers +# All rights reserved. +# +# This file is part of the Daemon BSD Source Code (Daemon Source Code). +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# =========================================================================== + +from os import system, remove +from sys import executable +from subprocess import run + +headers = [ + ( "vulkan_core", "w", "" ), + ( "vulkan_beta", "a", "VK_ENABLE_BETA_EXTENSIONS" ), + ( "vulkan_win32", "a", "VK_USE_PLATFORM_WIN32_KHR" ), + ( "vulkan_wayland", "a", "VK_USE_PLATFORM_WAYLAND_KHR" ), + ( "vulkan_xlib", "a", "VK_USE_PLATFORM_XLIB_KHR" ), + ( "vulkan_xlib_xrandr", "a", "VK_USE_PLATFORM_XLIB_XRANDR_EXT" ) +] + +with open( "FunctionDecls.h", "w" ) as f: + with open( "FunctionLoaderInstance.cpp", "w" ) as f1: + with open( "FunctionLoaderDevice.cpp", "w" ) as f2: + print( "" ) + +vulkanLoaderPath = "../../src/engine/renderer-vulkan/VulkanLoader/" + +for header in headers: + if header[2]: + run( [executable, "genvk.py", "-o", vulkanLoaderPath + "vulkan/", "-apiname", "vulkan", "-mode", header[1], + "-define", header[2], header[0] + ".h"], check = True ) + else: + run( [executable, "genvk.py", "-o", vulkanLoaderPath + "vulkan/", "-apiname", "vulkan", "-mode", header[1], + header[0] + ".h"], check = True ) + +with open( "FunctionDecls.h", "r" ) as inp: + with open( vulkanLoaderPath + "Vulkan.h", "w" ) as out: + out.write( inp.read() ) + out.write( '#endif // VULKAN_LOADER_H' ) + +with open( 'VulkanLoadFunctions.cpp', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp: + functionLoadStart = inp.read() + +with open( "FunctionLoaderInstance.cpp", "r" ) as inp: + with open( "FunctionLoaderDevice.cpp", "r" ) as inp2: + with open( vulkanLoaderPath + "VulkanLoadFunctions.cpp", "w" ) as out: + out.write( functionLoadStart ) + out.write( '\n\nvoid VulkanLoadInstanceFunctions( VkInstance instance ) {\n' ) + out.write( inp.read() ) + out.write( '}\n\n' ) + out.write( 'void VulkanLoadDeviceFunctions( VkDevice device ) {\n' ) + out.write( inp2.read() ) + out.write( '}' ) + +remove( "FunctionDecls.h" ) +remove( "FunctionLoaderInstance.cpp" ) +remove( "FunctionLoaderDevice.cpp" ) \ No newline at end of file diff --git a/libs/VulkanHeaders/Globals.py b/libs/VulkanHeaders/Globals.py new file mode 100644 index 0000000000..b76c1bbad5 --- /dev/null +++ b/libs/VulkanHeaders/Globals.py @@ -0,0 +1,44 @@ +# =========================================================================== +# +# Daemon BSD Source Code +# Copyright (c) 2025 Daemon Developers +# All rights reserved. +# +# This file is part of the Daemon BSD Source Code (Daemon Source Code). +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# =========================================================================== + +def init(): + global headerText + global functionDefinitionsText + + global functionLoadInstanceText + global functionLoadDeviceText + + headerText = '' + functionDefinitionsText = '' + + functionLoadInstanceText = '' + functionLoadDeviceText = '' \ No newline at end of file diff --git a/libs/VulkanHeaders/Vulkan.cpp b/libs/VulkanHeaders/Vulkan.cpp new file mode 100644 index 0000000000..7a8d8df510 --- /dev/null +++ b/libs/VulkanHeaders/Vulkan.cpp @@ -0,0 +1,4 @@ +// Auto-generated, do not modify + +#include "Vulkan.h" + diff --git a/libs/VulkanHeaders/Vulkan.h b/libs/VulkanHeaders/Vulkan.h new file mode 100644 index 0000000000..b8749e0f71 --- /dev/null +++ b/libs/VulkanHeaders/Vulkan.h @@ -0,0 +1,14 @@ +// Auto-generated, do not modify + +#ifndef VULKAN_LOADER_H +#define VULKAN_LOADER_H + +#ifdef _MSC_VER + #define VK_USE_PLATFORM_WIN32_KHR +#endif + +#define VK_ENABLE_BETA_EXTENSIONS + +#include "vulkan/vulkan.h" +#include "vulkan/vk_enum_string_helper.h" + diff --git a/libs/VulkanHeaders/VulkanLoadFunctions.cpp b/libs/VulkanHeaders/VulkanLoadFunctions.cpp new file mode 100644 index 0000000000..72b2fb3be3 --- /dev/null +++ b/libs/VulkanHeaders/VulkanLoadFunctions.cpp @@ -0,0 +1,43 @@ +// Auto-generated, do not modify + +#ifdef _MSC_VER + #include +#else + #include +#endif + +#include "Vulkan.h" + +#include "VulkanLoadFunctions.h" + +#ifdef _MSC_VER + HMODULE libVulkan; +#else + void* libVulkan; +#endif + +void VulkanLoaderInit() { + #ifdef _MSC_VER + libVulkan = LoadLibrary( "vulkan-1.dll" ); + vkGetInstanceProcAddr = ( PFN_vkGetInstanceProcAddr ) GetProcAddress( libVulkan, "vkGetInstanceProcAddr" ); + #else + libVulkan = dlopen( "libvulkan.so", RTLD_NOW ); + vkGetInstanceProcAddr = dlsym( libVulkan, "vkGetInstanceProcAddr" ); + #endif + + vkEnumerateInstanceVersion = ( PFN_vkEnumerateInstanceVersion ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceVersion" ); + + vkEnumerateInstanceExtensionProperties = ( PFN_vkEnumerateInstanceExtensionProperties ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceExtensionProperties" ); + + vkEnumerateInstanceLayerProperties = ( PFN_vkEnumerateInstanceLayerProperties ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceLayerProperties" ); + + vkCreateInstance = ( PFN_vkCreateInstance ) vkGetInstanceProcAddr( nullptr, "vkCreateInstance" ); +} + +void VulkanLoaderFree() { + #ifdef _MSC_VER + FreeLibrary( libVulkan ); + #else + dlclose( libVulkan ); + #endif +} \ No newline at end of file diff --git a/libs/VulkanHeaders/generator.py b/libs/VulkanHeaders/generator.py index 5d369a3614..bd0ac69a27 100644 --- a/libs/VulkanHeaders/generator.py +++ b/libs/VulkanHeaders/generator.py @@ -21,6 +21,7 @@ from spec_tools.util import getElemName, getElemType +import Globals def write(*args, **kwargs): file = kwargs.pop('file', sys.stdout) @@ -1124,6 +1125,14 @@ def makeCParamDecl(self, param, aligncol): text = noneStr(elem.text) tail = noneStr(elem.tail) + if text == "sType": + sType = param.get( "values" ) + + if sType: + text += " = " + sType + elif text == "VkStructureType": + text = "const VkStructureType" + if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail): # OpenXR-specific macro insertion - but not in apiinc for the spec tail = self.genOpts.conventions.make_voidpointer_alias(tail) @@ -1173,6 +1182,9 @@ def getCParamTypeLength(self, param): for elem in param: text = noneStr(elem.text) tail = noneStr(elem.tail) + + if text == "VkStructureType": + text = "const VkStructureType" if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail): # OpenXR-specific macro insertion @@ -1351,14 +1363,27 @@ def makeCDecls(self, cmd): # Leading text pdecl += noneStr(proto.text) tdecl += noneStr(proto.text) + # For each child element, if it is a wrap in appropriate # declaration. Otherwise append its contents and tail contents. + functionName = None + deviceFunction = True for elem in proto: text = noneStr(elem.text) tail = noneStr(elem.tail) + if elem.tag == 'name': pdecl += self.makeProtoName(text, tail) tdecl += self.makeTypedefName(text, tail) + + Globals.headerText += 'extern PFN_' + text + ' ' + text + ';\n\n' + Globals.functionDefinitionsText += 'PFN_' + text + ' ' + text + ';\n\n' + + if not text.endswith( ( 'vkGetInstanceProcAddr', 'vkEnumerateInstanceVersion', 'vkEnumerateInstanceExtensionProperties', 'vkEnumerateInstanceLayerProperties', 'vkCreateInstance', 'vkDestroyInstance' ) ): + functionName = text + + if text == 'vkGetDeviceProcAddr': + deviceFunction = False else: pdecl += text + tail tdecl += text + tail @@ -1376,6 +1401,22 @@ def makeCDecls(self, cmd): # self.indentFuncPointer # self.alignFuncParam n = len(params) + + if n > 0 and functionName: + for p in params: + for elem in p: + if deviceFunction and noneStr( elem.text ).endswith( ( 'VkInstance', 'VkPhysicalDevice', 'VkPhysicalDeviceGroup' ) ): + deviceFunction = False + break + + if not deviceFunction: + break + + if deviceFunction: + Globals.functionLoadDeviceText += '\t' + functionName + ' = ( PFN_' + functionName + ' ) vkGetDeviceProcAddr( device, "' + functionName + '" );\n\n' + else: + Globals.functionLoadInstanceText += '\t' + functionName + ' = ( PFN_' + functionName + ' ) vkGetInstanceProcAddr( instance, "' + functionName + '" );\n\n' + # Indented parameters if n > 0: indentdecl = '(\n' diff --git a/libs/VulkanHeaders/genvk.py b/libs/VulkanHeaders/genvk.py index 6e242d8819..0e07640ed7 100644 --- a/libs/VulkanHeaders/genvk.py +++ b/libs/VulkanHeaders/genvk.py @@ -1105,6 +1105,10 @@ def genTarget(args): help='generate MISRA C++-friendly headers') parser.add_argument('--iscts', action='store_true', dest='isCTS', help='Specify if this should generate CTS compatible code') + parser.add_argument('-mode', action='store', + help='w - write, a - append') + parser.add_argument('-define', action='store', + help='Pe-processor define to use') args = parser.parse_args() @@ -1148,12 +1152,16 @@ def genTarget(args): logDiag('* Dumping registry to regdump.txt') reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8')) + if not args.mode in ( 'w', 'a' ): + print( 'Unknown mode: ' + args.mode + '\nAvailable modes: w, a' ) + exit( -1 ) + # Finally, use the output generator to create the requested target if args.debug: pdb.run('reg.apiGen()') else: startTimer(args.time) - reg.apiGen() + reg.apiGen( args.registry.removesuffix( 'vk.xml' ), args.directory, args.mode, args.define ) endTimer(args.time, f"* Time to generate {options.filename} =") if not args.quiet: diff --git a/libs/VulkanHeaders/reg.py b/libs/VulkanHeaders/reg.py index 14183af15f..a8c2285026 100644 --- a/libs/VulkanHeaders/reg.py +++ b/libs/VulkanHeaders/reg.py @@ -15,6 +15,8 @@ from generator import GeneratorOptions, OutputGenerator, noneStr, write from apiconventions import APIConventions +import Globals + def apiNameMatch(str, supported): """Return whether a required api name matches a pattern specified for an XML 'api' attribute or 'supported' attribute. @@ -1656,7 +1658,7 @@ def tagValidExtensionStructs(self): for parent in self.validextensionstructs: self.validextensionstructs[parent].sort() - def apiGen(self): + def apiGen(self, inputDir, outputDir, mode, define): """Generate interface for specified versions using the current generator and generator options""" @@ -1844,6 +1846,18 @@ def apiGen(self): # generated. self.gen.logMsg('diag', 'PASS 3: GENERATE INTERFACES FOR FEATURES') self.gen.beginFile(self.genOpts) + + headerStart = '' + functionLoadStart = '' + if mode == "w": + with open( inputDir + 'Vulkan.h', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp: + headerStart = inp.read() + + with open( inputDir + 'VulkanLoadFunctions.cpp', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp: + functionLoadStart = inp.read() + + Globals.init() + for f in features: self.gen.logMsg('diag', 'PASS 3: Generating interface for', f.name) @@ -1870,6 +1884,59 @@ def apiGen(self): for s in self.syncpipelinedict: self.generateSyncPipeline(self.syncpipelinedict[s]) self.gen.endFile() + + outputDir = outputDir.rstrip( '/' ).rsplit( '/', 1 )[0] + '/' + + indent = "\t" if define else "" + + with open( 'FunctionDecls.h', mode = mode, encoding = 'utf-8', newline = '\n' ) as out: + if define: + out.write( "#if defined( " + define + " )\n" ) + + out.write( headerStart + indent + Globals.headerText ) + + if define: + out.write( "#endif\n\n" ) + + with open( outputDir + 'Vulkan.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out: + if mode == "w": + out.write( '// Auto-generated, do not modify\n\n' ) + out.write( '#include "Vulkan.h"\n\n' ) + + if define: + out.write( "#if defined( " + define + " )\n" ) + + out.write( indent + Globals.functionDefinitionsText ) + + if define: + out.write( "#endif\n\n" ) + + #with open( outputDir + 'VulkanLoadFunctions.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out: + # out.write( functionLoadStart ) + # out.write( '\n\nvoid VulkanLoadInstanceFunctions( VkInstance instance ) {\n' ) + # out.write( Globals.functionLoadInstanceText ) + # out.write( '}\n\n' ) + # out.write( 'void VulkanLoadDeviceFunctions( VkDevice device ) {\n' ) + # out.write( Globals.functionLoadDeviceText ) + # out.write( '}' ) + + with open( 'FunctionLoaderInstance.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out: + if define: + out.write( "#if defined( " + define + " )\n" ) + + out.write( Globals.functionLoadInstanceText ) + + if define: + out.write( "#endif\n\n" ) + + with open( 'FunctionLoaderDevice.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out: + if define: + out.write( "#if defined( " + define + " )\n" ) + + out.write( Globals.functionLoadDeviceText ) + + if define: + out.write( "#endif\n\n" ) def apiReset(self): """Reset type/enum/command dictionaries before generating another API. From f10467daf12fe32ef65bf30a76f2b9843e272f4e Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 15 Oct 2025 21:01:44 +0300 Subject: [PATCH 19/19] VulkanHeaders generator: use sized enums --- libs/VulkanHeaders/generator.py | 120 +++----------------------------- 1 file changed, 8 insertions(+), 112 deletions(-) diff --git a/libs/VulkanHeaders/generator.py b/libs/VulkanHeaders/generator.py index bd0ac69a27..2bff2ee8ed 100644 --- a/libs/VulkanHeaders/generator.py +++ b/libs/VulkanHeaders/generator.py @@ -623,117 +623,14 @@ def buildEnumCDecl(self, expand, groupinfo, groupName): self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for ', groupName, ' - must be an integer value\n') exit(1) - usebitmask = False - usedefine = False - - # Bitmask flags can be generated as either "static const uint{32,64}_t" values, - # or as 32-bit C enums. 64-bit types must use uint64_t values. - if groupElem.get('type') == 'bitmask': - if bitwidth > 32 or self.misracppstyle(): - usebitmask = True - if self.misracstyle(): - usedefine = True - - if usedefine or usebitmask: - # Validate the bitwidth and generate values appropriately - if bitwidth > 64: - self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for bitmask type ', groupName, ' - must be less than or equal to 64\n') - exit(1) - else: - return self.buildEnumCDecl_BitmaskOrDefine(groupinfo, groupName, bitwidth, usedefine) - else: - # Validate the bitwidth and generate values appropriately - if bitwidth > 32: - self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for enum type ', groupName, ' - must be less than or equal to 32\n') - exit(1) - else: - return self.buildEnumCDecl_Enum(expand, groupinfo, groupName) - - def buildEnumCDecl_BitmaskOrDefine(self, groupinfo, groupName, bitwidth, usedefine): - """Generate the C declaration for an "enum" that is actually a - set of flag bits""" - groupElem = groupinfo.elem - flagTypeName = groupElem.get('name') - - # Prefix - body = f"// Flag bits for {flagTypeName}\n" - - if bitwidth == 64: - body += f"typedef VkFlags64 {flagTypeName};\n"; + # Validate the bitwidth and generate values appropriately + if bitwidth > 64: + self.logMsg('error', 'Invalid value for bitwidth attribute (', groupElem.get('bitwidth'), ') for enum type ', groupName, ' - must be less than or equal to 64\n') + exit(1) else: - body += f"typedef VkFlags {flagTypeName};\n"; - - # Maximum allowable value for a flag (unsigned 64-bit integer) - maxValidValue = 2**(64) - 1 - minValidValue = 0 - - # Get a list of nested 'enum' tags. - enums = groupElem.findall('enum') - - # Check for and report duplicates, and return a list with them - # removed. - enums = self.checkDuplicateEnums(enums) - - # Accumulate non-numeric enumerant values separately and append - # them following the numeric values, to allow for aliases. - # NOTE: this does not do a topological sort yet, so aliases of - # aliases can still get in the wrong order. - aliasText = '' - - # Loop over the nested 'enum' tags. - for elem in enums: - # Convert the value to an integer and use that to track min/max. - # Values of form -(number) are accepted but nothing more complex. - # Should catch exceptions here for more complex constructs. Not yet. - (numVal, strVal) = self.enumToValue(elem, True, bitwidth, True) - name = elem.get('name') - - # Range check for the enum value - if numVal is not None and (numVal > maxValidValue or numVal < minValidValue): - self.logMsg('error', 'Allowable range for flag types in C is [', minValidValue, ',', maxValidValue, '], but', name, 'flag has a value outside of this (', strVal, ')\n') - exit(1) - - decl = self.genRequirements(name, mustBeFound = False) - - if self.isEnumRequired(elem): - protect = elem.get('protect') - if protect is not None: - body += f'#ifdef {protect}\n' - - body += self.deprecationComment(elem, indent = 0) - - if usedefine: - decl += f"#define {name} {strVal}\n" - elif self.misracppstyle(): - decl += f"static constexpr {flagTypeName} {name} {{{strVal}}};\n" - else: - # Some C compilers only allow initializing a 'static const' variable with a literal value. - # So initializing an alias from another 'static const' value would fail to compile. - # Work around this by chasing the aliases to get the actual value. - while numVal is None: - alias = self.registry.tree.find(f"enums/enum[@name='{strVal}']") - if alias is not None: - (numVal, strVal) = self.enumToValue(alias, True, bitwidth, True) - else: - self.logMsg('error', f'No such alias {strVal} for enum {name}') - decl += f"static const {flagTypeName} {name} = {strVal};\n" - - if numVal is not None: - body += decl - else: - aliasText += decl - - if protect is not None: - body += '#endif\n' - - # Now append the non-numeric enumerant values - body += aliasText - - # Postfix - - return ("bitmask", body) + return self.buildEnumCDecl_Enum(expand, groupinfo, groupName, bitwidth) - def buildEnumCDecl_Enum(self, expand, groupinfo, groupName): + def buildEnumCDecl_Enum(self, expand, groupinfo, groupName, bitwidth): """Generate the C declaration for an enumerated type""" groupElem = groupinfo.elem @@ -749,13 +646,12 @@ def buildEnumCDecl_Enum(self, expand, groupinfo, groupName): expandPrefix = expandName.rsplit(expandSuffix, 1)[0] # Prefix - body = ["typedef enum %s {" % groupName] + body = ["typedef enum %s : %s {" % ( groupName, "uint32_t" if bitwidth == 32 else "uint64_t" )] # @@ Should use the type="bitmask" attribute instead isEnum = ('FLAG_BITS' not in expandPrefix) - # Allowable range for a C enum - which is that of a signed 32-bit integer - maxValidValue = 2**(32 - 1) - 1 + maxValidValue = 2**(bitwidth - 1) - 1 minValidValue = (maxValidValue * -1) - 1 # Get a list of nested 'enum' tags.