(我见过类似的问题,但答案对我没有帮助,这就是我问的原因)
我将推送常量数据用于我的顶点和曲面细分评估着色器。
我声明用于存储矩阵的结构:
struct push_constant_data {
// vertex shader
alignas(16) glm::mat4 model_matrix;
// tessellation evaluation shader
alignas(16) glm::mat4 view_matrix;
alignas(16) glm::mat4 projection_matrix;
};
顶点着色器:
layout(push_constant) uniform push_data {
mat4 model_matrix;
} push;
曲面细分评估着色器:
layout(push_constant) uniform push_data {
layout(offset = 64)
mat4 view_matrix;
mat4 projection_matrix;
} push;
这就是我创建范围的方式:
vk::PushConstantRange vertex_range{};
vertex_range.offset = 0;
vertex_range.size = sizeof(glm::mat4);
vertex_range.stageFlags = vk::ShaderStageFlagBits::eVertex;
vk::PushConstantRange TES_range{};
TES_range.offset = sizeof(glm::mat4);
TES_range.size = 2 * sizeof(glm::mat4);
TES_range.stageFlags = vk::ShaderStageFlagBits::eTessellationEvaluation;
填充结构:
push_constant_data push{
{glm::mat4(1.0f)}, //model
{glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f))}, //view
{glm::perspective(glm::radians(45.0f), swapchain_extent.width / (float)swapchain_extent.height, 0.1f, 10.0f)} //projection
};
绑定推送常量:
commandBuffer.pushConstants(pipeline_layout_, vk::ShaderStageFlagBits::eVertex, 0, sizeof(glm::mat4), &push);
commandBuffer.pushConstants(pipeline_layout_, vk::ShaderStageFlagBits::eTessellationEvaluation, sizeof(glm::mat4), 2 * sizeof(glm::mat4), &push);
结果,我什么也没看到。当我使用
commandBuffer.pushConstants(
pipeline_layout_,
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eTessellationEvaluation,
0,
sizeof(push),
&push
);
我得到了我所需要的,当然还有验证层消息:
vkCmdPushConstants(): VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VkPipelineLayout 中的 VkPushConstantRange 0x9fde6b0000000014[] 重叠偏移 = 0 且大小 = 192,不包含 VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT。 Vulkan 规范规定:对于 offset 指定范围内的每个字节 和大小,对于 stageFlags 中的每个着色器阶段,必须有一个推送 布局中的恒定范围,包括该字节和该阶段 (https://vulkan.lunarg.com/doc/view/1.3.275.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdPushConstants-offset-01795)
问题解决了!
vkCmdPushConstants
' 参数 offset
和 size
仅适用于 GPU 端。
commandBuffer.pushConstants(pipeline_layout_, vk::ShaderStageFlagBits::eVertex, 0, sizeof(glm::mat4), &push.model_matrix);
std::array<glm::mat4, 2> matrices{ push.view_matrix, push.projection_matrix };
commandBuffer.pushConstants(pipeline_layout_, vk::ShaderStageFlagBits::eTessellationEvaluation, sizeof(glm::mat4), 2 * sizeof(glm::mat4), matrices.data());
注意
offset
不适用于 push
变量,请使用 指针算术 代替:push + sizeof(glm::mat4)
(作为 pValue
的 vkCmdPushConstants
)