static void vrend_framebuffer_texture_2d(struct vrend_resource *res,
                                         GLenum target, GLenum attachment,
                                         GLenum textarget, uint32_t texture,
                                         int32_t level, uint32_t samples)
{
   if (samples == 0) {
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   } else if (!has_feature(feat_implicit_msaa)) {
      /* fallback to non-msaa */
      report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   } else if (attachment == GL_COLOR_ATTACHMENT0){
      glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
                                           texture, level, samples);
   } else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_DEPTH_ATTACHMENT) {
      GLenum internalformat =
              attachment == GL_STENCIL_ATTACHMENT ?  GL_STENCIL_INDEX8 : GL_DEPTH_COMPONENT16;

      glGenRenderbuffers(1, &res->rbo_id);
      glBindRenderbuffer(GL_RENDERBUFFER, res->rbo_id);
      glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
                                          internalformat, res->base.width0,
                                          res->base.height0);
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
                                GL_RENDERBUFFER, res->rbo_id);
      glBindRenderbuffer(GL_RENDERBUFFER, 0);
   } else {
      /* unsupported attachment for EXT_multisampled_render_to_texture, fallback to non-msaa */
      report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   }
}
static void vrend_framebuffer_texture_2d(struct vrend_resource *res,
                                         GLenum target, GLenum attachment,
                                         GLenum textarget, uint32_t texture,
                                         int32_t level, uint32_t samples)
{
   if (samples == 0) {
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   } else if (!has_feature(feat_implicit_msaa)) {
       
      report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   } else if (attachment == GL_COLOR_ATTACHMENT0){
      glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
                                           texture, level, samples);
   } else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_DEPTH_ATTACHMENT) {
      GLenum internalformat =
              attachment == GL_STENCIL_ATTACHMENT ?  GL_STENCIL_INDEX8 : GL_DEPTH_COMPONENT16;

      glGenRenderbuffers(1, &res->rbo_id);
      glBindRenderbuffer(GL_RENDERBUFFER, res->rbo_id);
      glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
                                          internalformat, res->base.width0,
                                          res->base.height0);
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
                                GL_RENDERBUFFER, res->rbo_id);
      glBindRenderbuffer(GL_RENDERBUFFER, 0);
   } else {
       
      report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
      glFramebufferTexture2D(target, attachment, textarget, texture, level);
   }
}