mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Vulkan: Use the slab allocator for textures.
This commit is contained in:
parent
62b6432121
commit
27a5697a96
4 changed files with 44 additions and 16 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "Common/Vulkan/VulkanImage.h"
|
||||
#include "Common/Vulkan/VulkanMemory.h"
|
||||
|
||||
VkResult VulkanTexture::Create(int w, int h, VkFormat format) {
|
||||
tex_width = w;
|
||||
|
@ -234,9 +235,12 @@ void VulkanTexture::Wipe() {
|
|||
vulkan_->Delete().QueueDeleteImageView(view);
|
||||
view = VK_NULL_HANDLE;
|
||||
}
|
||||
if (mem) {
|
||||
if (mem && !allocator_) {
|
||||
vulkan_->Delete().QueueDeleteDeviceMemory(mem);
|
||||
mem = VK_NULL_HANDLE;
|
||||
} else if (mem) {
|
||||
allocator_->Free(mem, offset_);
|
||||
mem = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,18 +271,25 @@ void VulkanTexture::CreateDirect(int w, int h, int numMips, VkFormat format, VkI
|
|||
assert(res == VK_SUCCESS);
|
||||
|
||||
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs);
|
||||
VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
mem_alloc.memoryTypeIndex = 0;
|
||||
mem_alloc.allocationSize = mem_reqs.size;
|
||||
|
||||
// Find memory type - don't specify any mapping requirements
|
||||
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex);
|
||||
assert(pass);
|
||||
if (allocator_) {
|
||||
offset_ = allocator_->Allocate(mem_reqs, &mem);
|
||||
} else {
|
||||
VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
|
||||
mem_alloc.memoryTypeIndex = 0;
|
||||
mem_alloc.allocationSize = mem_reqs.size;
|
||||
|
||||
res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem);
|
||||
assert(res == VK_SUCCESS);
|
||||
// Find memory type - don't specify any mapping requirements
|
||||
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex);
|
||||
assert(pass);
|
||||
|
||||
res = vkBindImageMemory(vulkan_->GetDevice(), image, mem, 0);
|
||||
res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem);
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
offset_ = 0;
|
||||
}
|
||||
|
||||
res = vkBindImageMemory(vulkan_->GetDevice(), image, mem, offset_);
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
// Since we're going to blit to the target, set its layout to TRANSFER_DST
|
||||
|
@ -347,11 +358,13 @@ void VulkanTexture::Destroy() {
|
|||
mappableImage = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
if (mem) {
|
||||
if (mem && !allocator_) {
|
||||
vulkan_->Delete().QueueDeleteDeviceMemory(mem);
|
||||
if (mappableMemory == mem) {
|
||||
mappableMemory = VK_NULL_HANDLE;
|
||||
}
|
||||
} else if (mem) {
|
||||
allocator_->Free(mem, offset_);
|
||||
}
|
||||
|
||||
view = VK_NULL_HANDLE;
|
||||
|
|
|
@ -2,14 +2,17 @@
|
|||
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
|
||||
class VulkanDeviceAllocator;
|
||||
|
||||
// Wrapper around what you need to use a texture.
|
||||
// Not very optimal - if you have many small textures you should use other strategies.
|
||||
class VulkanTexture {
|
||||
public:
|
||||
VulkanTexture(VulkanContext *vulkan)
|
||||
VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator = nullptr)
|
||||
: vulkan_(vulkan), image(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), view(VK_NULL_HANDLE),
|
||||
tex_width(0), tex_height(0), numMips_(1), format_(VK_FORMAT_UNDEFINED),
|
||||
mappableImage(VK_NULL_HANDLE), mappableMemory(VK_NULL_HANDLE), needStaging(false) {
|
||||
mappableImage(VK_NULL_HANDLE), mappableMemory(VK_NULL_HANDLE), needStaging(false),
|
||||
allocator_(allocator), offset_(0) {
|
||||
memset(&mem_reqs, 0, sizeof(mem_reqs));
|
||||
}
|
||||
~VulkanTexture() {
|
||||
|
@ -47,4 +50,6 @@ private:
|
|||
VkDeviceMemory mappableMemory;
|
||||
VkMemoryRequirements mem_reqs;
|
||||
bool needStaging;
|
||||
VulkanDeviceAllocator *allocator_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
|
|
@ -66,8 +66,11 @@
|
|||
|
||||
#define TEXCACHE_MAX_TEXELS_SCALED (256*256) // Per frame
|
||||
|
||||
#define TEXCACHE_MIN_PRESSURE 16 * 1024 * 1024 // Total in GL
|
||||
#define TEXCACHE_SECOND_MIN_PRESSURE 4 * 1024 * 1024
|
||||
#define TEXCACHE_MIN_PRESSURE (16 * 1024 * 1024) // Total in GL
|
||||
#define TEXCACHE_SECOND_MIN_PRESSURE (4 * 1024 * 1024)
|
||||
|
||||
#define TEXCACHE_MIN_SLAB_SIZE (4 * 1024 * 1024)
|
||||
#define TEXCACHE_MAX_SLAB_SIZE (32 * 1024 * 1024)
|
||||
|
||||
// Note: some drivers prefer B4G4R4A4_UNORM_PACK16 over R4G4B4A4_UNORM_PACK16.
|
||||
#define VULKAN_4444_FORMAT VK_FORMAT_B4G4R4A4_UNORM_PACK16
|
||||
|
@ -137,6 +140,7 @@ TextureCacheVulkan::TextureCacheVulkan(VulkanContext *vulkan)
|
|||
timesInvalidatedAllThisFrame_ = 0;
|
||||
lastBoundTexture = nullptr;
|
||||
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;
|
||||
allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE);
|
||||
|
||||
SetupTextureDecoder();
|
||||
|
||||
|
@ -559,6 +563,8 @@ void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 buffe
|
|||
}
|
||||
|
||||
void TextureCacheVulkan::StartFrame() {
|
||||
// TODO: Better place?
|
||||
allocator_->End();
|
||||
lastBoundTexture = nullptr;
|
||||
timesInvalidatedAllThisFrame_ = 0;
|
||||
|
||||
|
@ -572,6 +578,8 @@ void TextureCacheVulkan::StartFrame() {
|
|||
} else {
|
||||
Decimate();
|
||||
}
|
||||
|
||||
allocator_->Begin();
|
||||
}
|
||||
|
||||
static inline u32 MiniHash(const u32 *ptr) {
|
||||
|
@ -1318,7 +1326,7 @@ void TextureCacheVulkan::SetTexture(VulkanPushBuffer *uploadBuffer) {
|
|||
}
|
||||
} else {
|
||||
entry->vkTex = new CachedTextureVulkan();
|
||||
entry->vkTex->texture_ = new VulkanTexture(vulkan_);
|
||||
entry->vkTex->texture_ = new VulkanTexture(vulkan_, allocator_);
|
||||
VulkanTexture *image = entry->vkTex->texture_;
|
||||
|
||||
const VkComponentMapping *mapping;
|
||||
|
|
|
@ -35,6 +35,7 @@ class DrawEngineVulkan;
|
|||
class VulkanContext;
|
||||
class VulkanTexture;
|
||||
class VulkanPushBuffer;
|
||||
class VulkanDeviceAllocator;
|
||||
|
||||
struct SamplerCacheKey {
|
||||
SamplerCacheKey() : fullKey(0) {}
|
||||
|
@ -140,6 +141,7 @@ private:
|
|||
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key);
|
||||
|
||||
VulkanContext *vulkan_;
|
||||
VulkanDeviceAllocator *allocator_;
|
||||
|
||||
TexCache secondCache;
|
||||
u32 secondCacheSizeEstimate_;
|
||||
|
|
Loading…
Add table
Reference in a new issue