Выравнивание структур по стандарту std140 со стороны процессора

Я полагаю, что это своего рода нечто среднее между вопросом о чистом языке C ++ и вопросом OpenGL. У меня есть единый буфер, и я выделяю в нем пространство размером байтов (ShaderData). Я использую макет std140 на стороне графического процессора в шейдере.

Согласно правилам std140, мне нужно добавить отступы в разных местах в моей структуре, чтобы убедиться, что такие вещи, как векторы, выровнены правильно. Структура ниже является примером (для моего света):

struct ShaderData {

float Light_Intensity;
float _pad1[3];    // align following vec3 on 4N boundary
Math::Vec3f Light_Position;
float _pad2;       // align following vec4 on 4N boundary
Math::Colour4f Light_Ambient;
Math::Colour4f Light_Diffuse;
Math::Colour4f Light_Specular;
float Light_AttenuationMin;
float Light_AttenuationMax;

} MyShaderData;

Это люди обычно делают в C ++, или есть специальные ключевые слова или прагмы для выравнивания отдельных элементов структуры ЦП, которые немного более аккуратны?

4

Решение

Нет, таким образом, вы просто тратите пространство. Вы должны найти оптимизированный макет в соответствии с правилами std140.

  • float нужно 4 байта и выровнено 4 байта
  • vec3 нужно 12 байтов и выровнено 16 байтов
  • vec4 нужно 16 байтов и выровнено 16 байтов

Это означает, что вы можете найти лучший макет для вашей структуры:

float Light_Intensity;          X
float _pad1[3];                  XXX
Math::Vec3f Light_Position;         XXX
float _pad2;                           X

Как вы можете видеть, вы тратите 4 байта, и что еще хуже, вы можете сделать что-то вроде:

Math::Vec3f Light_Position      XXX
float Light_Intensity;             X

Чтобы выровнять его и без необходимости тратить байт. Это работает, потому что vec3 будет выровнен по 16 байтовым границам, в то время как float будет по-прежнему выровнен по 4 байтовым границам.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]