diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index aa1cc592f6..19c8ca7b2e 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -19,15 +19,6 @@ using VideoCommon::ImageId;
 constexpr u32 MAX_TEXTURES = 64;
 constexpr u32 MAX_IMAGES = 16;
 
-template <typename Range>
-u32 AccumulateCount(const Range& range) {
-    u32 num{};
-    for (const auto& desc : range) {
-        num += desc.count;
-    }
-    return num;
-}
-
 size_t ComputePipelineKey::Hash() const noexcept {
     return static_cast<size_t>(
         Common::CityHash64(reinterpret_cast<const char*>(this), sizeof *this));
@@ -58,17 +49,17 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
     std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(),
                 uniform_buffer_sizes.begin());
 
-    num_texture_buffers = AccumulateCount(info.texture_buffer_descriptors);
-    num_image_buffers = AccumulateCount(info.image_buffer_descriptors);
+    num_texture_buffers = Shader::NumDescriptors(info.texture_buffer_descriptors);
+    num_image_buffers = Shader::NumDescriptors(info.image_buffer_descriptors);
 
-    const u32 num_textures{num_texture_buffers + AccumulateCount(info.texture_descriptors)};
+    const u32 num_textures{num_texture_buffers + Shader::NumDescriptors(info.texture_descriptors)};
     ASSERT(num_textures <= MAX_TEXTURES);
 
-    const u32 num_images{num_image_buffers + AccumulateCount(info.image_descriptors)};
+    const u32 num_images{num_image_buffers + Shader::NumDescriptors(info.image_descriptors)};
     ASSERT(num_images <= MAX_IMAGES);
 
     const bool is_glasm{assembly_program.handle != 0};
-    const u32 num_storage_buffers{AccumulateCount(info.storage_buffers_descriptors)};
+    const u32 num_storage_buffers{Shader::NumDescriptors(info.storage_buffers_descriptors)};
     use_storage_buffers =
         !is_glasm || num_storage_buffers < device.GetMaxGLASMStorageBufferBlocks();
     writes_global_memory = !use_storage_buffers &&
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index bccb37a586..43ab5c03b8 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -27,6 +27,7 @@ namespace OpenGL {
 namespace {
 using Shader::ImageBufferDescriptor;
 using Shader::ImageDescriptor;
+using Shader::NumDescriptors;
 using Shader::TextureBufferDescriptor;
 using Shader::TextureDescriptor;
 using Tegra::Texture::TexturePair;
@@ -35,15 +36,6 @@ using VideoCommon::ImageId;
 constexpr u32 MAX_TEXTURES = 64;
 constexpr u32 MAX_IMAGES = 8;
 
-template <typename Range>
-u32 AccumulateCount(const Range& range) {
-    u32 num{};
-    for (const auto& desc : range) {
-        num += desc.count;
-    }
-    return num;
-}
-
 GLenum Stage(size_t stage_index) {
     switch (stage_index) {
     case 0:
@@ -204,23 +196,23 @@ GraphicsPipeline::GraphicsPipeline(
             base_uniform_bindings[stage + 1] = base_uniform_bindings[stage];
             base_storage_bindings[stage + 1] = base_storage_bindings[stage];
 
-            base_uniform_bindings[stage + 1] += AccumulateCount(info.constant_buffer_descriptors);
-            base_storage_bindings[stage + 1] += AccumulateCount(info.storage_buffers_descriptors);
+            base_uniform_bindings[stage + 1] += NumDescriptors(info.constant_buffer_descriptors);
+            base_storage_bindings[stage + 1] += NumDescriptors(info.storage_buffers_descriptors);
         }
         enabled_uniform_buffer_masks[stage] = info.constant_buffer_mask;
         std::ranges::copy(info.constant_buffer_used_sizes, uniform_buffer_sizes[stage].begin());
 
-        const u32 num_tex_buffer_bindings{AccumulateCount(info.texture_buffer_descriptors)};
+        const u32 num_tex_buffer_bindings{NumDescriptors(info.texture_buffer_descriptors)};
         num_texture_buffers[stage] += num_tex_buffer_bindings;
         num_textures += num_tex_buffer_bindings;
 
-        const u32 num_img_buffers_bindings{AccumulateCount(info.image_buffer_descriptors)};
+        const u32 num_img_buffers_bindings{NumDescriptors(info.image_buffer_descriptors)};
         num_image_buffers[stage] += num_img_buffers_bindings;
         num_images += num_img_buffers_bindings;
 
-        num_textures += AccumulateCount(info.texture_descriptors);
-        num_images += AccumulateCount(info.image_descriptors);
-        num_storage_buffers += AccumulateCount(info.storage_buffers_descriptors);
+        num_textures += NumDescriptors(info.texture_descriptors);
+        num_images += NumDescriptors(info.image_descriptors);
+        num_storage_buffers += NumDescriptors(info.storage_buffers_descriptors);
 
         writes_global_memory |= std::ranges::any_of(
             info.storage_buffers_descriptors, [](const auto& desc) { return desc.is_written; });
@@ -423,13 +415,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
                 add_buffer(desc);
             }
         }
-        for (const auto& desc : info.texture_descriptors) {
-            texture_buffer_index += desc.count;
-        }
+        texture_buffer_index += Shader::NumDescriptors(info.texture_descriptors);
         if constexpr (Spec::has_images) {
-            for (const auto& desc : info.image_descriptors) {
-                texture_buffer_index += desc.count;
-            }
+            texture_buffer_index += Shader::NumDescriptors(info.image_descriptors);
         }
     }};
     if constexpr (Spec::enabled_stages[0]) {
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 02682bd764..42ef67628d 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -426,16 +426,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
             // Normal path
             programs[index] = TranslateProgram(pools.inst, pools.block, env, cfg, host_info);
 
-            for (const auto& desc : programs[index].info.storage_buffers_descriptors) {
-                total_storage_buffers += desc.count;
-            }
+            total_storage_buffers +=
+                Shader::NumDescriptors(programs[index].info.storage_buffers_descriptors);
         } else {
             // VertexB path when VertexA is present.
             auto& program_va{programs[0]};
             auto program_vb{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
-            for (const auto& desc : program_vb.info.storage_buffers_descriptors) {
-                total_storage_buffers += desc.count;
-            }
+            total_storage_buffers +=
+                Shader::NumDescriptors(program_vb.info.storage_buffers_descriptors);
             programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
         }
     }
@@ -510,10 +508,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
     Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
     auto program{TranslateProgram(pools.inst, pools.block, env, cfg, host_info)};
 
-    u32 num_storage_buffers{};
-    for (const auto& desc : program.info.storage_buffers_descriptors) {
-        num_storage_buffers += desc.count;
-    }
+    const u32 num_storage_buffers{Shader::NumDescriptors(program.info.storage_buffers_descriptors)};
     Shader::RuntimeInfo info;
     info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();