mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
Merge pull request #13261 from hrydgard/vulkan-debug-object-names
Vulkan: Add debug names to images
This commit is contained in:
17 files changed
+70
-30
No files matched your search
@@ -694,6 +694,14 @@ VkResult VulkanContext::InitDebugUtilsCallback() {
|
||||
return res;
|
||||
}
|
||||
|
||||
void VulkanContext::SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name) {
|
||||
VkDebugUtilsObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT };
|
||||
info.pObjectName = name;
|
||||
info.objectHandle = handle;
|
||||
info.objectType = type;
|
||||
vkSetDebugUtilsObjectNameEXT(device_, &info);
|
||||
}
|
||||
|
||||
VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) {
|
||||
winsys_ = winsys;
|
||||
winsysData1_ = data1;
|
||||
@@ -1383,7 +1391,7 @@ void VulkanDeleteList::PerformDeletes(VkDevice device) {
|
||||
}
|
||||
|
||||
void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation) {
|
||||
if (DeviceExtensions().KHR_dedicated_allocation) {
|
||||
if (Extensions().KHR_dedicated_allocation) {
|
||||
VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR};
|
||||
memReqInfo2.image = image;
|
||||
|
||||
|
||||
@@ -167,6 +167,14 @@ public:
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
// Simple workaround for the casting warning.
|
||||
template <class T>
|
||||
void SetDebugName(T handle, VkObjectType type, const char *name) {
|
||||
if (extensionsLookup_.EXT_debug_utils) {
|
||||
SetDebugNameImpl((uint64_t)handle, type, name);
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex);
|
||||
|
||||
VkPhysicalDevice GetPhysicalDevice(int n) const {
|
||||
@@ -267,13 +275,15 @@ public:
|
||||
MAX_INFLIGHT_FRAMES = 3,
|
||||
};
|
||||
|
||||
const VulkanDeviceExtensions &DeviceExtensions() { return extensionsLookup_; }
|
||||
const VulkanExtensions &Extensions() { return extensionsLookup_; }
|
||||
|
||||
void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation);
|
||||
|
||||
private:
|
||||
bool ChooseQueue();
|
||||
|
||||
void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name);
|
||||
|
||||
VkResult InitDebugUtilsCallback();
|
||||
|
||||
// A layer can expose extensions, keep track of those extensions here.
|
||||
@@ -307,7 +317,7 @@ private:
|
||||
|
||||
std::vector<const char *> device_extensions_enabled_;
|
||||
std::vector<VkExtensionProperties> device_extension_properties_;
|
||||
VulkanDeviceExtensions extensionsLookup_{};
|
||||
VulkanExtensions extensionsLookup_{};
|
||||
|
||||
std::vector<VkPhysicalDevice> physical_devices_;
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply the tag
|
||||
vulkan_ ->SetDebugName(image_, VK_OBJECT_TYPE_IMAGE, tag_.c_str());
|
||||
|
||||
VkMemoryRequirements mem_reqs{};
|
||||
bool dedicatedAllocation = false;
|
||||
vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation);
|
||||
@@ -161,6 +164,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Batch these.
|
||||
void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength) {
|
||||
VkBufferImageCopy copy_region{};
|
||||
copy_region.bufferOffset = offset;
|
||||
|
||||
@@ -489,7 +489,7 @@ bool VulkanLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions) {
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions) {
|
||||
// OK, let's use the above functions to get the rest.
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyInstance);
|
||||
LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices);
|
||||
@@ -554,7 +554,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensio
|
||||
// On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may
|
||||
// increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very
|
||||
// good for multi-device - not likely we'll ever try that anyway though.
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions) {
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) {
|
||||
WLOG("Vulkan device functions loaded.");
|
||||
|
||||
LOAD_DEVICE_FUNC(device, vkQueueSubmit);
|
||||
|
||||
@@ -215,7 +215,7 @@ extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
|
||||
extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
|
||||
|
||||
// For fast extension-enabled checks.
|
||||
struct VulkanDeviceExtensions {
|
||||
struct VulkanExtensions {
|
||||
bool EXT_debug_utils;
|
||||
bool KHR_maintenance1; // required for KHR_create_renderpass2
|
||||
bool KHR_maintenance2;
|
||||
@@ -236,6 +236,6 @@ bool VulkanMayBeAvailable();
|
||||
void VulkanSetAvailable(bool available);
|
||||
|
||||
bool VulkanLoad();
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions);
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions);
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions);
|
||||
void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions);
|
||||
void VulkanFree();
|
||||
@@ -1060,7 +1060,9 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,
|
||||
}
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth });
|
||||
char name[256];
|
||||
snprintf(name, sizeof(name), "%08x_%08x", vfb->fb_address, vfb->z_address);
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name });
|
||||
if (old.fbo) {
|
||||
INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format);
|
||||
if (vfb->fbo) {
|
||||
@@ -1329,7 +1331,9 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd
|
||||
vfb->usageFlags = FB_USAGE_RENDERTARGET;
|
||||
SetColorUpdated(vfb, 0);
|
||||
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED);
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth });
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address);
|
||||
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name });
|
||||
vfbs_.push_back(vfb);
|
||||
|
||||
u32 byteSize = ColorBufferByteSize(vfb);
|
||||
@@ -1417,7 +1421,9 @@ bool FramebufferManagerCommon::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb
|
||||
}
|
||||
}
|
||||
|
||||
nvfb->fbo = draw_->CreateFramebuffer({ nvfb->bufferWidth, nvfb->bufferHeight, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth });
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "download_temp");
|
||||
nvfb->fbo = draw_->CreateFramebuffer({ nvfb->bufferWidth, nvfb->bufferHeight, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth, name });
|
||||
if (!nvfb->fbo) {
|
||||
ERROR_LOG(FRAMEBUF, "Error creating GL FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
|
||||
return false;
|
||||
@@ -1744,7 +1750,8 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u
|
||||
|
||||
textureCache_->ForgetLastTexture();
|
||||
bool z_stencil = reason == TempFBO::STENCIL;
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth });
|
||||
const char *name = "temp_fbo";
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth, name });
|
||||
if (!fbo)
|
||||
return fbo;
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ bool PresentationCommon::AllocateFramebuffer(int w, int h) {
|
||||
}
|
||||
|
||||
// No depth/stencil for post processing
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 });
|
||||
Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888, "presentation" });
|
||||
if (!fbo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
}
|
||||
|
||||
char texName[128]{};
|
||||
snprintf(texName, sizeof(texName), "Texture%08x", entry->addr);
|
||||
snprintf(texName, sizeof(texName), "texture_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format));
|
||||
image->SetTag(texName);
|
||||
|
||||
bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, imageLayout, usage, mapping);
|
||||
|
||||
@@ -789,7 +789,7 @@ void GameInfoCache::SetupTexture(std::shared_ptr<GameInfo> &info, Draw::DrawCont
|
||||
using namespace Draw;
|
||||
if (tex.data.size()) {
|
||||
if (!tex.texture) {
|
||||
tex.texture = CreateTextureFromFileData(thin3d, (const uint8_t *)tex.data.data(), (int)tex.data.size(), ImageFileType::DETECT);
|
||||
tex.texture = CreateTextureFromFileData(thin3d, (const uint8_t *)tex.data.data(), (int)tex.data.size(), ImageFileType::DETECT, false, info->GetTitle().c_str());
|
||||
if (tex.texture) {
|
||||
tex.timeLoaded = time_now_d();
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ void HttpImageFileView::Draw(UIContext &dc) {
|
||||
}
|
||||
|
||||
if (!textureData_.empty()) {
|
||||
texture_ = CreateTextureFromFileData(dc.GetDrawContext(), (const uint8_t *)(textureData_.data()), (int)textureData_.size(), DETECT);
|
||||
texture_ = CreateTextureFromFileData(dc.GetDrawContext(), (const uint8_t *)(textureData_.data()), (int)textureData_.size(), DETECT, false, "store_icon");
|
||||
if (!texture_)
|
||||
textureFailed_ = true;
|
||||
textureData_.clear();
|
||||
|
||||
+5
-5
@@ -92,7 +92,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty
|
||||
return *num_levels > 0;
|
||||
}
|
||||
|
||||
bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips) {
|
||||
bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name) {
|
||||
generateMips_ = generateMips;
|
||||
using namespace Draw;
|
||||
|
||||
@@ -131,7 +131,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag
|
||||
desc.depth = 1;
|
||||
desc.mipLevels = generateMips ? potentialLevels : num_levels;
|
||||
desc.generateMips = generateMips && potentialLevels > num_levels;
|
||||
desc.tag = "LoadedFileData";
|
||||
desc.tag = name;
|
||||
for (int i = 0; i < num_levels; i++) {
|
||||
desc.initData.push_back(image[i]);
|
||||
}
|
||||
@@ -152,7 +152,7 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ
|
||||
ELOG("Failed to read file '%s'", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
bool retval = LoadFromFileData(buffer, fileSize, type, generateMips);
|
||||
bool retval = LoadFromFileData(buffer, fileSize, type, generateMips, filename.c_str());
|
||||
if (retval) {
|
||||
filename_ = filename;
|
||||
} else {
|
||||
@@ -202,11 +202,11 @@ Draw::Texture *ManagedTexture::GetTexture() {
|
||||
}
|
||||
|
||||
// TODO: Remove the code duplication between this and LoadFromFileData
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType type, bool generateMips) {
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType type, bool generateMips, const char *name) {
|
||||
if (!draw)
|
||||
return std::unique_ptr<ManagedTexture>();
|
||||
ManagedTexture *mtex = new ManagedTexture(draw);
|
||||
if (mtex->LoadFromFileData(data, size, type, generateMips)) {
|
||||
if (mtex->LoadFromFileData(data, size, type, generateMips, name)) {
|
||||
return std::unique_ptr<ManagedTexture>(mtex);
|
||||
} else {
|
||||
// Best to return a null pointer if we fail!
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ public:
|
||||
}
|
||||
|
||||
bool LoadFromFile(const std::string &filename, ImageFileType type = ImageFileType::DETECT, bool generateMips = false);
|
||||
bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type = ImageFileType::DETECT, bool generateMips = false);
|
||||
bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name);
|
||||
Draw::Texture *GetTexture(); // For immediate use, don't store.
|
||||
int Width() const { return texture_->Width(); }
|
||||
int Height() const { return texture_->Height(); }
|
||||
@@ -39,8 +39,8 @@ private:
|
||||
bool loadPending_ = false;
|
||||
};
|
||||
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType fileType, bool generateMips = false);
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips = false);
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType fileType, bool generateMips);
|
||||
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips, const char *name);
|
||||
|
||||
class GameIconView : public UI::InertView {
|
||||
public:
|
||||
|
||||
@@ -447,7 +447,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
|
||||
}
|
||||
}
|
||||
|
||||
bool emitLabels = vulkan_->DeviceExtensions().EXT_debug_utils;
|
||||
bool emitLabels = vulkan_->Extensions().EXT_debug_utils;
|
||||
for (size_t i = 0; i < steps.size(); i++) {
|
||||
const VKRStep &step = *steps[i];
|
||||
|
||||
|
||||
@@ -718,6 +718,8 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) {
|
||||
if (res != VK_SUCCESS)
|
||||
return false;
|
||||
|
||||
vulkan_->SetDebugName(depth_.image, VK_OBJECT_TYPE_IMAGE, "BackbufferDepth");
|
||||
|
||||
bool dedicatedAllocation = false;
|
||||
VkMemoryRequirements mem_reqs;
|
||||
vulkan_->GetImageMemoryRequirements(depth_.image, &mem_reqs, &dedicatedAllocation);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <thread>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
#include "math/dataconv.h"
|
||||
#include "math/math_util.h"
|
||||
@@ -30,7 +31,7 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int
|
||||
|
||||
class VKRFramebuffer {
|
||||
public:
|
||||
VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height) : vulkan_(vk) {
|
||||
VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag) : vulkan_(vk) {
|
||||
width = _width;
|
||||
height = _height;
|
||||
|
||||
@@ -50,6 +51,11 @@ public:
|
||||
fbci.layers = 1;
|
||||
|
||||
vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf);
|
||||
if (vk->Extensions().EXT_debug_utils) {
|
||||
vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str());
|
||||
vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str());
|
||||
vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
~VKRFramebuffer() {
|
||||
|
||||
@@ -311,6 +311,7 @@ struct FramebufferDesc {
|
||||
int numColorAttachments;
|
||||
bool z_stencil;
|
||||
FBColorDepth colorDepth;
|
||||
const char *tag; // For graphics debuggers
|
||||
};
|
||||
|
||||
// Binary compatible with D3D11 viewport.
|
||||
@@ -536,8 +537,8 @@ struct TextureDesc {
|
||||
int depth;
|
||||
int mipLevels;
|
||||
bool generateMips;
|
||||
// Optional, for tracking memory usage.
|
||||
std::string tag;
|
||||
// Optional, for tracking memory usage and graphcis debuggers.
|
||||
const char *tag;
|
||||
// Does not take ownership over pointed-to data.
|
||||
std::vector<const uint8_t *> initData;
|
||||
TextureCallback initDataCallback;
|
||||
|
||||
@@ -714,7 +714,9 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur
|
||||
height_ = desc.height;
|
||||
depth_ = desc.depth;
|
||||
vkTex_ = new VulkanTexture(vulkan_);
|
||||
vkTex_->SetTag(desc.tag);
|
||||
if (desc.tag) {
|
||||
vkTex_->SetTag(desc.tag);
|
||||
}
|
||||
VkFormat vulkanFormat = DataFormatToVulkan(format_);
|
||||
int bpp = GetBpp(vulkanFormat);
|
||||
int bytesPerPixel = bpp / 8;
|
||||
@@ -1462,7 +1464,7 @@ private:
|
||||
|
||||
Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) {
|
||||
VkCommandBuffer cmd = renderManager_.GetInitCmd();
|
||||
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height);
|
||||
VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height, desc.tag);
|
||||
return new VKFramebuffer(vkrfb);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user