统一缓冲区的Vulkan内存对齐

问题描述

我正在关注在线教程:vulkan-tutorial,作者在其中添加了描述符池和描述符集的功能

我正在使用Vulkan v1.2.135.0,并且我的着色器设置为#version 450

我几乎已经完成了本教程的这一部分,并且能够渲染旋转的正方形,并且在Debug模式下进行编译和运行时,Vulkan Layers没有任何错误

我接近上面链接提供的页面底部,他在glm::vec2结构中引入了UniformBufferOjbect,在{{1}中相同的对应结构中引入了vec2 }}。

他改变了这些:

shader.vert

到以下内容

// Defined in C++ file
struct UniformBufferObject {
    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 proj;
};

// Defined in shader.vert
layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;

我按照示例进行操作,并使用提供的工具重新编译了着色器,以将其转换为// Defined in C++ file struct UniformBufferObject { glm::vec2 foo; glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; // Defined in shader.vert layout(binding = 0) uniform UniformBufferObject { vec2 foo; mat4 model; mat4 view; mat4 proj; } ubo; 二进制文件。正如他所建议的那样,屏幕上没有呈现任何内容,这与Vulkan要求的SPV有关……

他通过说明如何解决此问题来简要说明了内存对齐问题。他建议做两件事...首先是使​​用C ++ 11或更高版本的memory-alignment修饰符。

他随后指出,如果我们要将alignas(16)更改为以下内容

UniformBufferObject

然后再次编译并运行该程序,使其可以正确呈现,但是,我仍然遇到黑屏。

他还建议在包含我执行过的头文件之前,先使用// Defined in C++ file struct UniformBufferObject { glm::vec2 foo; alignas(16) glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; 的{​​{1}}伪指令。它仍然没有在屏幕上呈现任何内容...

我什至将glm修改为:

#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES

但是,仍然没有任何渲染。我不知道为什么这不能按照本教程的建议进行。

解决方法

根据个人经验,UBO结构应与vec4保持一致。您的结构的第一个字段破坏了这种对齐方式。

最快(最快)修复可以

struct UniformBufferObject {
    glm::vec4 foo;
    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 proj;
};

在着色器中,只需使用ubo.foo.xy毛刷即可获得vec2。

当然,着色器代码也应修改为

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

vec2的对齐方式必须为8

  • 浮点数为4
  • vec2的对齐方式为8
  • vec3,vec4,mat4的对齐方式为16

您必须这样纠正:

return $dtF->diff($dtT)->format('%y years,%m months,%d days');

UBO使用std140规则,您可以检查此规则以了解如何处理它:)