-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option for using custom heaps and support D3D_FEATURE_LEVEL_1_0_CORE #469
base: master
Are you sure you want to change the base?
Changes from 4 commits
6a75b3e
3589b4a
ce4065f
b7a510f
c963765
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,7 +73,7 @@ Device::Device( | |
|
||
THROW_IF_FAILED(m_d3dModule->CreateDevice( | ||
adapter, | ||
D3D_FEATURE_LEVEL_11_0, | ||
D3D_FEATURE_LEVEL_1_0_CORE, | ||
IID_PPV_ARGS(&m_d3d))); | ||
|
||
if (debugLayersEnabled) | ||
|
@@ -94,6 +94,7 @@ Device::Device( | |
IID_GRAPHICS_PPV_ARGS(m_fence.ReleaseAndGetAddressOf()))); | ||
|
||
D3D12_COMMAND_QUEUE_DESC queueDesc = {}; | ||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT; | ||
queueDesc.Type = commandListType; | ||
THROW_IF_FAILED(m_d3d->CreateCommandQueue( | ||
&queueDesc, | ||
|
@@ -163,6 +164,34 @@ ComPtr<ID3D12Resource> Device::CreateDefaultBuffer( | |
return resource; | ||
} | ||
|
||
ComPtr<ID3D12Resource> Device::CreateBuffer( | ||
uint64_t sizeInBytes, | ||
D3D12_CPU_PAGE_PROPERTY cpuPageProperty, | ||
D3D12_MEMORY_POOL memoryPoolPreference, | ||
D3D12_RESOURCE_FLAGS resourceFlags, | ||
uint64_t alignment, | ||
D3D12_HEAP_FLAGS heapFlags) | ||
{ | ||
if (cpuPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN && memoryPoolPreference == D3D12_MEMORY_POOL_UNKNOWN) | ||
{ | ||
return CreateDefaultBuffer(sizeInBytes, resourceFlags, alignment, heapFlags); | ||
} | ||
|
||
auto resourceDesc = CD3DX12_RESOURCE_DESC::Buffer(sizeInBytes, resourceFlags, alignment); | ||
auto heapProps = CD3DX12_HEAP_PROPERTIES(cpuPageProperty, memoryPoolPreference); | ||
|
||
ComPtr<ID3D12Resource> resource; | ||
THROW_IF_FAILED(m_d3d->CreateCommittedResource( | ||
&heapProps, | ||
heapFlags, | ||
&resourceDesc, | ||
D3D12_RESOURCE_STATE_COMMON, | ||
nullptr, | ||
IID_GRAPHICS_PPV_ARGS(resource.ReleaseAndGetAddressOf()))); | ||
|
||
return resource; | ||
} | ||
|
||
ComPtr<ID3D12Resource> Device::CreateUploadBuffer( | ||
uint64_t sizeInBytes, | ||
D3D12_RESOURCE_FLAGS resourceFlags, | ||
|
@@ -247,23 +276,30 @@ void Device::RecordDispatch(const char* name, uint32_t threadGroupX, uint32_t th | |
PIXEndEvent(m_commandList.Get()); | ||
} | ||
|
||
Microsoft::WRL::ComPtr<ID3D12Resource> Device::Upload(uint64_t totalSize, gsl::span<const std::byte> data, std::wstring_view name) | ||
Microsoft::WRL::ComPtr<ID3D12Resource> Device::CreateBuffer( | ||
uint64_t totalSize, | ||
gsl::span<const std::byte> data, | ||
std::wstring_view name, | ||
D3D12_CPU_PAGE_PROPERTY cpuPageProperty, | ||
D3D12_MEMORY_POOL memoryPoolPreference | ||
) | ||
{ | ||
if (data.size() > totalSize) | ||
{ | ||
throw std::invalid_argument("Attempting to upload more data than the size of the buffer"); | ||
} | ||
|
||
auto defaultBuffer = CreateDefaultBuffer(totalSize); | ||
auto buffer = CreateBuffer(totalSize, cpuPageProperty, memoryPoolPreference); | ||
|
||
if (!name.empty()) | ||
{ | ||
defaultBuffer->SetName(name.data()); | ||
buffer->SetName(name.data()); | ||
} | ||
|
||
if (data.empty()) | ||
{ | ||
// No need to create an upload resource if the source data is empty. | ||
return defaultBuffer; | ||
return buffer; | ||
} | ||
|
||
auto uploadBuffer = CreateUploadBuffer(totalSize); | ||
|
@@ -279,20 +315,20 @@ Microsoft::WRL::ComPtr<ID3D12Resource> Device::Upload(uint64_t totalSize, gsl::s | |
D3D12_RESOURCE_BARRIER barriers[] = | ||
{ | ||
CD3DX12_RESOURCE_BARRIER::Transition( | ||
defaultBuffer.Get(), | ||
buffer.Get(), | ||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, | ||
D3D12_RESOURCE_STATE_COPY_DEST) | ||
}; | ||
m_commandList->ResourceBarrier(_countof(barriers), barriers); | ||
} | ||
|
||
m_commandList->CopyResource(defaultBuffer.Get(), uploadBuffer.Get()); | ||
m_commandList->CopyResource(buffer.Get(), uploadBuffer.Get()); | ||
|
||
{ | ||
D3D12_RESOURCE_BARRIER barriers[] = | ||
{ | ||
CD3DX12_RESOURCE_BARRIER::Transition( | ||
defaultBuffer.Get(), | ||
buffer.Get(), | ||
D3D12_RESOURCE_STATE_COPY_DEST, | ||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS) | ||
}; | ||
|
@@ -301,32 +337,32 @@ Microsoft::WRL::ComPtr<ID3D12Resource> Device::Upload(uint64_t totalSize, gsl::s | |
|
||
m_temporaryResources.push_back(std::move(uploadBuffer)); | ||
|
||
return defaultBuffer; | ||
return buffer; | ||
} | ||
|
||
std::vector<std::byte> Device::Download(Microsoft::WRL::ComPtr<ID3D12Resource> defaultBuffer) | ||
std::vector<std::byte> Device::Download(Microsoft::WRL::ComPtr<ID3D12Resource> buffer) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like upload, you can avoid the readback heap and just copy straight out of the buffer here if it's L0 and CPU-visible (call GetHeapProperties). |
||
{ | ||
auto readbackBuffer = CreateReadbackBuffer(defaultBuffer->GetDesc().Width); | ||
auto readbackBuffer = CreateReadbackBuffer(buffer->GetDesc().Width); | ||
readbackBuffer->SetName(L"Device::Download"); | ||
|
||
{ | ||
D3D12_RESOURCE_BARRIER barriers[] = | ||
{ | ||
CD3DX12_RESOURCE_BARRIER::Transition( | ||
defaultBuffer.Get(), | ||
buffer.Get(), | ||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, | ||
D3D12_RESOURCE_STATE_COPY_SOURCE) | ||
}; | ||
m_commandList->ResourceBarrier(_countof(barriers), barriers); | ||
} | ||
|
||
m_commandList->CopyResource(readbackBuffer.Get(), defaultBuffer.Get()); | ||
m_commandList->CopyResource(readbackBuffer.Get(), buffer.Get()); | ||
|
||
{ | ||
D3D12_RESOURCE_BARRIER barriers[] = | ||
{ | ||
CD3DX12_RESOURCE_BARRIER::Transition( | ||
defaultBuffer.Get(), | ||
buffer.Get(), | ||
D3D12_RESOURCE_STATE_COPY_SOURCE, | ||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS) | ||
}; | ||
|
@@ -335,9 +371,9 @@ std::vector<std::byte> Device::Download(Microsoft::WRL::ComPtr<ID3D12Resource> d | |
|
||
ExecuteCommandListAndWait(); | ||
|
||
std::vector<std::byte> outputBuffer(defaultBuffer->GetDesc().Width); | ||
std::vector<std::byte> outputBuffer(buffer->GetDesc().Width); | ||
{ | ||
size_t dataSize = defaultBuffer->GetDesc().Width; | ||
size_t dataSize = buffer->GetDesc().Width; | ||
CD3DX12_RANGE readRange(0, gsl::narrow<size_t>(dataSize)); | ||
void* readbackBufferData = nullptr; | ||
THROW_IF_FAILED(readbackBuffer->Map(0, &readRange, &readbackBufferData)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,14 @@ class Device | |
uint64_t alignment = 0, | ||
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE); | ||
|
||
Microsoft::WRL::ComPtr<ID3D12Resource> CreateBuffer( | ||
uint64_t sizeInBytes, | ||
D3D12_CPU_PAGE_PROPERTY cpuPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, | ||
D3D12_MEMORY_POOL memoryPoolPreference = D3D12_MEMORY_POOL_L0, | ||
D3D12_RESOURCE_FLAGS resourceFlags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, | ||
uint64_t alignment = 0, | ||
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE); | ||
|
||
Comment on lines
+47
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! Can you also delete the TODO on line 39? :) |
||
Microsoft::WRL::ComPtr<ID3D12Resource> CreateUploadBuffer( | ||
uint64_t sizeInBytes, | ||
D3D12_RESOURCE_FLAGS resourceFlags = D3D12_RESOURCE_FLAG_NONE, | ||
|
@@ -88,7 +96,12 @@ class Device | |
m_temporaryResources.emplace_back(std::move(object)); | ||
} | ||
|
||
Microsoft::WRL::ComPtr<ID3D12Resource> Upload(uint64_t totalSize, gsl::span<const std::byte> data, std::wstring_view name = {}); | ||
Microsoft::WRL::ComPtr<ID3D12Resource> CreateBuffer( | ||
uint64_t totalSize, | ||
gsl::span<const std::byte> data, | ||
std::wstring_view name, | ||
D3D12_CPU_PAGE_PROPERTY cpuPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE, | ||
D3D12_MEMORY_POOL memoryPoolPreference = D3D12_MEMORY_POOL_L0); | ||
Comment on lines
+103
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would default these to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch - thanks. This was an artifact of a previous approach. |
||
|
||
std::vector<std::byte> Download(Microsoft::WRL::ComPtr<ID3D12Resource>); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the heap is L0 and CPU-writable, there's no need to create the extra upload heap.