static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
                                      int shader_type, int next_ubo_id)
{
   uint32_t mask, dirty, update;
   struct pipe_constant_buffer *cb;
   struct vrend_resource *res;

   if (!has_feature(feat_ubo))
      return next_ubo_id;

   mask = ctx->sub->prog->ubo_used_mask[shader_type];
   dirty = ctx->sub->const_bufs_dirty[shader_type];
   update = dirty & ctx->sub->const_bufs_used_mask[shader_type];

   if (!update)
      return next_ubo_id + util_bitcount(mask);

   while (mask) {
      /* The const_bufs_used_mask stores the gallium uniform buffer indices */
      int i = u_bit_scan(&mask);

      if (update & (1 << i)) {
         /* The cbs array is indexed using the gallium uniform buffer index */
         cb = &ctx->sub->cbs[shader_type][i];
         res = (struct vrend_resource *)cb->buffer;

         glBindBufferRange(GL_UNIFORM_BUFFER, next_ubo_id, res->id,
                           cb->buffer_offset, cb->buffer_size);
         dirty &= ~(1 << i);
      }
      next_ubo_id++;
   }
   ctx->sub->const_bufs_dirty[shader_type] = dirty;

   return next_ubo_id;
}
static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
                                      int shader_type, int next_ubo_id)
{
   uint32_t mask, dirty, update;
   struct pipe_constant_buffer *cb;
   struct vrend_resource *res;

   if (!has_feature(feat_ubo))
      return next_ubo_id;

   mask = ctx->sub->prog->ubo_used_mask[shader_type];
   dirty = ctx->sub->const_bufs_dirty[shader_type];
   update = dirty & ctx->sub->const_bufs_used_mask[shader_type];

   if (!update)
      return next_ubo_id + util_bitcount(mask);

   while (mask) {
       
      int i = u_bit_scan(&mask);

      if (update & (1 << i)) {
          
         cb = &ctx->sub->cbs[shader_type][i];
         res = (struct vrend_resource *)cb->buffer;

         glBindBufferRange(GL_UNIFORM_BUFFER, next_ubo_id, res->id,
                           cb->buffer_offset, cb->buffer_size);
         dirty &= ~(1 << i);
      }
      next_ubo_id++;
   }
   ctx->sub->const_bufs_dirty[shader_type] = dirty;

   return next_ubo_id;
}