[d3d11] Add d3d11.maxImplicitDiscardSize option

This commit is contained in:
Philip Rebohle 2022-02-14 04:11:36 +01:00
parent 63bf928ab5
commit e1b3bc45ce
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 21 additions and 7 deletions

View File

@ -203,6 +203,14 @@
# d3d11.zeroWorkgroupMemory = False
# Resource size limit for implicit discards, in kilobytes. For small staging
# resources mapped with MAP_WRITE, DXVK will sometimes allocate new backing
# storage in order to avoid GPU synchronization, so setting this too high
# may cause memory issues, setting it to 0 disables the feature.
# d3d11.maxImplicitDiscardSize = 256
# Sets number of pipeline compiler threads.
#
# Supported values:

View File

@ -7,8 +7,6 @@ constexpr static uint32_t MinFlushIntervalUs = 750;
constexpr static uint32_t IncFlushIntervalUs = 250;
constexpr static uint32_t MaxPendingSubmits = 6;
constexpr static VkDeviceSize MaxImplicitDiscardSize = 256ull << 10;
namespace dxvk {
D3D11ImmediateContext::D3D11ImmediateContext(
@ -16,6 +14,7 @@ namespace dxvk {
const Rc<DxvkDevice>& Device)
: D3D11DeviceContext(pParent, Device, DxvkCsChunkFlag::SingleUse),
m_csThread(Device, Device->createContext()),
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
m_videoContext(this, Device) {
EmitCs([
cDevice = m_device,
@ -393,7 +392,7 @@ namespace dxvk {
auto buffer = pResource->GetBuffer();
auto sequenceNumber = pResource->GetSequenceNumber();
if (MapType != D3D11_MAP_READ && !MapFlags && bufferSize <= MaxImplicitDiscardSize) {
if (MapType != D3D11_MAP_READ && !MapFlags && bufferSize <= m_maxImplicitDiscardSize) {
SynchronizeCsThread(sequenceNumber);
bool hasWoAccess = buffer->isInUse(DxvkAccess::Write);
@ -514,11 +513,9 @@ namespace dxvk {
// Don't implicitly discard large buffers or buffers of images with
// multiple subresources, as that is likely to cause memory issues.
VkDeviceSize bufferSize = pResource->CountSubresources() == 1
? pResource->GetMappedSlice(Subresource).length
: MaxImplicitDiscardSize;
VkDeviceSize bufferSize = pResource->GetMappedSlice(Subresource).length;
if (bufferSize >= MaxImplicitDiscardSize) {
if (bufferSize >= m_maxImplicitDiscardSize || pResource->CountSubresources() > 1) {
// Don't check access flags, WaitForResource will return
// early anyway if the resource is currently in use
doFlags = DoWait;

View File

@ -125,6 +125,7 @@ namespace dxvk {
uint64_t m_eventCount = 0ull;
uint32_t m_mappedImageCount = 0u;
VkDeviceSize m_maxImplicitDiscardSize = 0ull;
dxvk::high_resolution_clock::time_point m_lastFlush
= dxvk::high_resolution_clock::now();

View File

@ -25,6 +25,11 @@ namespace dxvk {
this->syncInterval = config.getOption<int32_t>("dxgi.syncInterval", -1);
this->tearFree = config.getOption<Tristate>("dxgi.tearFree", Tristate::Auto);
int32_t maxImplicitDiscardSize = config.getOption<int32_t>("d3d11.maxImplicitDiscardSize", 256);
this->maxImplicitDiscardSize = maxImplicitDiscardSize >= 0
? VkDeviceSize(maxImplicitDiscardSize) << 10
: VkDeviceSize(~0ull);
this->constantBufferRangeCheck = config.getOption<bool>("d3d11.constantBufferRangeCheck", false)
&& DxvkGpuVendor(devInfo.core.properties.vendorID) != DxvkGpuVendor::Amd;

View File

@ -92,6 +92,9 @@ namespace dxvk {
/// Limit frame rate
int32_t maxFrameRate;
/// Limit discardable resource size
VkDeviceSize maxImplicitDiscardSize;
/// Defer surface creation until first present call. This
/// fixes issues with games that create multiple swap chains
/// for a single window that may interfere with each other.