From 2249b873ff78454160096b46f39c277211580fdc Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 8 Mar 2020 12:51:14 +1000 Subject: [PATCH] D3D11/StreamBuffer: Check feature support for MAP_NO_OVERWRITE before using --- src/common/d3d11/stream_buffer.cpp | 29 +++++++++++++++++++++++++++-- src/common/d3d11/stream_buffer.h | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/common/d3d11/stream_buffer.cpp b/src/common/d3d11/stream_buffer.cpp index c10acb276..38fbc4221 100644 --- a/src/common/d3d11/stream_buffer.cpp +++ b/src/common/d3d11/stream_buffer.cpp @@ -24,7 +24,7 @@ bool StreamBuffer::Create(ID3D11Device* device, D3D11_BIND_FLAG bind_flags, u32 { CD3D11_BUFFER_DESC desc(size, bind_flags, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE, 0, 0); ComPtr buffer; - const HRESULT hr = device->CreateBuffer(&desc, nullptr, &buffer); + HRESULT hr = device->CreateBuffer(&desc, nullptr, &buffer); if (FAILED(hr)) { Log_ErrorPrintf("Creating buffer failed: 0x%08X", hr); @@ -34,6 +34,31 @@ bool StreamBuffer::Create(ID3D11Device* device, D3D11_BIND_FLAG bind_flags, u32 m_buffer = std::move(buffer); m_size = size; m_position = 0; + + D3D11_FEATURE_DATA_D3D11_OPTIONS options = {}; + hr = device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options)); + if (SUCCEEDED(hr)) + { + if (bind_flags & D3D11_BIND_CONSTANT_BUFFER) + m_use_map_no_overwrite = options.MapNoOverwriteOnDynamicConstantBuffer; + else if (bind_flags & D3D11_BIND_SHADER_RESOURCE) + m_use_map_no_overwrite = options.MapNoOverwriteOnDynamicBufferSRV; + else + m_use_map_no_overwrite = true; + + if (!m_use_map_no_overwrite) + { + Log_WarningPrintf("Unable to use MAP_NO_OVERWRITE on buffer with bind flag %u, this may affect performance. " + "Update your driver/operating system.", + static_cast(bind_flags)); + } + } + else + { + Log_WarningPrintf("ID3D11Device::CheckFeatureSupport() failed: 0x%08X", hr); + m_use_map_no_overwrite = false; + } + return true; } @@ -55,7 +80,7 @@ void StreamBuffer::Release() StreamBuffer::MappingResult StreamBuffer::Map(ID3D11DeviceContext* context, u32 alignment, u32 min_size) { m_position = Common::AlignUp(m_position, alignment); - if ((m_position + min_size) >= m_size) + if ((m_position + min_size) >= m_size || !m_use_map_no_overwrite) { // wrap around m_position = 0; diff --git a/src/common/d3d11/stream_buffer.h b/src/common/d3d11/stream_buffer.h index cdc62931f..2e46f1862 100644 --- a/src/common/d3d11/stream_buffer.h +++ b/src/common/d3d11/stream_buffer.h @@ -39,5 +39,6 @@ private: ComPtr m_buffer; u32 m_size; u32 m_position; + bool m_use_map_no_overwrite = false; }; } // namespace GL \ No newline at end of file