Warm tip: This article is reproduced from serverfault.com, please click

Vulkan Push Constants never assigned or updated

发布于 2020-12-06 07:26:07

I have been reading through Sascha Willem's example on push constants here and have attempted to implement them myself.

Oddly the VkPhysicalDeviceProperties.limits.maxPushConstantsSize is 1437341456 bytes which makes me think something else is very wrong. After rechecking it is showing as a more realistic value of 256 (I assume I did something incorrectly previously)

In my test project I have uniform buffers working, and I then started to tinker with push constants which will hopefully explain the inbetween state of my vertex shader

Here are some details of what I implemented: From what I understand, on creating a pipeline layout I need to specify the push constant ranges, which I do like so:

VkPushConstantRange pushConstantRange {};
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
pushConstantRange.offset = 0;
pushConstantRange.size = sizeof(ObjectPushConstantData);

And I add the push constant ranges to the pipeline layout CI like so:

pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;

When creating my command buffers, I'm calling vkCmdPushConstants before drawing like so:

vkCmdPushConstants(this->commandBuffers[i], this->pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, static_cast<uint32_t>(sizeof(ObjectPushConstantData)), &testObject);
vkCmdDrawIndexed(this->commandBuffers[i], static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
   

The type ObjectPushConstantData looks like so:

struct ObjectPushConstantData {
    glm::vec3 position;
    glm::vec3 rotation;
};

My vertex shader looks like this:

#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;

layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;

layout(push_constant) uniform PushConsts {
    vec3 position;
    vec3 rotation;
} pushConsts;

layout(location = 0) out vec3 fragColor;

void main() {
    gl_Position = ubo.proj * ubo.view * ubo.model * vec4(pushConsts.position, 1.0);
    fragColor = inColor;
}    

 
Questioner
Tom Martin
Viewed
0
Sascha Willems 2020-12-08 04:36:07

After taking a look at your shader, this does not seem to be a problem related to the push constants, but rather the lack of taking the actual vertex position into account.

In this line:

gl_Position = ubo.proj * ubo.view * ubo.model * vec4(pushConsts.position, 1.0);

You only multiply the push constant position, which is uniform for all shader invocations.

It seems you forgot to include the actual vertex position, to which you'd typically just add your uniform push constant position like this:

gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition + pushConsts.position, 1.0);