3

I'm new to direct3d programming and I have been building a simple windows application to display 4 images one after other with d3d12. I know a basic understanding of the D3D12 architecture and so far I've created four command allocator (backb buffer size = 4) , a command list, a command queue, descriptor heap, and a fence. I also have loaded my images from file using WIC. I know somehow I have to make image texture data as a resource. While that part is still not clear, I'd like to clarify how I can make texture out of a loaded image in d3d12.

ngub05
  • 566
  • 1
  • 8
  • 15
  • If you are new to Direct3D, then stick with Direct3D 11. See [this thread](http://stackoverflow.com/questions/29719853/directx-c-3d-engine-programming-learn-now-or-wait-for-directx-12/29779660#29779660). – Chuck Walbourn Feb 23 '16 at 06:01
  • I'm going to build product where d3d12 is a requirement, that's why I'm sticking with it. – ngub05 Feb 23 '16 at 06:04
  • Direct3D 12 is an unforgiving API designed for experts. If you are already an expert in Direct3D 11, then you are ready to go. If not, stick with Direct3D 11. – Chuck Walbourn Feb 23 '16 at 06:07

1 Answers1

7

The basics of Direct3D 12 texture upload is demonstrated in the D3D12HelloTexture sample on the DirectX-Graphics-Samples GitHub repro.

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());
}

It uses the UpdateSubresources helper function the D3DX12.h C++ inline only utility header.

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.

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

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • If I'm not wrong I looked up GenerateTextureData() and found that the function not creating texture data from a bitmap. The code is quite helpful for me in understanding how a texture data can be used as a resource. But on the same time I wonder how can I create texture from a loaded bitmap? – ngub05 Feb 23 '16 at 09:34
  • You can look at [WICTextureLoader](https://github.com/Microsoft/DirectXTex/blob/master/WICTextureLoader/WICTextureLoader.cpp) for code on loading bitmap data using WIC. – Chuck Walbourn Feb 25 '16 at 06:53