Skip to content

Commit

Permalink
Merge pull request #75 from 01Pollux/wrapper-device-resource-fix
Browse files Browse the repository at this point in the history
Fixed resource allocation and memory binding for device wrapper
  • Loading branch information
dzhdanNV authored Jun 26, 2024
2 parents b73c998 + a2000f8 commit 70eb51a
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 32 deletions.
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

0 comments on commit 70eb51a

Please sign in to comment.