Home | History | Annotate | Download | only in i915
      1 /**************************************************************************
      2  *
      3  * Copyright 2003 VMware, Inc.
      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 VMWARE 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 #include "main/glheader.h"
     29 #include "main/image.h"
     30 #include "main/state.h"
     31 #include "main/mtypes.h"
     32 #include "main/condrender.h"
     33 #include "main/fbobject.h"
     34 #include "drivers/common/meta.h"
     35 
     36 #include "intel_context.h"
     37 #include "intel_buffers.h"
     38 #include "intel_mipmap_tree.h"
     39 #include "intel_regions.h"
     40 #include "intel_pixel.h"
     41 #include "intel_fbo.h"
     42 #include "intel_blit.h"
     43 
     44 #define FILE_DEBUG_FLAG DEBUG_PIXEL
     45 
     46 /**
     47  * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
     48  */
     49 static bool
     50 do_blit_copypixels(struct gl_context * ctx,
     51                    GLint srcx, GLint srcy,
     52                    GLsizei width, GLsizei height,
     53                    GLint dstx, GLint dsty, GLenum type)
     54 {
     55    struct intel_context *intel = intel_context(ctx);
     56    struct gl_framebuffer *fb = ctx->DrawBuffer;
     57    struct gl_framebuffer *read_fb = ctx->ReadBuffer;
     58    GLint orig_dstx;
     59    GLint orig_dsty;
     60    GLint orig_srcx;
     61    GLint orig_srcy;
     62    struct intel_renderbuffer *draw_irb = NULL;
     63    struct intel_renderbuffer *read_irb = NULL;
     64 
     65    /* Update draw buffer bounds */
     66    _mesa_update_state(ctx);
     67 
     68    switch (type) {
     69    case GL_COLOR:
     70       if (fb->_NumColorDrawBuffers != 1) {
     71 	 perf_debug("glCopyPixels() fallback: MRT\n");
     72 	 return false;
     73       }
     74 
     75       draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
     76       read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer);
     77       break;
     78    case GL_DEPTH_STENCIL_EXT:
     79       draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
     80       read_irb =
     81 	 intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
     82       break;
     83    case GL_DEPTH:
     84       perf_debug("glCopyPixels() fallback: GL_DEPTH\n");
     85       return false;
     86    case GL_STENCIL:
     87       perf_debug("glCopyPixels() fallback: GL_STENCIL\n");
     88       return false;
     89    default:
     90       perf_debug("glCopyPixels(): Unknown type\n");
     91       return false;
     92    }
     93 
     94    if (!draw_irb) {
     95       perf_debug("glCopyPixels() fallback: missing draw buffer\n");
     96       return false;
     97    }
     98 
     99    if (!read_irb) {
    100       perf_debug("glCopyPixels() fallback: missing read buffer\n");
    101       return false;
    102    }
    103 
    104    if (ctx->_ImageTransferState) {
    105       perf_debug("glCopyPixels(): Unsupported image transfer state\n");
    106       return false;
    107    }
    108 
    109    if (ctx->Depth.Test) {
    110       perf_debug("glCopyPixels(): Unsupported depth test state\n");
    111       return false;
    112    }
    113 
    114    if (ctx->Stencil._Enabled) {
    115       perf_debug("glCopyPixels(): Unsupported stencil test state\n");
    116       return false;
    117    }
    118 
    119    if (ctx->Fog.Enabled ||
    120        ctx->Texture._MaxEnabledTexImageUnit != -1 ||
    121        ctx->FragmentProgram._Enabled) {
    122       perf_debug("glCopyPixels(): Unsupported fragment shader state\n");
    123       return false;
    124    }
    125 
    126    if (ctx->Color.AlphaEnabled ||
    127        ctx->Color.BlendEnabled) {
    128       perf_debug("glCopyPixels(): Unsupported blend state\n");
    129       return false;
    130    }
    131 
    132    if (!ctx->Color.ColorMask[0][0] ||
    133        !ctx->Color.ColorMask[0][1] ||
    134        !ctx->Color.ColorMask[0][2] ||
    135        !ctx->Color.ColorMask[0][3]) {
    136       perf_debug("glCopyPixels(): Unsupported color mask state\n");
    137       return false;
    138    }
    139 
    140    if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) {
    141       perf_debug("glCopyPixels(): Unsupported pixel zoom\n");
    142       return false;
    143    }
    144 
    145    intel_prepare_render(intel);
    146 
    147    intel_flush(&intel->ctx);
    148 
    149    /* Clip to destination buffer. */
    150    orig_dstx = dstx;
    151    orig_dsty = dsty;
    152    if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
    153 			     fb->_Xmax, fb->_Ymax,
    154 			     &dstx, &dsty, &width, &height))
    155       goto out;
    156    /* Adjust src coords for our post-clipped destination origin */
    157    srcx += dstx - orig_dstx;
    158    srcy += dsty - orig_dsty;
    159 
    160    /* Clip to source buffer. */
    161    orig_srcx = srcx;
    162    orig_srcy = srcy;
    163    if (!_mesa_clip_to_region(0, 0,
    164 			     read_fb->Width, read_fb->Height,
    165 			     &srcx, &srcy, &width, &height))
    166       goto out;
    167    /* Adjust dst coords for our post-clipped source origin */
    168    dstx += srcx - orig_srcx;
    169    dsty += srcy - orig_srcy;
    170 
    171    if (!intel_miptree_blit(intel,
    172                            read_irb->mt, read_irb->mt_level, read_irb->mt_layer,
    173                            srcx, srcy, _mesa_is_winsys_fbo(read_fb),
    174                            draw_irb->mt, draw_irb->mt_level, draw_irb->mt_layer,
    175                            dstx, dsty, _mesa_is_winsys_fbo(fb),
    176                            width, height,
    177                            (ctx->Color.ColorLogicOpEnabled ?
    178                             ctx->Color.LogicOp : GL_COPY))) {
    179       DBG("%s: blit failure\n", __func__);
    180       return false;
    181    }
    182 
    183    if (ctx->Query.CurrentOcclusionObject)
    184       ctx->Query.CurrentOcclusionObject->Result += width * height;
    185 
    186 out:
    187    intel_check_front_buffer_rendering(intel);
    188 
    189    DBG("%s: success\n", __func__);
    190    return true;
    191 }
    192 
    193 
    194 void
    195 intelCopyPixels(struct gl_context * ctx,
    196                 GLint srcx, GLint srcy,
    197                 GLsizei width, GLsizei height,
    198                 GLint destx, GLint desty, GLenum type)
    199 {
    200    DBG("%s\n", __func__);
    201 
    202    if (!_mesa_check_conditional_render(ctx))
    203       return;
    204 
    205    if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
    206       return;
    207 
    208    /* this will use swrast if needed */
    209    _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
    210 }
    211