diff --git a/src/modules/graphics/Buffer.h b/src/modules/graphics/Buffer.h index 5ca409413..8c98d2b49 100644 --- a/src/modules/graphics/Buffer.h +++ b/src/modules/graphics/Buffer.h @@ -89,6 +89,7 @@ public: BufferUsageFlags usageFlags; BufferDataUsage dataUsage; bool zeroInitialize; + std::string debugName; Settings(uint32 usageflags, BufferDataUsage dataUsage) : usageFlags((BufferUsageFlags)usageflags) @@ -184,6 +185,8 @@ protected: // Usage hint. GL_[DYNAMIC, STATIC, STREAM]_DRAW. BufferDataUsage dataUsage; + std::string debugName; + bool mapped; MapType mappedType; bool immutable; diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 2071ce6f1..0e329c744 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -975,6 +975,7 @@ static StringMap::Entry setting { "canvas", Texture::SETTING_RENDER_TARGET }, { "computewrite", Texture::SETTING_COMPUTE_WRITE }, { "readable", Texture::SETTING_READABLE }, + { "debugname", Texture::SETTING_DEBUGNAME }, }; static StringMap settingTypes(settingTypeEntries, sizeof(settingTypeEntries)); diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 56fda383e..15f413ea7 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -175,6 +175,7 @@ public: SETTING_RENDER_TARGET, SETTING_COMPUTE_WRITE, SETTING_READABLE, + SETTING_DEBUGNAME, SETTING_MAX_ENUM }; @@ -194,6 +195,7 @@ public: bool renderTarget = false; bool computeWrite = false; OptionalBool readable; + std::string debugName; }; struct Slices diff --git a/src/modules/graphics/opengl/Buffer.cpp b/src/modules/graphics/opengl/Buffer.cpp index 787caf630..3222a6cd7 100644 --- a/src/modules/graphics/opengl/Buffer.cpp +++ b/src/modules/graphics/opengl/Buffer.cpp @@ -68,6 +68,7 @@ static GLenum getGLFormat(DataFormat format) Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) : love::graphics::Buffer(gfx, settings, format, size, arraylength) + , debugName(settings.debugName) { size = getSize(); arraylength = getArrayLength(); @@ -164,6 +165,9 @@ bool Buffer::load(const void *initialdata) glTexBuffer(target, glformat, buffer); } + if (!debugName.empty()) + glObjectLabel(GL_BUFFER, buffer, -1, debugName.c_str()); + return (glGetError() == GL_NO_ERROR); } diff --git a/src/modules/graphics/opengl/Buffer.h b/src/modules/graphics/opengl/Buffer.h index acee82aa7..001fedbe2 100644 --- a/src/modules/graphics/opengl/Buffer.h +++ b/src/modules/graphics/opengl/Buffer.h @@ -81,6 +81,8 @@ private: Range mappedRange; + std::string debugName; + }; // Buffer } // opengl diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index 8a9ad9655..7b38707e1 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -227,6 +227,7 @@ Texture::Texture(love::graphics::Graphics *gfx, const Settings &settings, const , framebufferStatus(GL_FRAMEBUFFER_COMPLETE) , textureGLError(GL_NO_ERROR) , actualSamples(1) + , debugName(settings.debugName) { if (data != nullptr) slices = *data; @@ -422,6 +423,14 @@ bool Texture::loadVolatile() setGraphicsMemorySize(memsize); + if (!debugName.empty()) + { + if (texture) + glObjectLabel(GL_TEXTURE, texture, -1, debugName.c_str()); + else + glObjectLabel(GL_FRAMEBUFFER, renderbuffer, -1, debugName.c_str()); + } + return true; } diff --git a/src/modules/graphics/opengl/Texture.h b/src/modules/graphics/opengl/Texture.h index 8ee52db9c..5ad41f41d 100644 --- a/src/modules/graphics/opengl/Texture.h +++ b/src/modules/graphics/opengl/Texture.h @@ -79,6 +79,8 @@ private: int actualSamples; + std::string debugName; + }; // Texture } // opengl diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 6a6226db1..6a3f5c963 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -58,6 +58,7 @@ static VkBufferUsageFlags getVulkanUsageFlags(BufferUsageFlags flags) Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) : love::graphics::Buffer(gfx, settings, format, size, arraylength) , zeroInitialize(settings.zeroInitialize) + , debugName(settings.debugName) , initialData(data) , vgfx(dynamic_cast(gfx)) , usageFlags(settings.usageFlags) @@ -108,6 +109,18 @@ bool Buffer::loadVolatile() else coherent = false; + if (!debugName.empty() && vgfx->getEnabledOptionalInstanceExtensions().debugInfo) + { + auto device = vgfx->getDevice(); + + VkDebugUtilsObjectNameInfoEXT nameInfo{}; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.objectType = VK_OBJECT_TYPE_IMAGE; + nameInfo.objectHandle = (uint64_t)buffer; + nameInfo.pObjectName = debugName.c_str(); + vkSetDebugUtilsObjectNameEXT(device, &nameInfo); + } + return true; } diff --git a/src/modules/graphics/vulkan/Buffer.h b/src/modules/graphics/vulkan/Buffer.h index e6dd674b3..c717a7708 100644 --- a/src/modules/graphics/vulkan/Buffer.h +++ b/src/modules/graphics/vulkan/Buffer.h @@ -71,6 +71,7 @@ private: BufferUsageFlags usageFlags; Range mappedRange; bool coherent; + std::string debugName; }; } // vulkan diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index c3a7c5c73..7b9c7938f 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -89,6 +89,8 @@ static void checkOptionalInstanceExtensions(OptionalInstanceExtensions& ext) { if (strcmp(extension.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0) ext.physicalDeviceProperties2 = true; + if (strcmp(extension.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) + ext.debugInfo = true; } } @@ -127,6 +129,8 @@ Graphics::Graphics() if (optionalInstanceExtensions.physicalDeviceProperties2) extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + if (optionalInstanceExtensions.debugInfo) + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); size_t additional_extension_count = extensions.size(); extensions.resize(additional_extension_count + count); @@ -1399,6 +1403,11 @@ const OptionalDeviceExtensions &Graphics::getEnabledOptionalDeviceExtensions() c return optionalDeviceExtensions; } +const OptionalInstanceExtensions& Graphics::getEnabledOptionalInstanceExtensions() const +{ + return optionalInstanceExtensions; +} + bool Graphics::checkValidationSupport() { uint32_t layerCount; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index e2ae0541b..fb7f9d6fb 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -144,6 +144,9 @@ struct OptionalInstanceExtensions { // VK_KHR_get_physical_device_properties2 bool physicalDeviceProperties2 = false; + + // VK_EXT_debug_info + bool debugInfo = false; }; struct OptionalDeviceExtensions @@ -318,6 +321,7 @@ public: void setComputeShader(Shader *computeShader); graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData(); const OptionalDeviceExtensions &getEnabledOptionalDeviceExtensions() const; + const OptionalInstanceExtensions& getEnabledOptionalInstanceExtensions() const; VkSampleCountFlagBits getMsaaCount(int requestedMsaa) const; void setVsync(int vsync); int getVsync() const; diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index b5edc0851..afaf70f6b 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -34,6 +34,7 @@ namespace vulkan Texture::Texture(love::graphics::Graphics *gfx, const Settings &settings, const Slices *data) : love::graphics::Texture(gfx, settings, data) , vgfx(dynamic_cast(gfx)) + , debugName(settings.debugName) , slices(settings.type) , imageAspect(0) { @@ -201,6 +202,19 @@ bool Texture::loadVolatile() setGraphicsMemorySize(memsize); + if (!debugName.empty()) + { + if (vgfx->getEnabledOptionalInstanceExtensions().debugInfo) + { + VkDebugUtilsObjectNameInfoEXT nameInfo{}; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.objectType = VK_OBJECT_TYPE_IMAGE; + nameInfo.objectHandle = (uint64_t)textureImage; + nameInfo.pObjectName = debugName.c_str(); + vkSetDebugUtilsObjectNameEXT(device, &nameInfo); + } + } + return true; } diff --git a/src/modules/graphics/vulkan/Texture.h b/src/modules/graphics/vulkan/Texture.h index 571621a05..63684da3b 100644 --- a/src/modules/graphics/vulkan/Texture.h +++ b/src/modules/graphics/vulkan/Texture.h @@ -85,6 +85,7 @@ private: Slices slices; int layerCount = 0; VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT; + std::string debugName; }; } // vulkan diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 27338cdc6..9c1ec4355 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -738,6 +738,13 @@ static void luax_checktexturesettings(lua_State *L, int idx, bool opt, bool chec if (!forceRenderTarget.hasValue) s.renderTarget = luax_boolflag(L, idx, Texture::getConstant(Texture::SETTING_RENDER_TARGET), s.renderTarget); + lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_DEBUGNAME)); + if (!lua_isnoneornil(L, -1)) + { + s.debugName = luaL_checkstring(L, -1); + } + lua_pop(L, 1); + lua_getfield(L, idx, Texture::getConstant(Texture::SETTING_FORMAT)); if (!lua_isnoneornil(L, -1)) { @@ -1569,6 +1576,10 @@ static void luax_optbuffersettings(lua_State *L, int idx, Buffer::Settings &sett lua_getfield(L, idx, "usage"); settings.dataUsage = luax_optdatausage(L, -1, settings.dataUsage); + + lua_getfield(L, idx, "debugname"); + settings.debugName = luax_checkstring(L, -1); + lua_pop(L, 1); }