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
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 Commands
If VK_EXT_blend_operation_advanced is supported:
If VK_EXT_conservative_rasterization is supported:
If VK_EXT_depth_clip_control is supported:
If VK_EXT_depth_clip_enable is supported:
If VK_EXT_line_rasterization is supported:
If VK_EXT_provoking_vertex is supported:
If VK_EXT_sample_locations is supported:
If VK_EXT_transform_feedback is supported:
If VK_NV_clip_space_w_scaling is supported:
If VK_NV_coverage_reduction_mode is supported:
If VK_NV_fragment_coverage_to_color is supported:
If VK_NV_framebuffer_mixed_samples is supported:
If VK_NV_representative_fragment_test is supported:
If VK_NV_shading_rate_image is supported:
If VK_NV_viewport_swizzle is supported:
New Structures
-
Extending VkPhysicalDeviceFeatures2, VkDeviceCreateInfo:
-
Extending VkPhysicalDeviceProperties2:
-
Extending VkPipelineShaderStageCreateInfo, VkShaderCreateInfoEXT:
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
-
VK_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);
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.