diff options
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_subimage.c | 214 |
1 files changed, 114 insertions, 100 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index 851b09e6454..1492740c273 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -40,112 +40,121 @@ #define FILE_DEBUG_FLAG DEBUG_TEXTURE -static void -intelTexSubimage(struct gl_context * ctx, - GLint dims, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint width, GLint height, GLint depth, - GLsizei imageSize, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +static bool +intel_blit_texsubimage(struct gl_context * ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); GLuint dstRowStride = 0; drm_intel_bo *temp_bo = NULL, *dst_bo = NULL; unsigned int blit_x = 0, blit_y = 0; + unsigned long pitch; + uint32_t tiling_mode = I915_TILING_NONE; /* Try to do a blit upload of the subimage if the texture is * currently busy. */ - if (intelImage->mt && - intelImage->mt->region->tiling != I915_TILING_Y && - intel->gen < 6 && target == GL_TEXTURE_2D && - drm_intel_bo_busy(dst_bo)) { - unsigned long pitch; - uint32_t tiling_mode = I915_TILING_NONE; - - DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(target), - level, xoffset, yoffset, width, height); - - pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, - format, type, pixels, packing, - "glTexSubImage"); - if (!pixels) - return; - - temp_bo = drm_intel_bo_alloc_tiled(intel->bufmgr, - "subimage blit bo", - width, height, - intelImage->mt->cpp, - &tiling_mode, - &pitch, - 0); - if (temp_bo == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); - return; - } - - if (drm_intel_gem_bo_map_gtt(temp_bo)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); - return; - } - - texImage->Data = temp_bo->virtual; - texImage->ImageOffsets[0] = 0; - dstRowStride = pitch; - - intel_miptree_get_image_offset(intelImage->mt, level, - intelImage->base.Face, 0, - &blit_x, &blit_y); - blit_x += xoffset; - blit_y += yoffset; - xoffset = 0; - yoffset = 0; - - if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); - } - - GLboolean ret; - unsigned int dst_pitch = intelImage->mt->region->pitch * - intelImage->mt->cpp; - - drm_intel_gem_bo_unmap_gtt(temp_bo); - texImage->Data = NULL; - - ret = intelEmitCopyBlit(intel, - intelImage->mt->cpp, - dstRowStride / intelImage->mt->cpp, - temp_bo, 0, GL_FALSE, - dst_pitch / intelImage->mt->cpp, dst_bo, 0, - intelImage->mt->region->tiling, - 0, 0, blit_x, blit_y, width, height, - GL_COPY); - assert(ret); - - drm_intel_bo_unreference(temp_bo); - _mesa_unmap_teximage_pbo(ctx, packing); - return; + if (!intelImage->mt) + return false; + + /* The blitter can't handle Y tiling */ + if (intelImage->mt->region->tiling == I915_TILING_Y) + return false; + + if (target != GL_TEXTURE_2D) + return false; + + /* On gen6, it's probably not worth swapping to the blit ring to do + * this because of all the overhead involved. + */ + if (intel->gen >= 6) + return false; + + dst_bo = intel_region_buffer(intel, intelImage->mt->region, + INTEL_WRITE_PART); + + if (!drm_intel_bo_busy(dst_bo)) + return false; + + DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, xoffset, yoffset, width, height); + + pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, + format, type, pixels, packing, + "glTexSubImage"); + if (!pixels) + return false; + + temp_bo = drm_intel_bo_alloc_tiled(intel->bufmgr, + "subimage blit bo", + width, height, + intelImage->mt->cpp, + &tiling_mode, + &pitch, + 0); + if (temp_bo == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + return false; + } + + if (drm_intel_gem_bo_map_gtt(temp_bo)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + return false; } - _mesa_store_texsubimage3d(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, - packing, texObj, texImage); + texImage->Data = temp_bo->virtual; + texImage->ImageOffsets[0] = 0; + dstRowStride = pitch; + + intel_miptree_get_image_offset(intelImage->mt, level, + intelImage->base.Face, 0, + &blit_x, &blit_y); + blit_x += xoffset; + blit_y += yoffset; + xoffset = 0; + yoffset = 0; + + if (!_mesa_texstore(ctx, 2, texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + xoffset, yoffset, 0, + dstRowStride, + texImage->ImageOffsets, + width, height, 1, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + } + + GLboolean ret; + unsigned int dst_pitch = intelImage->mt->region->pitch * + intelImage->mt->cpp; + + drm_intel_gem_bo_unmap_gtt(temp_bo); + texImage->Data = NULL; + + ret = intelEmitCopyBlit(intel, + intelImage->mt->cpp, + dstRowStride / intelImage->mt->cpp, + temp_bo, 0, GL_FALSE, + dst_pitch / intelImage->mt->cpp, dst_bo, 0, + intelImage->mt->region->tiling, + 0, 0, blit_x, blit_y, width, height, + GL_COPY); + assert(ret); + + drm_intel_bo_unreference(temp_bo); + _mesa_unmap_teximage_pbo(ctx, packing); + + return true; } static void @@ -160,14 +169,19 @@ intelTexSubImage2D(struct gl_context * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - intelTexSubimage(ctx, 2, - target, level, - xoffset, yoffset, 0, - width, height, 1, 0, - format, type, pixels, packing, texObj, texImage); + if (!intel_blit_texsubimage(ctx, target, level, + xoffset, yoffset, + width, height, + format, type, pixels, packing, + texObj, texImage)) { + _mesa_store_texsubimage2d(ctx, target, level, + xoffset, yoffset, + width, height, + format, type, pixels, + packing, texObj, texImage); + } } - void intelInitTextureSubImageFuncs(struct dd_function_table *functions) { |