Direct3D11: перелистывание ID3D11Texture2D

Я выполняю захват заднего буфера Direct3D. Когда я загружаю пиксели, кадр изображения переворачивается вдоль его вертикальной оси. Можно ли "сказать" D3D перевернуть кадр при копировании ресурса или при создании цели ID3D11Texture2D?

Вот как я это делаю:

Текстура, в которую я копирую буфер кадра, создается так:

    D3D11_TEXTURE2D_DESC description =
    {
        desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1,
        DXGI_FORMAT_R8G8B8A8_UNORM,
        { 1, 0 }, // DXGI_SAMPLE_DESC
        D3D11_USAGE_STAGING,//transder from GPU to CPU
        0, D3D11_CPU_ACCESS_READ, 0
    };
    D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 };
     device->CreateTexture2D(&description, &data, &pNewTexture);

Затем на каждом кадре я делаю:

     pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface));
     pContext->CopyResource(pNewTexture, pSurface);
     D3D11_MAPPED_SUBRESOURCE resource; 
     pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource);
     //reading from resource.pData
     //...

PS: у меня нет контроля над конвейером рендеринга. Я подключаю внешнее приложение с этим кодом. Кроме того, я не хочу связываться с пиксельным буфером на процессоре, как обратное копирование в цикле и т. Д. Низкая задержка копирования является высоким приоритетом.

ОБНОВИТЬ:

Я также попробовал это:

    D3D11_BOX box;
    box.left = 0;
    box.right = desc.BufferDesc.Width;
    box.top = desc.BufferDesc.Height;
    box.bottom = 0;
    box.front = 0;
    box.back = 1;
    pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box);

Что заставляет фрейм быть пустым от его содержания.

2 ответа

Создайте текстуру с D3D11_USAGE_DEAFULT, с CPUAccessFlags=0 и BindFlags=D3D11_BIND_SHADER_RESOURCE. CopyResource к нему буфер буфера обмена. Создайте еще одну текстуру с помощью D3D11_BIND_RENDER_TARGET. Установите его как цель рендеринга, установите пиксельный шейдер и нарисуйте перевернутый квад, используя первую текстуру. Теперь вы сможете скопировать вторую текстуру в промежуточную текстуру, которую вы используете сейчас. Это должно быть быстрее, чем копирование данных перевернутого изображения с использованием процессора. Однако это решение потребует больше ресурсов на графическом процессоре и может быть сложным в настройке.

Все подключенные к Direct3D ресурсы должны обрабатываться построчно, так что просто переверните копию:

auto ptr = reinterpret_cast<const uint8_t>(resource.pData)
           + (desc.BufferDesc.Height - 1) * resource.RowPitch;

for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y )
{
    // do something with the data in ptr
    // which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes
    // i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4
    ptr -= resource.RowPitch;
}

Для многих примеров работы с ресурсами Direct3D см. DirectXTex.

Другие вопросы по тегам