Skip to content
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

Fixed resource allocation and memory binding for device wrapper #75

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Include/Extensions/NRIWrapperD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "NRIDeviceCreation.h"

NRI_FORWARD_STRUCT(ID3D12Heap);
NRI_FORWARD_STRUCT(D3D12_HEAP_DESC);
NRI_FORWARD_STRUCT(ID3D12Device);
NRI_FORWARD_STRUCT(ID3D12Resource);
NRI_FORWARD_STRUCT(ID3D12CommandQueue);
Expand Down Expand Up @@ -49,6 +50,7 @@ NRI_STRUCT(TextureD3D12Desc)
NRI_STRUCT(MemoryD3D12Desc)
{
ID3D12Heap* d3d12Heap;
const D3D12_HEAP_DESC* d3d12HeapDesc;
};

NRI_STRUCT(AccelerationStructureD3D12Desc)
Expand Down
4 changes: 4 additions & 0 deletions Source/D3D11/BufferD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ BufferD3D11::~BufferD3D11() {
}

Result BufferD3D11::Create(const MemoryD3D11& memory) {
// Buffer was already created externally
if (m_Buffer)
return Result::SUCCESS;

MemoryLocation memoryLocation = memory.GetType();

D3D11_BUFFER_DESC desc = {};
Expand Down
4 changes: 4 additions & 0 deletions Source/D3D11/TextureD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
using namespace nri;

Result TextureD3D11::Create(const MemoryD3D11* memory) {
// Texture was already created externally
if (m_Texture)
return Result::SUCCESS;

const DxgiFormat& dxgiFormat = GetDxgiFormat(m_Desc.format);

uint32_t bindFlags = 0;
Expand Down
9 changes: 7 additions & 2 deletions Source/D3D12/BufferD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Result BufferD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset, bool
MaybeUnused(isAccelerationStructureBuffer);
const D3D12_HEAP_DESC& heapDesc = memory->GetHeapDesc();

// Buffer was already created externally
if (m_Buffer)
return Result::SUCCESS;

#ifdef NRI_USE_AGILITY_SDK
if (m_Device.GetVersion() >= 10) {
D3D12_RESOURCE_DESC1 desc1 = {};
Expand All @@ -47,7 +51,8 @@ Result BufferD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset, bool
DXGI_FORMAT* castableFormats = nullptr; // TODO: add castable formats, see options12.RelaxedFormatCastingSupported

if (memory->RequiresDedicatedAllocation()) {
HRESULT hr = m_Device->CreateCommittedResource3(&heapDesc.Properties, D3D12_HEAP_FLAG_CREATE_NOT_ZEROED, &desc1, D3D12_BARRIER_LAYOUT_UNDEFINED, nullptr, nullptr,
HRESULT hr = m_Device->CreateCommittedResource3(
&heapDesc.Properties, heapDesc.Flags, &desc1, D3D12_BARRIER_LAYOUT_UNDEFINED, nullptr, nullptr,
castableFormatNum, castableFormats, IID_PPV_ARGS(&m_Buffer));
RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D12Device10::CreateCommittedResource3()");
} else {
Expand All @@ -70,7 +75,7 @@ Result BufferD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset, bool
initialState |= D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE;

if (memory->RequiresDedicatedAllocation()) {
HRESULT hr = m_Device->CreateCommittedResource(&heapDesc.Properties, D3D12_HEAP_FLAG_CREATE_NOT_ZEROED, &desc, initialState, nullptr, IID_PPV_ARGS(&m_Buffer));
HRESULT hr = m_Device->CreateCommittedResource(&heapDesc.Properties, heapDesc.Flags, &desc, initialState, nullptr, IID_PPV_ARGS(&m_Buffer));
RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D12Device::CreateCommittedResource()");
} else {
HRESULT hr = m_Device->CreatePlacedResource(*memory, offset, &desc, initialState, nullptr, IID_PPV_ARGS(&m_Buffer));
Expand Down
2 changes: 1 addition & 1 deletion Source/D3D12/MemoryD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Result MemoryD3D12::Create(const MemoryType memoryType, uint64_t size) {

Result MemoryD3D12::Create(const MemoryD3D12Desc& memoryDesc) {
m_Heap = memoryDesc.d3d12Heap;
m_HeapDesc = m_Heap->GetDesc();
m_HeapDesc = m_Heap ? m_Heap->GetDesc() : *memoryDesc.d3d12HeapDesc;

return Result::SUCCESS;
}
2 changes: 1 addition & 1 deletion Source/D3D12/SharedD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ void nri::ConvertRects(D3D12_RECT* rectsD3D12, const Rect* rects, uint32_t rectN
}

uint64_t nri::GetMemorySizeD3D12(const MemoryD3D12Desc& memoryD3D12Desc) {
return memoryD3D12Desc.d3d12Heap->GetDesc().SizeInBytes;
return memoryD3D12Desc.d3d12Heap ? memoryD3D12Desc.d3d12Heap->GetDesc().SizeInBytes : memoryD3D12Desc.d3d12HeapDesc->SizeInBytes;
}

bool nri::GetTextureDesc(const TextureD3D12Desc& textureD3D12Desc, TextureDesc& textureDesc) {
Expand Down
8 changes: 6 additions & 2 deletions Source/D3D12/TextureD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Result TextureD3D12::Create(const TextureD3D12Desc& textureDesc) {
}

Result TextureD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset) {
// Texture was already created externally
if (m_Texture)
return Result::SUCCESS;

const D3D12_HEAP_DESC& heapDesc = memory->GetHeapDesc();
D3D12_CLEAR_VALUE clearValue = {GetDxgiFormat(m_Desc.format).typed};

Expand All @@ -52,7 +56,7 @@ Result TextureD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset) {
DXGI_FORMAT* castableFormats = nullptr; // TODO: add castable formats, see options12.RelaxedFormatCastingSupported

if (memory->RequiresDedicatedAllocation()) {
HRESULT hr = m_Device->CreateCommittedResource3(&heapDesc.Properties, D3D12_HEAP_FLAG_CREATE_NOT_ZEROED, &desc1, initialLayout,
HRESULT hr = m_Device->CreateCommittedResource3(&heapDesc.Properties, heapDesc.Flags, &desc1, initialLayout,
isRenderableSurface ? &clearValue : nullptr, nullptr, castableFormatNum, castableFormats, IID_PPV_ARGS(&m_Texture));
RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D12Device10::CreateCommittedResource3()");
} else {
Expand All @@ -70,7 +74,7 @@ Result TextureD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset) {

if (memory->RequiresDedicatedAllocation()) {
HRESULT hr = m_Device->CreateCommittedResource(
&heapDesc.Properties, D3D12_HEAP_FLAG_CREATE_NOT_ZEROED, &desc, D3D12_RESOURCE_STATE_COMMON, isRenderableSurface ? &clearValue : nullptr, IID_PPV_ARGS(&m_Texture));
&heapDesc.Properties, heapDesc.Flags, &desc, D3D12_RESOURCE_STATE_COMMON, isRenderableSurface ? &clearValue : nullptr, IID_PPV_ARGS(&m_Texture));
RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D12Device::CreateCommittedResource()");
} else {
HRESULT hr = m_Device->CreatePlacedResource(*memory, offset, &desc, D3D12_RESOURCE_STATE_COMMON, isRenderableSurface ? &clearValue : nullptr, IID_PPV_ARGS(&m_Texture));
Expand Down
4 changes: 4 additions & 0 deletions Source/VK/AccelerationStructureVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ struct AccelerationStructureVK {
return m_Buffer;
}

inline bool OwnsNativeObjects() const {
return m_OwnsNativeObjects;
}

~AccelerationStructureVK();

Result Create(const AccelerationStructureDesc& accelerationStructureDesc);
Expand Down
4 changes: 4 additions & 0 deletions Source/VK/BufferVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ struct BufferVK {
return m_Desc;
}

inline bool OwnsNativeObjects() const {
return m_OwnsNativeObjects;
}

~BufferVK();

Result Create(const BufferDesc& bufferDesc);
Expand Down
46 changes: 29 additions & 17 deletions Source/VK/DeviceVK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1677,6 +1677,8 @@ inline Result DeviceVK::BindBufferMemory(const BufferMemoryBindingDesc* memoryBi
return Result::SUCCESS;

VkBindBufferMemoryInfo* infos = STACK_ALLOC(VkBindBufferMemoryInfo, memoryBindingDescNum);
uint32_t boundMemoryNum = 0;

for (uint32_t i = 0; i < memoryBindingDescNum; i++) {
const BufferMemoryBindingDesc& bindingDesc = memoryBindingDescs[i];

Expand All @@ -1686,21 +1688,25 @@ inline Result DeviceVK::BindBufferMemory(const BufferMemoryBindingDesc* memoryBi
const MemoryTypeUnpack unpack = {memoryImpl.GetType()};
const MemoryTypeInfo& memoryTypeInfo = unpack.info;

if (memoryTypeInfo.isDedicated == 1)
if (memoryImpl.OwnsNativeObjects() && memoryTypeInfo.isDedicated == 1)
memoryImpl.CreateDedicated(bufferImpl);

VkBindBufferMemoryInfo& info = infos[i];
info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO};
info.buffer = bufferImpl.GetHandle();
info.memory = memoryImpl.GetHandle();
info.memoryOffset = bindingDesc.offset;
if (bufferImpl.OwnsNativeObjects()) {
VkBindBufferMemoryInfo& info = infos[boundMemoryNum++];
info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO};
info.buffer = bufferImpl.GetHandle();
info.memory = memoryImpl.GetHandle();
info.memoryOffset = bindingDesc.offset;
}

if (IsHostVisibleMemory(memoryTypeInfo.memoryLocation))
bufferImpl.SetHostMemory(memoryImpl, info.memoryOffset);
bufferImpl.SetHostMemory(memoryImpl, bindingDesc.offset);
}

VkResult result = m_VK.BindBufferMemory2(m_Device, memoryBindingDescNum, infos);
RETURN_ON_FAILURE(this, result == VK_SUCCESS, GetReturnCode(result), "vkBindBufferMemory2 returned %d", (int32_t)result);
if (boundMemoryNum > 0) {
VkResult result = m_VK.BindBufferMemory2(m_Device, boundMemoryNum, infos);
RETURN_ON_FAILURE(this, result == VK_SUCCESS, GetReturnCode(result), "vkBindBufferMemory2 returned %d", (int32_t)result);
}

for (uint32_t i = 0; i < memoryBindingDescNum; i++) {
BufferVK& bufferImpl = *(BufferVK*)memoryBindingDescs[i].buffer;
Expand All @@ -1715,6 +1721,8 @@ inline Result DeviceVK::BindTextureMemory(const TextureMemoryBindingDesc* memory
return Result::SUCCESS;

VkBindImageMemoryInfo* infos = STACK_ALLOC(VkBindImageMemoryInfo, memoryBindingDescNum);
uint32_t boundMemoryNum = 0;

for (uint32_t i = 0; i < memoryBindingDescNum; i++) {
const TextureMemoryBindingDesc& bindingDesc = memoryBindingDescs[i];

Expand All @@ -1724,18 +1732,22 @@ inline Result DeviceVK::BindTextureMemory(const TextureMemoryBindingDesc* memory
const MemoryTypeUnpack unpack = {memoryImpl.GetType()};
const MemoryTypeInfo& memoryTypeInfo = unpack.info;

if (memoryTypeInfo.isDedicated)
if (memoryImpl.OwnsNativeObjects() && memoryTypeInfo.isDedicated)
memoryImpl.CreateDedicated(textureImpl);

VkBindImageMemoryInfo& info = infos[i];
info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO};
info.image = textureImpl.GetHandle();
info.memory = memoryImpl.GetHandle();
info.memoryOffset = bindingDesc.offset;
if (textureImpl.OwnsNativeObjects()) {
VkBindImageMemoryInfo& info = infos[boundMemoryNum++];
info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO};
info.image = textureImpl.GetHandle();
info.memory = memoryImpl.GetHandle();
info.memoryOffset = bindingDesc.offset;
}
}

VkResult result = m_VK.BindImageMemory2(m_Device, memoryBindingDescNum, infos);
RETURN_ON_FAILURE(this, result == VK_SUCCESS, GetReturnCode(result), "vkBindImageMemory2 returned %d", (int32_t)result);
if (boundMemoryNum > 0) {
VkResult result = m_VK.BindImageMemory2(m_Device, memoryBindingDescNum, infos);
RETURN_ON_FAILURE(this, result == VK_SUCCESS, GetReturnCode(result), "vkBindImageMemory2 returned %d", (int32_t)result);
}

return Result::SUCCESS;
}
Expand Down
4 changes: 4 additions & 0 deletions Source/VK/MemoryVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ struct MemoryVK {
return m_MappedMemory;
}

inline bool OwnsNativeObjects() const {
return m_OwnsNativeObjects;
}

~MemoryVK();

Result Create(const MemoryType memoryType, uint64_t size);
Expand Down
4 changes: 4 additions & 0 deletions Source/VK/TextureVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ struct TextureVK {
return GetDimension(GraphicsAPI::VULKAN, m_Desc, dimensionIndex, mip);
}

inline bool OwnsNativeObjects() const {
return m_OwnsNativeObjects;
}

~TextureVK();

Result Create(const TextureDesc& textureDesc);
Expand Down
19 changes: 10 additions & 9 deletions Source/Validation/DeviceVal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,10 @@ Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingD

RETURN_ON_FAILURE(this, !buffer.IsBoundToMemory(), Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].buffer' is already bound to memory", i);

destDesc = srcDesc;
destDesc.memory = memory.GetImpl();
destDesc.buffer = buffer.GetImpl();

// Skip validation if memory has been created from GAPI object using a wrapper extension
if (memory.GetMemoryLocation() == MemoryLocation::MAX_NUM)
continue;
Expand All @@ -652,10 +656,6 @@ Result DeviceVal::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingD
const bool memorySizeIsUnknown = memory.GetSize() == 0;

RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "BindBufferMemory: 'memoryBindingDescs[%u].offset' is invalid", i);

destDesc = srcDesc;
destDesc.memory = memory.GetImpl();
destDesc.buffer = buffer.GetImpl();
}

const Result result = m_CoreAPI.BindBufferMemory(m_Device, memoryBindingDescsImpl, memoryBindingDescNum);
Expand Down Expand Up @@ -687,6 +687,10 @@ Result DeviceVal::BindTextureMemory(const TextureMemoryBindingDesc* memoryBindin

RETURN_ON_FAILURE(this, !texture.IsBoundToMemory(), Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].texture' is already bound to memory", i);

destDesc = srcDesc;
destDesc.memory = memory.GetImpl();
destDesc.texture = texture.GetImpl();

// Skip validation if memory has been created from GAPI object using a wrapper extension
if (memory.GetMemoryLocation() == MemoryLocation::MAX_NUM)
continue;
Expand All @@ -704,10 +708,6 @@ Result DeviceVal::BindTextureMemory(const TextureMemoryBindingDesc* memoryBindin
const bool memorySizeIsUnknown = memory.GetSize() == 0;

RETURN_ON_FAILURE(this, memorySizeIsUnknown || rangeMax <= memory.GetSize(), Result::INVALID_ARGUMENT, "BindTextureMemory: 'memoryBindingDescs[%u].offset' is invalid", i);

destDesc = srcDesc;
destDesc.memory = memory.GetImpl();
destDesc.texture = texture.GetImpl();
}

const Result result = m_CoreAPI.BindTextureMemory(m_Device, memoryBindingDescsImpl, memoryBindingDescNum);
Expand Down Expand Up @@ -1028,7 +1028,8 @@ Result DeviceVal::CreateTextureD3D12(const TextureD3D12Desc& textureDesc, Textur
}

Result DeviceVal::CreateMemoryD3D12(const MemoryD3D12Desc& memoryDesc, Memory*& memory) {
RETURN_ON_FAILURE(this, memoryDesc.d3d12Heap != nullptr, Result::INVALID_ARGUMENT, "CreateMemoryD3D12: 'memoryDesc.d3d12Heap' is NULL");
RETURN_ON_FAILURE(
this, (memoryDesc.d3d12Heap != nullptr || memoryDesc.d3d12HeapDesc != nullptr), Result::INVALID_ARGUMENT, "CreateMemoryD3D12: 'memoryDesc.d3d12Heap' is NULL");

Memory* memoryImpl = nullptr;
const Result result = m_WrapperD3D12API.CreateMemoryD3D12(m_Device, memoryDesc, memoryImpl);
Expand Down
Loading