From 0637fdf82e3f1f98983457cf8f7c6666445d4457 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 17:02:49 +0200 Subject: [PATCH] [d3d11] Implement tiled buffer creation --- src/d3d11/d3d11_buffer.cpp | 44 ++++++++++++++++++++++++++------- src/d3d11/d3d11_buffer.h | 4 ++- src/d3d11/d3d11_device.cpp | 5 ++-- src/d3d11/d3d11_device.h | 2 ++ src/d3d11/d3d11_initializer.cpp | 10 +++++--- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 3069d71ef..55e8d0b69 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -13,7 +13,8 @@ namespace dxvk { m_desc (*pDesc), m_resource (this), m_d3d10 (this) { - DxvkBufferCreateInfo info; + DxvkBufferCreateInfo info; + info.flags = 0; info.size = pDesc->ByteWidth; info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; @@ -66,6 +67,12 @@ namespace dxvk { info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT; } + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { + info.flags |= VK_BUFFER_CREATE_SPARSE_BINDING_BIT + | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT + | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT; + } + // Create the buffer and set the entire buffer slice as mapped, // so that we only have to update it when invalidating th buffer m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags()); @@ -162,15 +169,11 @@ namespace dxvk { } - HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) { + HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc, D3D11_TILED_RESOURCES_TIER TiledTier) { // Zero-sized buffers are illegal - if (!pDesc->ByteWidth) + if (!pDesc->ByteWidth && !(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) return E_INVALIDARG; - // We don't support tiled resources - if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED)) - return E_INVALIDARG; - // Constant buffer size must be a multiple of 16 if ((pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) && (pDesc->ByteWidth & 0xF)) @@ -191,7 +194,27 @@ namespace dxvk { // Mip generation obviously doesn't work for buffers if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) return E_INVALIDARG; - + + // Basic validation for tiled buffers + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { + if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) + || (pDesc->Usage != D3D11_USAGE_DEFAULT) + || (pDesc->CPUAccessFlags) + || (!TiledTier)) + return E_INVALIDARG; + } + + // Basic validation for tile pools + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) { + if ((pDesc->MiscFlags & ~D3D11_RESOURCE_MISC_TILE_POOL) + || (pDesc->ByteWidth % SparseMemoryPageSize) + || (pDesc->Usage != D3D11_USAGE_DEFAULT) + || (pDesc->BindFlags) + || (pDesc->CPUAccessFlags) + || (!TiledTier)) + return E_INVALIDARG; + } + if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)) pDesc->StructureByteStride = 0; @@ -209,7 +232,10 @@ namespace dxvk { VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags() const { VkMemoryPropertyFlags memoryFlags = 0; - + + if (m_desc.MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED)) + return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + switch (m_desc.Usage) { case D3D11_USAGE_IMMUTABLE: memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index b13b18aa0..90d069b01 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -138,10 +138,12 @@ namespace dxvk { * \brief Normalizes buffer description * * \param [in] pDesc Buffer description + * \param [in] TiledTier Tiled resources tier * \returns \c S_OK if the parameters are valid */ static HRESULT NormalizeBufferProperties( - D3D11_BUFFER_DESC* pDesc); + D3D11_BUFFER_DESC* pDesc, + D3D11_TILED_RESOURCES_TIER TiledTier); private: diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 42124597f..1feeb2b95 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -45,7 +45,8 @@ namespace dxvk { m_dxvkAdapter (m_dxvkDevice->adapter()), m_d3d11Formats (m_dxvkDevice), m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), - m_dxbcOptions (m_dxvkDevice, m_d3d11Options) { + m_dxbcOptions (m_dxvkDevice, m_d3d11Options), + m_tiledResourcesTier(DetermineTiledResourcesTier(m_dxvkDevice->features(), m_dxvkDevice->properties())) { m_initializer = new D3D11Initializer(this); m_context = new D3D11ImmediateContext(this, m_dxvkDevice); m_d3d10Device = new D3D10Device(this, m_context.ptr()); @@ -84,7 +85,7 @@ namespace dxvk { return E_INVALIDARG; D3D11_BUFFER_DESC desc = *pDesc; - HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc); + HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc, m_tiledResourcesTier); if (FAILED(hr)) return hr; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index fef0dca11..8d25a9ed7 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -455,6 +455,8 @@ namespace dxvk { D3D11StateObjectSet m_samplerObjects; D3D11ShaderModuleSet m_shaderModules; + D3D11_TILED_RESOURCES_TIER m_tiledResourcesTier; + HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, DxvkShaderKey ShaderKey, diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 9aa9ac672..b90dbff6b 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -30,11 +30,13 @@ namespace dxvk { void D3D11Initializer::InitBuffer( D3D11Buffer* pBuffer, const D3D11_SUBRESOURCE_DATA* pInitialData) { - VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags(); + if (!(pBuffer->Desc()->MiscFlags & D3D11_RESOURCE_MISC_TILED)) { + VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags(); - (memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - ? InitHostVisibleBuffer(pBuffer, pInitialData) - : InitDeviceLocalBuffer(pBuffer, pInitialData); + (memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + ? InitHostVisibleBuffer(pBuffer, pInitialData) + : InitDeviceLocalBuffer(pBuffer, pInitialData); + } }