Using Vulkan Push Constants to Update Small Uniform Data Efficiently
Learn how to declare, create, and use Vulkan push constants for fast updates of small uniform data, with validation steps and fallback guidance.
30 Apr 2026, 12:42 UTC

Desired outcome
Update a small block of uniform data (e.g., a color factor or a transformation scalar) from the CPU each frame without the overhead of descriptor set updates, by using Vulkan push constants.
Prerequisites
- A Vulkan instance and a physical device that supports Vulkan 1.0 or later.
- A logical device with a graphics queue created.
- The Vulkan validation layers enabled (for debugging).
- Basic knowledge of pipeline layout creation and command buffer recording.
Focused procedure
Query the implementation limit
Call
vkGetPhysicalDevicePropertiesto obtainVkPhysicalDevicePropertiesand readmaxPushConstantsSize. Ensure your intended push constant size is ≤ this value (commonly 128 bytes).VkPhysicalDeviceProperties props; vkGetPhysicalDeviceProperties(physicalDevice, &props); uint32_t maxPushSize = props.limits.maxPushConstantsSize; // Example: assert(myPushConstantSize <= maxPushSize);Define the push constant range
Create a
VkPushConstantRangespecifying the shader stages that will read the data, the byte offset (must be 0 for a single block), and the size (must be a multiple of 4).VkPushConstantRange pushRange = {}; pushRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; pushRange.offset = 0; pushRange.size = sizeof(MyPushConstantBlock); // e.g., 16 bytesCreate the pipeline layout
Include the push constant range in
VkPipelineLayoutCreateInfowhen creating the layout.VkPipelineLayoutCreateInfo layoutInfo = {}; layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layoutInfo.setLayoutCount = 0; // no descriptor sets for this example layoutInfo.pSetLayouts = nullptr; layoutInfo.pushConstantRangeCount = 1; layoutInfo.pPushConstantRanges = &pushRange; VkPipelineLayout pipelineLayout; vkCreatePipelineLayout(device, &layoutInfo, nullptr, &pipelineLayout);Declare the push constant block in the shader
In GLSL, use the
layout(push_constant)qualifier. The block must match the size and ordering declared on the CPU side.layout(push_constant) uniform PushConstants { vec4 colorFactor; // 16 bytes } pc; void main() { vec4 baseColor = vec4(1.0, 0.0, 0.0, 1.0); fragColor = baseColor * pc.colorFactor; }Record the command buffer
Before the draw or dispatch that consumes the constants, call
vkCmdPushConstantswith the same layout, stage flags, offset, size, and a pointer to the data.// Assuming myData is a MyPushConstantBlock filled by the CPU vkCmdPushConstants( commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(MyPushConstantBlock), &myData ); // Now issue the draw/dispatch vkCmdDraw(commandBuffer, vertexCount, 1, 0, 0);Expected checks and validation
- Run the application with validation layers enabled. No
VK_VALIDATION_ERRORmessages related to push constants should appear. - Verify the shader output: for example, render a quad where the push constant drives a color factor and confirm the rendered color changes as the CPU updates the data.
- Optionally, query
maxPushConstantsSizeat runtime and assert that your declared size ≤ that value.
- Run the application with validation layers enabled. No
Recovery options
If validation reports that the push constant range exceeds the device limit or that the size/offset is misaligned:
- Reduce the size of the push constant block to fit within
maxPushConstantsSize. - Ensure the size is a multiple of 4 bytes and the offset is 0 (or a multiple of 4).
- If more data is needed, fall back to updating a descriptor set containing a uniform buffer; this avoids the per‑call push constant overhead but incurs descriptor set binding cost.
Limitations
- The maximum push constant size is implementation‑dependent; many hardware vendors expose 128 bytes, but some may offer less.
- Each call to
vkCmdPushConstantsincurs a CPU‑to‑GPU transfer cost; batching multiple draws that share the same constant minimizes this overhead. - Misaligned offsets or sizes that are not multiples of 4 bytes can lead to validation errors or undefined behavior on certain GPUs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.