Home | History | Annotate | Download | only in intel
      1 /**************************************************************************
      2  *
      3  * Copyright 2003 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 #include "main/mtypes.h"
     29 #include "main/enums.h"
     30 #include "main/image.h"
     31 #include "main/teximage.h"
     32 #include "main/texstate.h"
     33 #include "main/fbobject.h"
     34 
     35 #include "drivers/common/meta.h"
     36 
     37 #include "intel_screen.h"
     38 #include "intel_context.h"
     39 #include "intel_mipmap_tree.h"
     40 #include "intel_regions.h"
     41 #include "intel_fbo.h"
     42 #include "intel_tex.h"
     43 #include "intel_blit.h"
     44 
     45 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
     46 
     47 
     48 bool
     49 intel_copy_texsubimage(struct intel_context *intel,
     50                        struct intel_texture_image *intelImage,
     51                        GLint dstx, GLint dsty,
     52                        struct intel_renderbuffer *irb,
     53                        GLint x, GLint y, GLsizei width, GLsizei height)
     54 {
     55    struct gl_context *ctx = &intel->ctx;
     56    struct intel_region *region;
     57    const GLenum internalFormat = intelImage->base.Base.InternalFormat;
     58    bool copy_supported = false;
     59    bool copy_supported_with_alpha_override = false;
     60 
     61    intel_prepare_render(intel);
     62 
     63    if (!intelImage->mt || !irb || !irb->mt) {
     64       if (unlikely(INTEL_DEBUG & DEBUG_PERF))
     65 	 fprintf(stderr, "%s fail %p %p (0x%08x)\n",
     66 		 __FUNCTION__, intelImage->mt, irb, internalFormat);
     67       return false;
     68    } else {
     69       region = irb->mt->region;
     70       assert(region);
     71    }
     72 
     73    copy_supported = intelImage->base.Base.TexFormat == intel_rb_format(irb);
     74 
     75    /* Converting ARGB8888 to XRGB8888 is trivial: ignore the alpha bits */
     76    if (intel_rb_format(irb) == MESA_FORMAT_ARGB8888 &&
     77        intelImage->base.Base.TexFormat == MESA_FORMAT_XRGB8888) {
     78       copy_supported = true;
     79    }
     80 
     81    /* Converting XRGB8888 to ARGB8888 requires setting the alpha bits to 1.0 */
     82    if (intel_rb_format(irb) == MESA_FORMAT_XRGB8888 &&
     83        intelImage->base.Base.TexFormat == MESA_FORMAT_ARGB8888) {
     84       copy_supported_with_alpha_override = true;
     85    }
     86 
     87    if (!copy_supported && !copy_supported_with_alpha_override) {
     88       if (unlikely(INTEL_DEBUG & DEBUG_PERF))
     89 	 fprintf(stderr, "%s mismatched formats %s, %s\n",
     90 		 __FUNCTION__,
     91 		 _mesa_get_format_name(intelImage->base.Base.TexFormat),
     92 		 _mesa_get_format_name(intel_rb_format(irb)));
     93       return false;
     94    }
     95 
     96    {
     97       GLuint image_x, image_y;
     98       GLshort src_pitch;
     99 
    100       /* get dest x/y in destination texture */
    101       intel_miptree_get_image_offset(intelImage->mt,
    102 				     intelImage->base.Base.Level,
    103 				     intelImage->base.Base.Face,
    104 				     0,
    105 				     &image_x, &image_y);
    106 
    107       /* The blitter can't handle Y-tiled buffers. */
    108       if (intelImage->mt->region->tiling == I915_TILING_Y) {
    109 	 return false;
    110       }
    111 
    112       if (_mesa_is_winsys_fbo(ctx->ReadBuffer)) {
    113 	 /* Flip vertical orientation for system framebuffers */
    114 	 y = ctx->ReadBuffer->Height - (y + height);
    115 	 src_pitch = -region->pitch;
    116       } else {
    117 	 /* reading from a FBO, y is already oriented the way we like */
    118 	 src_pitch = region->pitch;
    119       }
    120 
    121       /* blit from src buffer to texture */
    122       if (!intelEmitCopyBlit(intel,
    123 			     intelImage->mt->cpp,
    124 			     src_pitch,
    125 			     region->bo,
    126 			     0,
    127 			     region->tiling,
    128 			     intelImage->mt->region->pitch,
    129 			     intelImage->mt->region->bo,
    130 			     0,
    131 			     intelImage->mt->region->tiling,
    132 			     irb->draw_x + x, irb->draw_y + y,
    133 			     image_x + dstx, image_y + dsty,
    134 			     width, height,
    135 			     GL_COPY)) {
    136 	 return false;
    137       }
    138    }
    139 
    140    if (copy_supported_with_alpha_override)
    141       intel_set_teximage_alpha_to_one(ctx, intelImage);
    142 
    143    return true;
    144 }
    145 
    146 
    147 static void
    148 intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
    149                      struct gl_texture_image *texImage,
    150                      GLint xoffset, GLint yoffset, GLint zoffset,
    151                      struct gl_renderbuffer *rb,
    152                      GLint x, GLint y,
    153                      GLsizei width, GLsizei height)
    154 {
    155    if (dims == 3 || !intel_copy_texsubimage(intel_context(ctx),
    156                                intel_texture_image(texImage),
    157                                xoffset, yoffset,
    158                                intel_renderbuffer(rb), x, y, width, height)) {
    159       fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
    160       _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
    161                                  xoffset, yoffset, zoffset,
    162                                  rb, x, y, width, height);
    163    }
    164 }
    165 
    166 
    167 void
    168 intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
    169 {
    170    functions->CopyTexSubImage = intelCopyTexSubImage;
    171 }
    172