opengl - uint64_t 类型数组的 UBO 填充
问题描述
我有以下情况。UBO 结构,在一个数组中保存 4 个 uint64_t。
struct MaterialData{
uint64_t comps[4];
};
layout (std140, binding = 0) uniform MaterialBlock {
MaterialData data[50];
}material;
问题是,只有 index = 0 才能给我正确的数据。但是如果我更改为 uint64_t 的 GLSL 内置类型向量,一切正常:
struct MaterialData{
u64vec4 textures;
};
它肯定与 std140 的填充规则有关。这是OpenGL 4.5 规范所说的:
如果成员是标量或向量数组,则根据规则 (1)、(2) 和 (3) 设置基本对齐方式和数组跨度以匹配单个数组元素的基本对齐方式,并向上舍入为vec4 的基本对齐方式。数组末尾可能有填充;数组后面的成员的基本偏移量向上舍入到基本对齐的下一个倍数。
所以我从这部分理解
基本对齐和数组步幅设置为匹配单个数组元素的基本对齐
每个数组的成员对齐是成员的大小,即 8 个字节。虽然这并不完全清楚。实际上它不起作用。我可以与 u64vec4 相处,但我想知道如何填充数组uint64_t?
解决方案
你错过了关键短语:
并四舍五入到 vec4 的基本对齐
这意味着 64 位整数数组的步幅与 vec4 的对齐方式相同:16。因此,数组中的 64 位整数有 8 个字节的有用数据,然后是 8 个字节的填充,然后是下一个元素。
因此,在 C++ 中,等效数组必须类似于:
struct 64_bit_array_element
{
std::uint64_t value;
std::uint8_t padding[8];
};
struct UBO
{
64_bit_array_element comps[4];
};
当然,这是非常浪费的。处理此问题的更好方法是使用 s 数组u64vec2
。
或者您可以只使用 SSBO 和std430
布局,规范中的违规行不适用。
推荐阅读
- jquery - 特定年龄的最小和最大日期的 jQuery 验证
- excel - 在表格中工作时的 Excel VBA 性能问题 (listobject)
- swift - 如何减少从 NSLocale.Key.currencyCode 返回的货币代码数量
- excel - 在动态表上使用 VBA 的 Excel-IE 自动化
- c++ - 在 vector.push_back(foo{}) 三次调用构造函数时创建的静态结构对象
- java - 在 TouchImageView 中获取图像的点击位置,并按比例调整图像的大小以缩放?
- python - XGBoost 收敛于高深度和儿童体重
- arrays - 在数组中搜索数据 [Node.JS]
- hl7-fhir - 使用 HL7-FHIR 标准的提供者信息
- prestashop - 在 Prestashop 1.6 中付款后我应该使用哪个钩子来获取有关购物车的信息