ошибка при создании 2d текстуры с динамическим форматом - PullRequest
0 голосов
/ 07 мая 2019

Я довольно новичок в DirectX. и я спотыкаюсь с ресурсом обработки.

Хорошо. Сначала я создал текстуру, которую я могу читать / писать в графическом процессоре, и она работала хорошо. И теперь, как вы можете проверить в моем коде, я хотел также прочитать эту текстуру в CPU (чтение со стороны приложения), поэтому я отредактировал использование от USAGE_DEFAULT до USAGE_DYNAMIC.

Microsoft::WRL::ComPtr<ID3D11Texture2D> outputTexture;

D3D11_TEXTURE2D_DESC outputTex_desc;
outputTex_desc.Format = DXGI_FORMAT_R32_FLOAT;
outputTex_desc.Width = 3;
outputTex_desc.Height = 3;
outputTex_desc.MipLevels = 1;
outputTex_desc.ArraySize = 1;
outputTex_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | 
                           D3D11_BIND_SHADER_RESOURCE;
outputTex_desc.SampleDesc.Count = msCount;
outputTex_desc.SampleDesc.Quality = msQuality;
outputTex_desc.Usage = D3D11_USAGE_DYNAMIC;
outputTex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
outputTex_desc.MiscFlags = 0;

// CREATE 'TEXTURE'
device->CreateTexture2D(      // FAIL HERE !!!
            &outputTex_desc,
            nullptr,
            outputTexture.GetAddressOf());
// CREATE 'SRV'
...
// CREATE 'UAV'
...

и он начинает терпеть неудачу именно тогда, когда он выполняет 'device-> CreateTexture2D ()'

любой совет был бы удивительным.

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Первые два шага в отладке любой программы Direct3D 11:

  1. Убедитесь, что вы проверяете каждый HRESULT на успех (макрос SUCCEEDED) или сбой (макрос FAILED). Если безопасно игнорировать возвращаемое значение во время выполнения, функция возвращает void. См. ThrowIfFailed .
  2. Включите устройство отладки Direct3D и найдите выходные данные отладки (например, используйте D3D11_CREATE_DEVICE_DEBUG в конфигурации отладки).

Если вы включите отладочное устройство Direct3D , вы получите подробную информацию о том, почему API во многих случаях возвращает коды ошибок.

Если вы это сделаете, вы увидите ошибку для этого кода:

D3D11 ERROR: ID3D11Device::CreateTexture2D: A D3D11_USAGE_DYNAMIC Resource
may only have the D3D11_CPU_ACCESS_WRITE CPUAccessFlags set.
[ STATE_CREATION ERROR #98: CREATETEXTURE2D_INVALIDCPUACCESSFLAGS]

Чтобы ЧИТАТЬ его на ЦП, сначала необходимо скопировать в D3D11_USAGE_STAGING Ресурс. Например, исходный код для этого см. В ScreenGrab коде из DirectX Tool Kit .

Вы не упоминаете, какие у вас значения msCount или msQuality. Я предположил 1 и 0 соответственно. Если вы используете любые другие значения, вы получите:

D3D11 ERROR: ID3D11Device::CreateTexture2D: Multisampling is not supported
with the D3D11_BIND_UNORDERED_ACCESS BindFlag.  SampleDesc.Count must be 1
and SampleDesc.Quality must be 0.
[ STATE_CREATION ERROR #99: CREATETEXTURE2D_INVALIDBINDFLAGS]
0 голосов
/ 15 мая 2019

Чтобы получить доступ к текстуре из процессора (режим чтения), вам нужно создать отдельную промежуточную текстуру, а затем скопировать в нее текстуру.

Это флаги для текстуры только для gpu (обратите внимание, я выставляю счетчик выборок равным 1, так как доступ к БПЛА не разрешен для текстур с несколькими выборками)

D3D11_TEXTURE2D_DESC gpuTexDesc;
gpuTexDesc.Format = DXGI_FORMAT_R32_FLOAT;
gpuTexDesc.Width = 3;
gpuTexDesc.Height = 3;
gpuTexDesc.MipLevels = 1;
gpuTexDesc.ArraySize = 1;
gpuTexDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | 
                       D3D11_BIND_SHADER_RESOURCE;
gpuTexDesc.SampleDesc.Count = 1;
gpuTexDesc.SampleDesc.Quality = 0;
gpuTexDesc.Usage = D3D11_USAGE_DEFAULT;
gpuTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_NONE;
gpuTexDesc.MiscFlags = 0;

Затем вы создаете вторую текстуру для чтения

D3D11_TEXTURE2D_DESC readTexDesc;
readTexDesc.Format = DXGI_FORMAT_R32_FLOAT;
readTexDesc.Width = 3;
readTexDesc.Height = 3;
readTexDesc.MipLevels = 1;
readTexDesc.ArraySize = 1;
readTexDesc.BindFlags = 0; //No bind flags allowed for staging
gpuTexDesc.SampleDesc.Count = 1;
gpuTexDesc.SampleDesc.Quality = 0;
gpuTexDesc.Usage = D3D11_USAGE_STAGING; //need staging flag for read
gpuTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
gpuTexDesc.MiscFlags = 0;

тогда вы можете использовать CopyResource :

deviceContext->CopyResource(readTex, gpuTex);

Как только вы закончите, вы можете наконец получить доступ к данным текстуры для чтения, используя Карта

D3D11_MAPPED_SUBRESOURCE MappedResource;
deviceContext->Map(readTex, 0, D3D11_MAP_READ, 0, &MappedResource);

MappedResource предоставит вам доступ к данным в процессоре, как только вы закончите обработку, не забудьте Unmap ресурс.

deviceContext->Unmap(readTex, 0);
...