Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  /*
  29.   * Authors:
  30.   *   Brian Paul
  31.   */
  32.  
  33. #include "main/imports.h"
  34. #include "main/image.h"
  35. #include "main/macros.h"
  36.  
  37. #include "st_context.h"
  38. #include "st_texture.h"
  39. #include "st_cb_blit.h"
  40. #include "st_cb_fbo.h"
  41.  
  42. #include "util/u_blit.h"
  43. #include "util/u_inlines.h"
  44.  
  45.  
  46. void
  47. st_init_blit(struct st_context *st)
  48. {
  49.    st->blit = util_create_blit(st->pipe, st->cso_context);
  50. }
  51.  
  52.  
  53. void
  54. st_destroy_blit(struct st_context *st)
  55. {
  56.    util_destroy_blit(st->blit);
  57.    st->blit = NULL;
  58. }
  59.  
  60.  
  61. #if FEATURE_EXT_framebuffer_blit
  62.  
  63. static void
  64. st_BlitFramebuffer(struct gl_context *ctx,
  65.                    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  66.                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  67.                    GLbitfield mask, GLenum filter)
  68. {
  69.    const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
  70.                                     GL_STENCIL_BUFFER_BIT);
  71.    struct st_context *st = st_context(ctx);
  72.    const uint pFilter = ((filter == GL_NEAREST)
  73.                          ? PIPE_TEX_MIPFILTER_NEAREST
  74.                          : PIPE_TEX_MIPFILTER_LINEAR);
  75.    struct gl_framebuffer *readFB = ctx->ReadBuffer;
  76.    struct gl_framebuffer *drawFB = ctx->DrawBuffer;
  77.  
  78.    if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
  79.                         &dstX0, &dstY0, &dstX1, &dstY1)) {
  80.       return; /* nothing to draw/blit */
  81.    }
  82.  
  83.    if (st_fb_orientation(drawFB) == Y_0_TOP) {
  84.       /* invert Y for dest */
  85.       dstY0 = drawFB->Height - dstY0;
  86.       dstY1 = drawFB->Height - dstY1;
  87.    }
  88.  
  89.    if (st_fb_orientation(readFB) == Y_0_TOP) {
  90.       /* invert Y for src */
  91.       srcY0 = readFB->Height - srcY0;
  92.       srcY1 = readFB->Height - srcY1;
  93.    }
  94.  
  95.    if (srcY0 > srcY1 && dstY0 > dstY1) {
  96.       /* Both src and dst are upside down.  Swap Y to make it
  97.        * right-side up to increase odds of using a fast path.
  98.        * Recall that all Gallium raster coords have Y=0=top.
  99.        */
  100.       GLint tmp;
  101.       tmp = srcY0;
  102.       srcY0 = srcY1;
  103.       srcY1 = tmp;
  104.       tmp = dstY0;
  105.       dstY0 = dstY1;
  106.       dstY1 = tmp;
  107.    }
  108.  
  109.    if (mask & GL_COLOR_BUFFER_BIT) {
  110.       struct gl_renderbuffer_attachment *srcAtt =
  111.          &readFB->Attachment[readFB->_ColorReadBufferIndex];
  112.  
  113.       if(srcAtt->Type == GL_TEXTURE) {
  114.          struct st_texture_object *srcObj =
  115.             st_texture_object(srcAtt->Texture);
  116.          struct st_renderbuffer *dstRb =
  117.             st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
  118.          struct pipe_surface *dstSurf = dstRb->surface;
  119.  
  120.          if (!srcObj->pt)
  121.             return;
  122.  
  123.          util_blit_pixels(st->blit, srcObj->pt, srcAtt->TextureLevel,
  124.                           srcX0, srcY0, srcX1, srcY1,
  125.                           srcAtt->Zoffset + srcAtt->CubeMapFace,
  126.                           dstSurf, dstX0, dstY0, dstX1, dstY1,
  127.                           0.0, pFilter);
  128.       }
  129.       else {
  130.          struct st_renderbuffer *srcRb =
  131.             st_renderbuffer(readFB->_ColorReadBuffer);
  132.          struct st_renderbuffer *dstRb =
  133.             st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
  134.          struct pipe_surface *srcSurf = srcRb->surface;
  135.          struct pipe_surface *dstSurf = dstRb->surface;
  136.  
  137.          util_blit_pixels(st->blit,
  138.                           srcRb->texture, srcSurf->u.tex.level,
  139.                           srcX0, srcY0, srcX1, srcY1,
  140.                           srcSurf->u.tex.first_layer,
  141.                           dstSurf, dstX0, dstY0, dstX1, dstY1,
  142.                           0.0, pFilter);
  143.       }
  144.    }
  145.  
  146.    if (mask & depthStencil) {
  147.       /* depth and/or stencil blit */
  148.  
  149.       /* get src/dst depth surfaces */
  150.       struct gl_renderbuffer_attachment *srcDepth =
  151.          &readFB->Attachment[BUFFER_DEPTH];
  152.       struct gl_renderbuffer_attachment *dstDepth =
  153.          &drawFB->Attachment[BUFFER_DEPTH];
  154.       struct gl_renderbuffer_attachment *srcStencil =
  155.          &readFB->Attachment[BUFFER_STENCIL];
  156.       struct gl_renderbuffer_attachment *dstStencil =
  157.          &drawFB->Attachment[BUFFER_STENCIL];
  158.  
  159.       struct st_renderbuffer *srcDepthRb =
  160.          st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
  161.       struct st_renderbuffer *dstDepthRb =
  162.          st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
  163.       struct pipe_surface *dstDepthSurf =
  164.          dstDepthRb ? dstDepthRb->surface : NULL;
  165.  
  166.       if ((mask & depthStencil) == depthStencil &&
  167.           st_is_depth_stencil_combined(srcDepth, srcStencil) &&
  168.           st_is_depth_stencil_combined(dstDepth, dstStencil)) {
  169.  
  170.          /* Blitting depth and stencil values between combined
  171.           * depth/stencil buffers.  This is the ideal case for such buffers.
  172.           */
  173.          util_blit_pixels(st->blit,
  174.                           srcDepthRb->texture,
  175.                           srcDepthRb->surface->u.tex.level,
  176.                           srcX0, srcY0, srcX1, srcY1,
  177.                           srcDepthRb->surface->u.tex.first_layer,
  178.                           dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
  179.                           0.0, pFilter);
  180.       }
  181.       else {
  182.          /* blitting depth and stencil separately */
  183.  
  184.          if (mask & GL_DEPTH_BUFFER_BIT) {
  185.             util_blit_pixels(st->blit, srcDepthRb->texture,
  186.                              srcDepthRb->surface->u.tex.level,
  187.                              srcX0, srcY0, srcX1, srcY1,
  188.                              srcDepthRb->surface->u.tex.first_layer,
  189.                              dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
  190.                              0.0, pFilter);
  191.          }
  192.  
  193.          if (mask & GL_STENCIL_BUFFER_BIT) {
  194.             /* blit stencil only */
  195.             _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
  196.          }
  197.       }
  198.    }
  199. }
  200.  
  201.  
  202. void
  203. st_init_blit_functions(struct dd_function_table *functions)
  204. {
  205.    functions->BlitFramebuffer = st_BlitFramebuffer;
  206. }
  207.  
  208. #endif /* FEATURE_EXT_framebuffer_blit */
  209.