### Sample setup for GPA Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_AMD_gpa_interface.adoc Example of setting up and beginning a GPA sample. ```c VkGpaSampleBeginInfoAMD sampleInfo = { VK_STRUCTURE_TYPE_GPA_SAMPLE_BEGIN_INFO_AMD, 0 }; sampleInfo.sampleType = VK_GPA_SAMPLE_TYPE_CUMULATIVE_AMD; sampleInfo.cacheFlushOnCounterCollection = VK_TRUE; // Enable CPG block counter that always counters upwards { VkGpaPerfCounterAMD perfCounter = {}; perfCounter.blockType = VK_GPA_PERF_BLOCK_CPG_AMD; perfCounter.blockInstance = 0; perfCounter.eventID = 0; counters.push_back(perfCounter); } // Enable every SPI counter that counts the number of gfx CS waves initialized (applicable to Gfx11 and Gfx12 hardware for graphics applications) for (uint32_t i = 0; i < spiBlock.instanceCount; ++i) { VkGpaPerfCounterAMD perfCounter = {}; perfCounter.blockType = VK_GPA_PERF_BLOCK_SPI_AMD; perfCounter.blockInstance = i; perfCounter.eventID = 42; counters.push_back(perfCounter); } sampleInfo.perfCounterCount = counters.size(); sampleInfo.pPerfCounters = &counters[0]; uint32_t sampleID = 0; vkCmdBeginGpaSampleAMD(cmdbuf->handle, primarySession, &sampleInfo, &sampleID); // // write commands for workload into cmdbuf // vkCmdEndGpaSampleAMD(cmdbuf->handle, primarySession, sampleID); ``` -------------------------------- ### Micromap Build and Creation Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_opacity_micromap.adoc This snippet demonstrates the process of building and creating a micromap, including getting build sizes, creating a buffer, and creating the micromap object. ```c VkMicromapBuildInfoEXT mmBuildInfo = { VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT }; mmBuildInfo... = ; vkGetMicromapBuildSizesEXT(..., &mmBuildInfo, &sizeInfo) CreateBuffer(sizeInfo) VkMicromapCreateInfoEXT mmCreateInfo = { VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT }; mmCreateInfo... = ; vkCreateMicromapEXT(device, mmCreateInfo, null, µmap) mmBuildInfo = ...; vkCmdBuildMicromapsEXT(cmd, 1, &mmBuildInfo); ``` -------------------------------- ### Vulkan Command Naming Examples Source: https://github.com/khronosgroup/vulkan-docs/blob/main/style/naming.adoc Illustrates the naming conventions for Vulkan commands, including creation, command buffer recording, and get commands. ```c // Creation command VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( ... ); // Command buffer recording command VKAPI_ATTR VkResult VKAPI_CALL vkCmdBindPipeline( ... ); // Get command VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( ... ); ``` -------------------------------- ### Get new binaries and store to application cache Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_pipeline_binary.adoc This example illustrates the process of creating new pipeline binaries, retrieving their data, and storing them along with their keys in an application cache. ```c++ VkPipelineBinaryCreateInfoKHR createInfo; createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_BINARY_CREATE_INFO_KHR; createInfo.pNext = NULL; createInfo.pKeysAndDataInfo = NULL; createInfo.pipeline = graphicsPipeline; createInfo.pPipelineCreateInfo = NULL; VkPipelineBinaryHandlesInfoKHR handlesInfo; handlesInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_BINARY_HANDLES_INFO_KHR; handlesInfo.pNext = NULL; handlesInfo.pipelineBinaryCount = 0; handlesInfo.pPipelineBinaries = NULL; vkCreatePipelineBinariesKHR(device, &createInfo, NULL, &handlesInfo); std::vector pipelineBinaries; pipelineBinaries.resize(handlesInfo.pipelineBinaryCount); handlesInfo.pPipelineBinaries = pipelineBinaries.data(); vkCreatePipelineBinariesKHR(device, &createInfo, NULL, &handlesInfo); vector binaryKeys; binaryKeys.resize(handlesInfo.pipelineBinaryCount); // Store to application cache for (int i = 0; i < handlesInfo.pipelineBinaryCount; ++i) { VkPipelineBinaryDataInfoKHR binaryInfo; binaryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_BINARY_DATA_INFO_KHR; binaryInfo.pNext = NULL; binaryInfo.pipelineBinary = pipelineBinaries[i]; size_t binaryDataSize = 0; vkGetPipelineBinaryDataKHR(device, &binaryInfo, &binaryKeys[i], &binaryDataSize, NULL); vector data; binaryData.resize(binaryDataSize); vkGetPipelineBinaryDataKHR(device, &binaryInfo, &binaryKeys[i], &binaryDataSize, binaryData.data()); ApplicationBinaryCache.insert(binaryKeys[i], binaryData); } // Store pipeline key -> binary keys mapping ApplicationCache.insert(pipelineKey, binaryKeys); // Free any possible resources associated with binary creation for the pipeline vkReleaseCapturedPipelineDataKHR(device, graphicsPipeline, NULL); ``` -------------------------------- ### Example Query for Layered Implementation Properties Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_maintenance7.adoc Example demonstrating how to query properties for a layered implementation stack. ```c layers->pLayeredApis[0].layeredAPI = VK_PHYSICAL_DEVICE_LAYERED_API_D3D12_KHR; // other fields layers->pLayeredApis[1].layeredAPI = VK_PHYSICAL_DEVICE_LAYERED_API_VULKAN_KHR; // other fields // If driverProperties is a VkPhysicalDeviceDriverProperties chained to // VkPhysicalDeviceLayeredApiVulkanPropertiesKHR::properties that is in turn // chained to layers->pLayeredApis[1].pNext: driverProperties->driverID = VK_DRIVER_ID_MESA_DOZEN; // other fields ``` -------------------------------- ### GLSL Example with Invocation Reordering Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_ray_tracing_invocation_reorder.adoc Example demonstrating invocation reordering in GLSL. ```glsl #version 460 #extension GL_EXT_ray_tracing : enable #extension GL_EXT_buffer_reference_uvec2 : enable #extension GL_NV_shader_invocation_reorder : enable layout(binding = 0) uniform accelerationStructureEXT as; layout(binding = 1, rgba32f) uniform image2D img; layout(binding = 2) uniform RayParams { vec3 origin;}; layout(location = 0) rayPayloadEXT vec4 Color; layout(buffer_reference, hitobjectshaderrecordext) buffer SRB { uint materialId; }; layout(location = 0) hitObjectAttributeEXT vec3 sphereAABB; void main() { //Trace rays executing custom intersection/any-hit vec4 outputColor = vec4(0); hitObjectEXT hObj; //Initialize to an empty hit object hitObjectRecordEmptyEXT(hObj); hitObjectTraceRayEXT(hObj, as, 0, 0, 0, 4, 0, origin + vec3(gl_LaunchIDEXT.xyz), 0.0f, origin + vec3(gl_LaunchIDEXT.xyz) + vec3(0,0,1.0f), 1.0f, 0); uint materialIdHint = 0; if (hitObjectIsHitEXT(hObj)) { uvec2 handle = hitObjectGetShaderRecordBufferHandleEXT(hObj); materialIdHint = SRB(handle).materialId; } //Reorder threads based on hit object and additional hint on material type //Use 3 LSB bits only reorderThreadEXT(hObj, materialIdHint, 3); //Execute closest hit shaders only if (hitObjectIsHitEXT(hObj)) { //Get Attributes of intersection hitObjectGetAttributesEXT(hObj, 0); hitObjectExecuteShaderEXT(hObj, 0); outputColor = vec4(Color.x + distance(sphereAABB, vec3(0))); } imageStore(img, ivec2(gl_LaunchIDEXT.xy), outputColor); } ``` -------------------------------- ### Example: Collecting Per Picture Partition Feedback Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_encode_feedback2.adoc This example demonstrates how to set up a query pool to collect per-picture partition feedback. It assumes the video profile supports all relevant feedback flags and enables them during query pool creation. ```c // For simplicity, we define here the maximum picture partitions we intend to support #define MAX_ENCODE_PICTURE_PARTITIONS 16 // Assuming the video profile supports all whole-picture and per picture partition // encode feedback values, we enable all of them when creating the query pool // In practice, not all implementations and video profiles will support all of these VkQueryPool queryPool = VK_NULL_HANDLE; VkVideoProfileInfoKHR profileInfo = { ... }; ``` -------------------------------- ### Ray Generation GLSL Shader Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/appendices/VK_KHR_ray_tracing_pipeline.adoc An example of a GLSL shader for ray generation, demonstrating the use of the GL_EXT_ray_tracing extension. This shader is a starting point for implementing ray tracing functionalities. ```glsl #version 450 core #extension GL_EXT_ray_tracing : require ``` -------------------------------- ### Elapsed Timer Query Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_QCOM_elapsed_timer_query.adoc This example demonstrates how to use VK_QCOM_elapsed_timer_query to measure the execution time of a draw call. It includes starting and ending queries, submitting command buffers, and retrieving results. ```c // Insert pipeline barrier/event here with scopes specifying the first draw and the second draw // commands if want to measure the total execution time of the second draw. Otherwise, // vkCmdBeginQuery below will only start once the first draw completes execution, even // if that is after the second draw starts. It can be desirable though to not // insert this barrier and measure the actual frame cost of the second draw by not including // the time hidden by pipelining, and to reduce the effect of observation on the system. vkCmdBeginQuery(cmdBuf, queryPool, queryIndex, 0); vkCmdDraw(cmdBuf, ...); vkCmdEndQuery(cmdBuf, queryPool, queryIndex++); vkCmdEndRendering(cmdBuf); ... VkSubmitInfo submitInfo = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = &cmdBuf, ... }; vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); vkQueueWaitIdle(queue); uint64_t results[MaxQueries]; vkGetQueryPoolResults(device, queryPool, 0, queryIndex, sizeof(results), results, sizeof(results[0]), VK_QUERY_RESULT_64_BIT); for (uint32_t i = 0; i < queryIndex; i++) { printf("Draw %u took %fns\n", i, results[i] * limits.timestampPeriod); } ``` -------------------------------- ### Render Pass Setup for Multiple Queues Source: https://github.com/khronosgroup/vulkan-docs/wiki/Synchronization-Examples-(Legacy-synchronization-APIs) Demonstrates the setup of a Vulkan render pass, considering scenarios where queue ownership transfers might be necessary. It highlights the attachment and subpass descriptions. ```APIDOC ## Render Pass Setup for Multiple Queues ### Description This section details the configuration of a Vulkan render pass, including attachment and subpass descriptions, in preparation for rendering operations that may involve queue ownership transfers. ### Method `vkCreateRenderPass` ### Endpoint N/A (Function Call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body ```c VkAttachmentReference attachmentReference = { .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; // Subpass containing first draw VkSubpassDescription subpass = { ... .colorAttachmentCount = 1, .pColorAttachments = &attachmentReference, ... }; VkAttachmentDescription attachmentDescription = { ... .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, ... .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; /* Due to these necessary extra synchronization points, it makes more sense to omit the sub pass external dependencies (which can't express a queue transfer), and batch the relevant operations with the new pipeline barriers we're introducing. */ VkRenderPassCreateInfo renderPassCreateInfo = { ... .attachmentCount = 1, .pAttachments = &attachmentDescription, .subpassCount = 1, .pSubpasses = &subpass, .dependencyCount = 0, .pDependencies = NULL}; ``` ### Request Example ```json { "example": "VkRenderPassCreateInfo configuration for render pass setup." } ``` ### Response #### Success Response (200) - **VkRenderPass** (object) - Handle to the created render pass. #### Response Example ```json { "example": "vkCreateRenderPass(..., &renderPassCreateInfo, NULL, &renderPass);" } ``` ``` -------------------------------- ### Get Windows QueryPerformanceCounter Timestamp Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/synchronization.adoc Example of capturing a timestamp using the Windows QueryPerformanceCounter API. This is comparable with Vulkan's VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR. ```c LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return counter.QuadPart; ``` -------------------------------- ### Vulkan Image Upload Setup (C) Source: https://github.com/khronosgroup/vulkan-docs/wiki/Synchronization-Examples This C code snippet demonstrates the setup for uploading image data from the CPU to a Vulkan image. It includes creating a staging buffer for transfer, an image for sampling, allocating and binding memory with appropriate properties (host-visible for staging, device-local for image), mapping the staging buffer, writing data, and flushing the memory. ```c const uint32_t imageDataSize = ... ; VkBufferCreateInfo stagingCreateInfo = { ... , .size = imageDataSize, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, ... }; VkBuffer stagingBuffer; vkCreateBuffer(device, &stagingCreateInfo, NULL, &stagingBuffer); VkImageCreateInfo imageCreateInfo = { ... , .tiling = VK_IMAGE_TILING_OPTIMAL, .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, ... }; VkImage image; vkCreateImage(device, &imageCreateInfo, NULL, &image); ... // Allocate and memory bind memory for these resources. // Ensure that the staging buffer uses a memory type that has // VK_MEMORY_PROPERTY_HOST_VISIBLE property and doesn't have // VK_MEMORY_PROPERTY_DEVICE_LOCAL. // The image memory should be the opposite - it should include // VK_MEMORY_PROPERTY_DEVICE_LOCAL and should not have // VK_MEMORY_PROPERTY_HOST_VISIBLE. // Use the example code documented in the description of // VkPhysicalDeviceMemoryProperties: // https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkPhysicalDeviceMemoryProperties.html ... void* stagingData; vkMapMemory( ... , stagingMemory, stagingMemoryOffset, imageDataSize, 0, &stagingData); // Write data directly into the mapped pointer fread(stagingData, imageDataSize, 1, imageFile); // Flush the memory range // If the memory type of stagingMemory includes VK_MEMORY_PROPERTY_HOST_COHERENT, skip this step // Align to the VkPhysicalDeviceProperties::nonCoherentAtomSize uint32_t alignedSize = (imageDataSize-1) - ((imageDataSize-1) % nonCoherentAtomSize) + nonCoherentAtomSize; // Setup the range VkMappedMemoryRange stagingRange = { ... , .memory = stagingMemory, .offset = stagingMemoryOffset, .size = alignedSize}; // Flush the range vkFlushMappedMemoryRanges(device, 1, &stagingRange); ``` -------------------------------- ### Get binaries from application cache Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_pipeline_binary.adoc This example demonstrates how to retrieve pipeline keys and their associated binary data from an application cache. ```c++ // Get the pipeline key VkPipelineCreateInfoKHR pipelineCreateInfo; pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_INFO_KHR; pipelineCreateInfo.pNext = &graphicsCreateInfo; VkPipelineBinaryKeyKHR pipelineKey; vkGetPipelineKeyKHR(device, &pipelineCreateInfo, &pipelineKey); // Get the binary keys vector binaryKeys; ApplicationCache.get(pipelineKey, binaryKeys); // Get the binary data std::vector pipelineDatas; pipelineDatas.resize(binaryKeys.size()); for (int i = 0; i < binaryKeys.size(); ++i) { // Retrieve VkPipelineBinaryKHR handle from cache ApplicationBinaryCache.get(binaryKeys[i], &pipelineDatas[i]); } ``` -------------------------------- ### Example Implementor's Note Markup Source: https://github.com/khronosgroup/vulkan-docs/blob/main/style/markup.adoc Illustrates the AsciiDoc syntax for an 'Implementor's Note', often controlled by a conditional like 'implementation-guide'. These notes provide guidelines for Vulkan implementation developers. ```asciidoc ifdef::implementation-guide[] .Implementor's Note ==== Contents of an implementor's note go here. ==== ``` -------------------------------- ### Vulkan Feature Definition Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/registry.adoc This XML snippet shows the start of a Vulkan feature definition, including its API version and name. ```xml > chapter. * pname:pCommandPool is a pointer to a slink:VkCommandPool handle in which the created pool is returned. ``` -------------------------------- ### Video Encode Queue Setup Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_encode_queue.adoc Steps required before an application can start recording command buffers with video encode operations. ```pseudocode 1. Query queue family properties for video codec operations using vkGetPhysicalDeviceQueueFamilyProperties2 and VkQueueFamilyVideoPropertiesKHR. 2. Query VkQueueFamilyQueryResultStatusPropertiesKHR for VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR support if needed. 3. Construct VkVideoProfileInfoKHR describing the video profile (codec, subsampling, bit depths, etc.). 4. Query video capabilities using vkGetPhysicalDeviceVideoCapabilitiesKHR. 5. Query supported image/picture format properties using vkGetPhysicalDeviceVideoFormatPropertiesKHR and select suitable formats. 6. Create encode input images with appropriate usage flags and bind memory. Create image views. 7. Create DPB images if needed, with appropriate usage flags and bind memory. Create image views. 8. Create a destination video bitstream buffer with VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR usage. 9. Create a query pool if result status or feedback queries are needed. 10. Create the video session using the video encode profile and supported parameters. 11. Create a video session parameters object if needed. ``` -------------------------------- ### Vulkan Buffer Creation and Memory Setup (C) Source: https://github.com/khronosgroup/vulkan-docs/wiki/Synchronization-Examples This snippet demonstrates the creation of staging and vertex buffers in Vulkan. It outlines the necessary VkBufferCreateInfo structures, buffer creation calls, and the crucial step of allocating and binding memory, emphasizing the distinct memory property requirements for staging (HOST_VISIBLE, not DEVICE_LOCAL) and vertex buffers (DEVICE_LOCAL, not HOST_VISIBLE). It also shows how to map memory for data transfer and flush the mapped range. ```c const uint32_t vertexDataSize = ... ; const void* pData = ... ; // Create a staging buffer for upload VkBufferCreateInfo stagingCreateInfo = { ... .size = vertexDataSize, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, ... }; VkBuffer stagingBuffer; vkCreateBuffer(device, &stagingCreateInfo, NULL, &stagingBuffer); // Create the vertex buffer VkBufferCreateInfo vertexCreateInfo = { ... .size = vertexDataSize, .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, ... }; VkBuffer vertexBuffer; vkCreateBuffer(device, &vertexCreateInfo, NULL, &vertexBuffer); ... // Allocate and memory bind memory for these buffers. // Ensure that the staging buffer uses a memory type that has // VK_MEMORY_PROPERTY_HOST_VISIBLE property and doesn't have // VK_MEMORY_PROPERTY_DEVICE_LOCAL. // The vertex buffer memory should be the opposite - it should include // VK_MEMORY_PROPERTY_DEVICE_LOCAL and should not have // VK_MEMORY_PROPERTY_HOST_VISIBLE. // Use the example code documented in the description of // VkPhysicalDeviceMemoryProperties: // https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkPhysicalDeviceMemoryProperties.html ... // Map the staging buffers - if you plan to re-use these (which you should), // keep them mapped. // Ideally just map the whole range at once as well. void* stagingData; vkMapMemory( ... stagingMemory, stagingMemoryOffset, vertexDataSize, 0, &stagingData); // Write data directly into the mapped pointer fread(stagingData, vertexDataSize, 1, vertexFile); // Flush the memory range // If the memory type of stagingMemory includes VK_MEMORY_PROPERTY_HOST_COHERENT, skip this step // Align to the VkPhysicalDeviceProperties::nonCoherentAtomSize uint32_t alignedSize = (vertexDataSize-1) - ((vertexDataSize-1) % nonCoherentAtomSize) + nonCoherentAtomSize; // Setup the range VkMappedMemoryRange stagingRange = { ... .memory = stagingMemory, .offset = stagingMemoryOffset, .size = alignedSize}; // Flush the range vkFlushMappedMemoryRanges(device, 1, &stagingRange); ``` -------------------------------- ### Get POSIX CLOCK_MONOTONIC_RAW Timestamp Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/synchronization.adoc Example of capturing a timestamp from the POSIX CLOCK_MONOTONIC_RAW time domain. This is useful for comparing with Vulkan's VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR. ```c struct timespec tv; clock_gettime(CLOCK_MONOTONIC_RAW, &tv); return tv.tv_nsec + tv.tv_sec*1000000000ull; ``` -------------------------------- ### Get POSIX CLOCK_MONOTONIC Timestamp Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/synchronization.adoc Example of capturing a timestamp from the POSIX CLOCK_MONOTONIC time domain. This is useful for comparing with Vulkan's VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR. ```c struct timespec tv; clock_gettime(CLOCK_MONOTONIC, &tv); return tv.tv_nsec + tv.tv_sec*1000000000ull; ``` -------------------------------- ### Using inline queries with a video session Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_maintenance1.adoc This example demonstrates how to create a video session with inline query support and how to create a query pool. ```c // Create video session with inline query support VkVideoSessionKHR videoSession = VK_NULL_HANDLE; VkVideoSessionCreateInfoKHR createInfo = { .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR, .pNext = NULL, .queueFamilyIndex = ... // index of queue family that supports the video codec operation .flags = VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR, // opt-in to use inline queries ... }; vkCreateVideoSessionKHR(device, &createInfo, NULL, &videoSession); // Create query pool as usual VkQueryPool queryPool = VK_NULL_HANDLE; VkVideoProfileInfoKHR profileInfo = { ... }; VkQueryPoolCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, .pNext = &profileInfo, ``` -------------------------------- ### Vulkan Extension and Layer Naming Examples Source: https://github.com/khronosgroup/vulkan-docs/blob/main/style/extensions.adoc Demonstrates the naming patterns for core API versions, Khronos-ratified extensions, multi-vendor extensions, vendor-specific extensions, and layers using both author IDs and FQDNs. ```c // Core API version name for Vulkan 1.1 VK_VERSION_1_1 // Khronos ratified extension name VK_KHR_mirror_clamp_to_edge // Multi-vendor extension name VK_EXT_debug_marker // Vendor extension name using author ID NV VK_NV_glsl_shader // Vendor layer name using author ID LUNARG VK_LAYER_LUNARG_vktrace // Layer name using the FQDN www.3dxcl.invalid instead of an author ID VK_LAYER_invalid_3dxcl_www ``` -------------------------------- ### Instances Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/initialization.adoc Introduction to Vulkan instances, highlighting the absence of global state. ```APIDOC ## Instances ### Description Vulkan operates without global state, meaning all per-application state is managed within instance objects. An instance is the top-level object in Vulkan, created via `vkCreateInstance`. ### Method `vkCreateInstance` ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **pCreateInfo** (VkInstanceCreateInfo*) - Pointer to a structure containing information to create the instance. - **pAllocator** (const VkAllocationCallbacks*) - Optional pointer to custom allocators. ### Request Example ```json { "example": "vkCreateInstance(createInfo, allocator)" } ``` ### Response #### Success Response (200) - **pInstance** (VkInstance*) - Pointer to the handle of the created instance object. #### Response Example ```json { "example": "VkInstance handle" } ``` ``` -------------------------------- ### Video Coding Operation Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_queue.adoc This snippet demonstrates the basic workflow of issuing a video coding operation using Vulkan, including starting and ending queries, and checking the results. ```c .queryType = VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, ... }; vkCreateQueryPool(device, &createInfo, NULL, &queryPool); ... vkBeginCommandBuffer(commandBuffer, ...); ... vkCmdBeginVideoCodingKHR(commandBuffer, ...); ... vkCmdBeginQuery(commandBuffer, queryPool, 0, 0); // Issue video coding operation ... vkCmdEndQuery(commandBuffer, queryPool, 0); ... vkCmdEndVideoCodingKHR(commandBuffer, ...); ... vkEndCommandBuffer(commandBuffer); ... VkQueryResultStatusKHR status; vkGetQueryPoolResults(device, queryPool, 0, 1, sizeof(status), &status, sizeof(status), VK_QUERY_RESULT_WITH_STATUS_BIT_KHR); if (status == VK_QUERY_RESULT_STATUS_NOT_READY_KHR /* 0 */) { // Query result not ready yet ... } else if (status > 0) { // Video coding operation was successful, enum values indicate specific success status code ... } else if (status < 0) { // Video coding operation was unsuccessful, enum values indicate specific failure status code ... } ``` -------------------------------- ### Example Usage of VK_EXT_layer_settings Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_layer_settings.adoc This snippet demonstrates how to use VK_EXT_layer_settings to configure layer settings during instance creation. ```cpp const VkLayerSettingEXT settings[] = { {kLayerName, kLayerSettingsSimulateCapabilities, VK_LAYER_SETTING_TYPE_STRING_EXT, static_cast(std::size(simulate_capabilities)), simulate_capabilities}, {kLayerName, kLayerSettingsDebugReports, VK_LAYER_SETTING_TYPE_STRING_EXT, static_cast(std::size(debug_reports)), debug_reports} }; const VkLayerSettingsCreateInfoEXT layer_settings_create_info{ VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, static_cast(std::size(settings)), settings}; VkInstanceCreateInfo inst_create_info = {}; ... inst_create_info.pNext = &layer_settings_create_info; vkCreateInstance(&inst_create_info, nullptr, &_instances); ``` -------------------------------- ### Record decode operation with reconstructed picture information (DISTINCT mode) Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_decode_queue.adoc Example of recording a decode operation with reconstructed picture information in DISTINCT mode, including setup reference slot. ```c // Bound reference resource list provided has to include reconstructed picture resource vkCmdBeginVideoCodingKHR(commandBuffer, ...); VkVideoPictureResourceInfoKHR decodeOutputPictureResource = { .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR, .pNext = NULL, .codedOffset = ... // offset within the image subresource (typically { 0, 0 }) .codedExtent = ... // extent of decoded picture (typically the video frame size) .baseArrayLayer = 0, .imageViewBinding = outputImageView }; VkVideoPictureResourceInfoKHR reconstructedPictureResource = { .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR, .pNext = NULL, .codedOffset = ... // offset within the image subresource (typically { 0, 0 }) .codedExtent = ... // extent of reconstructed picture (typically the video frame size) .baseArrayLayer = ... // layer to use for setup picture in DPB .imageViewBinding = dpbImageView }; VkVideoReferenceSlotInfoKHR setupSlotInfo = { .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, .pNext = ... // pointer to codec-specific reconstructed picture information structure .slotIndex = ... // DPB slot index to use with the reconstructed picture // (optionally activated per the codec-specific semantics) .pPictureResource = &reconstructedPictureResource }; VkVideoDecodeInfoKHR decodeInfo = { .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR, .pNext = ... // pointer to codec-specific picture information structure ... .dstPictureResource = decodeOutputPictureResource, .pSetupReferenceSlot = &setupSlotInfo, ... }; vkCmdDecodeVideoKHR(commandBuffer, &decodeInfo); vkCmdEndVideoCodingKHR(commandBuffer, ...); ``` -------------------------------- ### Descriptor Set Layout Bindings Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_descriptor_buffer.adoc This code snippet demonstrates how to define descriptor set layout bindings for various descriptor types, including sampled images, uniform texel buffers, samplers, and storage buffers. It also shows the setup for using immutable samplers, both externally provided and embedded. ```c VkSampler immutableSamplers[4]; // Create these somehow. // When using descriptor buffers, it is generally a good idea to separate out samplers and resources into separate sets, // since descriptor buffers containing samplers might be very limited in size. const VkDescriptorSetLayoutBinding setLayout0[] = { { 0, // binding VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType 2, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags NULL // pImmutableSamplers }, { 1, // binding VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // descriptorType 2, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags NULL // pImmutableSamplers } }; const VkDescriptorSetLayoutBinding setLayout1[] = { { 0, // binding VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType 2, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags &immutableSamplers[0], // pImmutableSamplers }, { 1, // binding VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType 2, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags NULL, } }; const VkDescriptorSetLayoutBinding setLayout2[] = { // binding to a single image descriptor { 0, // binding VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType 1, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags NULL // pImmutableSamplers } }; // Embedded immutable samplers are internally allocated and we do not need to allocate anything. const VkDescriptorSetLayoutBinding setLayout3[] = { { 0, // binding VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType 1, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags &immutableSamplers[2], // pImmutableSamplers }, { 1, // binding VK_DESCRIPTOR_TYPE_SAMPLER, // descriptorType ``` -------------------------------- ### Using quantization maps Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_video_encode_quantization_map.adoc This example illustrates the steps involved in using quantization maps for video encoding. It covers creating a video session with quantization map support, setting up video session parameters, and creating the necessary image and image view resources. ```c // Create video session with quantization map support VkVideoSessionKHR videoSession = VK_NULL_HANDLE; VkVideoSessionCreateInfoKHR videoSessionCreateInfo = { ... }; // Include the corresponding session creation flag videoSessionCreateInfo.flags |= VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_{QUANTIZATION_DELTA|EMPHASIS}_MAP_BIT_KHR; vkCreateVideoSessionKHR(device, &videoSessionCreateInfo, NULL, &videoSession); // Create video session parameters against the used quantization map texel size VkVideoSessionParametersKHR videoSessionParameters = VK_NULL_HANDLE; VkVideoEncodeQuantizationMapSessionParametersCreateInfoKHR vspQuantizationMapInfo = { .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUANTIZATION_MAP_SESSION_PARAMETERS_CREATE_INFO_KHR, .pNext = ... // pointer to additional video session parameters create infos .quantizationMapTexelSize = ... // one of the supported texel sizes reported by vkGetPhysicalDeviceVideoFormatPropertiesKHR }; VkVideoSessionParametersCreateInfoKHR videoSessionParametersCreateInfo = { .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR, .pNext = &vspQuantizationMapInfo, .flags = VK_VIDEO_SESSION_PARAMETERS_CREATE_QUANTIZATION_MAP_COMPATIBLE_BIT_KHR | ... ... }; vkCreateVideoSessionParametersKHR(device, &videoSessionParametersCreateInfo, NULL, &videoSessionParameters); // Create quantization map image and image view VkImage image = VK_NULL_HANDLE; VkImageView imageView = VK_NULL_HANDLE; VkImageCreateInfo imageCreateInfo = { ... }; // Include the corresponding image usage flag imageCreateInfo.usage |= VK_IMAGE_USAGE_VIDEO_ENCODE_{QUANTIZATION_DELTA|EMPHASIS}_MAP_BIT_KHR; vkCreateImage(device, &imageCreateInfo, NULL, &image); ... vkCreateImageView(device, &imageViewCreateInfo, NULL, &imageView); ``` -------------------------------- ### Pipeline Layout Creation Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/descriptorsets.adoc Example demonstrating the creation of a VkPipelineLayout object with descriptor set layouts and push constant ranges. ```APIDOC ## API Example [source,c++] ---- const VkDescriptorSetLayout layouts[] = { layout1, layout2 }; const VkPushConstantRange ranges[] = { { .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, .offset = 0, .size = 4 }, { .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, .offset = 4, .size = 4 }, }; const VkPipelineLayoutCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .pNext = NULL, .flags = 0, .setLayoutCount = 2, .pSetLayouts = layouts, .pushConstantRangeCount = 2, .pPushConstantRanges = ranges }; VkPipelineLayout myPipelineLayout; myResult = vkCreatePipelineLayout( myDevice, &createInfo, NULL, &myPipelineLayout); ---- ``` -------------------------------- ### Get NV Cooperative Matrix Properties Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/shaders.adoc Enumerates cooperative matrix properties. Call with pProperties as NULL to get the count, then with a populated array to get the properties. ```c #include void enumerate_cooperative_matrix_properties_nv(VkPhysicalDevice physicalDevice) { uint32_t propertyCount; // Get the number of properties available vkGetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, &propertyCount, NULL); // Allocate memory for the properties VkCooperativeMatrixPropertiesNV* properties = (VkCooperativeMatrixPropertiesNV*) malloc(propertyCount * sizeof(VkCooperativeMatrixPropertiesNV)); // Get the actual properties if (vkGetPhysicalDeviceCooperativeMatrixPropertiesNV(physicalDevice, &propertyCount, properties) == VK_SUCCESS) { // Process the properties } free(properties); } ``` -------------------------------- ### pipelineBinaryInternalCache usage example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_KHR_pipeline_binary.adoc Example of how pipelineBinaryInternalCache can be used. ```c++ VkGraphicsPipelineCreateInfo graphicsCreateInfo; VkPipelineCreateInfoKHR pipelineCreateInfo; ``` -------------------------------- ### Initialize and Begin Vulkan Render Pass (C) Source: https://github.com/khronosgroup/vulkan-docs/blob/main/appendices/VK_EXT_fragment_density_map.adoc Demonstrates the initialization of the VkRenderPassBeginInfo structure and the subsequent call to vkCmdBeginRenderPass2 to begin a render pass in Vulkan. This process is crucial for setting up rendering operations within a command buffer. ```c VkRenderPassBeginInfo renderPassBeginInfo = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // ... .renderPass = renderPass, .framebuffer = framebuffer, // ... }; // Can no longer modify the fdmImage's contents after this call vkCmdBeginRenderPass2(commandBuffer, &renderPassBeginInfo, pSubpassBeginInfo); ``` -------------------------------- ### GLSL Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_descriptor_heap.adoc Example of shader resource declarations. ```glsl layout(binding = 0) uniform sampler2D foo[8]; layout(binding = 2) uniform sampler2D bar; ``` -------------------------------- ### Ray Tracing Stack Size Calculation Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/chapters/raytracing.adoc Illustrates how an application can compute a more accurate ray tracing stack size by considering specific shader usage patterns, which can be smaller than the default. ```text code:rayGenStack {plus} max(code:closestHit1Stack, code:miss1Stack) {plus} max(code:closestHit2Stack, code:miss2Stack) ``` -------------------------------- ### Simple Resource Bindings Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_EXT_descriptor_heap.adoc This example demonstrates mapping descriptor set layout and pipeline layout creation to the new structure, illustrating a descriptor set layout with three resources, one using variable descriptor count flags. ```c const uint32_t UniformBufferArrayCount = 12; const uint32_t InlineBlockDescriptorSize = 256; VkDescriptorSetLayoutBinding bindings[4]; VkDescriptorBindingFlags bindingFlags[4]; // 12 uniform buffers available only to the vertex shader bindings[0].binding = 0; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; bindings[0].descriptorCount = UniformBufferArrayCount; bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; bindings[0].pImmutableSampler = NULL; bindingFlags[0] = 0; // A combined image sampler bindings[1].binding = 1; bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[1].descriptorCount = 1; bindings[1].stageFlags = VK_SHADER_STAGE_ALL; bindings[1].pImmutableSampler = NULL; bindingFlags[1] = 0; // An inline uniform block bindings[2].binding = 2; bindings[2].descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; bindings[2].descriptorCount = InlineBlockSize; bindings[2].stageFlags = VK_SHADER_STAGE_ALL; bindings[2].pImmutableSampler = NULL; bindingFlags[2] = 0; // A storage buffer array with variable descriptor count and all the descriptor flags bindings[3].binding = 3; bindings[3].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; bindings[3].descriptorCount = UINT32_MAX; bindings[3].stageFlags = VK_SHADER_STAGE_ALL; bindings[3].pImmutableSampler = NULL; bindingFlags[3] = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; VkDescriptorSetLayoutBindingFlagsCreateInfo dslFlagsInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, .pNext = NULL, .bindingCount = 4, .pBindings = bindingFlags}; ``` -------------------------------- ### Shader Code Example Source: https://github.com/khronosgroup/vulkan-docs/blob/main/proposals/VK_QCOM_shader_multiple_wait_queues.adoc Example of using multiple wait queues in a shader. ```glsl [[multiple_wait_queuesQCOM(2)]] for (step = 0; step < TOTAL_K; step += TILE_K) { uint subMatrixAStart = row * STRIDE_A + step; uint subMatrixBStart = col * STRIDE_B + step; coopMatLoad(matA, inputA.x, subMatrixAStart, STRIDE_A, gl_CooperativeMatrixLayoutRowMajor); // Global to CoopMat coopMatLoad(matB, inputB.x, subMatrixBStart, STRIDE_B, gl_CooperativeMatrixLayoutColumnMajor); // Global to CoopMat matC = coopMatMulAdd(matA, matB, matC); } ```