Почему я не могу получить bool, упакованную и выровненную в постоянный буфер D3D?

Хорошо, мне тяжело достать 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 и заполнить структуру разными способами без везения. Каков правильный способ сделать это?

9 голосов | спросил KlashnikovKid 19 Jam1000000amThu, 19 Jan 2012 01:22:55 +040012 2012, 01:22:55

3 ответа


9

Для эффективности константные буферы будут отображаться таким образом, чтобы значения не ограничивали GPU регистры . Каждый регистр состоит из четырех поплавков размером (16 байт), поэтому постоянные структуры буфера должны быть кратными ему на графическом процессоре. Ваша структура C ++ должна быть дополнена соответствующим образом, если вы хотите использовать ее в качестве удобства для отображения данных (это, обратите внимание, не всегда хорошо масштабируется).

Таким образом, ваша проблема заключается в том, что логическое значение HLSL имеет четыре байта, но один байт на стороне процессора (в вашей конкретной реализации). Это приведет к тому, что структура C ++ не будет правильно выровнена: значимый бит логического значения (значение 0 или 1) будет храниться в младшем значении байта значения, а так как размеры не согласуются с местоположением этого байта в памяти будет отличаться в версиях структуры CPU и GPU.

Вручную вставлять соответствующее заполнение и обеспечивать правильное выравнивание по 16 байт или просто использовать подходящий размер, например целое число, должно устранить проблему. Этот поток также может пригодиться вам поскольку он содержит более подробное обсуждение примерно той же проблемы.

ответил Josh 19 Jam1000000amThu, 19 Jan 2012 02:27:57 +040012 2012, 02:27:57
3

Хорошо, сделал некоторое чтение и заметил, что hlsl bool по существу является 32-битным целым числом. Поэтому я просто использовал int в структуре c ++ для решения моей проблемы.

struct GeometryBufferPass_MaterialBuffer {
    XMFLOAT3 diffuse;
    float specularExponent;
    XMFLOAT3 specular;
    int isTextured;
};
ответил KlashnikovKid 19 Jam1000000amThu, 19 Jan 2012 02:04:07 +040012 2012, 02:04:07
0

float, bool и int не нужны строки для endian, особенно для нескольких элементов.

Переключение на int или float работает в некоторых примерах, перечисленных здесь, в порядке их выравнивания между элементами XMFLOAT3, поэтому ссылки указаны правильно. Однако, если вам нужно объявить массив или несколько элементов в структуре для int, float (нет типов XM), то вы, скорее всего, обнаружите, что значения графического процессора не соответствуют значениям в наборе в структуре ЦП.

Я, конечно, делал это при добавлении массива типа int, который будет использоваться для типа освещения.

Самый простой способ - придерживаться XM-типов, которые выравниваются на 16, что может потребовать потраченных впустую элементов /байтов, но сортирует для вас endian. E.G XMINT4 и просто использовал первый элемент .x для вашего значения, или если у вас есть необходимость, используйте другие элементы для другой цели, но это означает плохое присвоение имен (обязательно прокомментируйте). Примечание: массив XMINT2 также будет не в логическом порядке

ответил DavrosX 12 J000000Tuesday16 2016, 15:45:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132