Skip to content

Commit

Permalink
Clip block transfer destinations. Should fix crash in #10011. Stats: …
Browse files Browse the repository at this point in the history
…Invent some sort of usage metric for device memory allocators.
  • Loading branch information
hrydgard committed Dec 3, 2017
1 parent cc2e162 commit aa0cc67
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
19 changes: 17 additions & 2 deletions Common/Vulkan/VulkanMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_);
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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_);

Expand Down
2 changes: 2 additions & 0 deletions Common/Vulkan/VulkanMemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions GPU/Vulkan/FramebufferVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions GPU/Vulkan/TextureCacheVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.