diff --git a/src/dxvk/dxvk_bind_mask.h b/src/dxvk/dxvk_bind_mask.h
index bba3b520..46d5ab29 100644
--- a/src/dxvk/dxvk_bind_mask.h
+++ b/src/dxvk/dxvk_bind_mask.h
@@ -16,9 +16,10 @@ namespace dxvk {
    * binding-related specialization constants in shaders.
    * \tparam N Number of binding slots
    */
-  class DxvkBindingMask {
+  template<uint32_t BindingCount>
+  class DxvkBindingSet {
     constexpr static uint32_t BitCount = 32;
-    constexpr static uint32_t IntCount = (MaxNumActiveBindings + BitCount - 1) / BitCount;
+    constexpr static uint32_t IntCount = (BindingCount + BitCount - 1) / BitCount;
   public:
     
     /**
@@ -27,7 +28,7 @@ namespace dxvk {
      * \param [in] slot The binding ID
      * \returns \c true if the binding is active
      */
-    bool isBound(uint32_t slot) const {
+    bool test(uint32_t slot) const {
       const uint32_t intId = slot / BitCount;
       const uint32_t bitId = slot % BitCount;
       const uint32_t bitMask = 1u << bitId;
@@ -40,7 +41,7 @@ namespace dxvk {
      * \param [in] slot The binding ID
      * \returns \c true if the state has changed
      */
-    bool setBound(uint32_t slot) {
+    bool set(uint32_t slot) {
       const uint32_t intId = slot / BitCount;
       const uint32_t bitId = slot % BitCount;
       const uint32_t bitMask = 1u << bitId;
@@ -56,7 +57,7 @@ namespace dxvk {
      * \param [in] slot The binding ID
      * \returns \c true if the state has changed
      */
-    bool setUnbound(uint32_t slot) {
+    bool clr(uint32_t slot) {
       const uint32_t intId = slot / BitCount;
       const uint32_t bitId = slot % BitCount;
       const uint32_t bitMask = 1u << bitId;
@@ -82,6 +83,8 @@ namespace dxvk {
     uint32_t m_slots[IntCount];
     
   };
+
+  using DxvkBindingMask = DxvkBindingSet<MaxNumActiveBindings>;
   
   
   /**
diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp
index 2efae089..25b1cffa 100644
--- a/src/dxvk/dxvk_compute.cpp
+++ b/src/dxvk/dxvk_compute.cpp
@@ -95,7 +95,7 @@ namespace dxvk {
     
     DxvkSpecConstants specData;
     for (uint32_t i = 0; i < m_layout->bindingCount(); i++)
-      specData.set(i, state.bsBindingMask.isBound(i), true);
+      specData.set(i, state.bsBindingMask.test(i), true);
     
     VkSpecializationInfo specInfo = specData.getSpecInfo();
     
diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp
index 35d2cf14..03c502dc 100644
--- a/src/dxvk/dxvk_context.cpp
+++ b/src/dxvk/dxvk_context.cpp
@@ -3543,7 +3543,7 @@ namespace dxvk {
       switch (binding.type) {
         case VK_DESCRIPTOR_TYPE_SAMPLER:
           if (res.sampler != nullptr) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
             
             m_descInfos[i].image.sampler     = res.sampler->handle();
             m_descInfos[i].image.imageView   = VK_NULL_HANDLE;
@@ -3551,14 +3551,14 @@ namespace dxvk {
             
             m_cmd->trackResource(res.sampler);
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].image = m_device->dummySamplerDescriptor();
           } break;
         
         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
           if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
             
             m_descInfos[i].image.sampler     = VK_NULL_HANDLE;
             m_descInfos[i].image.imageView   = res.imageView->handle(binding.view);
@@ -3570,14 +3570,14 @@ namespace dxvk {
             m_cmd->trackResource(res.imageView);
             m_cmd->trackResource(res.imageView->image());
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].image = m_device->dummyImageViewDescriptor(binding.view);
           } break;
         
         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
           if (res.sampler != nullptr && res.imageView != nullptr
            && res.imageView->handle(binding.view) != VK_NULL_HANDLE) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
 
             m_descInfos[i].image.sampler     = res.sampler->handle();
             m_descInfos[i].image.imageView   = res.imageView->handle(binding.view);
@@ -3590,14 +3590,14 @@ namespace dxvk {
             m_cmd->trackResource(res.imageView);
             m_cmd->trackResource(res.imageView->image());
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].image = m_device->dummyImageSamplerDescriptor(binding.view);
           } break;
         
         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
           if (res.bufferView != nullptr) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
             
             res.bufferView->updateView();
             m_descInfos[i].texelBuffer = res.bufferView->handle();
@@ -3605,32 +3605,32 @@ namespace dxvk {
             m_cmd->trackResource(res.bufferView);
             m_cmd->trackResource(res.bufferView->buffer());
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].texelBuffer = m_device->dummyBufferViewDescriptor();
           } break;
         
         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
           if (res.bufferSlice.defined()) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
             m_descInfos[i] = res.bufferSlice.getDescriptor();
             
             m_cmd->trackResource(res.bufferSlice.buffer());
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
           } break;
         
         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
           if (res.bufferSlice.defined()) {
-            updatePipelineState |= bindMask.setBound(i);
+            updatePipelineState |= bindMask.set(i);
             m_descInfos[i] = res.bufferSlice.getDescriptor();
             m_descInfos[i].buffer.offset = 0;
             
             m_cmd->trackResource(res.bufferSlice.buffer());
           } else {
-            updatePipelineState |= bindMask.setUnbound(i);
+            updatePipelineState |= bindMask.clr(i);
             m_descInfos[i].buffer = m_device->dummyBufferDescriptor();
           } break;
         
@@ -3992,7 +3992,7 @@ namespace dxvk {
     bool requiresBarrier = false;
 
     for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) {
-      if (m_state.cp.state.bsBindingMask.isBound(i)) {
+      if (m_state.cp.state.bsBindingMask.test(i)) {
         const DxvkDescriptorSlot binding = layout->binding(i);
         const DxvkShaderResourceSlot& slot = m_rc[binding.slot];
 
@@ -4061,7 +4061,7 @@ namespace dxvk {
     auto layout = m_state.cp.pipeline->layout();
     
     for (uint32_t i = 0; i < layout->bindingCount(); i++) {
-      if (m_state.cp.state.bsBindingMask.isBound(i)) {
+      if (m_state.cp.state.bsBindingMask.test(i)) {
         const DxvkDescriptorSlot binding = layout->binding(i);
         const DxvkShaderResourceSlot& slot = m_rc[binding.slot];
 
diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp
index 27be4767..012527af 100644
--- a/src/dxvk/dxvk_graphics.cpp
+++ b/src/dxvk/dxvk_graphics.cpp
@@ -192,7 +192,7 @@ namespace dxvk {
     specData.set(uint32_t(DxvkSpecConstantId::RasterizerSampleCount), sampleCount, VK_SAMPLE_COUNT_1_BIT);
     
     for (uint32_t i = 0; i < m_layout->bindingCount(); i++)
-      specData.set(i, state.bsBindingMask.isBound(i), true);
+      specData.set(i, state.bsBindingMask.test(i), true);
     
     for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
       if ((m_fsOut & (1 << i)) != 0) {