From e4649253e84a0c5e9e00a270830d4222e3281f9c Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Fri, 24 Jul 2026 14:23:55 -0300 Subject: [PATCH] add 'shaderatomics' field to love.graphics.getTextureFormats' usage table arg. Currently only r32i and r32ui are supported (on capable systems). --- src/modules/graphics/Texture.h | 14 ++++++++------ src/modules/graphics/opengl/OpenGL.cpp | 5 +++++ src/modules/graphics/vulkan/Graphics.cpp | 10 ++++++++++ src/modules/graphics/wrap_Graphics.cpp | 3 +++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 558429e2b..3a322ddad 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -60,12 +60,13 @@ enum TextureType enum PixelFormatUsage { - PIXELFORMATUSAGE_SAMPLE, // Any sampling in shaders. - PIXELFORMATUSAGE_LINEAR, // Linear filtering. - PIXELFORMATUSAGE_RENDERTARGET, // Usable as a render target. - PIXELFORMATUSAGE_BLEND, // Blend support when used as a render target. - PIXELFORMATUSAGE_MSAA, // MSAA support when used as a render target. - PIXELFORMATUSAGE_COMPUTEWRITE, // Writable in compute shaders via imageStore. + PIXELFORMATUSAGE_SAMPLE, // Any sampling in shaders. + PIXELFORMATUSAGE_LINEAR, // Linear filtering. + PIXELFORMATUSAGE_RENDERTARGET, // Usable as a render target. + PIXELFORMATUSAGE_BLEND, // Blend support when used as a render target. + PIXELFORMATUSAGE_MSAA, // MSAA support when used as a render target. + PIXELFORMATUSAGE_COMPUTEWRITE, // Writable in compute shaders via imageStore. + PIXELFORMATUSAGE_SHADERATOMICS, // Supports atomic load/store in compute shaders. PIXELFORMATUSAGE_MAX_ENUM }; @@ -78,6 +79,7 @@ enum PixelFormatUsageFlags PIXELFORMATUSAGEFLAGS_BLEND = (1 << PIXELFORMATUSAGE_BLEND), PIXELFORMATUSAGEFLAGS_MSAA = (1 << PIXELFORMATUSAGE_MSAA), PIXELFORMATUSAGEFLAGS_COMPUTEWRITE = (1 << PIXELFORMATUSAGE_COMPUTEWRITE), + PIXELFORMATUSAGEFLAGS_SHADERATOMICS = (1 << PIXELFORMATUSAGE_SHADERATOMICS), }; struct SamplerState diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index c1f627721..68b682982 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -1990,6 +1990,11 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat) case PIXELFORMAT_RGBA32_UINT: case PIXELFORMAT_RGB10A2_UINT: flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET; + if (pixelformat == PIXELFORMAT_R32_INT || pixelformat == PIXELFORMAT_R32_UINT) + { + if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_2) + flags |= PIXELFORMATUSAGEFLAGS_SHADERATOMICS; + } if (GLAD_VERSION_4_3) flags |= computewrite; if (GLAD_ES_VERSION_3_1) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 92f8eb0c0..63befa123 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1237,6 +1237,16 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, uint32 usage) return false; } + if (usage & PIXELFORMATUSAGEFLAGS_SHADERATOMICS) + { + if (!(featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) + return false; + + // TODO: supporting float formats when available may need GLSL extensions. + if (format != PIXELFORMAT_R32_INT && format != PIXELFORMAT_R32_UINT) + return false; + } + if (usage & PIXELFORMATUSAGEFLAGS_MSAA) { VkImageFormatProperties properties; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 349927c3a..d815646c2 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -3007,6 +3007,7 @@ int w_getTextureFormats(lua_State *L) bool rt = luax_checkboolflag(L, 1, Texture::getConstant(Texture::SETTING_RENDER_TARGET)); bool computewrite = luax_boolflag(L, 1, Texture::getConstant(Texture::SETTING_COMPUTE_WRITE), false); + bool shaderatomics = luax_boolflag(L, 1, "shaderatomics", false); OptionalBool readable; lua_getfield(L, 1, Texture::getConstant(Texture::SETTING_READABLE)); @@ -3034,6 +3035,8 @@ int w_getTextureFormats(lua_State *L) usage |= PIXELFORMATUSAGEFLAGS_SAMPLE; if (computewrite) usage |= PIXELFORMATUSAGEFLAGS_COMPUTEWRITE; + if (shaderatomics) + usage |= PIXELFORMATUSAGEFLAGS_SHADERATOMICS; luax_pushboolean(L, instance()->isPixelFormatSupported(format, (PixelFormatUsageFlags) usage)); lua_setfield(L, -2, name);