Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright 2003 VMware, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 #include "main/image.h"
     27 #include "main/state.h"
     28 #include "main/mtypes.h"
     29 #include "main/condrender.h"
     30 #include "main/fbobject.h"
     31 #include "drivers/common/meta.h"
     32 
     33 #include "brw_context.h"
     34 #include "intel_buffers.h"
     35 #include "intel_mipmap_tree.h"
     36 #include "intel_pixel.h"
     37 #include "intel_fbo.h"
     38 #include "intel_blit.h"
     39 #include "intel_batchbuffer.h"
     40 
     41 #define FILE_DEBUG_FLAG DEBUG_PIXEL
     42 
     43 /**
     44  * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
     45  */
     46 static bool
     47 do_blit_copypixels(struct gl_context * ctx,
     48                    GLint srcx, GLint srcy,
     49                    GLsizei width, GLsizei height,
     50                    GLint dstx, GLint dsty, GLenum type)
     51 {
     52    struct brw_context *brw = brw_context(ctx);
     53    struct gl_framebuffer *fb = ctx->DrawBuffer;
     54    struct gl_framebuffer *read_fb = ctx->ReadBuffer;
     55    GLint orig_dstx;
     56    GLint orig_dsty;
     57    GLint orig_srcx;
     58    GLint orig_srcy;
     59    struct intel_renderbuffer *draw_irb = NULL;
     60    struct intel_renderbuffer *read_irb = NULL;
     61 
     62    /* Update draw buffer bounds */
     63    _mesa_update_state(ctx);
     64 
     65    intel_prepare_render(brw);
     66 
     67    switch (type) {
     68    case GL_COLOR:
     69       if (fb->_NumColorDrawBuffers != 1) {
     70 	 perf_debug("glCopyPixels() fallback: MRT\n");
     71 	 return false;
     72       }
     73 
     74       draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
     75       read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer);
     76       break;
     77    case GL_DEPTH_STENCIL_EXT:
     78       draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
     79       read_irb =
     80 	 intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
     81       break;
     82    case GL_DEPTH:
     83       perf_debug("glCopyPixels() fallback: GL_DEPTH\n");
     84       return false;
     85    case GL_STENCIL:
     86       perf_debug("glCopyPixels() fallback: GL_STENCIL\n");
     87       return false;
     88    default:
     89       perf_debug("glCopyPixels(): Unknown type\n");
     90       return false;
     91    }
     92 
     93    if (!draw_irb) {
     94       perf_debug("glCopyPixels() fallback: missing draw buffer\n");
     95       return false;
     96    }
     97 
     98    if (!read_irb) {
     99       perf_debug("glCopyPixels() fallback: missing read buffer\n");
    100       return false;
    101    }
    102 
    103    if (draw_irb->mt->num_samples > 1 || read_irb->mt->num_samples > 1) {
    104       perf_debug("glCopyPixels() fallback: multisampled buffers\n");
    105       return false;
    106    }
    107 
    108    if (ctx->_ImageTransferState) {
    109       perf_debug("glCopyPixels(): Unsupported image transfer state\n");
    110       return false;
    111    }
    112 
    113    if (ctx->Depth.Test) {
    114       perf_debug("glCopyPixels(): Unsupported depth test state\n");
    115       return false;
    116    }
    117 
    118    if (ctx->Stencil._Enabled) {
    119       perf_debug("glCopyPixels(): Unsupported stencil test state\n");
    120       return false;
    121    }
    122 
    123    if (ctx->Fog.Enabled ||
    124        ctx->Texture._MaxEnabledTexImageUnit != -1 ||
    125        ctx->FragmentProgram._Enabled) {
    126       perf_debug("glCopyPixels(): Unsupported fragment shader state\n");
    127       return false;
    128    }
    129 
    130    if (ctx->Color.AlphaEnabled ||
    131        ctx->Color.BlendEnabled) {
    132       perf_debug("glCopyPixels(): Unsupported blend state\n");
    133       return false;
    134    }
    135 
    136    if (!ctx->Color.ColorMask[0][0] ||
    137        !ctx->Color.ColorMask[0][1] ||
    138        !ctx->Color.ColorMask[0][2] ||
    139        !ctx->Color.ColorMask[0][3]) {
    140       perf_debug("glCopyPixels(): Unsupported color mask state\n");
    141       return false;
    142    }
    143 
    144    if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) {
    145       perf_debug("glCopyPixels(): Unsupported pixel zoom\n");
    146       return false;
    147    }
    148 
    149    intel_batchbuffer_flush(brw);
    150 
    151    /* Clip to destination buffer. */
    152    orig_dstx = dstx;
    153    orig_dsty = dsty;
    154    if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
    155 			     fb->_Xmax, fb->_Ymax,
    156 			     &dstx, &dsty, &width, &height))
    157       goto out;
    158    /* Adjust src coords for our post-clipped destination origin */
    159    srcx += dstx - orig_dstx;
    160    srcy += dsty - orig_dsty;
    161 
    162    /* Clip to source buffer. */
    163    orig_srcx = srcx;
    164    orig_srcy = srcy;
    165    if (!_mesa_clip_to_region(0, 0,
    166 			     read_fb->Width, read_fb->Height,
    167 			     &srcx, &srcy, &width, &height))
    168       goto out;
    169    /* Adjust dst coords for our post-clipped source origin */
    170    dstx += srcx - orig_srcx;
    171    dsty += srcy - orig_srcy;
    172 
    173    if (!intel_miptree_blit(brw,
    174                            read_irb->mt, read_irb->mt_level, read_irb->mt_layer,
    175                            srcx, srcy, _mesa_is_winsys_fbo(read_fb),
    176                            draw_irb->mt, draw_irb->mt_level, draw_irb->mt_layer,
    177                            dstx, dsty, _mesa_is_winsys_fbo(fb),
    178                            width, height,
    179                            (ctx->Color.ColorLogicOpEnabled ?
    180                             ctx->Color.LogicOp : GL_COPY))) {
    181       DBG("%s: blit failure\n", __func__);
    182       return false;
    183    }
    184 
    185    if (ctx->Query.CurrentOcclusionObject)
    186       ctx->Query.CurrentOcclusionObject->Result += width * height;
    187 
    188 out:
    189 
    190    DBG("%s: success\n", __func__);
    191    return true;
    192 }
    193 
    194 
    195 void
    196 intelCopyPixels(struct gl_context * ctx,
    197                 GLint srcx, GLint srcy,
    198                 GLsizei width, GLsizei height,
    199                 GLint destx, GLint desty, GLenum type)
    200 {
    201    DBG("%s\n", __func__);
    202 
    203    if (!_mesa_check_conditional_render(ctx))
    204       return;
    205 
    206    if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
    207       return;
    208 
    209    /* this will use swrast if needed */
    210    _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
    211 }
    212