D3D11 CreateTexture2D 的 D3D12 等价物是什么?

What is the D3D12 equivalent of D3D11 CreateTexture2D?

我是 direct3d 编程的新手,我一直在构建一个简单的 windows 应用程序来使用 d3d12 依次显示 4 个图像。 我对 D3D12 体系结构有基本的了解,到目前为止,我已经创建了四个命令分配器(backb 缓冲区大小 = 4)、一个命令列表、一个命令队列、描述符堆和一个栅栏。我还使用 WIC 从文件中加载了我的图像。 我知道我必须以某种方式将图像纹理数据作为资源。虽然那部分还不清楚,但我想澄清一下如何从 d3d12 中加载的图像制作纹理。

Direct3D 12 纹理上传的基础知识在 DirectX-Graphics-Samples GitHub 重现的 D3D12HelloTexture 示例中进行了演示。

ComPtr<ID3D12Resource> textureUploadHeap;

// Create the texture.
{
    // Describe and create a Texture2D.
    D3D12_RESOURCE_DESC textureDesc = {};
    textureDesc.MipLevels = 1;
    textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    textureDesc.Width = TextureWidth;
    textureDesc.Height = TextureHeight;
    textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    textureDesc.DepthOrArraySize = 1;
    textureDesc.SampleDesc.Count = 1;
    textureDesc.SampleDesc.Quality = 0;
    textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

    ThrowIfFailed(m_device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
        D3D12_HEAP_FLAG_NONE,
        &textureDesc,
        D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr,
        IID_PPV_ARGS(&m_texture)));

    const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_texture.Get(), 0, 1);

    // Create the GPU upload buffer.
    ThrowIfFailed(m_device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
        D3D12_HEAP_FLAG_NONE,
        &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
        D3D12_RESOURCE_STATE_GENERIC_READ,
        nullptr,
        IID_PPV_ARGS(&textureUploadHeap)));

    // Copy data to the intermediate upload heap and then schedule a copy 
    // from the upload heap to the Texture2D.
    std::vector<UINT8> texture = GenerateTextureData();

    D3D12_SUBRESOURCE_DATA textureData = {};
    textureData.pData = &texture[0];
    textureData.RowPitch = TextureWidth * TexturePixelSize;
    textureData.SlicePitch = textureData.RowPitch * TextureHeight;

    UpdateSubresources(m_commandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, 1, &textureData);
    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));

    // Describe and create a SRV for the texture.
    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.Format = textureDesc.Format;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MipLevels = 1;
    m_device->CreateShaderResourceView(m_texture.Get(), &srvDesc, m_srvHeap->GetCPUDescriptorHandleForHeapStart());
}

它使用 UpdateSubresources 辅助函数 D3DX12.h C++ 内联实用头文件。

As an example of the complications of using Direct3D 12 instead of Direct3D 11, this code only works correctly if you are loading a texture for a pixel shader. If you use the texture for a vertex shader or a geometry shader, then it might crash. Or it might work. Or it might work sometimes and not others. This is also only one way to load textures in Direct3D 12, and not even the particularly most efficient.

更新: DirectX Tool Kit for DirectX12 is now available. Take a look at DDSTextureLoader and WICTextureLoader.