Permalink
Browse files

Clip block transfer destinations. Should fix crash in #10011. Stats: …

…Invent some sort of usage metric for device memory allocators.
  • Loading branch information...
hrydgard committed Dec 3, 2017
1 parent cc2e162 commit aa0cc6712ff93602983c429b0e3d5bbd8c65dc4a
@@ -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 @@ class VulkanDeviceAllocator {
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());
}

0 comments on commit aa0cc67

Please sign in to comment.