diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 9551a1704a..597907bb70 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -60,7 +60,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } @@ -79,12 +79,14 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, // 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); + _assert_(pass); res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem_); if (res != VK_SUCCESS) { _assert_msg_(G3D, res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + vkDestroyImage(vulkan_->GetDevice(), image_, nullptr); + image_ = nullptr; return false; } @@ -93,7 +95,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, res = vkBindImageMemory(vulkan_->GetDevice(), image_, mem_, offset_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + // This leaks the image and memory. Should not really happen though... + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } @@ -108,8 +111,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, break; default: // If you planned to use UploadMip, you want VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. After the - // upload, you can transition. - assert(false); + // upload, you can transition using EndCreate. + _assert_(false); break; } } @@ -135,7 +138,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips, res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view_); if (res != VK_SUCCESS) { - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + // This leaks the image. + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } return true; diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 6ee742751b..4855dd6e41 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -131,8 +131,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag if (image[i]) free(image[i]); } - - return true; + return texture_ != nullptr; } bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType type, bool generateMips) { @@ -172,4 +171,4 @@ std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *dra ManagedTexture *mtex = new ManagedTexture(draw); mtex->LoadFromFileData(data, size, type, generateMips); return std::move(std::unique_ptr(mtex)); -} \ No newline at end of file +} diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 58cee3ee00..1f5660adfb 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -304,7 +304,7 @@ public: VKTexture(VulkanContext *vulkan, VkCommandBuffer cmd, VulkanPushBuffer *pushBuffer, const TextureDesc &desc, VulkanDeviceAllocator *alloc) : vulkan_(vulkan), mipLevels_(desc.mipLevels), format_(desc.format) { bool result = Create(cmd, pushBuffer, desc, alloc); - assert(result); + _assert_(result); } ~VKTexture() { @@ -650,8 +650,8 @@ enum class TextureState { bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const TextureDesc &desc, VulkanDeviceAllocator *alloc) { // Zero-sized textures not allowed. - assert(desc.width * desc.height * desc.depth > 0); - assert(push); + _assert_(desc.width * desc.height * desc.depth > 0); // remember to set depth to 1! + _assert_(push); format_ = desc.format; mipLevels_ = desc.mipLevels; width_ = desc.width; @@ -667,7 +667,10 @@ 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; } - vkTex_->CreateDirect(cmd, width_, height_, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits); + if (!vkTex_->CreateDirect(cmd, 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; + } if (desc.initData.size()) { int w = width_; int h = height_; @@ -1017,6 +1020,12 @@ InputLayout *VKContext::CreateInputLayout(const InputLayoutDesc &desc) { } Texture *VKContext::CreateTexture(const TextureDesc &desc) { + if (!push_) { + // Too early! Fail. + ELOG("Can't create textures before the first frame has started."); + return nullptr; + } + _assert_(renderManager_.GetInitCmd()); return new VKTexture(vulkan_, renderManager_.GetInitCmd(), push_, desc, allocator_); } diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 6ad2d78c8c..a148a0b60d 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -32,7 +32,7 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi void UIContext::BeginFrame() { if (!uitexture_) { - uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM); + uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM, false); if (!uitexture_) { PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); FLOG("Failed to load ui_atlas.zim");