static int bind_ubo_locs(struct vrend_linked_shader_program *sprog,
                         int shader_type, int next_ubo_id)
{
   if (!has_feature(feat_ubo))
      return next_ubo_id;

   const struct vrend_shader_info *sinfo = &sprog->ss[shader_type]->sel->sinfo;
   if (sinfo->ubo_used_mask) {
      const char *prefix = pipe_shader_to_prefix(shader_type);

      unsigned mask = sinfo->ubo_used_mask;
      while (mask) {
         uint32_t ubo_idx = u_bit_scan(&mask);
         char name[32];
         if (sinfo->ubo_indirect)
            snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1);
         else
            snprintf(name, 32, "%subo%d", prefix, ubo_idx);

         GLuint loc = glGetUniformBlockIndex(sprog->id, name);
         glUniformBlockBinding(sprog->id, loc, next_ubo_id++);
      }
   }

   sprog->ubo_used_mask[shader_type] = sinfo->ubo_used_mask;

   return next_ubo_id;
}
static int bind_ubo_locs(struct vrend_linked_shader_program *sprog,
                         int shader_type, int next_ubo_id)
{
   if (!has_feature(feat_ubo))
      return next_ubo_id;

   const struct vrend_shader_info *sinfo = &sprog->ss[shader_type]->sel->sinfo;
   if (sinfo->ubo_used_mask) {
      const char *prefix = pipe_shader_to_prefix(shader_type);

      unsigned mask = sinfo->ubo_used_mask;
      while (mask) {
         uint32_t ubo_idx = u_bit_scan(&mask);
         char name[32];
         if (sinfo->ubo_indirect)
            snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1);
         else
            snprintf(name, 32, "%subo%d", prefix, ubo_idx);

         GLuint loc = glGetUniformBlockIndex(sprog->id, name);
         glUniformBlockBinding(sprog->id, loc, next_ubo_id++);
      }
   }

   sprog->ubo_used_mask[shader_type] = sinfo->ubo_used_mask;

   return next_ubo_id;
}