mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-12 13:54:14 +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
|
# 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
|
# Resource size limit for implicit discards, in kilobytes. For small staging
|
||||||
# resources mapped with MAP_WRITE, DXVK will sometimes allocate new backing
|
# resources mapped with MAP_WRITE, DXVK will sometimes allocate new backing
|
||||||
# storage in order to avoid GPU synchronization, so setting this too high
|
# storage in order to avoid GPU synchronization, so setting this too high
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../util/util_bit.h"
|
||||||
|
|
||||||
#include "dxvk_device.h"
|
#include "dxvk_device.h"
|
||||||
#include "dxvk_memory.h"
|
#include "dxvk_memory.h"
|
||||||
#include "dxvk_sparse.h"
|
#include "dxvk_sparse.h"
|
||||||
@ -1254,9 +1256,17 @@ namespace dxvk {
|
|||||||
allocation->m_address = address;
|
allocation->m_address = address;
|
||||||
allocation->m_size = size;
|
allocation->m_size = size;
|
||||||
|
|
||||||
if (chunk.memory.mapPtr)
|
if (chunk.memory.mapPtr) {
|
||||||
allocation->m_mapPtr = reinterpret_cast<char*>(chunk.memory.mapPtr) + offset;
|
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) {
|
if (chunk.memory.buffer) {
|
||||||
allocation->m_buffer = chunk.memory.buffer;
|
allocation->m_buffer = chunk.memory.buffer;
|
||||||
allocation->m_bufferOffset = offset;
|
allocation->m_bufferOffset = offset;
|
||||||
@ -1322,6 +1332,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkMemoryAllocator::freeAllocation(
|
void DxvkMemoryAllocator::freeAllocation(
|
||||||
DxvkResourceAllocation* allocation) {
|
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)) {
|
if (allocation->m_flags.test(DxvkAllocationFlag::CanCache)) {
|
||||||
// Return cacheable allocations to the shared cache
|
// Return cacheable allocations to the shared cache
|
||||||
allocation->destroyBufferViews();
|
allocation->destroyBufferViews();
|
||||||
@ -1523,6 +1538,9 @@ namespace dxvk {
|
|||||||
"\n size: ", memory.size, " bytes"));
|
"\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,
|
Logger::debug(str::format("Mapped memory region 0x", std::hex,
|
||||||
reinterpret_cast<uintptr_t>(memory.mapPtr), " - 0x",
|
reinterpret_cast<uintptr_t>(memory.mapPtr), " - 0x",
|
||||||
reinterpret_cast<uintptr_t>(memory.mapPtr) + memory.size - 1u));
|
reinterpret_cast<uintptr_t>(memory.mapPtr) + memory.size - 1u));
|
||||||
|
@ -465,12 +465,23 @@ namespace dxvk {
|
|||||||
* \brief Resource allocation flags
|
* \brief Resource allocation flags
|
||||||
*/
|
*/
|
||||||
enum class DxvkAllocationFlag : uint32_t {
|
enum class DxvkAllocationFlag : uint32_t {
|
||||||
|
/// Allocation owns the given VkDeviceMemory allocation
|
||||||
|
/// and is not suballocated from an existing chunk.
|
||||||
OwnsMemory = 0,
|
OwnsMemory = 0,
|
||||||
|
/// Allocation owns a dedicated VkBuffer object rather
|
||||||
|
/// than the global buffer for the parent chunk, if any.
|
||||||
OwnsBuffer = 1,
|
OwnsBuffer = 1,
|
||||||
|
/// Allocation owns a VkImage object.
|
||||||
OwnsImage = 2,
|
OwnsImage = 2,
|
||||||
|
/// Allocation can use an allocation cache.
|
||||||
CanCache = 3,
|
CanCache = 3,
|
||||||
|
/// Allocation can be relocated for defragmentation.
|
||||||
CanMove = 4,
|
CanMove = 4,
|
||||||
|
/// Allocation is imported from an external API.
|
||||||
Imported = 5,
|
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>;
|
using DxvkAllocationFlags = Flags<DxvkAllocationFlag>;
|
||||||
|
@ -13,6 +13,7 @@ namespace dxvk {
|
|||||||
hud = config.getOption<std::string>("dxvk.hud", "");
|
hud = config.getOption<std::string>("dxvk.hud", "");
|
||||||
tearFree = config.getOption<Tristate>("dxvk.tearFree", Tristate::Auto);
|
tearFree = config.getOption<Tristate>("dxvk.tearFree", Tristate::Auto);
|
||||||
hideIntegratedGraphics = config.getOption<bool> ("dxvk.hideIntegratedGraphics", false);
|
hideIntegratedGraphics = config.getOption<bool> ("dxvk.hideIntegratedGraphics", false);
|
||||||
|
zeroMappedMemory = config.getOption<bool> ("dxvk.zeroMappedMemory", false);
|
||||||
deviceFilter = config.getOption<std::string>("dxvk.deviceFilter", "");
|
deviceFilter = config.getOption<std::string>("dxvk.deviceFilter", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@ namespace dxvk {
|
|||||||
// incorrectly assume monitor layouts.
|
// incorrectly assume monitor layouts.
|
||||||
bool hideIntegratedGraphics = false;
|
bool hideIntegratedGraphics = false;
|
||||||
|
|
||||||
|
/// Clears all mapped memory to zero.
|
||||||
|
bool zeroMappedMemory = false;
|
||||||
|
|
||||||
// Device name
|
// Device name
|
||||||
std::string deviceFilter;
|
std::string deviceFilter;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user