mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-24 05:49:58 +00:00
Merge pull request #11838 from hrydgard/dedicated-alloc-fix
VulkanImage: Fix issue where we'd try to free dedicated allocations from the allocator
This commit is contained in:
commit
2c9aa561b1
@ -30,7 +30,7 @@ static bool IsDepthStencilFormat(VkFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
|
||||
bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage, const VkComponentMapping *mapping) {
|
||||
Wipe();
|
||||
|
||||
width_ = w;
|
||||
@ -75,7 +75,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
bool dedicatedAllocation = false;
|
||||
vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation);
|
||||
|
||||
if (allocator_ && !dedicatedAllocation) {
|
||||
if (allocator && !dedicatedAllocation) {
|
||||
allocator_ = allocator;
|
||||
offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag());
|
||||
if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) {
|
||||
ELOG("Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits);
|
||||
@ -231,10 +232,13 @@ void VulkanTexture::Destroy() {
|
||||
if (image_ != VK_NULL_HANDLE) {
|
||||
vulkan_->Delete().QueueDeleteImage(image_);
|
||||
}
|
||||
if (mem_ != VK_NULL_HANDLE && !allocator_) {
|
||||
vulkan_->Delete().QueueDeleteDeviceMemory(mem_);
|
||||
} else if (mem_ != VK_NULL_HANDLE) {
|
||||
allocator_->Free(mem_, offset_);
|
||||
mem_ = VK_NULL_HANDLE;
|
||||
if (mem_ != VK_NULL_HANDLE) {
|
||||
if (allocator_) {
|
||||
allocator_->Free(mem_, offset_);
|
||||
mem_ = VK_NULL_HANDLE;
|
||||
allocator_ = nullptr;
|
||||
} else {
|
||||
vulkan_->Delete().QueueDeleteDeviceMemory(mem_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ class VulkanDeviceAllocator;
|
||||
// Not very optimal - if you have many small textures you should use other strategies.
|
||||
class VulkanTexture {
|
||||
public:
|
||||
VulkanTexture(VulkanContext *vulkan, VulkanDeviceAllocator *allocator)
|
||||
: vulkan_(vulkan), allocator_(allocator) {
|
||||
VulkanTexture(VulkanContext *vulkan)
|
||||
: vulkan_(vulkan) {
|
||||
}
|
||||
~VulkanTexture() {
|
||||
Destroy();
|
||||
@ -18,7 +18,7 @@ public:
|
||||
// Fast uploads from buffer. Mipmaps supported.
|
||||
// Usage must at least include VK_IMAGE_USAGE_TRANSFER_DST_BIT in order to use UploadMip.
|
||||
// When using UploadMip, initialLayout should be VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
|
||||
bool CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
|
||||
bool CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *allocator, int w, int h, int numMips, VkFormat format, VkImageLayout initialLayout, VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, const VkComponentMapping *mapping = nullptr);
|
||||
void UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength); // rowLength is in pixels
|
||||
void GenerateMip(VkCommandBuffer cmd, int mip);
|
||||
void EndCreate(VkCommandBuffer cmd, bool vertexTexture = false);
|
||||
@ -55,7 +55,7 @@ private:
|
||||
int32_t height_ = 0;
|
||||
int32_t numMips_ = 1;
|
||||
VkFormat format_ = VK_FORMAT_UNDEFINED;
|
||||
VulkanDeviceAllocator *allocator_;
|
||||
VulkanDeviceAllocator *allocator_ = nullptr; // If set, memory is from this allocator.
|
||||
size_t offset_ = 0;
|
||||
std::string tag_;
|
||||
};
|
||||
|
@ -129,16 +129,18 @@ VulkanTexture *DepalShaderCacheVulkan::GetClutTexture(GEPaletteFormat clutFormat
|
||||
VkFormat destFormat = GetClutDestFormat(clutFormat, &componentMapping);
|
||||
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;
|
||||
|
||||
VulkanTexture *vktex = new VulkanTexture(vulkan_);
|
||||
vktex->SetTag("DepalClut");
|
||||
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
if (!vktex->CreateDirect(cmd, alloc_, texturePixels, 1, 1, destFormat,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) {
|
||||
ERROR_LOG(G3D, "Failed to create texture for CLUT");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VkBuffer pushBuffer;
|
||||
uint32_t pushOffset = push_->PushAligned(rawClut, 1024, 4, &pushBuffer);
|
||||
|
||||
VulkanTexture *vktex = new VulkanTexture(vulkan_, alloc_);
|
||||
vktex->SetTag("DepalClut");
|
||||
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
if (!vktex->CreateDirect(cmd, texturePixels, 1, 1, destFormat,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, &componentMapping)) {
|
||||
Crash();
|
||||
}
|
||||
vktex->UploadMip(cmd, 0, texturePixels, 1, pushBuffer, pushOffset, texturePixels);
|
||||
vktex->EndCreate(cmd);
|
||||
|
||||
|
@ -195,9 +195,9 @@ void FramebufferManagerVulkan::MakePixelTexture(const u8 *srcPixels, GEBufferFor
|
||||
VkCommandBuffer initCmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
|
||||
// There's only ever a few of these alive, don't need to stress the allocator with these big ones.
|
||||
drawPixelsTex_ = new VulkanTexture(vulkan_, nullptr);
|
||||
drawPixelsTex_ = new VulkanTexture(vulkan_);
|
||||
drawPixelsTex_->SetTag("DrawPixels");
|
||||
if (!drawPixelsTex_->CreateDirect(initCmd, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
|
||||
if (!drawPixelsTex_->CreateDirect(initCmd, nullptr, width, height, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) {
|
||||
// out of memory?
|
||||
delete drawPixelsTex_;
|
||||
drawPixelsTex_ = nullptr;
|
||||
|
@ -351,7 +351,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr
|
||||
depalShaderCache_->SetPushBuffer(drawEngine_->GetPushBufferForTextureData());
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
VulkanTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
drawEngine_->SetDepalTexture(clutTexture->GetImageView());
|
||||
drawEngine_->SetDepalTexture(clutTexture ? clutTexture->GetImageView() : VK_NULL_HANDLE);
|
||||
// Only point filtering enabled.
|
||||
samplerKey.magFilt = false;
|
||||
samplerKey.minFilt = false;
|
||||
@ -599,7 +599,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
|
||||
{
|
||||
delete entry->vkTex;
|
||||
entry->vkTex = new VulkanTexture(vulkan_, allocator_);
|
||||
entry->vkTex = new VulkanTexture(vulkan_);
|
||||
VulkanTexture *image = entry->vkTex;
|
||||
|
||||
const VkComponentMapping *mapping;
|
||||
@ -625,7 +625,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
snprintf(texName, sizeof(texName), "Texture%08x", entry->addr);
|
||||
image->SetTag(texName);
|
||||
|
||||
bool allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
if (!allocSuccess && !lowMemoryMode_) {
|
||||
WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode");
|
||||
lowMemoryMode_ = true;
|
||||
@ -644,7 +644,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
scaleFactor = 1;
|
||||
actualFmt = dstFmt;
|
||||
|
||||
allocSuccess = image->CreateDirect(cmdInit, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping);
|
||||
}
|
||||
|
||||
if (!allocSuccess) {
|
||||
|
@ -630,11 +630,11 @@ static inline VkSamplerAddressMode AddressModeToVulkan(Draw::TextureAddressMode
|
||||
VulkanTexture *VKContext::GetNullTexture() {
|
||||
if (!nullTexture_) {
|
||||
VkCommandBuffer cmdInit = renderManager_.GetInitCmd();
|
||||
nullTexture_ = new VulkanTexture(vulkan_, allocator_);
|
||||
nullTexture_ = new VulkanTexture(vulkan_);
|
||||
nullTexture_->SetTag("Null");
|
||||
int w = 8;
|
||||
int h = 8;
|
||||
nullTexture_->CreateDirect(cmdInit, w, h, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
nullTexture_->CreateDirect(cmdInit, allocator_, w, h, 1, VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
uint32_t bindOffset;
|
||||
VkBuffer bindBuf;
|
||||
@ -713,7 +713,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
||||
width_ = desc.width;
|
||||
height_ = desc.height;
|
||||
depth_ = desc.depth;
|
||||
vkTex_ = new VulkanTexture(vulkan_, alloc);
|
||||
vkTex_ = new VulkanTexture(vulkan_);
|
||||
vkTex_->SetTag(desc.tag);
|
||||
VkFormat vulkanFormat = DataFormatToVulkan(format_);
|
||||
int bpp = GetBpp(vulkanFormat);
|
||||
@ -723,7 +723,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
||||
// Gonna have to generate some, which requires TRANSFER_SRC
|
||||
usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
}
|
||||
if (!vkTex_->CreateDirect(cmd, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) {
|
||||
if (!vkTex_->CreateDirect(cmd, alloc, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) {
|
||||
ELOG("Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_);
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user