Skip to content

BufferHelpers

Chuck Walbourn edited this page Oct 29, 2023 · 6 revisions
DirectXTK

Helpers functions for creating Direct3D resources from CPU data.

Header

#include <BufferHelpers.h>

Creating vertex/index buffers

The CreateStaticBuffer helper is used to create Direct3D buffer type resources such as vertex buffers or index buffers.

HRESULT CreateStaticBuffer(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    const void* ptr, size_t count, size_t stride,
    D3D12_RESOURCE_STATES afterState,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

template<typename T>
HRESULT CreateStaticBuffer(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    T const* data, size_t count,
    D3D12_RESOURCE_STATES afterState,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

template<typename T>
HRESULT CreateStaticBuffer(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    T const& data,
    D3D12_RESOURCE_STATES afterState,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

These all make use of the ResourceUploadBatch to handle the transfer of the data to video memory via an upload heap.

Examples

ResourceUploadBatch resourceUpload(device);

resourceUpload.Begin();

static const VertexPositionColor s_vertexData[3] =
{
    { XMFLOAT3{ 0.0f,   0.5f,  0.5f }, XMFLOAT4{ 1.0f, 0.0f, 0.0f, 1.0f } },  // Top / Red
    { XMFLOAT3{ 0.5f,  -0.5f,  0.5f }, XMFLOAT4{ 0.0f, 1.0f, 0.0f, 1.0f } },  // Right / Green
    { XMFLOAT3{ -0.5f, -0.5f,  0.5f }, XMFLOAT4{ 0.0f, 0.0f, 1.0f, 1.0f } }   // Left / Blue
};

ComPtr<ID3D12Resource> vb;
DX::ThrowIfFailed(
  CreateStaticBuffer(device, resourceUpload,
    s_vertexData,                // const void *ptr
    std:size(s_vertexData),      // size_t count
    sizeof(VertexPositionColor), // size_t stride
    D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, &vb)
  );

auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
uploadResourcesFinished.wait();  

When creating from an array using VertexTypes, a template simplifies this to:

ComPtr<ID3D12Resource> vb;
DX::ThrowIfFailed(
  CreateStaticBuffer(device, resourceUpload,
     s_vertexData, std::size(s_vertexData),
    D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, &vb)
  );

Finally, you can create from C++ containers like std::vector:

std::vector<uint16_t> indices;

...

ComPtr<ID3D12Resource> ib;
DX::ThrowIfFailed(
  CreateStaticBuffer(device, resourceUpload, indices, D3D12_RESOURCE_STATE_INDEX_BUFFER, &ib)
  );

See Model for creating vertex buffers/index buffers from disk files.

Creating upload resources

For many common upload scenarios, the ResourceUploadBatch is a useful abstraction for managing an upload heap and resource copies. For direct creation of a resource in a upload heap, you can make use of CreateUploadBuffer.

HRESULT CreateUploadBuffer(ID3D12Device* device,
    const void* ptr,
    size_t count,
    size_t stride,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

template<typename T>
HRESULT CreateUploadBuffer(ID3D12Device* device,
    T const* data,
    size_t count,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

template<typename T>
HRESULT CreateUploadBuffer(ID3D12Device* device,
    T const& data,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

Creating textures

The CreateTextureFromMemory helpers can be used to create Direct3D 1D, 2D, or 3D texture resources. For the 2D version, you can enable auto-generation of mipmaps.

HRESULT CreateTextureFromMemory(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    size_t width,
    DXGI_FORMAT format,
    const D3D12_SUBRESOURCE_DATA& initData,
    ID3D12Resource** texture,
    D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

HRESULT CreateTextureFromMemory(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    size_t width, size_t height,
    DXGI_FORMAT format,
    const D3D12_SUBRESOURCE_DATA& initData,
    ID3D12Resource** texture,
    bool generateMips = false,
    D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

HRESULT CreateTextureFromMemory(ID3D12Device* device,
    ResourceUploadBatch& resourceUpload,
    size_t width, size_t height, size_t depth,
    DXGI_FORMAT format,
    const D3D12_SUBRESOURCE_DATA& initData,
    ID3D12Resource** texture,
    D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
    D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE);

Examples

To create a 'default' texture (i.e. a 1x1 white pixel):

ResourceUploadBatch resourceUpload(device);

resourceUpload.Begin();

const uint32_t s_pixel = 0xffffffff;

D3D12_SUBRESOURCE_DATA initData = { &s_pixel, sizeof(uint32_t), 0 };

ComPtr<ID3D12Resource> defaultTex;
DX::ThrowIfFailed(
    CreateTextureFromMemory(device, resourceUpload,
        1u, 1u, DXGI_FORMAT_R8G8B8A8_UNORM, initData,
        &defaultTex)
    );

auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
uploadResourcesFinished.wait();

CreateShaderResourceView(device, defaultTex.Get(), /*cpuDescriptor*/ );

See DDSTextureLoader and WICTextureLoader for creating textures from disk files.

Creating unordered access views (UAV)

When creating a texture or loading it from disk, you can specify the D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS resource flag to enable usage as a UAV. For creating an uninitialized UAV buffer resource, you can make use of CreateUAVBuffer.

HRESULT CreateUAVBuffer(ID3D12Device* device,
    uint64_t bufferSize,
    ID3D12Resource** pBuffer,
    D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON,
    D3D12_RESOURCE_FLAGS additionalResFlags = D3D12_RESOURCE_FLAG_NONE);

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally