Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright 2006 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 portionsalloc
     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/enums.h"
     27 #include "main/image.h"
     28 #include "main/glformats.h"
     29 #include "main/mtypes.h"
     30 #include "main/condrender.h"
     31 #include "main/fbobject.h"
     32 #include "main/teximage.h"
     33 #include "main/texobj.h"
     34 #include "main/texstate.h"
     35 #include "main/bufferobj.h"
     36 #include "swrast/swrast.h"
     37 #include "drivers/common/meta.h"
     38 
     39 #include "brw_context.h"
     40 #include "intel_screen.h"
     41 #include "intel_blit.h"
     42 #include "intel_buffers.h"
     43 #include "intel_fbo.h"
     44 #include "intel_mipmap_tree.h"
     45 #include "intel_pixel.h"
     46 #include "intel_buffer_objects.h"
     47 
     48 #define FILE_DEBUG_FLAG DEBUG_PIXEL
     49 
     50 static bool
     51 do_blit_drawpixels(struct gl_context * ctx,
     52 		   GLint x, GLint y, GLsizei width, GLsizei height,
     53 		   GLenum format, GLenum type,
     54 		   const struct gl_pixelstore_attrib *unpack,
     55 		   const GLvoid * pixels)
     56 {
     57    struct brw_context *brw = brw_context(ctx);
     58    struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj);
     59    GLuint src_offset;
     60    drm_intel_bo *src_buffer;
     61 
     62    DBG("%s\n", __func__);
     63 
     64    if (!intel_check_blit_fragment_ops(ctx, false))
     65       return false;
     66 
     67    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
     68       DBG("%s: fallback due to MRT\n", __func__);
     69       return false;
     70    }
     71 
     72    intel_prepare_render(brw);
     73 
     74    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
     75    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
     76 
     77    mesa_format src_format = _mesa_format_from_format_and_type(format, type);
     78    if (_mesa_format_is_mesa_array_format(src_format))
     79       src_format = _mesa_format_from_array_format(src_format);
     80    mesa_format dst_format = irb->mt->format;
     81 
     82    /* We can safely discard sRGB encode/decode for the DrawPixels interface */
     83    src_format = _mesa_get_srgb_format_linear(src_format);
     84    dst_format = _mesa_get_srgb_format_linear(dst_format);
     85 
     86    if (!intel_miptree_blit_compatible_formats(src_format, dst_format)) {
     87       DBG("%s: bad format for blit\n", __func__);
     88       return false;
     89    }
     90 
     91    if (unpack->SwapBytes || unpack->LsbFirst ||
     92        unpack->SkipPixels || unpack->SkipRows) {
     93       DBG("%s: bad packing params\n", __func__);
     94       return false;
     95    }
     96 
     97    int src_stride = _mesa_image_row_stride(unpack, width, format, type);
     98    bool src_flip = false;
     99    /* Mesa flips the src_stride for unpack->Invert, but we want our mt to have
    100     * a normal src_stride.
    101     */
    102    if (unpack->Invert) {
    103       src_stride = -src_stride;
    104       src_flip = true;
    105    }
    106 
    107    src_offset = (GLintptr)pixels;
    108    src_offset += _mesa_image_offset(2, unpack, width, height,
    109 				    format, type, 0, 0, 0);
    110 
    111    src_buffer = intel_bufferobj_buffer(brw, src, src_offset,
    112                                        height * src_stride);
    113 
    114    struct intel_mipmap_tree *pbo_mt =
    115       intel_miptree_create_for_bo(brw,
    116                                   src_buffer,
    117                                   irb->mt->format,
    118                                   src_offset,
    119                                   width, height, 1,
    120                                   src_stride,
    121                                   0);
    122    if (!pbo_mt)
    123       return false;
    124 
    125    if (!intel_miptree_blit(brw,
    126                            pbo_mt, 0, 0,
    127                            0, 0, src_flip,
    128                            irb->mt, irb->mt_level, irb->mt_layer,
    129                            x, y, _mesa_is_winsys_fbo(ctx->DrawBuffer),
    130                            width, height, GL_COPY)) {
    131       DBG("%s: blit failed\n", __func__);
    132       intel_miptree_release(&pbo_mt);
    133       return false;
    134    }
    135 
    136    intel_miptree_release(&pbo_mt);
    137 
    138    if (ctx->Query.CurrentOcclusionObject)
    139       ctx->Query.CurrentOcclusionObject->Result += width * height;
    140 
    141    DBG("%s: success\n", __func__);
    142    return true;
    143 }
    144 
    145 void
    146 intelDrawPixels(struct gl_context * ctx,
    147                 GLint x, GLint y,
    148                 GLsizei width, GLsizei height,
    149                 GLenum format,
    150                 GLenum type,
    151                 const struct gl_pixelstore_attrib *unpack,
    152                 const GLvoid * pixels)
    153 {
    154    struct brw_context *brw = brw_context(ctx);
    155 
    156    if (!_mesa_check_conditional_render(ctx))
    157       return;
    158 
    159    if (format == GL_STENCIL_INDEX) {
    160       _swrast_DrawPixels(ctx, x, y, width, height, format, type,
    161                          unpack, pixels);
    162       return;
    163    }
    164 
    165    if (_mesa_is_bufferobj(unpack->BufferObj)) {
    166       if (do_blit_drawpixels(ctx, x, y, width, height, format, type, unpack,
    167 			     pixels)) {
    168 	 return;
    169       }
    170 
    171       perf_debug("%s: fallback to generic code in PBO case\n", __func__);
    172    }
    173 
    174    _mesa_meta_DrawPixels(ctx, x, y, width, height, format, type,
    175                          unpack, pixels);
    176 }
    177