diff --git a/src/d3d9/d3d9_common_buffer.cpp b/src/d3d9/d3d9_common_buffer.cpp index adeb957e4..40b406b8b 100644 --- a/src/d3d9/d3d9_common_buffer.cpp +++ b/src/d3d9/d3d9_common_buffer.cpp @@ -57,6 +57,28 @@ namespace dxvk { } } + + D3D9_COMMON_BUFFER_MAP_MODE D3D9CommonBuffer::DetermineMapMode(const D3D9Options* options) const { + if (m_desc.Pool != D3DPOOL_DEFAULT) + return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER; + + if (!(m_desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY))) + return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER; + + // Tests show that DISCARD does not work for pure SWVP devices. + // So force staging buffer path to avoid stalls. + // Dark Romance: Vampire in Love also expects draws to be synchronous + // and breaks if we respect NOOVERWRITE. + // D&D Temple of Elemental Evil breaks if we respect DISCARD. + if (m_parent->CanOnlySWVP()) + return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER; + + if (!options->allowDirectBufferMapping) + return D3D9_COMMON_BUFFER_MAP_MODE_BUFFER; + + return D3D9_COMMON_BUFFER_MAP_MODE_DIRECT; + } + Rc D3D9CommonBuffer::CreateBuffer() const { DxvkBufferCreateInfo info; diff --git a/src/d3d9/d3d9_common_buffer.h b/src/d3d9/d3d9_common_buffer.h index cf6726924..b21913f84 100644 --- a/src/d3d9/d3d9_common_buffer.h +++ b/src/d3d9/d3d9_common_buffer.h @@ -89,11 +89,7 @@ namespace dxvk { /** * \brief Determine the mapping mode of the buffer, (ie. direct mapping or backed) */ - inline D3D9_COMMON_BUFFER_MAP_MODE DetermineMapMode(const D3D9Options* options) const { - return (m_desc.Pool == D3DPOOL_DEFAULT && (m_desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)) && options->allowDirectBufferMapping) - ? D3D9_COMMON_BUFFER_MAP_MODE_DIRECT - : D3D9_COMMON_BUFFER_MAP_MODE_BUFFER; - } + D3D9_COMMON_BUFFER_MAP_MODE DetermineMapMode(const D3D9Options* options) const; /** * \brief Get the mapping mode of the buffer, (ie. direct mapping or backed) diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index eba85c0b8..a5b8a00ea 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -998,6 +998,10 @@ namespace dxvk { } } + bool CanOnlySWVP() const { + return m_behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING; + } + private: DxvkCsChunkRef AllocCsChunk() { @@ -1024,10 +1028,9 @@ namespace dxvk { } } - bool CanSWVP() { + bool CanSWVP() const { return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING); } - void DetermineConstantLayouts(bool canSWVP); D3D9BufferSlice AllocUPBuffer(VkDeviceSize size);