Exemplo n.º 1
0
/**
 * Implementation of up or downsampling for window-system MSAA miptrees.
 */
void
brw_meta_updownsample(struct brw_context *brw,
                      struct intel_mipmap_tree *src_mt,
                      struct intel_mipmap_tree *dst_mt)
{
   struct gl_context *ctx = &brw->ctx;
   GLuint fbos[2], src_rbo, dst_rbo, src_fbo, dst_fbo;
   GLenum drawbuffer;
   GLbitfield attachment, blit_bit;

   if (_mesa_get_format_base_format(src_mt->format) == GL_DEPTH_COMPONENT ||
       _mesa_get_format_base_format(src_mt->format) == GL_DEPTH_STENCIL) {
      attachment = GL_DEPTH_ATTACHMENT;
      drawbuffer = GL_NONE;
      blit_bit = GL_DEPTH_BUFFER_BIT;
   } else {
      attachment = GL_COLOR_ATTACHMENT0;
      drawbuffer = GL_COLOR_ATTACHMENT0;
      blit_bit = GL_COLOR_BUFFER_BIT;
   }

   brw_emit_mi_flush(brw);

   _mesa_meta_begin(ctx, MESA_META_ALL);
   _mesa_GenFramebuffers(2, fbos);
   src_rbo = brw_get_rb_for_slice(brw, src_mt, 0, 0, false);
   dst_rbo = brw_get_rb_for_slice(brw, dst_mt, 0, 0, false);
   src_fbo = fbos[0];
   dst_fbo = fbos[1];

   _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo);
   _mesa_FramebufferRenderbuffer(GL_READ_FRAMEBUFFER, attachment,
                                 GL_RENDERBUFFER, src_rbo);
   _mesa_ReadBuffer(drawbuffer);

   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo);
   _mesa_FramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, attachment,
                                 GL_RENDERBUFFER, dst_rbo);
   _mesa_DrawBuffer(drawbuffer);

   _mesa_BlitFramebuffer(0, 0,
                         src_mt->logical_width0, src_mt->logical_height0,
                         0, 0,
                         dst_mt->logical_width0, dst_mt->logical_height0,
                         blit_bit, GL_NEAREST);

   _mesa_DeleteRenderbuffers(1, &src_rbo);
   _mesa_DeleteRenderbuffers(1, &dst_rbo);
   _mesa_DeleteFramebuffers(2, fbos);

   _mesa_meta_end(ctx);

   brw_emit_mi_flush(brw);
}
Exemplo n.º 2
0
void
brw_meta_resolve_color(struct brw_context *brw,
                       struct intel_mipmap_tree *mt)
{
   struct gl_context *ctx = &brw->ctx;
   GLuint fbo, rbo;
   struct rect rect;

   intel_batchbuffer_emit_mi_flush(brw);

   _mesa_meta_begin(ctx, MESA_META_ALL);

   _mesa_GenFramebuffers(1, &fbo);
   rbo = brw_get_rb_for_slice(brw, mt, 0, 0, false);

   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
   _mesa_FramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                 GL_COLOR_ATTACHMENT0,
                                 GL_RENDERBUFFER, rbo);
   _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);

   brw_fast_clear_init(brw);

   use_rectlist(brw, true);

   brw_bind_rep_write_shader(brw, (float *) fast_clear_color);

   set_fast_clear_op(brw, GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE);

   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
   get_resolve_rect(brw, mt, &rect);

   brw_draw_rectlist(ctx, &rect, 1);

   set_fast_clear_op(brw, 0);
   use_rectlist(brw, false);

   _mesa_DeleteRenderbuffers(1, &rbo);
   _mesa_DeleteFramebuffers(1, &fbo);

   _mesa_meta_end(ctx);

   /* We're typically called from intel_update_state() and we're supposed to
    * return with the state all updated to what it was before
    * brw_meta_resolve_color() was called.  The meta rendering will have
    * messed up the state and we need to call _mesa_update_state() again to
    * get back to where we were supposed to be when resolve was called.
    */
   if (ctx->NewState)
      _mesa_update_state(ctx);
}
Exemplo n.º 3
0
/** A partial implementation of glCopyImageSubData
 *
 * This is a partial implementation of glCopyImageSubData that works only
 * if both textures are uncompressed and the destination texture is
 * renderable.  It uses a slight abuse of a texture view (see make_view) to
 * turn the source texture into the destination texture type and then uses
 * _mesa_meta_BlitFramebuffers to do the copy.
 */
bool
_mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
                                         struct gl_texture_image *src_tex_image,
                                         struct gl_renderbuffer *src_renderbuffer,
                                         int src_x, int src_y, int src_z,
                                         struct gl_texture_image *dst_tex_image,
                                         struct gl_renderbuffer *dst_renderbuffer,
                                         int dst_x, int dst_y, int dst_z,
                                         int src_width, int src_height)
{
   mesa_format src_format, dst_format;
   GLint src_internal_format, dst_internal_format;
   GLuint src_view_texture = 0;
   struct gl_texture_image *src_view_tex_image;
   GLuint fbos[2];
   bool success = false;
   GLbitfield mask;
   GLenum status, attachment;

   if (src_renderbuffer) {
      src_format = src_renderbuffer->Format;
      src_internal_format = src_renderbuffer->InternalFormat;
   } else {
      assert(src_tex_image);
      src_format = src_tex_image->TexFormat;
      src_internal_format = src_tex_image->InternalFormat;
   }

   if (dst_renderbuffer) {
      dst_format = dst_renderbuffer->Format;
      dst_internal_format = dst_renderbuffer->InternalFormat;
   } else {
      assert(dst_tex_image);
      dst_format = dst_tex_image->TexFormat;
      dst_internal_format = dst_tex_image->InternalFormat;
   }

   if (_mesa_is_format_compressed(src_format))
      return false;

   if (_mesa_is_format_compressed(dst_format))
      return false;

   if (src_internal_format == dst_internal_format) {
      src_view_tex_image = src_tex_image;
   } else {
      if (src_renderbuffer) {
         assert(src_tex_image == NULL);
         src_tex_image = wrap_renderbuffer(ctx, src_renderbuffer);
      }
      if (!make_view(ctx, src_tex_image, &src_view_tex_image, &src_view_texture,
                     dst_tex_image->InternalFormat))
         goto cleanup;
   }

   /* We really only need to stash the bound framebuffers and scissor. */
   _mesa_meta_begin(ctx, MESA_META_SCISSOR);

   _mesa_GenFramebuffers(2, fbos);
   _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);

   switch (_mesa_get_format_base_format(src_format)) {
   case GL_DEPTH_COMPONENT:
      attachment = GL_DEPTH_ATTACHMENT;
      mask = GL_DEPTH_BUFFER_BIT;
      break;
   case GL_DEPTH_STENCIL:
      attachment = GL_DEPTH_STENCIL_ATTACHMENT;
      mask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
      break;
   case GL_STENCIL_INDEX:
      attachment = GL_STENCIL_ATTACHMENT;
      mask = GL_STENCIL_BUFFER_BIT;
      break;
   default:
      attachment = GL_COLOR_ATTACHMENT0;
      mask = GL_COLOR_BUFFER_BIT;
      _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);
      _mesa_ReadBuffer(GL_COLOR_ATTACHMENT0);
   }

   if (src_view_tex_image) {
      /* Prefer the tex image because, even if we have a renderbuffer, we may
       * have had to wrap it in a texture view.
       */
      _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, attachment,
                                src_view_tex_image, src_z);
   } else {
      _mesa_FramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
                                    attachment,
                                    GL_RENDERBUFFER,
                                    src_renderbuffer->Name);
   }

   status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER);
   if (status != GL_FRAMEBUFFER_COMPLETE)
      goto meta_end;

   if (dst_renderbuffer) {
      _mesa_FramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
                                    attachment,
                                    GL_RENDERBUFFER,
                                    dst_renderbuffer->Name);
   } else {
      _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, attachment,
                                dst_tex_image, dst_z);
   }

   status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
   if (status != GL_FRAMEBUFFER_COMPLETE)
      goto meta_end;

   /* Since we've bound a new draw framebuffer, we need to update its
    * derived state -- _Xmin, etc -- for BlitFramebuffer's clipping to
    * be correct.
    */
   _mesa_update_state(ctx);

   /* We skip the core BlitFramebuffer checks for format consistency.
    * We have already created views to ensure that the texture formats
    * match.
    */
   ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
                               src_x, src_y,
                               src_x + src_width, src_y + src_height,
                               dst_x, dst_y,
                               dst_x + src_width, dst_y + src_height,
                               mask, GL_NEAREST);

   success = true;

meta_end:
   _mesa_DeleteFramebuffers(2, fbos);
   _mesa_meta_end(ctx);

cleanup:
   _mesa_DeleteTextures(1, &src_view_texture);

   /* If we got a renderbuffer source, delete the temporary texture */
   if (src_renderbuffer && src_tex_image)
      ctx->Driver.DeleteTexture(ctx, src_tex_image->TexObject);

   return success;
}