Home | History | Annotate | Download | only in intel
      1 
      2 /**************************************************************************
      3  *
      4  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 #include "main/mtypes.h"
     30 #include "main/pbo.h"
     31 #include "main/texobj.h"
     32 #include "main/texstore.h"
     33 #include "main/texcompress.h"
     34 #include "main/enums.h"
     35 
     36 #include "intel_context.h"
     37 #include "intel_tex.h"
     38 #include "intel_mipmap_tree.h"
     39 #include "intel_blit.h"
     40 
     41 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
     42 
     43 static bool
     44 intel_blit_texsubimage(struct gl_context * ctx,
     45 		       struct gl_texture_image *texImage,
     46 		       GLint xoffset, GLint yoffset,
     47 		       GLint width, GLint height,
     48 		       GLenum format, GLenum type, const void *pixels,
     49 		       const struct gl_pixelstore_attrib *packing)
     50 {
     51    struct intel_context *intel = intel_context(ctx);
     52    struct intel_texture_image *intelImage = intel_texture_image(texImage);
     53    GLuint dstRowStride = 0;
     54    drm_intel_bo *temp_bo = NULL;
     55    unsigned int blit_x = 0, blit_y = 0;
     56    unsigned long pitch;
     57    uint32_t tiling_mode = I915_TILING_NONE;
     58    GLubyte *dstMap;
     59 
     60    /* Try to do a blit upload of the subimage if the texture is
     61     * currently busy.
     62     */
     63    if (!intelImage->mt)
     64       return false;
     65 
     66    /* The blitter can't handle Y tiling */
     67    if (intelImage->mt->region->tiling == I915_TILING_Y)
     68       return false;
     69 
     70    if (texImage->TexObject->Target != GL_TEXTURE_2D)
     71       return false;
     72 
     73    /* On gen6, it's probably not worth swapping to the blit ring to do
     74     * this because of all the overhead involved.
     75     */
     76    if (intel->gen >= 6)
     77       return false;
     78 
     79    if (!drm_intel_bo_busy(intelImage->mt->region->bo))
     80       return false;
     81 
     82    DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n",
     83        __FUNCTION__,
     84        _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
     85        texImage->Level, xoffset, yoffset, width, height);
     86 
     87    pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1,
     88 					format, type, pixels, packing,
     89 					"glTexSubImage");
     90    if (!pixels)
     91       return false;
     92 
     93    temp_bo = drm_intel_bo_alloc_tiled(intel->bufmgr,
     94 				      "subimage blit bo",
     95 				      width, height,
     96 				      intelImage->mt->cpp,
     97 				      &tiling_mode,
     98 				      &pitch,
     99 				      0);
    100    if (temp_bo == NULL) {
    101       _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
    102       return false;
    103    }
    104 
    105    if (drm_intel_gem_bo_map_gtt(temp_bo)) {
    106       _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
    107       return false;
    108    }
    109 
    110    dstMap = temp_bo->virtual;
    111    dstRowStride = pitch;
    112 
    113    intel_miptree_get_image_offset(intelImage->mt, texImage->Level,
    114 				  intelImage->base.Base.Face, 0,
    115 				  &blit_x, &blit_y);
    116    blit_x += xoffset;
    117    blit_y += yoffset;
    118 
    119    if (!_mesa_texstore(ctx, 2, texImage->_BaseFormat,
    120 		       texImage->TexFormat,
    121 		       dstRowStride,
    122 		       &dstMap,
    123 		       width, height, 1,
    124 		       format, type, pixels, packing)) {
    125       _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
    126    }
    127 
    128    bool ret;
    129    unsigned int dst_pitch = intelImage->mt->region->pitch *
    130       intelImage->mt->cpp;
    131 
    132    drm_intel_gem_bo_unmap_gtt(temp_bo);
    133 
    134    ret = intelEmitCopyBlit(intel,
    135 			   intelImage->mt->cpp,
    136 			   dstRowStride / intelImage->mt->cpp,
    137 			   temp_bo, 0, false,
    138 			   dst_pitch / intelImage->mt->cpp,
    139 			   intelImage->mt->region->bo, 0,
    140 			   intelImage->mt->region->tiling,
    141 			   0, 0, blit_x, blit_y, width, height,
    142 			   GL_COPY);
    143    assert(ret);
    144 
    145    drm_intel_bo_unreference(temp_bo);
    146    _mesa_unmap_teximage_pbo(ctx, packing);
    147 
    148    return true;
    149 }
    150 
    151 static void
    152 intelTexSubImage(struct gl_context * ctx,
    153                  GLuint dims,
    154                  struct gl_texture_image *texImage,
    155                  GLint xoffset, GLint yoffset, GLint zoffset,
    156                  GLsizei width, GLsizei height, GLsizei depth,
    157                  GLenum format, GLenum type,
    158                  const GLvoid * pixels,
    159                  const struct gl_pixelstore_attrib *packing)
    160 {
    161    /* The intel_blit_texsubimage() function only handles 2D images */
    162    if (dims != 2 || !intel_blit_texsubimage(ctx, texImage,
    163 			       xoffset, yoffset,
    164 			       width, height,
    165 			       format, type, pixels, packing)) {
    166       _mesa_store_texsubimage(ctx, dims, texImage,
    167                               xoffset, yoffset, zoffset,
    168                               width, height, depth,
    169                               format, type, pixels, packing);
    170    }
    171 }
    172 
    173 void
    174 intelInitTextureSubImageFuncs(struct dd_function_table *functions)
    175 {
    176    functions->TexSubImage = intelTexSubImage;
    177 }
    178