diff options
Diffstat (limited to 'src/mesa/drivers/common')
| -rw-r--r-- | src/mesa/drivers/common/meta.c | 120 | ||||
| -rw-r--r-- | src/mesa/drivers/common/meta.h | 1 | 
2 files changed, 96 insertions, 25 deletions
| diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 8ed6479e34..ec0da71fb9 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -43,6 +43,7 @@  #include "main/macros.h"  #include "main/matrix.h"  #include "main/polygon.h" +#include "main/readpix.h"  #include "main/scissor.h"  #include "main/shaders.h"  #include "main/stencil.h" @@ -83,8 +84,8 @@ struct save_state     /** META_FOG */     GLboolean Fog; -   /** META_PIXELSTORE */ -   /* XXX / TO-DO */ +   /** META_PIXEL_STORE */ +   struct gl_pixelstore_attrib Pack, Unpack;     /** META_RASTERIZATION */     GLenum FrontPolygonMode, BackPolygonMode; @@ -143,6 +144,7 @@ struct blit_state  {     GLuint ArrayObj;     GLuint VBO; +   GLuint DepthFP;  }; @@ -244,29 +246,26 @@ _mesa_meta_free(GLcontext *ctx)         * still get freed by _mesa_free_context_data().         */ -      if (meta->TempTex.TexObj) { -         _mesa_DeleteTextures(1, &meta->TempTex.TexObj); -      } +      _mesa_DeleteTextures(1, &meta->TempTex.TexObj); -      if (meta->Blit.VBO) { -         _mesa_DeleteBuffersARB(1, & meta->Blit.VBO); -         _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj); -      } +      /* glBlitFramebuffer */ +      _mesa_DeleteBuffersARB(1, & meta->Blit.VBO); +      _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj); +      _mesa_DeletePrograms(1, &meta->Blit.DepthFP); -      if (meta->Clear.VBO) { -         _mesa_DeleteBuffersARB(1, & meta->Clear.VBO); -         _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj); -      } +      /* glClear */ +      _mesa_DeleteBuffersARB(1, & meta->Clear.VBO); +      _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj); -      if (meta->CopyPix.VBO) { -         _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO); -         _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj); -      } +      /* glCopyPixels */ +      _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO); +      _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj); -      if (meta->DrawPix.VBO) { -         _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO); -         _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj); -      } +      /* glDrawPixels */ +      _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO); +      _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj); +      _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP); +      _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);     }     _mesa_free(ctx->Meta); @@ -324,6 +323,13 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state)           _mesa_set_enable(ctx, GL_FOG, GL_FALSE);     } +   if (state & META_PIXEL_STORE) { +      save->Pack = ctx->Pack; +      save->Unpack = ctx->Unpack; +      ctx->Pack = ctx->DefaultPacking; +      ctx->Unpack = ctx->DefaultPacking; +   } +     if (state & META_RASTERIZATION) {        save->FrontPolygonMode = ctx->Polygon.FrontMode;        save->BackPolygonMode = ctx->Polygon.BackMode; @@ -514,6 +520,11 @@ _mesa_meta_end(GLcontext *ctx)        _mesa_set_enable(ctx, GL_FOG, save->Fog);     } +   if (state & META_PIXEL_STORE) { +      ctx->Pack = save->Pack; +      ctx->Unpack = save->Unpack; +   } +     if (state & META_RASTERIZATION) {        _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);        _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); @@ -861,6 +872,38 @@ setup_drawpix_texture(struct temp_texture *tex,  /** + * One-time init for drawing depth pixels. + */ +static void +init_blit_depth_pixels(GLcontext *ctx) +{ +   static const char *program = +      "!!ARBfp1.0\n" +      "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" +      "END \n"; +   char program2[200]; +   struct blit_state *blit = &ctx->Meta->Blit; +   struct temp_texture *tex = get_temp_texture(ctx); +   const char *texTarget; + +   assert(blit->DepthFP == 0); + +   /* replace %s with "RECT" or "2D" */ +   assert(strlen(program) + 4 < sizeof(program2)); +   if (tex->Target == GL_TEXTURE_RECTANGLE) +      texTarget = "RECT"; +   else +      texTarget = "2D"; +   _mesa_snprintf(program2, sizeof(program2), program, texTarget); + +   _mesa_GenPrograms(1, &blit->DepthFP); +   _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); +   _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, +                          strlen(program2), (const GLubyte *) program2); +} + + +/**   * Meta implementation of ctx->Driver.BlitFramebuffer() in terms   * of texture mapping and polygon rendering.   */ @@ -964,9 +1007,36 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,        _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);        mask &= ~GL_COLOR_BUFFER_BIT;     } +     if (mask & GL_DEPTH_BUFFER_BIT) { -      /* XXX todo (need fragment shader) */ +      GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint)); +      if (tmp) { +         if (!blit->DepthFP) +            init_blit_depth_pixels(ctx); + +         /* maybe change tex format here */ +         newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT); + +         _mesa_ReadPixels(srcX, srcY, srcW, srcH, +                          GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); + +         setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH, +                               GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); + +         _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); +         _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); +         _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); +         _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); +         _mesa_DepthFunc(GL_ALWAYS); +         _mesa_DepthMask(GL_TRUE); + +         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); +         mask &= ~GL_DEPTH_BUFFER_BIT; + +         _mesa_free(tmp); +      }     } +     if (mask & GL_STENCIL_BUFFER_BIT) {        /* XXX can't easily do stencil */     } @@ -975,8 +1045,7 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,     _mesa_meta_end(ctx); -   /* XXX, TO-DO: try to handle these cases above! */ -   if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) { +   if (mask) {        _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,                                dstX0, dstY0, dstX1, dstY1, mask, filter);     } @@ -991,7 +1060,8 @@ _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)  {     struct clear_state *clear = &ctx->Meta->Clear;     GLfloat verts[4][7]; /* four verts of X,Y,Z,R,G,B,A */ -   GLbitfield metaSave = META_ALL - META_SCISSOR; /* all but scissor */ +   /* save all state but scissor, pixel pack/unpack */ +   GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;     if (buffers & BUFFER_BITS_COLOR) {        /* if clearing color buffers, don't save/restore colormask */ diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h index a9c5f98043..b03b64c48a 100644 --- a/src/mesa/drivers/common/meta.h +++ b/src/mesa/drivers/common/meta.h @@ -45,6 +45,7 @@  #define META_TEXTURE       0x400  #define META_VERTEX        0x800  #define META_VIEWPORT     0x1000 +#define META_PIXEL_STORE  0x2000  #define META_ALL            ~0x0  /*@}*/ | 
