1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-12 13:08:50 +01:00

[dxvk] Zero-initialize newly allocated buffer slices on creation

Fixes random flicker in God of War. Since patch 1.0.9, the game's lighting
system relies on MAP_DISCARD returning a zero-initialized memory slices for
its constant buffers, or some lights would get skipped in various compute
passes. Changing the memset to e.g. write 0xFF instead of 0 shows this issue.
This commit is contained in:
Philip Rebohle 2022-03-24 02:46:25 +01:00
parent e440fa26ab
commit 6b8e8afd5b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 11 additions and 5 deletions

View File

@ -29,8 +29,10 @@ namespace dxvk {
? MaxBufferSize / m_physSliceStride ? MaxBufferSize / m_physSliceStride
: 1; : 1;
// Allocate the initial set of buffer slices // Allocate the initial set of buffer slices. Only clear
m_buffer = allocBuffer(m_physSliceCount); // buffer memory if there is more than one slice, since
// we expect the client api to initialize the first slice.
m_buffer = allocBuffer(m_physSliceCount, m_physSliceCount > 1);
DxvkBufferSliceHandle slice; DxvkBufferSliceHandle slice;
slice.handle = m_buffer.buffer; slice.handle = m_buffer.buffer;
@ -52,7 +54,7 @@ namespace dxvk {
} }
DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount) const { DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount, bool clear) const {
auto vkd = m_device->vkd(); auto vkd = m_device->vkd();
VkBufferCreateInfo info; VkBufferCreateInfo info;
@ -124,6 +126,9 @@ namespace dxvk {
handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS) handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS)
throw DxvkError("DxvkBuffer: Failed to bind device memory"); throw DxvkError("DxvkBuffer: Failed to bind device memory");
if (clear && (m_memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
std::memset(handle.memory.mapPtr(0), 0, info.size);
return handle; return handle;
} }

View File

@ -245,7 +245,7 @@ namespace dxvk {
// backing buffer and add all slices to the free list. // backing buffer and add all slices to the free list.
if (unlikely(m_freeSlices.empty())) { if (unlikely(m_freeSlices.empty())) {
if (likely(!m_lazyAlloc)) { if (likely(!m_lazyAlloc)) {
DxvkBufferHandle handle = allocBuffer(m_physSliceCount); DxvkBufferHandle handle = allocBuffer(m_physSliceCount, true);
for (uint32_t i = 0; i < m_physSliceCount; i++) for (uint32_t i = 0; i < m_physSliceCount; i++)
pushSlice(handle, i); pushSlice(handle, i);
@ -317,7 +317,8 @@ namespace dxvk {
} }
DxvkBufferHandle allocBuffer( DxvkBufferHandle allocBuffer(
VkDeviceSize sliceCount) const; VkDeviceSize sliceCount,
bool clear) const;
VkDeviceSize computeSliceAlignment() const; VkDeviceSize computeSliceAlignment() const;