diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index a4f4cb9c..3bbdc308 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -9,8 +9,9 @@ namespace dxvk { D3D11Buffer::D3D11Buffer( D3D11Device* pDevice, const D3D11_BUFFER_DESC* pDesc) - : m_device (pDevice), - m_desc (*pDesc) { + : m_device (pDevice), + m_desc (*pDesc), + m_buffer (CreateBuffer(pDesc)) { } @@ -62,7 +63,7 @@ namespace dxvk { D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedSubresource) { - const Rc buffer = GetDXVKBuffer(); + const Rc buffer = m_buffer; if (buffer->mapPtr(0) == nullptr) { Logger::err("D3D11: Cannot map a device-local buffer"); @@ -122,8 +123,13 @@ namespace dxvk { } - Rc D3D11Buffer::GetDXVKBuffer() { - return m_buffer; + DxvkBufferSlice D3D11Buffer::GetCurrentBufferSlice() const { + return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth); + } + + + DxvkBufferSlice D3D11Buffer::GetInitialBufferSlice() const { + return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth); } diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index df7a55ff..717ee0a8 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -11,8 +11,17 @@ namespace dxvk { class D3D11DeviceContext; - class D3D11Buffer : public D3D11DeviceChild { + class D3D11BufferStorage { + public: + + private: + + }; + + + class D3D11Buffer : public D3D11DeviceChild { + static constexpr VkDeviceSize BufferSliceAlignment = 64; public: D3D11Buffer( @@ -46,14 +55,15 @@ namespace dxvk { void Unmap( D3D11DeviceContext* pContext); - Rc GetDXVKBuffer(); + DxvkBufferSlice GetCurrentBufferSlice() const; + DxvkBufferSlice GetInitialBufferSlice() const; private: - Com m_device; - D3D11_BUFFER_DESC m_desc; + const Com m_device; + const D3D11_BUFFER_DESC m_desc; - Rc m_buffer; + Rc m_buffer; Rc CreateBuffer( const D3D11_BUFFER_DESC* pDesc) const; diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index d8cd2540..f928c242 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -395,23 +395,28 @@ namespace dxvk { pDstResource->GetType(&resourceType); if (resourceType == D3D11_RESOURCE_DIMENSION_BUFFER) { - Com bufferResource; - - pDstResource->QueryInterface( - __uuidof(IDXGIBufferResourcePrivate), - reinterpret_cast(&bufferResource)); + const auto bufferResource = static_cast(pDstResource); + const auto bufferSlice = bufferResource->GetCurrentBufferSlice(); VkDeviceSize offset = 0; - VkDeviceSize size = VK_WHOLE_SIZE; + VkDeviceSize size = bufferSlice.bufferRange(); if (pDstBox != nullptr) { offset = pDstBox->left; size = pDstBox->right - pDstBox->left; } - m_context->updateBuffer( - bufferResource->GetDXVKBuffer(), - offset, size, pSrcData); + if (offset + size > bufferSlice.bufferRange()) { + Logger::err("D3D11: UpdateSubresource: Buffer size out of bounds"); + return; + } + + if (size != 0) { + m_context->updateBuffer( + bufferSlice.buffer(), + bufferSlice.bufferOffset() + offset, + size, pSrcData); + } } else { Logger::err("D3D11DeviceContext::UpdateSubresource: Images not yet supported"); } @@ -628,18 +633,20 @@ namespace dxvk { binding.stride = pStrides[i]; } - DxvkBufferSlice dxvkBinding; + DxvkBufferSlice bufferSlice; if (binding.buffer != nullptr) { - Rc dxvkBuffer = binding.buffer->GetDXVKBuffer(); + const DxvkBufferSlice baseSlice = + binding.buffer->GetCurrentBufferSlice(); - dxvkBinding = DxvkBufferSlice( - dxvkBuffer, binding.offset, - dxvkBuffer->info().size - binding.offset); + bufferSlice = DxvkBufferSlice( + baseSlice.buffer(), + baseSlice.bufferOffset() + binding.offset, + baseSlice.bufferRange() - binding.offset); } m_context->bindVertexBuffer( - StartSlot + i, dxvkBinding, + StartSlot + i, bufferSlice, binding.stride); } } @@ -655,17 +662,18 @@ namespace dxvk { binding.format = Format; m_state.ia.indexBuffer = binding; - DxvkBufferSlice dxvkBinding; + DxvkBufferSlice bufferSlice; if (binding.buffer != nullptr) { - Rc dxvkBuffer = binding.buffer->GetDXVKBuffer(); + const DxvkBufferSlice baseSlice = + binding.buffer->GetCurrentBufferSlice(); - dxvkBinding = DxvkBufferSlice( - dxvkBuffer, binding.offset, - dxvkBuffer->info().size - binding.offset); + bufferSlice = DxvkBufferSlice( + baseSlice.buffer(), + baseSlice.bufferOffset() + binding.offset, + baseSlice.bufferRange() - binding.offset); } - // As in Vulkan, the index format can be either a 32-bit // unsigned integer or a 16-bit unsigned integer, no other // formats are allowed. @@ -680,7 +688,7 @@ namespace dxvk { } m_context->bindIndexBuffer( - dxvkBinding, indexType); + bufferSlice, indexType); } @@ -1462,13 +1470,10 @@ namespace dxvk { pBindings->at(StartSlot + i) = buffer; // Figure out which part of the buffer to bind - DxvkBufferSlice bindingInfo; + DxvkBufferSlice bufferSlice; - if (buffer != nullptr) { - bindingInfo = DxvkBufferSlice( - buffer->GetDXVKBuffer(), - 0, VK_WHOLE_SIZE); - } + if (buffer != nullptr) + bufferSlice = buffer->GetCurrentBufferSlice(); // Bind buffer to the DXVK resource slot const VkPipelineBindPoint bindPoint @@ -1481,7 +1486,7 @@ namespace dxvk { StartSlot + i); m_context->bindResourceBuffer( - bindPoint, slotId, bindingInfo); + bindPoint, slotId, bufferSlice); } } } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 30935c79..e66a58ed 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1147,14 +1147,17 @@ namespace dxvk { void D3D11Device::InitBuffer( D3D11Buffer* pBuffer, const D3D11_SUBRESOURCE_DATA* pInitialData) { - const Rc buffer = pBuffer->GetDXVKBuffer(); + const DxvkBufferSlice bufferSlice + = pBuffer->GetCurrentBufferSlice(); if (pInitialData != nullptr) { std::lock_guard lock(m_resourceInitMutex);; m_resourceInitContext->beginRecording( m_dxvkDevice->createCommandList()); m_resourceInitContext->updateBuffer( - buffer, 0, buffer->info().size, + bufferSlice.buffer(), + bufferSlice.bufferOffset(), + bufferSlice.bufferRange(), pInitialData->pSysMem); m_dxvkDevice->submitCommandList( m_resourceInitContext->endRecording(), diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index 867d91ec..ec9c2a39 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -14,6 +14,7 @@ #include "../util/util_enum.h" #include "../util/util_error.h" +#include "../util/util_math.h" #include "../util/util_string.h" #include diff --git a/src/dxgi/dxgi_resource.cpp b/src/dxgi/dxgi_resource.cpp index e14eafc4..f1ba60ce 100644 --- a/src/dxgi/dxgi_resource.cpp +++ b/src/dxgi/dxgi_resource.cpp @@ -57,55 +57,6 @@ namespace dxvk { m_layer = pLayer; } - - - - DxgiBufferResource::DxgiBufferResource( - IDXGIDevicePrivate* pDevice, - const dxvk::DxvkBufferCreateInfo* pCreateInfo, - VkMemoryPropertyFlags memoryFlags, - UINT usageFlags) - : Base(pDevice, usageFlags) { - m_buffer = pDevice->GetDXVKDevice()->createBuffer( - *pCreateInfo, memoryFlags); - } - - - DxgiBufferResource::~DxgiBufferResource() { - - } - - - HRESULT STDMETHODCALLTYPE DxgiBufferResource::QueryInterface(REFIID riid, void** ppvObject) { - COM_QUERY_IFACE(riid, ppvObject, IUnknown); - COM_QUERY_IFACE(riid, ppvObject, IDXGIObject); - COM_QUERY_IFACE(riid, ppvObject, IDXGIDeviceSubObject); - COM_QUERY_IFACE(riid, ppvObject, IDXGIResource); - COM_QUERY_IFACE(riid, ppvObject, IDXGIBufferResourcePrivate); - - if (m_layer != nullptr) - return m_layer->QueryInterface(riid, ppvObject); - - Logger::err("DxgiBufferResource::QueryInterface: Unknown interface query"); - return E_NOINTERFACE; - } - - - HRESULT STDMETHODCALLTYPE DxgiBufferResource::GetParent(REFIID riid, void** ppParent) { - Logger::err("DxgiBufferResource::GetParent: Unknown interface query"); - return E_NOINTERFACE; - } - - - Rc STDMETHODCALLTYPE DxgiBufferResource::GetDXVKBuffer() { - return m_buffer; - } - - - void STDMETHODCALLTYPE DxgiBufferResource::SetResourceLayer(IUnknown* pLayer) { - m_layer = pLayer; - } - } @@ -127,21 +78,4 @@ extern "C" { } } - - DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate( - IDXGIDevicePrivate* pDevice, - const dxvk::DxvkBufferCreateInfo* pCreateInfo, - VkMemoryPropertyFlags memoryFlags, - UINT usageFlags, - IDXGIBufferResourcePrivate** ppResource) { - try { - *ppResource = dxvk::ref(new dxvk::DxgiBufferResource( - pDevice, pCreateInfo, memoryFlags, usageFlags)); - return S_OK; - } catch (const dxvk::DxvkError& e) { - dxvk::Logger::err(e.message()); - return DXGI_ERROR_UNSUPPORTED; - } - } - } \ No newline at end of file diff --git a/src/dxgi/dxgi_resource.h b/src/dxgi/dxgi_resource.h index dc9087a0..396ec2e8 100644 --- a/src/dxgi/dxgi_resource.h +++ b/src/dxgi/dxgi_resource.h @@ -100,45 +100,6 @@ namespace dxvk { IUnknown* m_layer = nullptr; }; - - - /** - * \brief Buffer resource - * - * Stores a DXVK buffer and provides a method to retrieve - * it. D3D buffers will be backed by a buffer resource. - */ - class DxgiBufferResource : public DxgiResource { - using Base = DxgiResource; - public: - - DxgiBufferResource( - IDXGIDevicePrivate* pDevice, - const dxvk::DxvkBufferCreateInfo* pCreateInfo, - VkMemoryPropertyFlags memoryFlags, - UINT usageFlags); - - ~DxgiBufferResource(); - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void **ppvObject) final; - - HRESULT STDMETHODCALLTYPE GetParent( - REFIID riid, - void **ppParent) final; - - Rc STDMETHODCALLTYPE GetDXVKBuffer() final; - - void STDMETHODCALLTYPE SetResourceLayer( - IUnknown* pLayer) final; - - private: - - Rc m_buffer; - IUnknown* m_layer = nullptr; - - }; } @@ -152,11 +113,4 @@ extern "C" { UINT usageFlags, IDXGIImageResourcePrivate** ppResource); - DLLEXPORT HRESULT __stdcall DXGICreateBufferResourcePrivate( - IDXGIDevicePrivate* pDevice, - const dxvk::DxvkBufferCreateInfo* pCreateInfo, - VkMemoryPropertyFlags memoryFlags, - UINT usageFlags, - IDXGIBufferResourcePrivate** ppResource); - } \ No newline at end of file diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 80d17a4a..8c125203 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -176,7 +176,7 @@ namespace dxvk { m_offset(rangeOffset), m_length(rangeLength) { } - Rc resource() const { + Rc buffer() const { return m_buffer; } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 72397c5a..6dc45692 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -446,9 +446,6 @@ namespace dxvk { const void* data) { this->renderPassEnd(); - if (size == VK_WHOLE_SIZE) - size = buffer->info().size - offset; - if (size != 0) { // Vulkan specifies that small amounts of data (up to 64kB) // can be copied to a buffer directly. Anything larger than @@ -907,7 +904,7 @@ namespace dxvk { m_state.vi.indexBuffer.bufferOffset(), m_state.vi.indexType); m_cmd->trackResource( - m_state.vi.indexBuffer.resource()); + m_state.vi.indexBuffer.buffer()); } } } @@ -925,7 +922,7 @@ namespace dxvk { if (handle != VK_NULL_HANDLE) { m_cmd->cmdBindVertexBuffers(i, 1, &handle, &offset); - m_cmd->trackResource(vbo.resource()); + m_cmd->trackResource(vbo.buffer()); } } } diff --git a/src/util/util_math.h b/src/util/util_math.h index c0b155fa..7a6386a9 100644 --- a/src/util/util_math.h +++ b/src/util/util_math.h @@ -9,4 +9,9 @@ namespace dxvk { return n; } + template + T align(T what, T to) { + return (what + to - 1) & ~(to - 1); + } + } \ No newline at end of file