diff --git a/gfx/drivers_shader/glslang_util.c b/gfx/drivers_shader/glslang_util.c
index e8169cda70..4b05ec1388 100644
--- a/gfx/drivers_shader/glslang_util.c
+++ b/gfx/drivers_shader/glslang_util.c
@@ -341,3 +341,15 @@ void glslang_build_vec4(float *data, unsigned width, unsigned height)
    data[2] = 1.0f / (float)(width);
    data[3] = 1.0f / (float)(height);
 }
+
+unsigned glslang_num_miplevels(unsigned width, unsigned height)
+{
+   unsigned size   = MAX(width, height);
+   unsigned levels = 0;
+   while (size)
+   {
+      levels++;
+      size >>= 1;
+   }
+   return levels;
+}
diff --git a/gfx/drivers_shader/glslang_util.h b/gfx/drivers_shader/glslang_util.h
index c489dfe65d..90b94613f9 100644
--- a/gfx/drivers_shader/glslang_util.h
+++ b/gfx/drivers_shader/glslang_util.h
@@ -85,6 +85,8 @@ enum slang_texture_semantic slang_name_to_texture_semantic_array(
 
 void glslang_build_vec4(float *data, unsigned width, unsigned height);
 
+unsigned glslang_num_miplevels(unsigned width, unsigned height);
+
 RETRO_END_DECLS
 
 #endif
diff --git a/gfx/drivers_shader/shader_gl_core.cpp b/gfx/drivers_shader/shader_gl_core.cpp
index c8665ae66a..f8c3426f63 100644
--- a/gfx/drivers_shader/shader_gl_core.cpp
+++ b/gfx/drivers_shader/shader_gl_core.cpp
@@ -264,18 +264,6 @@ static const uint32_t opaque_frag[] =
 #include "../drivers/vulkan_shaders/opaque.frag.inc"
 ;
 
-static unsigned num_miplevels(unsigned width, unsigned height)
-{
-   unsigned size = MAX(width, height);
-   unsigned levels = 0;
-   while (size)
-   {
-      levels++;
-      size >>= 1;
-   }
-   return levels;
-}
-
 struct Texture
 {
    gl_core_filter_chain_texture texture;
@@ -584,7 +572,7 @@ void Framebuffer::init()
    if (size.height == 0)
       size.height = 1;
 
-   levels = num_miplevels(size.width, size.height);
+   levels = glslang_num_miplevels(size.width, size.height);
    if (max_levels < levels)
       levels = max_levels;
    if (levels == 0)
@@ -625,7 +613,7 @@ void Framebuffer::init()
                glGenTextures(1, &image);
                glBindTexture(GL_TEXTURE_2D, image);
 
-               levels = num_miplevels(size.width, size.height);
+               levels = glslang_num_miplevels(size.width, size.height);
                if (max_levels < levels)
                   levels = max_levels;
                glTexStorage2D(GL_TEXTURE_2D, levels,
@@ -2086,7 +2074,7 @@ static unique_ptr<gl_core_shader::StaticTexture> gl_core_filter_chain_load_lut(
    if (!image_texture_load(&image, shader->path))
       return {};
 
-   unsigned levels = shader->mipmap ? gl_core_shader::num_miplevels(image.width, image.height) : 1;
+   unsigned levels = shader->mipmap ? glslang_num_miplevels(image.width, image.height) : 1;
 
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp
index f6456b1a1d..60fb2a7538 100644
--- a/gfx/drivers_shader/shader_vulkan.cpp
+++ b/gfx/drivers_shader/shader_vulkan.cpp
@@ -431,18 +431,6 @@ struct vulkan_filter_chain
       void update_history_info();
 };
 
-static unsigned num_miplevels(unsigned width, unsigned height)
-{
-   unsigned size   = MAX(width, height);
-   unsigned levels = 0;
-   while (size)
-   {
-      levels++;
-      size >>= 1;
-   }
-   return levels;
-}
-
 static uint32_t find_memory_type_fallback(
       const VkPhysicalDeviceMemoryProperties &mem_props,
       uint32_t device_reqs, uint32_t host_reqs)
@@ -556,7 +544,7 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
    image_info.extent.height        = image.height;
    image_info.extent.depth         = 1;
    image_info.mipLevels            = shader->mipmap 
-      ? num_miplevels(image.width, image.height) : 1;
+      ? glslang_num_miplevels(image.width, image.height) : 1;
    image_info.arrayLayers          = 1;
    image_info.samples              = VK_SAMPLE_COUNT_1_BIT;
    image_info.tiling               = VK_IMAGE_TILING_OPTIMAL;
@@ -2385,7 +2373,8 @@ void Framebuffer::init(DeferredDisposer *disposer)
    info.extent.width      = size.width;
    info.extent.height     = size.height;
    info.extent.depth      = 1;
-   info.mipLevels         = min(max_levels, num_miplevels(size.width, size.height));
+   info.mipLevels         = min(max_levels,
+         glslang_num_miplevels(size.width, size.height));
    info.arrayLayers       = 1;
    info.samples           = VK_SAMPLE_COUNT_1_BIT;
    info.tiling            = VK_IMAGE_TILING_OPTIMAL;