mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
fix(agc): clear a reused pooled buffer's unused tail on macOS
MoltenVK has no robustBufferAccess2, so a robust read past the end of a pooled buffer is clamped into its slot instead of returning zero. A 100-byte buffer placed in a 256-byte slot then read the bytes an earlier user left there (0xabababab), and agc_driver_pooled_buffer_range failed. On macOS, when a host-coherent mapped slot is handed to a new buffer, the bytes past the requested size are cleared to zero. Linux and Windows compile the same code as before.
This commit is contained in:
1 parent
a3987a1eca
commit
8a9a741b68
1 file changed
+17
@@ -6,11 +6,22 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp"
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#ifdef __APPLE__
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
namespace AgcDriver::Graphics {
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef __APPLE__
|
||||
void ClearPooledTail(void* mapping, std::size_t size, VkDeviceSize mappedBytes, VkMemoryPropertyFlags properties) {
|
||||
if (mapping == nullptr || (properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0 || mappedBytes <= size) return;
|
||||
std::memset(static_cast<std::byte*>(mapping) + size, 0, static_cast<std::size_t>(mappedBytes - size));
|
||||
}
|
||||
|
||||
#endif
|
||||
VkDeviceSize ClassAllocationBytes(const VkMemoryRequirements& requirements, std::size_t capacity) {
|
||||
const auto alignment = std::max<VkDeviceSize>(requirements.alignment, 1);
|
||||
return std::max<VkDeviceSize>(requirements.size, (static_cast<VkDeviceSize>(capacity) + alignment - 1) / alignment * alignment);
|
||||
@@ -52,6 +63,9 @@ Buffer::Buffer(const Context& context, std::size_t size, VkBufferUsageFlags usag
|
||||
capacity = allocation->bytes;
|
||||
offset = allocation->offset;
|
||||
slab = allocation->slab;
|
||||
#ifdef __APPLE__
|
||||
ClearPooledTail(mapping, size, std::min<VkDeviceSize>(capacity, allocationBytes), properties);
|
||||
#endif
|
||||
if (allocation->bufferBytes != size) {
|
||||
context.Function<PFN_vkDestroyBuffer>("vkDestroyBuffer")(context.device, buffer, nullptr);
|
||||
buffer = VK_NULL_HANDLE;
|
||||
@@ -93,6 +107,9 @@ Buffer::Buffer(const Context& context, std::size_t size, VkBufferUsageFlags usag
|
||||
Check(context.Function<PFN_vkBindBufferMemory>("vkBindBufferMemory")(context.device, buffer, memory, offset), "vkBindBufferMemory slab");
|
||||
initializeAddress(usage);
|
||||
mapping = slot.mapping;
|
||||
#ifdef __APPLE__
|
||||
ClearPooledTail(mapping, size, capacity, properties);
|
||||
#endif
|
||||
ready = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user