Skip to content

Commit

Permalink
Add CreateUploadBuffer and CreateUAVBuffer helpers (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
walbourn authored Oct 28, 2023
1 parent e2675ae commit 9b236c6
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Inc/BufferHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#endif

#include <cstddef>
#include <cstdint>


namespace DirectX
Expand Down Expand Up @@ -61,6 +62,42 @@ namespace DirectX
afterState, pBuffer, resFlags);
}

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

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

template<typename T>
HRESULT CreateUploadBuffer(_In_ ID3D12Device* device,
_In_reads_(count) T const* data,
size_t count,
_COM_Outptr_ ID3D12Resource** pBuffer,
D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ,
D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE) noexcept
{
return CreateUploadBuffer(device, data, count, sizeof(T), pBuffer, initialState, resFlags);
}

template<typename T>
HRESULT CreateUploadBuffer(_In_ ID3D12Device* device,
T const& data,
_COM_Outptr_ ID3D12Resource** pBuffer,
D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ,
D3D12_RESOURCE_FLAGS resFlags = D3D12_RESOURCE_FLAG_NONE) noexcept
{
return CreateUploadBuffer(device, data.data(), data.size(), sizeof(typename T::value_type),
pBuffer, initialState, resFlags);
}

// Helpers for creating texture from memory arrays.
HRESULT __cdecl CreateTextureFromMemory(_In_ ID3D12Device* device,
ResourceUploadBatch& resourceUpload,
Expand Down
107 changes: 107 additions & 0 deletions Src/BufferHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,113 @@ HRESULT DirectX::CreateStaticBuffer(
}


//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::CreateUAVBuffer(
ID3D12Device* device,
uint64_t bufferSize,
ID3D12Resource** pBuffer,
D3D12_RESOURCE_STATES initialState,
D3D12_RESOURCE_FLAGS additionalResFlags) noexcept
{
if (!pBuffer)
return E_INVALIDARG;

*pBuffer = nullptr;

if (!device || !bufferSize)
return E_INVALIDARG;

static constexpr uint64_t c_maxBytes = D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u;

if (bufferSize > c_maxBytes)
{
DebugTrace("ERROR: Resource size too large for DirectX 12 (size %llu)\n", bufferSize);
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}

auto const desc = CD3DX12_RESOURCE_DESC::Buffer(bufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS | additionalResFlags);

const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_DEFAULT);

ComPtr<ID3D12Resource> res;
HRESULT hr = device->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&desc,
initialState,
nullptr,
IID_GRAPHICS_PPV_ARGS(res.GetAddressOf()));
if (FAILED(hr))
return hr;

*pBuffer = res.Detach();

return S_OK;
}


//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::CreateUploadBuffer(
ID3D12Device* device,
const void* ptr,
size_t count,
size_t stride,
ID3D12Resource** pBuffer,
D3D12_RESOURCE_STATES initialState,
D3D12_RESOURCE_FLAGS resFlags) noexcept
{
if (!pBuffer)
return E_INVALIDARG;

*pBuffer = nullptr;

if (!device || !count || !stride)
return E_INVALIDARG;

const uint64_t sizeInbytes = uint64_t(count) * uint64_t(stride);

static constexpr uint64_t c_maxBytes = D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u;

if (sizeInbytes > c_maxBytes)
{
DebugTrace("ERROR: Resource size too large for DirectX 12 (size %llu)\n", sizeInbytes);
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}

auto const desc = CD3DX12_RESOURCE_DESC::Buffer(sizeInbytes, resFlags);

const CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_UPLOAD);

ComPtr<ID3D12Resource> res;
HRESULT hr = device->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&desc,
initialState,
nullptr,
IID_GRAPHICS_PPV_ARGS(res.GetAddressOf()));
if (FAILED(hr))
return hr;

if (ptr)
{
void* mappedPtr = nullptr;
hr = res->Map(0, nullptr, &mappedPtr);
if (FAILED(hr))
return hr;

memcpy(mappedPtr, ptr, static_cast<const size_t>(sizeInbytes));
res->Unmap(0, nullptr);
}

*pBuffer = res.Detach();

return S_OK;
}


//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::CreateTextureFromMemory(
Expand Down

0 comments on commit 9b236c6

Please sign in to comment.