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:
parent
601aa54139
commit
9acc4a1a82
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,6 +59,9 @@ namespace dxvk {
|
||||
Rc<DxvkBuffer> CreateBuffer(
|
||||
const D3D11_BUFFER_DESC* pDesc) const;
|
||||
|
||||
VkMemoryPropertyFlags GetMemoryFlags(
|
||||
const D3D11_BUFFER_DESC* pDesc) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user