VK_EXT_shader_object(3)

# VK_EXT_shader_object(3) Manual Page

## Name

VK_EXT_shader_object - device extension

Loading… please wait.

## Registered Extension Number

483

## Revision

1

## Ratification Status

Ratified

## Extension and Version Dependencies

VK_KHR_get_physical_device_properties2
or
Version 1.1
and
VK_KHR_dynamic_rendering
or
Version 1.3

## API Interactions

- Interacts with VK_VERSION_1_1

- Interacts with VK_VERSION_1_3

- Interacts with VK_EXT_blend_operation_advanced

- Interacts with VK_EXT_conservative_rasterization

- Interacts with VK_EXT_depth_clip_control

- Interacts with VK_EXT_depth_clip_enable

- Interacts with VK_EXT_fragment_density_map

- Interacts with VK_EXT_line_rasterization

- Interacts with VK_EXT_mesh_shader

- Interacts with VK_EXT_provoking_vertex

- Interacts with VK_EXT_sample_locations

- Interacts with VK_EXT_subgroup_size_control

- Interacts with VK_EXT_transform_feedback

- Interacts with VK_KHR_device_group

- Interacts with VK_KHR_fragment_shading_rate

- Interacts with VK_NV_clip_space_w_scaling

- Interacts with VK_NV_coverage_reduction_mode

- Interacts with VK_NV_fragment_coverage_to_color

- Interacts with VK_NV_framebuffer_mixed_samples

- Interacts with VK_NV_mesh_shader

- Interacts with VK_NV_representative_fragment_test

- Interacts with VK_NV_shading_rate_image

- Interacts with VK_NV_viewport_swizzle

## Contact

- Daniel Story daniel-story

## Extension Proposal

VK_EXT_shader_object

## Other Extension Metadata

Last Modified Date

  2023-03-30

Interactions and External Dependencies

  - Interacts with `VK_EXT_extended_dynamic_state`

  - Interacts with `VK_EXT_extended_dynamic_state2`

  - Interacts with `VK_EXT_extended_dynamic_state3`

  - Interacts with `VK_EXT_vertex_input_dynamic_state`

IP Status

  No known IP claims.

Contributors

  - Piers Daniell, NVIDIA

  - Sandy Jamieson, Nintendo

  - Žiga Markuš, LunarG

  - Tobias Hector, AMD

  - Alex Walters, Imagination

  - Shahbaz Youssefi, Google

  - Ralph Potter, Samsung

  - Jan-Harald Fredriksen, ARM

  - Connor Abott, Valve

  - Arseny Kapoulkine, Roblox

  - Patrick Doane, Activision

  - Jeff Leger, Qualcomm

  - Stu Smith, AMD

  - Chris Glover, Google

  - Ricardo Garcia, Igalia

  - Faith Ekstrand, Collabora

  - Timur Kristóf, Valve

  - Constantine Shablya, Collabora

  - Daniel Koch, NVIDIA

  - Alyssa Rosenzweig, Collabora

  - Mike Blumenkrantz, Valve

  - Samuel Pitoiset, Valve

  - Qun Lin, AMD

  - Spencer Fricke, LunarG

  - Soroush Faghihi Kashani, Imagination

## Description

This extension introduces a new VkShaderEXT object type which represents a single compiled shader stage. Shader objects provide a more flexible alternative to VkPipeline objects, which may be helpful in certain use cases.

## New Object Types

- VkShaderEXT

## New Commands

- vkCmdBindShadersEXT

- vkCmdBindVertexBuffers2EXT

- vkCmdSetAlphaToCoverageEnableEXT

- vkCmdSetAlphaToOneEnableEXT

- vkCmdSetColorBlendEnableEXT

- vkCmdSetColorBlendEquationEXT

- vkCmdSetColorWriteMaskEXT

- vkCmdSetCullModeEXT

- vkCmdSetDepthBiasEnableEXT

- vkCmdSetDepthBoundsTestEnableEXT

- vkCmdSetDepthClampEnableEXT

- vkCmdSetDepthCompareOpEXT

- vkCmdSetDepthTestEnableEXT

- vkCmdSetDepthWriteEnableEXT

- vkCmdSetFrontFaceEXT

- vkCmdSetLogicOpEXT

- vkCmdSetLogicOpEnableEXT

- vkCmdSetPatchControlPointsEXT

- vkCmdSetPolygonModeEXT

- vkCmdSetPrimitiveRestartEnableEXT

- vkCmdSetPrimitiveTopologyEXT

- vkCmdSetRasterizationSamplesEXT

- vkCmdSetRasterizerDiscardEnableEXT

- vkCmdSetSampleMaskEXT

- vkCmdSetScissorWithCountEXT

- vkCmdSetStencilOpEXT

- vkCmdSetStencilTestEnableEXT

- vkCmdSetTessellationDomainOriginEXT

- vkCmdSetVertexInputEXT

- vkCmdSetViewportWithCountEXT

- vkCreateShadersEXT

- vkDestroyShaderEXT

- vkGetShaderBinaryDataEXT

If VK_EXT_blend_operation_advanced is supported:

- vkCmdSetColorBlendAdvancedEXT

If VK_EXT_conservative_rasterization is supported:

- vkCmdSetConservativeRasterizationModeEXT

- vkCmdSetExtraPrimitiveOverestimationSizeEXT

If VK_EXT_depth_clip_control is supported:

- vkCmdSetDepthClipNegativeOneToOneEXT

If VK_EXT_depth_clip_enable is supported:

- vkCmdSetDepthClipEnableEXT

If VK_EXT_line_rasterization is supported:

- vkCmdSetLineRasterizationModeEXT

- vkCmdSetLineStippleEnableEXT

If VK_EXT_provoking_vertex is supported:

- vkCmdSetProvokingVertexModeEXT

If VK_EXT_sample_locations is supported:

- vkCmdSetSampleLocationsEnableEXT

If VK_EXT_transform_feedback is supported:

- vkCmdSetRasterizationStreamEXT

If VK_NV_clip_space_w_scaling is supported:

- vkCmdSetViewportWScalingEnableNV

If VK_NV_coverage_reduction_mode is supported:

- vkCmdSetCoverageReductionModeNV

If VK_NV_fragment_coverage_to_color is supported:

- vkCmdSetCoverageToColorEnableNV

- vkCmdSetCoverageToColorLocationNV

If VK_NV_framebuffer_mixed_samples is supported:

- vkCmdSetCoverageModulationModeNV

- vkCmdSetCoverageModulationTableEnableNV

- vkCmdSetCoverageModulationTableNV

If VK_NV_representative_fragment_test is supported:

- vkCmdSetRepresentativeFragmentTestEnableNV

If VK_NV_shading_rate_image is supported:

- vkCmdSetShadingRateImageEnableNV

If VK_NV_viewport_swizzle is supported:

- vkCmdSetViewportSwizzleNV

## New Structures

- VkColorBlendAdvancedEXT

- VkColorBlendEquationEXT

- VkShaderCreateInfoEXT

- VkVertexInputAttributeDescription2EXT

- VkVertexInputBindingDescription2EXT

- Extending VkPhysicalDeviceFeatures2, VkDeviceCreateInfo:

  - VkPhysicalDeviceShaderObjectFeaturesEXT

- Extending VkPhysicalDeviceProperties2:

  - VkPhysicalDeviceShaderObjectPropertiesEXT

- Extending VkPipelineShaderStageCreateInfo, VkShaderCreateInfoEXT:

  - VkShaderRequiredSubgroupSizeCreateInfoEXT

## New Enums

- VkShaderCodeTypeEXT

- VkShaderCreateFlagBitsEXT

## New Bitmasks

- VkShaderCreateFlagsEXT

## New Enum Constants

- `VK_EXT_SHADER_OBJECT_EXTENSION_NAME`

- `VK_EXT_SHADER_OBJECT_SPEC_VERSION`

- Extending VkObjectType:

  - `VK_OBJECT_TYPE_SHADER_EXT`

- Extending VkResult:

  - `VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT`

- Extending VkStructureType:

  - `VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT`

  - `VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT`

  - `VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT`

  - `VK_STRUCTURE_TYPE_SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT`

  - `VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT`

  - `VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT`

If VK_EXT_fragment_density_map is supported:

- Extending VkShaderCreateFlagBitsEXT:

  - `VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT`

If VK_EXT_mesh_shader or VK_NV_mesh_shader is supported:

- Extending VkShaderCreateFlagBitsEXT:

  - `VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT`

If VK_EXT_subgroup_size_control or Version 1.3 is supported:

- Extending VkShaderCreateFlagBitsEXT:

  - `VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT`

  - `VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT`

If VK_KHR_device_group or Version 1.1 is supported:

- Extending VkShaderCreateFlagBitsEXT:

  - `VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT`

If VK_KHR_fragment_shading_rate is supported:

- Extending VkShaderCreateFlagBitsEXT:

  - `VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT`

## Examples

Example 1

Create linked pair of vertex and fragment shaders.

    // Logical device created with the shaderObject feature enabled
    VkDevice device;

    // SPIR-V shader code for a vertex shader, along with its size in bytes
    void* pVertexSpirv;
    size_t vertexSpirvSize;

    // SPIR-V shader code for a fragment shader, along with its size in bytes
    void* pFragmentSpirv;
    size_t fragmentSpirvSize;

    // Descriptor set layout compatible with the shaders
    VkDescriptorSetLayout descriptorSetLayout;

    VkShaderCreateInfoEXT shaderCreateInfos[2] =
    {
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,
            .stage = VK_SHADER_STAGE_VERTEX_BIT,
            .nextStage = VK_SHADER_STAGE_FRAGMENT_BIT,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = vertexSpirvSize,
            .pCode = pVertexSpirv,
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        },
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,
            .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
            .nextStage = 0,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = fragmentSpirvSize,
            .pCode = pFragmentSpirv,
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        }
    };

    VkResult result;
    VkShaderEXT shaders[2];

    result = vkCreateShadersEXT(device, 2, &shaderCreateInfos, NULL, shaders);
    if (result != VK_SUCCESS)
    {
        // Handle error
    }

Later, during command buffer recording, bind the linked shaders and draw.

    // Command buffer in the recording state
    VkCommandBuffer commandBuffer;

    // Vertex and fragment shader objects created above
    VkShaderEXT shaders[2];

    // Assume vertex buffers, descriptor sets, etc. have been bound, and existing
    // state setting commands have been called to set all required state

    const VkShaderStageFlagBits stages[2] =
    {
        VK_SHADER_STAGE_VERTEX_BIT,
        VK_SHADER_STAGE_FRAGMENT_BIT
    };

    // Bind linked shaders
    vkCmdBindShadersEXT(commandBuffer, 2, stages, shaders);

    // Equivalent to the previous line. Linked shaders can be bound one at a time,
    // in any order:
    // vkCmdBindShadersEXT(commandBuffer, 1, &stages[1], &shaders[1]);
    // vkCmdBindShadersEXT(commandBuffer, 1, &stages[0], &shaders[0]);

    // The above is sufficient to draw if the device was created with the
    // tessellationShader and geometryShader features disabled. Otherwise, since
    // those stages should not execute, vkCmdBindShadersEXT() must be called at
    // least once with each of their stages in pStages before drawing:

    const VkShaderStageFlagBits unusedStages[3] =
    {
        VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
        VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
        VK_SHADER_STAGE_GEOMETRY_BIT
    };

    // NULL pShaders is equivalent to an array of stageCount VK_NULL_HANDLE values,
    // meaning no shaders are bound to those stages, and that any previously bound
    // shaders are unbound
    vkCmdBindShadersEXT(commandBuffer, 3, unusedStages, NULL);

    // Graphics shader objects may only be used to draw inside dynamic render pass
    // instances begun with vkCmdBeginRendering(), assume one has already been begun

    // Draw a triangle
    vkCmdDraw(commandBuffer, 3, 1, 0, 0);

Example 2

Create unlinked vertex, geometry, and fragment shaders.

    // Logical device created with the shaderObject feature enabled
    VkDevice device;

    // SPIR-V shader code for vertex shaders, along with their sizes in bytes
    void* pVertexSpirv[2];
    size_t vertexSpirvSize[2];

    // SPIR-V shader code for a geometry shader, along with its size in bytes
    void pGeometrySpirv;
    size_t geometrySpirvSize;

    // SPIR-V shader code for fragment shaders, along with their sizes in bytes
    void* pFragmentSpirv[2];
    size_t fragmentSpirvSize[2];

    // Descriptor set layout compatible with the shaders
    VkDescriptorSetLayout descriptorSetLayout;

    VkShaderCreateInfoEXT shaderCreateInfos[5] =
    {
        // Stage order does not matter
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = 0,
            .stage = VK_SHADER_STAGE_GEOMETRY_BIT,
            .nextStage = VK_SHADER_STAGE_FRAGMENT_BIT,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = pGeometrySpirv,
            .pCode = geometrySpirvSize,
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        },
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = 0,
            .stage = VK_SHADER_STAGE_VERTEX_BIT,
            .nextStage = VK_SHADER_STAGE_GEOMETRY_BIT,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = vertexSpirvSize[0],
            .pCode = pVertexSpirv[0],
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        },
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = 0,
            .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
            .nextStage = 0,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = fragmentSpirvSize[0],
            .pCode = pFragmentSpirv[0],
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        },
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = 0,
            .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
            .nextStage = 0,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = fragmentSpirvSize[1],
            .pCode = pFragmentSpirv[1],
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        },
        {
            .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
            .pNext = NULL,
            .flags = 0,
            .stage = VK_SHADER_STAGE_VERTEX_BIT,
            // Suppose we want this vertex shader to be able to be followed by
            // either a geometry shader or fragment shader:
            .nextStage = VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
            .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
            .codeSize = vertexSpirvSize[1],
            .pCode = pVertexSpirv[1],
            .pName = "main",
            .setLayoutCount = 1,
            .pSetLayouts = &descriptorSetLayout;
            .pushConstantRangeCount = 0,
            .pPushConstantRanges = NULL,
            .pSpecializationInfo = NULL
        }
    };

    VkResult result;
    VkShaderEXT shaders[5];

    result = vkCreateShadersEXT(device, 5, &shaderCreateInfos, NULL, shaders);
    if (result != VK_SUCCESS)
    {
        // Handle error
    }

Later, during command buffer recording, bind the linked shaders in different combinations and draw.

    // Command buffer in the recording state
    VkCommandBuffer commandBuffer;

    // Vertex, geometry, and fragment shader objects created above
    VkShaderEXT shaders[5];

    // Assume vertex buffers, descriptor sets, etc. have been bound, and existing
    // state setting commands have been called to set all required state

    const VkShaderStageFlagBits stages[3] =
    {
        // Any order is allowed
        VK_SHADER_STAGE_FRAGMENT_BIT,
        VK_SHADER_STAGE_VERTEX_BIT,
        VK_SHADER_STAGE_GEOMETRY_BIT,
    };

    VkShaderEXT bindShaders[3] =
    {
        shaders[2], // FS
        shaders[1], // VS
        shaders[0]  // GS
    };

    // Bind unlinked shaders
    vkCmdBindShadersEXT(commandBuffer, 3, stages, bindShaders);

    // Assume the tessellationShader feature is disabled, so vkCmdBindShadersEXT()
    // need not have been called with either tessellation stage

    // Graphics shader objects may only be used to draw inside dynamic render pass
    // instances begun with vkCmdBeginRendering(), assume one has already been begun

    // Draw a triangle
    vkCmdDraw(commandBuffer, 3, 1, 0, 0);

    // Bind a different unlinked fragment shader
    const VkShaderStageFlagBits fragmentStage = VK_SHADER_STAGE_FRAGMENT_BIT;
    vkCmdBindShadersEXT(commandBuffer, 1, &fragmentStage, &shaders[3]);

    // Draw another triangle
    vkCmdDraw(commandBuffer, 3, 1, 0, 0);

    // Bind a different unlinked vertex shader
    const VkShaderStageFlagBits vertexStage = VK_SHADER_STAGE_VERTEX_BIT;
    vkCmdBindShadersEXT(commandBuffer, 1, &vertexStage, &shaders[4]);

    // Draw another triangle
    vkCmdDraw(commandBuffer, 3, 1, 0, 0);

## Version History

- Revision 1, 2023-03-30 (Daniel Story)

  - Initial draft

## See Also

VkColorBlendAdvancedEXT, VkColorBlendEquationEXT, VkPhysicalDeviceShaderObjectFeaturesEXT, VkPhysicalDeviceShaderObjectPropertiesEXT, VkShaderCodeTypeEXT, VkShaderCreateFlagBitsEXT, VkShaderCreateFlagsEXT, VkShaderCreateInfoEXT, VkShaderEXT, VkShaderRequiredSubgroupSizeCreateInfoEXT, VkVertexInputAttributeDescription2EXT, VkVertexInputBindingDescription2EXT, vkCmdBindShadersEXT, vkCmdBindVertexBuffers2EXT, vkCmdSetAlphaToCoverageEnableEXT, vkCmdSetAlphaToOneEnableEXT, vkCmdSetColorBlendEnableEXT, vkCmdSetColorBlendEquationEXT, vkCmdSetColorWriteMaskEXT, vkCmdSetCullModeEXT, vkCmdSetDepthBiasEnableEXT, vkCmdSetDepthBoundsTestEnableEXT, vkCmdSetDepthClampEnableEXT, vkCmdSetDepthCompareOpEXT, vkCmdSetDepthTestEnableEXT, vkCmdSetDepthWriteEnableEXT, vkCmdSetFrontFaceEXT, vkCmdSetLogicOpEXT, vkCmdSetLogicOpEnableEXT, vkCmdSetPatchControlPointsEXT, vkCmdSetPolygonModeEXT, vkCmdSetPrimitiveRestartEnableEXT, vkCmdSetPrimitiveTopologyEXT, vkCmdSetRasterizationSamplesEXT, vkCmdSetRasterizerDiscardEnableEXT, vkCmdSetSampleMaskEXT, vkCmdSetScissorWithCountEXT, vkCmdSetStencilOpEXT, vkCmdSetStencilTestEnableEXT, vkCmdSetTessellationDomainOriginEXT, vkCmdSetVertexInputEXT, vkCmdSetViewportWithCountEXT, vkCreateShadersEXT, vkDestroyShaderEXT, vkGetShaderBinaryDataEXT

## Document Notes

For more information, see the Vulkan Specification

This page is a generated document. Fixes and changes should be made to the generator scripts, not directly.

## Copyright

Copyright 2014-2024 The Khronos Group Inc.

SPDX-License-Identifier: CC-BY-4.0