2013-11-13 6 views
3

Я полагаю, что это своего рода крест между чистым вопросом на C++ и вопросом OpenGL. У меня есть единый буфер, и я выделяю в нем пробелы в байтах sizeof (ShaderData). Я использую макет std140 на стороне графического процессора в шейдере.Выравнивание структур с 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 байта.

+1

ОК, правильно, я видел это минуту назад. Но в общем случае (а не в моем конкретном случае), что лучше всего подходит для заполнения? Всегда ли * оптимизированный порядок, который не требует этого? Кажется маловероятным. – Robinson

+0

AFAIK нет стандартизованного способа определения дополнения в общем виде, который не так, как вы делаете (фиктивные элементы структуры). Существуют некоторые директивы '# pragma', связанные с выравниванием, но я не уверен, насколько они стандартизированы. http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html – Jack

+0

Я думаю, вы должны пойти что-то вроде '#pragma pack (push, 16)', чтобы установить выравнивание, а затем '#pragma pack (pop) 'восстановить его после. – Jack

 Смежные вопросы

  • Нет связанных вопросов^_^