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

WIP: tiling support #28

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
51 changes: 51 additions & 0 deletions Include/Extensions/NRITiling.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

NRI_NAMESPACE_BEGIN

NRI_STRUCT(TilePool);

NRI_STRUCT(SubresourceTilingDesc)
{
uint32_t widthInTiles;
uint16_t heightInTiles;
uint16_t depthInTiles;
uint32_t resourceOffsetInTiles;
};

NRI_STRUCT(TileBindDesc)
{
NRI_NAME(TextureRegionDesc) region; // all sizes in pixels, not tiles!
NRI_NAME(TilePool)* tilePool;
uint64_t offsetInTiles;
};

NRI_STRUCT(TextureTilingRequirementsDesc)
{
NRI_NAME(Dim_t) tileWidth;
NRI_NAME(Dim_t) tileHeight;
NRI_NAME(Dim_t) tileDepth;
NRI_NAME(Mip_t) mipStandardNum;
NRI_NAME(Mip_t) mipPackedNum;
uint32_t packedTileNum;
uint32_t startPackedTileIndex;
};

/*
Result(NRI_CALL* GetTextureTiling)(Device& device, NRI_NAME_REF(Texture) texture, uint32_t* tileNum, const NRI_NAME_REF(PackedMipInfoDesc) packedMipInfo,
NRI_NAME_REF(TileShapeDesc), uint32_t subresourceNum, const NRI_NAME_REF(SubresourceTilingDesc) subresourceTilings);

*/

NRI_STRUCT(TilingInterface)
{
Result(NRI_CALL* CreateTilePool)(Device& device, uint32_t nodeMask, NRI_NAME(MemoryType) memoryType, uint64_t poolSize, NRI_NAME_REF(TilePool*) tilePool);
void(NRI_CALL* DestroyTilePool)(Device& device, NRI_NAME_REF(TilePool) tilePool);

void(NRI_CALL* GetSubresourceTiling)(Device& device, uint32_t subresource, NRI_NAME_REF(SubresourceTilingDesc) subresourceTiling);
void(NRI_CALL * GetTextureTilingRequirements)(Device & device, NRI_NAME_REF(TextureTilingRequirementsDesc) memoryRequirements);

Result(NRI_CALL* BindTextureTiles)(Device& device, NRI_NAME_REF(CommandQueue) commandQueue, NRI_NAME_REF(Texture) texture, const NRI_NAME(TileBindDesc)* binds, uint32_t bindNum);

};

NRI_NAMESPACE_END
5 changes: 4 additions & 1 deletion Include/NRIDescs.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,8 @@ NRI_STRUCT(TextureDesc)
NRI_NAME(Mip_t) mipNum;
NRI_NAME(Dim_t) arraySize;
NRI_NAME(Sample_t) sampleNum;
uint32_t nodeMask;
uint32_t nodeMask;
bool tiled;
};

NRI_STRUCT(BufferDesc)
Expand Down Expand Up @@ -1398,6 +1399,8 @@ NRI_STRUCT(DeviceDesc)
bool isRegisterAliasingSupported;
bool isSubsetAllocationSupported;
bool isFloat16Supported;
bool isTilingSupported;
bool isVolumeTilingSupported; // 3D textures tiling
};

NRI_NAMESPACE_END
53 changes: 53 additions & 0 deletions Source/D3D12/CommandQueueD3D12.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// © 2021 NVIDIA Corporation

#include "SharedD3D12.h"
#include "TextureD3D12.h"
#include "MemoryD3D12.h"
#include "CommandQueueD3D12.h"
#include "CommandBufferD3D12.h"

Expand Down Expand Up @@ -70,4 +72,55 @@ inline Result CommandQueueD3D12::WaitForIdle()
return helperWaitIdle.WaitIdle();
}

inline Result CommandQueueD3D12::BindTextureTiles(Texture& texture, const TileBindDesc* binds, uint32_t bindNum)
{
TextureD3D12& nativeTexture = (TextureD3D12&)texture;
TextureTilingRequirementsDesc tilingRequirements = nativeTexture.GetTilingRequirements();

// TODO: batch multiple calls of UpdateTileMappings into one
for (size_t i = 0; i < bindNum; i++)
{
const TileBindDesc& bind = binds[i];
D3D12_TILE_REGION_SIZE tileRegion = {};
uint32_t subresource = nativeTexture.GetSubresourceIndex(bind.region.arrayOffset, bind.region.mipOffset);
D3D12_TILED_RESOURCE_COORDINATE resourceCoordinate = {};
if (nativeTexture.IsPackedSubresource(subresource))
{
// Don't use any offsets here, just update an entire packed mip
resourceCoordinate.Subresource = tilingRequirements.startPackedTileIndex;
tileRegion.NumTiles = tilingRequirements.packedTileNum;
tileRegion.UseBox = FALSE;
}
else
{
resourceCoordinate.Subresource = subresource;
resourceCoordinate.X = bind.region.x / tilingRequirements.tileWidth;
resourceCoordinate.Y = bind.region.y / tilingRequirements.tileHeight;
resourceCoordinate.Z = bind.region.z / tilingRequirements.tileDepth;
tileRegion.Width = bind.region.width / tilingRequirements.tileWidth;
tileRegion.Height = bind.region.height / tilingRequirements.tileHeight;
tileRegion.Depth = bind.region.depth / tilingRequirements.tileDepth;
tileRegion.NumTiles = tileRegion.Width * tileRegion.Height * tileRegion.Depth;
tileRegion.UseBox = TRUE;
}

D3D12_TILE_RANGE_FLAGS rangeFlag = bind.tilePool == nullptr ? D3D12_TILE_RANGE_FLAG_NONE : D3D12_TILE_RANGE_FLAG_NULL;
UINT heapTiledOffset = bind.offsetInTiles;

MemoryD3D12* memory = (MemoryD3D12*)bind.tilePool;
m_CommandQueue->UpdateTileMappings(
nativeTexture,
1,
&resourceCoordinate,
&tileRegion,
*memory,
1,
&rangeFlag,
&heapTiledOffset,
&tileRegion.NumTiles,
D3D12_TILE_MAPPING_FLAG_NONE
);
}
}

#include "CommandQueueD3D12.hpp"
1 change: 1 addition & 0 deletions Source/D3D12/CommandQueueD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct CommandQueueD3D12
Result UploadData(const TextureUploadDesc* textureUploadDescs, uint32_t textureUploadDescNum,
const BufferUploadDesc* bufferUploadDescs, uint32_t bufferUploadDescNum);
Result WaitForIdle();
Result BindTextureTiles(Texture& texture, const TileBindDesc* binds, uint32_t bindNum);

private:
DeviceD3D12& m_Device;
Expand Down
10 changes: 7 additions & 3 deletions Source/D3D12/DeviceD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "MemoryD3D12.h"
#include "BufferD3D12.h"
#include "TextureD3D12.h"
#include "TilingD3D12.h"
#include "DescriptorD3D12.h"
#include "PipelineLayoutD3D12.h"
#include "PipelineD3D12.h"
Expand Down Expand Up @@ -375,6 +376,8 @@ void DeviceD3D12::FillDesc(bool enableValidation)
if (FAILED(hr))
REPORT_ERROR(this, "ID3D12Device::CheckFeatureSupport(options7) failed, result = 0x%08X!", hr);

#ifdef NRI_USE_AGILITY_SDK
// D3D12_FEATURE_DATA_D3D12_OPTIONS8 is not supported on Windows 10 LTSC (21H2)
D3D12_FEATURE_DATA_D3D12_OPTIONS8 options8 = {};
hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS8, &options8, sizeof(options8));
if (FAILED(hr))
Expand Down Expand Up @@ -405,7 +408,6 @@ void DeviceD3D12::FillDesc(bool enableValidation)
if (FAILED(hr))
REPORT_ERROR(this, "ID3D12Device::CheckFeatureSupport(options13) failed, result = 0x%08X!", hr);

#ifdef NRI_USE_AGILITY_SDK
D3D12_FEATURE_DATA_D3D12_OPTIONS14 options14 = {};
hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &options14, sizeof(options14));
if (FAILED(hr))
Expand Down Expand Up @@ -606,6 +608,8 @@ void DeviceD3D12::FillDesc(bool enableValidation)
m_Desc.isRegisterAliasingSupported = true;
m_Desc.isSubsetAllocationSupported = true;
m_Desc.isFloat16Supported = options4.Native16BitShaderOpsSupported;
m_Desc.isTilingSupported = options.TiledResourcesTier != D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED;
m_Desc.isVolumeTilingSupported = options.TiledResourcesTier >= D3D12_TILED_RESOURCES_TIER_3;
}

//================================================================================================================
Expand Down Expand Up @@ -807,9 +811,9 @@ inline void DeviceD3D12::DestroyQueryPool(QueryPool& queryPool)
Deallocate(GetStdAllocator(), (QueryPoolD3D12*)&queryPool);
}

inline Result DeviceD3D12::AllocateMemory(const MemoryType memoryType, uint64_t size, Memory*& memory)
inline Result DeviceD3D12::AllocateMemory(const MemoryType memoryType, uint64_t size, bool tiling, Memory*& memory)
{
return CreateImplementation<MemoryD3D12>(memory, memoryType, size);
return CreateImplementation<MemoryD3D12>(memory, memoryType, tiling, size);
}

inline Result DeviceD3D12::BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum)
Expand Down
3 changes: 2 additions & 1 deletion Source/D3D12/DeviceD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ struct DeviceD3D12 final : public DeviceBase
void DestroyPipeline(Pipeline& pipeline);
void DestroyFence(Fence& queueSemaphore);
void DestroyQueryPool(QueryPool& queryPool);
Result AllocateMemory(const MemoryType memoryType, uint64_t size, Memory*& memory);
Result AllocateMemory(const MemoryType memoryType, uint64_t size, bool tiling, Memory*& memory);
Result BindBufferMemory(const BufferMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum);
Result BindTextureMemory(const TextureMemoryBindingDesc* memoryBindingDescs, uint32_t memoryBindingDescNum);
void FreeMemory(Memory& memory);
Expand All @@ -149,6 +149,7 @@ struct DeviceD3D12 final : public DeviceBase
Result FillFunctionTable(WrapperD3D12Interface& wrapperD3D12Interface) const;
Result FillFunctionTable(RayTracingInterface& rayTracingInterface) const;
Result FillFunctionTable(MeshShaderInterface& meshShaderInterface) const;
Result FillFunctionTable(TilingInterface& tilingInterface) const;
Result FillFunctionTable(HelperInterface& helperInterface) const;

private:
Expand Down
32 changes: 32 additions & 0 deletions Source/D3D12/DeviceD3D12.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "DeviceD3D12.h"
// © 2021 NVIDIA Corporation

Declare_PartiallyFillFunctionTable_Functions(D3D12)
Expand Down Expand Up @@ -431,6 +432,37 @@ Result DeviceD3D12::FillFunctionTable(MeshShaderInterface& meshShaderInterface)

#pragma endregion

#pragma region[ Tiling ]

/*
Result(NRI_CALL* CreateTilePool)(uint64_t poolSize, NRI_NAME(MemoryLocation) memoryLocation, NRI_NAME_REF(TilePool*) tilePool);
void(NRI_CALL* DestroyTilePool)(NRI_NAME_REF(TilePool) tilePool);

Result(NRI_CALL* GetTextureTiling)(NRI_NAME_REF(Texture) texture, uint32_t* tileNum, const NRI_NAME_REF(PackedMipInfoDesc) packedMipInfo, NRI_NAME_REF(TileShapeDesc), uint32_t
subresourceNum, const NRI_NAME_REF(SubresourceTilingDesc) subresourceTilings);

Result(NRI_CALL* BindTextureTiles)(NRI_NAME_REF(CommandQueue) commandQueue, NRI_NAME_REF(Texture) texture, const NRI_NAME(TileBindDesc)* binds, uint32_t bindNum);

*/

static Result NRI_CALL CreateTilePool(Device& device, uint32_t nodeMask, MemoryType memoryType, uint64_t poolSize, NRI_NAME_REF(TilePool*) tilePool)
{
return ((DeviceD3D12&)device).AllocateMemory(memoryType, poolSize, (Memory*&)tilePool);
}

Result nri::DeviceD3D12::FillFunctionTable(TilingInterface& tilingInterface) const
{
if (!m_Desc.isTilingSupported)
return Result::UNSUPPORTED;

tilingInterface = {};
tilingInterface.CreateTilePool = ::CreateTilePool;

return ValidateFunctionTable(tilingInterface);
}

#pragma endregion

#pragma region [ Helper ]

static uint32_t NRI_CALL CountAllocationNum(Device& device, const ResourceGroupDesc& resourceGroupDesc)
Expand Down
2 changes: 1 addition & 1 deletion Source/D3D12/MemoryD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using namespace nri;

Result MemoryD3D12::Create(const MemoryType memoryType, uint64_t size)
Result MemoryD3D12::Create(const MemoryType memoryType, bool tiling, uint64_t size)
{
D3D12_HEAP_DESC heapDesc = {};
heapDesc.SizeInBytes = size;
Expand Down
2 changes: 1 addition & 1 deletion Source/D3D12/MemoryD3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct MemoryD3D12
inline DeviceD3D12& GetDevice() const
{ return m_Device; }

Result Create(const MemoryType memoryType, uint64_t size);
Result Create(const MemoryType memoryType, bool tiling, uint64_t size);
Result Create(const MemoryD3D12Desc& memoryDesc);

//================================================================================================================
Expand Down
1 change: 1 addition & 0 deletions Source/D3D12/SharedD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ bool nri::GetTextureDesc(const TextureD3D12Desc& textureD3D12Desc, TextureDesc&
textureDesc.arraySize = textureDesc.type == TextureType::TEXTURE_3D ? 1 : (Dim_t)desc.DepthOrArraySize;
textureDesc.sampleNum = (uint8_t)desc.SampleDesc.Count;
textureDesc.nodeMask = ALL_NODES; // TODO: not in D3D12_RESOURCE_DESC...
textureDesc.tiled = desc.Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE;

if (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
textureDesc.usageMask |= TextureUsageBits::COLOR_ATTACHMENT;
Expand Down
68 changes: 65 additions & 3 deletions Source/D3D12/TextureD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,72 @@ static D3D12_RESOURCE_DESC GetResourceDesc(const TextureDesc& textureDesc)
desc.MipLevels = textureDesc.mipNum;
desc.Format = GetDxgiFormat(textureDesc.format).typeless;
desc.SampleDesc.Count = textureDesc.sampleNum;
desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.Layout = textureDesc.tiled ? D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE : D3D12_TEXTURE_LAYOUT_UNKNOWN;
desc.Flags = GetTextureFlags(textureDesc.usageMask);

return desc;
}

SubresourceTilingDesc nri::TextureD3D12::GetSubresourceTiling(Dim_t arrayOffset, Mip_t mipOffset) const
{
const uint32_t subresourceIndex = GetSubresourceIndex(arrayOffset, mipOffset);
RETURN_ON_FAILURE(&m_Device, subresourceIndex < m_SubresourceTilings.size(), {}, "Trying to access unexisting or packed subresource");
return m_SubresourceTilings.at(subresourceIndex);
}

inline TextureTilingRequirementsDesc nri::TextureD3D12::GetTilingRequirements() const
{
return m_TilingRequirements;
}

void nri::TextureD3D12::ObtainTilingInfo()
{
UINT numTiles = 0;
D3D12_PACKED_MIP_INFO packedMipInfo = {};
D3D12_TILE_SHAPE tileShape = {};
UINT subresourceCount = m_Desc.arraySize * m_Desc.mipNum;
D3D12_SUBRESOURCE_TILING* tilings = STACK_ALLOC(D3D12_SUBRESOURCE_TILING, subresourceCount);
((ID3D12Device*)m_Device)->GetResourceTiling(m_Texture, &numTiles, &packedMipInfo, &tileShape, &subresourceCount, 0, tilings);

m_TilingRequirements.mipPackedNum = packedMipInfo.NumPackedMips;
m_TilingRequirements.mipStandardNum = packedMipInfo.NumStandardMips;
m_TilingRequirements.packedTileNum = packedMipInfo.NumTilesForPackedMips;
m_TilingRequirements.startPackedTileIndex = packedMipInfo.StartTileIndexInOverallResource;
m_TilingRequirements.tileWidth = tileShape.WidthInTexels;
m_TilingRequirements.tileHeight = tileShape.HeightInTexels;
m_TilingRequirements.tileDepth = tileShape.DepthInTexels;

m_SubresourceTilings.reserve(packedMipInfo.NumStandardMips);
for (size_t i = 0; i < packedMipInfo.NumStandardMips; i++) {
const D3D12_SUBRESOURCE_TILING& tiling = tilings[i];
m_SubresourceTilings.emplace_back(
SubresourceTilingDesc{tiling.WidthInTiles, tiling.HeightInTiles, tiling.DepthInTiles, tiling.StartTileIndexInOverallResource}
);
}
}

Result TextureD3D12::Create(const TextureDesc& textureDesc)
{
if (textureDesc.tiled)
{
D3D12_RESOURCE_DESC desc = GetResourceDesc(textureDesc);
D3D12_CLEAR_VALUE clearValue = {GetDxgiFormat(textureDesc.format).typed};
bool isRenderableSurface = desc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);

RETURN_ON_FAILURE(&m_Device, m_Device.GetDesc().isTilingSupported, Result::UNSUPPORTED, "Tiled textures are not supported on this device");
HRESULT hr = ((ID3D12Device*)m_Device)->CreateReservedResource(
&desc,
D3D12_RESOURCE_STATE_COMMON,
isRenderableSurface ? &clearValue : nullptr,
IID_PPV_ARGS(&m_Texture)
);

RETURN_ON_BAD_HRESULT(&m_Device, hr, "ID3D12Device::CreateReservedResource()");
}

m_Desc = textureDesc;
if (m_Desc.tiled)
ObtainTilingInfo();

return Result::SUCCESS;
}
Expand All @@ -38,19 +95,23 @@ Result TextureD3D12::Create(const TextureD3D12Desc& textureDesc)
return Result::INVALID_ARGUMENT;

m_Texture = textureDesc.d3d12Resource;
if (m_Desc.tiled)
ObtainTilingInfo();

return Result::SUCCESS;
}

Result TextureD3D12::BindMemory(const MemoryD3D12* memory, uint64_t offset)
{
RETURN_ON_FAILURE(&m_Device, !m_Desc.tiled, Result::INVALID_ARGUMENT, "Tile textures can't be binded directly. Use \"TilingInteface\" for such purposes.");

D3D12_RESOURCE_DESC desc = GetResourceDesc(m_Desc);
const D3D12_HEAP_DESC& heapDesc = memory->GetHeapDesc();
D3D12_CLEAR_VALUE clearValue = { GetDxgiFormat(m_Desc.format).typed };
bool isRenderableSurface = desc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);

if (memory->RequiresDedicatedAllocation())
if (memory->RequiresDedicatedAllocation())
{
const D3D12_HEAP_DESC& heapDesc = memory->GetHeapDesc();
HRESULT hr = ((ID3D12Device*)m_Device)->CreateCommittedResource(
&heapDesc.Properties,
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED,
Expand Down Expand Up @@ -107,4 +168,5 @@ inline void TextureD3D12::GetMemoryInfo(MemoryLocation memoryLocation, MemoryDes
m_Device.GetMemoryInfo(memoryLocation, desc, memoryDesc);
}


#include "TextureD3D12.hpp"
Loading
Loading