1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 02:52:10 +01:00

[d3d11] Map default constant buffers to host memory

Improves performance in applications that use UpdateSubresources
to frequently update constant buffers, such as Unigine Heaven,
Unigine Valley and Homefront.
This commit is contained in:
Philip Rebohle 2018-01-18 11:55:27 +01:00
parent 601aa54139
commit 9acc4a1a82
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 46 additions and 3 deletions

View File

@ -120,7 +120,23 @@ namespace dxvk {
}
return m_device->GetDXVKDevice()->createBuffer(
info, GetMemoryFlagsForUsage(pDesc->Usage));
info, GetMemoryFlags(pDesc));
}
VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags(
const D3D11_BUFFER_DESC* pDesc) const {
// Default constant buffers may get updated frequently with calls
// to D3D11DeviceContext::UpdateSubresource, so we'll map them to
// host memory in order to allow direct access to the buffer
if ((pDesc->Usage == D3D11_USAGE_DEFAULT)
&& (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)) {
return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
}
// Use default memory flags for the intended use
return GetMemoryFlagsForUsage(pDesc->Usage);
}
}

View File

@ -59,6 +59,9 @@ namespace dxvk {
Rc<DxvkBuffer> CreateBuffer(
const D3D11_BUFFER_DESC* pDesc) const;
VkMemoryPropertyFlags GetMemoryFlags(
const D3D11_BUFFER_DESC* pDesc) const;
};
}

View File

@ -213,7 +213,7 @@ namespace dxvk {
const D3D11Buffer* resource = static_cast<D3D11Buffer*>(pResource);
const Rc<DxvkBuffer> buffer = resource->GetBufferSlice().buffer();
if (buffer->mapPtr(0) == nullptr) {
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
Logger::err("D3D11: Cannot map a device-local buffer");
return E_INVALIDARG;
}
@ -680,7 +680,14 @@ namespace dxvk {
return;
}
if (size != 0) {
if (size == 0)
return;
if (((size == bufferSlice.length())
&& (bufferSlice.memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) {
m_context->invalidateBuffer(bufferSlice.buffer());
std::memcpy(bufferSlice.mapPtr(0), pSrcData, size);
} else {
m_context->updateBuffer(
bufferSlice.buffer(),
bufferSlice.offset() + offset,

View File

@ -102,6 +102,17 @@ namespace dxvk {
return m_info;
}
/**
* \brief Memory type flags
*
* Use this to determine whether a
* buffer is mapped to host memory.
* \returns Vulkan memory flags
*/
VkMemoryPropertyFlags memFlags() const {
return m_memFlags;
}
/**
* \brief Buffer handle
* \returns Buffer handle
@ -260,6 +271,12 @@ namespace dxvk {
return m_buffer->resource();
}
VkMemoryPropertyFlags memFlags() const {
return m_buffer != nullptr
? m_buffer->memFlags()
: 0;
}
VkBuffer handle() const {
return m_buffer != nullptr
? m_buffer->handle()