diff --git a/src/modules/graphics/Buffer.cpp b/src/modules/graphics/Buffer.cpp index 3ebbc61d1..9345859c6 100644 --- a/src/modules/graphics/Buffer.cpp +++ b/src/modules/graphics/Buffer.cpp @@ -38,6 +38,7 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vectorimmutable = immutable; }; bool isImmutable() const { return immutable; } @@ -184,6 +188,8 @@ class Buffer : public love::Object, public Resource // 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..a6f3936ee 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -178,6 +178,7 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices) , requestedMSAA(settings.msaa > 1 ? settings.msaa : 0) , samplerState() , graphicsMemorySize(0) + , debugName(settings.debugName) { const auto &caps = gfx->getCapabilities(); int requestedMipmapCount = settings.mipmapCount; @@ -975,6 +976,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..b9d156c95 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -175,6 +175,7 @@ class Texture : public Drawable, public Resource SETTING_RENDER_TARGET, SETTING_COMPUTE_WRITE, SETTING_READABLE, + SETTING_DEBUGNAME, SETTING_MAX_ENUM }; @@ -194,6 +195,7 @@ class Texture : public Drawable, public Resource bool renderTarget = false; bool computeWrite = false; OptionalBool readable; + std::string debugName; }; struct Slices @@ -288,6 +290,8 @@ class Texture : public Drawable, public Resource Quad *getQuad() const; + const std::string &getDebugName() const { return debugName; } + static int getTotalMipmapCount(int w, int h); static int getTotalMipmapCount(int w, int h, int d); @@ -343,6 +347,8 @@ class Texture : public Drawable, public Resource int64 graphicsMemorySize; + std::string debugName; + }; // Texture } // graphics diff --git a/src/modules/graphics/opengl/Buffer.cpp b/src/modules/graphics/opengl/Buffer.cpp index 787caf630..be437d3ec 100644 --- a/src/modules/graphics/opengl/Buffer.cpp +++ b/src/modules/graphics/opengl/Buffer.cpp @@ -164,6 +164,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/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index 8a9ad9655..9343a9f68 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -422,6 +422,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..321f7b21c 100644 --- a/src/modules/graphics/opengl/Texture.h +++ b/src/modules/graphics/opengl/Texture.h @@ -78,7 +78,6 @@ class Texture final : public love::graphics::Texture, public Volatile GLenum textureGLError; int actualSamples; - }; // Texture } // opengl diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 6a6226db1..48c89deac 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -108,6 +108,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_BUFFER; + nameInfo.objectHandle = (uint64_t)buffer; + nameInfo.pObjectName = debugName.c_str(); + vkSetDebugUtilsObjectNameEXT(device, &nameInfo); + } + return true; } diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index c3a7c5c73..d3ca164f1 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..b4173c009 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 @@ class Graphics final : public love::graphics::Graphics 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..7a02b0224 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -201,6 +201,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/wrap_Buffer.cpp b/src/modules/graphics/wrap_Buffer.cpp index d4073d6e0..e020c1ae4 100644 --- a/src/modules/graphics/wrap_Buffer.cpp +++ b/src/modules/graphics/wrap_Buffer.cpp @@ -413,6 +413,17 @@ static int w_Buffer_isBufferType(lua_State *L) return 1; } +static int w_Buffer_getDebugName(lua_State *L) +{ + Buffer *t = luax_checkbuffer(L, 1); + const std::string &debugName = t->getDebugName(); + if (debugName.empty()) + lua_pushnil(L); + else + luax_pushstring(L, debugName); + return 1; +} + static const luaL_Reg w_Buffer_functions[] = { { "setArrayData", w_Buffer_setArrayData }, @@ -422,6 +433,7 @@ static const luaL_Reg w_Buffer_functions[] = { "getSize", w_Buffer_getSize }, { "getFormat", w_Buffer_getFormat }, { "isBufferType", w_Buffer_isBufferType }, + { "getDebugName", w_Buffer_getDebugName }, { 0, 0 } }; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 27338cdc6..bc92aa97e 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)) { @@ -1570,6 +1577,11 @@ 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_pop(L, 1); + + lua_getfield(L, idx, "debugname"); + if (!lua_isnoneornil(L, -1)) + settings.debugName = luax_checkstring(L, -1); + lua_pop(L, 1); } static Buffer::DataDeclaration luax_checkdatadeclaration(lua_State* L, int formattableidx, int arrayindex, int declindex, bool requirename) diff --git a/src/modules/graphics/wrap_Texture.cpp b/src/modules/graphics/wrap_Texture.cpp index 00f6058af..8198d9a57 100644 --- a/src/modules/graphics/wrap_Texture.cpp +++ b/src/modules/graphics/wrap_Texture.cpp @@ -474,6 +474,17 @@ int w_Texture_renderTo(lua_State *L) return 0; } +static int w_Texture_getDebugName(lua_State *L) +{ + Texture *t = luax_checktexture(L, 1); + const std::string &debugName = t->getDebugName(); + if (debugName.empty()) + lua_pushnil(L); + else + luax_pushstring(L, debugName); + return 1; +} + const luaL_Reg w_Texture_functions[] = { { "getTextureType", w_Texture_getTextureType }, @@ -506,6 +517,7 @@ const luaL_Reg w_Texture_functions[] = { "generateMipmaps", w_Texture_generateMipmaps }, { "replacePixels", w_Texture_replacePixels }, { "renderTo", w_Texture_renderTo }, + { "getDebugName", w_Texture_getDebugName }, // Deprecated { "newImageData", w_Texture_newImageData },