mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Clip block transfer destinations. Should fix crash in #10011. Stats: Invent some sort of usage metric for device memory allocators.
This commit is contained in:
parent
cc2e162a00
commit
aa0cc6712f
4 changed files with 32 additions and 4 deletions
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Vulkan/VulkanMemory.h"
|
||||
#include "math/math_util.h"
|
||||
|
||||
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size) : device_(vulkan->GetDevice()), buf_(0), offset_(0), size_(size), writePtr_(nullptr) {
|
||||
vulkan->MemoryTypeFromProperties(0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &memoryTypeIndex_);
|
||||
|
@ -197,8 +198,10 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic
|
|||
return ALLOCATE_FAILED;
|
||||
}
|
||||
|
||||
size_t size = reqs.size;
|
||||
|
||||
size_t align = reqs.alignment <= SLAB_GRAIN_SIZE ? 1 : (size_t)(reqs.alignment >> SLAB_GRAIN_SHIFT);
|
||||
size_t blocks = (size_t)((reqs.size + SLAB_GRAIN_SIZE - 1) >> SLAB_GRAIN_SHIFT);
|
||||
size_t blocks = (size_t)((size + SLAB_GRAIN_SIZE - 1) >> SLAB_GRAIN_SHIFT);
|
||||
|
||||
const size_t numSlabs = slabs_.size();
|
||||
for (size_t i = 0; i < numSlabs; ++i) {
|
||||
|
@ -220,7 +223,7 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic
|
|||
}
|
||||
|
||||
// Okay, we couldn't fit it into any existing slabs. We need a new one.
|
||||
if (!AllocateSlab(reqs.size)) {
|
||||
if (!AllocateSlab(size)) {
|
||||
return ALLOCATE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -274,6 +277,18 @@ bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t b
|
|||
return true;
|
||||
}
|
||||
|
||||
int VulkanDeviceAllocator::ComputeUsagePercent() const {
|
||||
int blockSum = 0;
|
||||
int blocksUsed = 0;
|
||||
for (int i = 0; i < slabs_.size(); i++) {
|
||||
blockSum += (int)slabs_[i].usage.size();
|
||||
for (int j = 0; j < slabs_[i].usage.size(); j++) {
|
||||
blocksUsed += slabs_[i].usage[j] != 0 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
return 100 * blocksUsed / blockSum;
|
||||
}
|
||||
|
||||
void VulkanDeviceAllocator::Free(VkDeviceMemory deviceMemory, size_t offset) {
|
||||
assert(!destroyed_);
|
||||
|
||||
|
|
|
@ -150,6 +150,8 @@ public:
|
|||
int GetMinSlabSize() const { return (int)minSlabSize_; }
|
||||
int GetMaxSlabSize() const { return (int)maxSlabSize_; }
|
||||
|
||||
int ComputeUsagePercent() const;
|
||||
|
||||
private:
|
||||
static const size_t SLAB_GRAIN_SIZE = 1024;
|
||||
static const uint8_t SLAB_GRAIN_SHIFT = 10;
|
||||
|
|
|
@ -482,6 +482,17 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
|
|||
return;
|
||||
}
|
||||
|
||||
// Perform a little bit of clipping first.
|
||||
// Block transfer coords are unsigned so I don't think we need to clip on the left side..
|
||||
if (dstX + w > dst->bufferWidth) {
|
||||
w -= dstX + w - dst->bufferWidth;
|
||||
}
|
||||
if (dstY + h > dst->bufferHeight) {
|
||||
h -= dstY + h - dst->bufferHeight;
|
||||
}
|
||||
if (w == 0 || h == 0)
|
||||
return;
|
||||
|
||||
float srcXFactor = (float)src->renderWidth / (float)src->bufferWidth;
|
||||
float srcYFactor = (float)src->renderHeight / (float)src->bufferHeight;
|
||||
const int srcBpp = src->format == GE_FORMAT_8888 ? 4 : 2;
|
||||
|
|
|
@ -820,6 +820,6 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve
|
|||
}
|
||||
|
||||
void TextureCacheVulkan::GetStats(char *ptr, size_t size) {
|
||||
snprintf(ptr, size, "Alloc: %d blocks\nSlab min/max: %d/%d\n",
|
||||
allocator_->GetBlockCount(), allocator_->GetMinSlabSize(), allocator_->GetMaxSlabSize());
|
||||
snprintf(ptr, size, "Alloc: %d slabs\nSlab min/max: %d/%d\nAlloc usage: %d%%",
|
||||
allocator_->GetBlockCount(), allocator_->GetMinSlabSize(), allocator_->GetMaxSlabSize(), allocator_->ComputeUsagePercent());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue