繁体   English   中英

用于统一缓冲区的 Vulkan Memory Alignment

[英]Vulkan Memory Alignment for Uniform Buffers

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

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

我几乎完成了教程的这一部分,我能够渲染一个旋转的正方形,当我在调试模式下编译和运行时,我没有从 Vulkan 层中得到任何错误。

我在上面链接提供的页面底部附近,他在 UniformBufferOjbect 结构中引入了glm::vec2 vec2 UniformBufferOjbect的同一相应结构中引入了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;

我按照示例并使用提供的工具重新编译着色器以将其转换为SPV二进制文件。 正如他所暗示的那样,屏幕上没有渲染任何内容,因为这与 Vulkan 所需的memory-alignment有关......

他通过说明如何解决此问题简要解释了 memory alignment 问题。 他建议做两件事……第一件事是使用 C++11 或更高版本的alignas(16)修饰符。

然后他指出,如果我们UniformBufferObject更改为以下内容:

// Defined in C++ file
struct UniformBufferObject {
    glm::vec2 foo;
    alignas(16) glm::mat4 model;
    glm::mat4 view;
    glm::mat4 proj;
};

然后再次编译并运行程序,它应该可以正确呈现,但是,我仍然出现黑屏。

他还建议在包含我所做的 header 文件之前使用glm#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES指令。 它仍然没有在屏幕上渲染任何东西......

我什至将UniformBufferObject修改为:

// Defined in C++ file
struct UniformBufferObject {
    glm::vec2 foo;
    alignas(16) glm::mat4 model;
    alignas(16) glm::mat4 view;
    alignas(16) glm::mat4 proj;
};

仍然没有渲染。 我不知道为什么这不能按照教程的建议工作。

根据个人经验,UBO 结构应该与 vec4 对齐。 您的结构的第一个字段打破了这个 alignment。

快速(est)修复可以是

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

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

当然,shader代码也应该修改为

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

vec2 的对齐必须为 8

  • 浮动 4 对齐
  • vec2 对齐 8
  • 一个 vec3, vec4, mat4 一个 16 的对齐

你必须这样纠正:

struct UniformBufferObject {
    alignas(8) glm::vec2 foo;
    alignas(16) glm::mat4 model;
    alignas(16) glm::mat4 view;
    alignas(16) glm::mat4 proj;
};

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM