Хорошо, мне трудно собрать bool и выровнять его в константный буфер hlsl, и я не знаю почему.
Вот буфер в hlsl
cbuffer MaterialBuffer : register(b1) {
float3 materialDiffuseAlbedo;
float materialSpecularExponent;
float3 materialSpecularAlbedo;
bool isTextured;
};
И вот это в C ++
struct GeometryBufferPass_MaterialBuffer {
XMFLOAT3 diffuse;
float specularExponent;
XMFLOAT3 specular;
bool isTextured;
};
Я безуспешно пытался переместить bool и дополнить структуру различными способами. Как правильно это сделать?
directx
hlsl
data-structure
KlashnikovKid
источник
источник
Ответы:
Для эффективности постоянные буферы будут отображаться так, чтобы значения не перекрывали регистры GPU . Каждый регистр имеет четыре числа с плавающей запятой (16 байтов), поэтому структуры постоянного буфера должны быть кратны их на GPU. Ваша структура C ++ должна быть дополнена соответствующим образом, если вы хотите использовать ее для удобства отображения данных (обратите внимание, это не всегда хорошо масштабируется).
Ваша проблема в том, что логическое значение HLSL составляет четыре байта, но один байт на стороне процессора (в вашей конкретной реализации). Это приводит к тому, что ваша структура C ++ не выравнивается должным образом: значащий бит логического значения (0 или 1, который имеет значение) будет храниться в байте значения с наименьшей значимостью, и поскольку размеры не соответствуют местоположению этого байта в памяти будет отличаться в версиях CPU и GPU структуры.
Ручная вставка соответствующего отступа и обеспечение правильного 16-байтового выравнивания, или просто использование типа соответствующего размера, такого как целое число, должны решить проблему. Эта ветка также может быть вам полезна, так как содержит более глубокое обсуждение примерно той же проблемы.
источник
isTextured
вписывается в тот же регистр, так как он должен был бы попасть в следующий. Таким образом, он целиком врезался в следующий регистр». Второй регистр состоит изspecular
первых трех компонентов иisTextured
в последнем, так что я не вижу, чтобы что-то попадало в следующий регистр? Очевидно, имеет значение 1-байтовая или 4-байтовая длина bool, но любой из них будет вписыватьсяspecular
в тот же регистр.Хорошо, немного прочел и заметил, что hlsl bool - это 32-битное целое число. Поэтому я просто использовал int в структуре c ++ для решения моей проблемы.
источник
float, bool и int не обязательны для endian, особенно для нескольких элементов.
Переключение на int или float работает в некоторых из перечисленных здесь примеров, поскольку оно выровнено между элементами XMFLOAT3, поэтому на них ссылаются правильно. Однако, если вам нужно объявить массив или несколько элементов в структуре для int, float (без типов XM), вы, скорее всего, обнаружите, что значения GPU не соответствуют значениям, заданным в структуре CPU.
Я, конечно, сделал при добавлении массива типа int, который будет использоваться для освещения типа.
Самый простой способ, который я нашел, - это придерживаться типов XM, которые выровнены по 16, что может потребовать потерянных элементов / байтов, но сортирует для вас порядок байтов. Например, XMINT4 и просто использовал первый элемент .x для вашего значения, или, если у вас есть необходимость, тогда используйте другие элементы для другой цели, но означает плохое именование (обязательно комментируйте). Примечание: массив XMINT2 также будет не в логическом порядке
источник