mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Add option to clear mapped memory regions to zero
This commit is contained in:
parent
e9574a4155
commit
ed83534970
@ -267,6 +267,15 @@
|
||||
# d3d11.zeroWorkgroupMemory = False
|
||||
|
||||
|
||||
# Clears mapped memory to zero when suballocated memory is freed. This will
|
||||
# drastically increase CPU overhead and should only be used as a last resort
|
||||
# if a game does not properly initialize mapped buffers on its own.
|
||||
#
|
||||
# Supported values: True, False
|
||||
|
||||
# dxvk.zeroMappedMemory = 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
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "../util/util_bit.h"
|
||||
|
||||
#include "dxvk_device.h"
|
||||
#include "dxvk_memory.h"
|
||||
#include "dxvk_sparse.h"
|
||||
@ -1254,9 +1256,17 @@ namespace dxvk {
|
||||
allocation->m_address = address;
|
||||
allocation->m_size = size;
|
||||
|
||||
if (chunk.memory.mapPtr)
|
||||
if (chunk.memory.mapPtr) {
|
||||
allocation->m_mapPtr = reinterpret_cast<char*>(chunk.memory.mapPtr) + offset;
|
||||
|
||||
if (unlikely(m_device->config().zeroMappedMemory)) {
|
||||
// Some games will not write mapped buffers and will break if
|
||||
// there is any stale data stored within. Clear when the allocation is
|
||||
// freed, so that subsequent allocations will receive cleared buffers.
|
||||
allocation->m_flags.set(DxvkAllocationFlag::ClearOnFree);
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.memory.buffer) {
|
||||
allocation->m_buffer = chunk.memory.buffer;
|
||||
allocation->m_bufferOffset = offset;
|
||||
@ -1322,6 +1332,11 @@ namespace dxvk {
|
||||
|
||||
void DxvkMemoryAllocator::freeAllocation(
|
||||
DxvkResourceAllocation* allocation) {
|
||||
if (allocation->m_flags.test(DxvkAllocationFlag::ClearOnFree)) {
|
||||
if (allocation->m_mapPtr)
|
||||
bit::bclear(allocation->m_mapPtr, allocation->m_size);
|
||||
}
|
||||
|
||||
if (allocation->m_flags.test(DxvkAllocationFlag::CanCache)) {
|
||||
// Return cacheable allocations to the shared cache
|
||||
allocation->destroyBufferViews();
|
||||
@ -1523,6 +1538,9 @@ namespace dxvk {
|
||||
"\n size: ", memory.size, " bytes"));
|
||||
}
|
||||
|
||||
if (m_device->config().zeroMappedMemory)
|
||||
bit::bclear(memory.mapPtr, memory.size);
|
||||
|
||||
Logger::debug(str::format("Mapped memory region 0x", std::hex,
|
||||
reinterpret_cast<uintptr_t>(memory.mapPtr), " - 0x",
|
||||
reinterpret_cast<uintptr_t>(memory.mapPtr) + memory.size - 1u));
|
||||
|
@ -465,12 +465,23 @@ namespace dxvk {
|
||||
* \brief Resource allocation flags
|
||||
*/
|
||||
enum class DxvkAllocationFlag : uint32_t {
|
||||
/// Allocation owns the given VkDeviceMemory allocation
|
||||
/// and is not suballocated from an existing chunk.
|
||||
OwnsMemory = 0,
|
||||
/// Allocation owns a dedicated VkBuffer object rather
|
||||
/// than the global buffer for the parent chunk, if any.
|
||||
OwnsBuffer = 1,
|
||||
/// Allocation owns a VkImage object.
|
||||
OwnsImage = 2,
|
||||
/// Allocation can use an allocation cache.
|
||||
CanCache = 3,
|
||||
/// Allocation can be relocated for defragmentation.
|
||||
CanMove = 4,
|
||||
/// Allocation is imported from an external API.
|
||||
Imported = 5,
|
||||
/// Memory must be cleared to zero when the allocation
|
||||
/// is freed. Only used to work around app bugs.
|
||||
ClearOnFree = 6,
|
||||
};
|
||||
|
||||
using DxvkAllocationFlags = Flags<DxvkAllocationFlag>;
|
||||
|
@ -13,6 +13,7 @@ namespace dxvk {
|
||||
hud = config.getOption<std::string>("dxvk.hud", "");
|
||||
tearFree = config.getOption<Tristate>("dxvk.tearFree", Tristate::Auto);
|
||||
hideIntegratedGraphics = config.getOption<bool> ("dxvk.hideIntegratedGraphics", false);
|
||||
zeroMappedMemory = config.getOption<bool> ("dxvk.zeroMappedMemory", false);
|
||||
deviceFilter = config.getOption<std::string>("dxvk.deviceFilter", "");
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,9 @@ namespace dxvk {
|
||||
// incorrectly assume monitor layouts.
|
||||
bool hideIntegratedGraphics = false;
|
||||
|
||||
/// Clears all mapped memory to zero.
|
||||
bool zeroMappedMemory = false;
|
||||
|
||||
// Device name
|
||||
std::string deviceFilter;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user