diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/state_tracker/st_cb_clear.c | 183 | 
1 files changed, 64 insertions, 119 deletions
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index bec32db050..5bdc6a1330 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -2,6 +2,7 @@   *    * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.   * All Rights Reserved. + * Copyright 2009 VMware, Inc.  All Rights Reserved.   *    * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the @@ -29,6 +30,7 @@    * Authors:    *   Keith Whitwell <keith@tungstengraphics.com>    *   Brian Paul +  *   Michel Dänzer    */  #include "main/glheader.h" @@ -373,101 +375,6 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) -static void -clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ -   struct st_renderbuffer *strb = st_renderbuffer(rb); - -   if (!strb->surface) -      return; - -   if (check_clear_color_with_quad( ctx, rb )) { -      /* masking or scissoring */ -      clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE); -   } -   else { -      /* clear whole buffer w/out masking */ -      uint clearValue; -      /* NOTE: we always pass the clear color as PIPE_FORMAT_A8R8G8B8_UNORM -       * at this time! -       */ -      util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue); -      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); -   } -} - - -static void -clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ -   struct st_renderbuffer *strb = st_renderbuffer(rb); - -   if (!strb->surface) -      return; - -   if (check_clear_depth_with_quad(ctx, rb)) { -      /* scissoring or we have a combined depth/stencil buffer */ -      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_FALSE); -   } -   else { -      /* simple clear of whole buffer */ -      uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear); -      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); -   } -} - - -static void -clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ -   struct st_renderbuffer *strb = st_renderbuffer(rb); - -   if (!strb->surface) -      return; - -   if (check_clear_stencil_with_quad(ctx, rb)) { -      /* masking or scissoring or combined depth/stencil buffer */ -      clear_with_quad(ctx, GL_FALSE, GL_FALSE, GL_TRUE); -   } -   else { -      /* simple clear of whole buffer */ -      GLuint clearValue = ctx->Stencil.Clear; - -      switch (strb->surface->format) { -      case PIPE_FORMAT_S8Z24_UNORM: -         clearValue <<= 24; -         break; -      default: -         ; /* no-op, stencil value is in least significant bits */ -      }   - -      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); -   } -} - - -static void -clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ -   struct st_renderbuffer *strb = st_renderbuffer(rb); - -   if (!strb->surface) -      return; - -   if (check_clear_depth_stencil_with_quad(ctx, rb)) { -      /* masking or scissoring */ -      clear_with_quad(ctx, GL_FALSE, GL_TRUE, GL_TRUE); -   } -   else { -      /* clear whole buffer w/out masking */ -      GLuint clearValue = util_pack_z_stencil(strb->surface->format, -                                              ctx->Depth.Clear, -                                              ctx->Stencil.Clear); -      ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); -   } -} - -  void st_flush_clear( struct st_context *st )  {     /* Release vertex buffer to avoid synchronous rendering if we were @@ -493,51 +400,89 @@ static void st_clear(GLcontext *ctx, GLbitfield mask)        = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;     struct gl_renderbuffer *stencilRb        = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; -   GLbitfield cmask = mask & BUFFER_BITS_COLOR; +   GLbitfield quad_buffers = 0; +   GLbitfield clear_buffers = 0; +   GLuint i; -   /* This makes sure the softpipe has the latest scissor, etc values */ +   /* This makes sure the pipe has the latest scissor, etc values */     st_validate_state( st ); -   /* -    * XXX TO-DO: -    * If we're going to use clear_with_quad() for any reason, use it to -    * clear as many other buffers as possible. -    * As it is now, we sometimes call clear_with_quad() three times to clear -    * color/depth/stencil individually... -    */ +   if (mask & BUFFER_BITS_COLOR) { +      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { +         GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; -   if (cmask) { -      GLuint b; -      for (b = 0; cmask; b++) { -         if (cmask & (1 << b)) { +         if (mask & (1 << b)) {              struct gl_renderbuffer *rb                 = ctx->DrawBuffer->Attachment[b].Renderbuffer; +            struct st_renderbuffer *strb; +              assert(rb); -            clear_color_buffer(ctx, rb); -            cmask &= ~(1 << b); /* turn off bit */ + +            strb = st_renderbuffer(rb); + +            if (!strb->surface) +               continue; + +            if (check_clear_color_with_quad( ctx, rb )) +               quad_buffers |= PIPE_CLEAR_COLOR; +            else +               clear_buffers |= PIPE_CLEAR_COLOR;           } -         assert(b < BUFFER_COUNT);        }     } -   if (mask & BUFFER_BIT_ACCUM) { -      st_clear_accum_buffer(ctx, -                       ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); -   } -     if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) {        /* clearing combined depth + stencil */ -      clear_depth_stencil_buffer(ctx, depthRb); +      struct st_renderbuffer *strb = st_renderbuffer(depthRb); + +      if (strb->surface) { +         if (check_clear_depth_stencil_with_quad(ctx, depthRb)) +            quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +         else +            clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +      }     }     else {        /* separate depth/stencil clears */        if (mask & BUFFER_BIT_DEPTH) { -         clear_depth_buffer(ctx, depthRb); +         struct st_renderbuffer *strb = st_renderbuffer(depthRb); + +         if (strb->surface) { +            if (check_clear_depth_with_quad(ctx, depthRb)) +               quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +            else +               clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +         }        }        if (mask & BUFFER_BIT_STENCIL) { -         clear_stencil_buffer(ctx, stencilRb); +         struct st_renderbuffer *strb = st_renderbuffer(stencilRb); + +         if (strb->surface) { +            if (check_clear_stencil_with_quad(ctx, stencilRb)) +               quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +            else +               clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; +         }        }     } + +   /* +    * If we're going to use clear_with_quad() for any reason, use it for +    * everything possible. +    */ +   if (quad_buffers) { +      quad_buffers |= clear_buffers; +      clear_with_quad(ctx, +                      quad_buffers & PIPE_CLEAR_COLOR, +                      mask & BUFFER_BIT_DEPTH, +                      mask & BUFFER_BIT_STENCIL); +   } else if (clear_buffers) +      ctx->st->pipe->clear(ctx->st->pipe, clear_buffers, ctx->Color.ClearColor, +                           ctx->Depth.Clear, ctx->Stencil.Clear); + +   if (mask & BUFFER_BIT_ACCUM) +      st_clear_accum_buffer(ctx, +                            ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);  }  | 
