From b07c78bfe94c17e6fccba70923b03a29c751fde1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 28 Sep 2011 16:07:56 -0700 Subject: [PATCH] intel: Consolidate texture validation copy code, and reuse it correctly. The path for ->Data was failing to be called for the FBO draw offset fallback, and also had mismatched compressed texture support code. This drops the intel_prepare_render() in the blit path. We aren't copying to/from a GL_FRONT buffer, so it doesn't matter. --- src/mesa/drivers/dri/intel/intel_fbo.c | 11 +- .../drivers/dri/intel/intel_mipmap_tree.c | 185 +++++++++--------- .../drivers/dri/intel/intel_mipmap_tree.h | 20 +- src/mesa/drivers/dri/intel/intel_regions.c | 31 --- src/mesa/drivers/dri/intel/intel_regions.h | 10 - .../drivers/dri/intel/intel_tex_validate.c | 42 +--- 6 files changed, 106 insertions(+), 193 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index c0fb8d89bb5..d87dabb3606 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -729,7 +729,6 @@ intel_render_texture(struct gl_context * ctx, * into that. */ struct intel_context *intel = intel_context(ctx); - struct intel_mipmap_tree *old_mt = intel_image->mt; struct intel_mipmap_tree *new_mt; new_mt = intel_miptree_create(intel, image->TexObject->Target, @@ -741,17 +740,11 @@ intel_render_texture(struct gl_context * ctx, intel_image->base.Base.Depth, GL_TRUE); - intel_miptree_image_copy(intel, - new_mt, - intel_image->base.Base.Face, - intel_image->base.Base.Level, - old_mt); - - intel_miptree_release(&intel_image->mt); - intel_image->mt = new_mt; + intel_miptree_copy_teximage(intel, intel_image, new_mt); intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset); intel_region_reference(&irb->region, intel_image->mt->region); + intel_miptree_release(&new_mt); } #endif /* update drawing region, etc */ diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index c25df35ff84..553a21e817c 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -30,8 +30,10 @@ #include "intel_regions.h" #include "intel_tex_layout.h" #include "intel_tex.h" +#include "intel_blit.h" #include "main/enums.h" #include "main/formats.h" +#include "main/teximage.h" #define FILE_DEBUG_FLAG DEBUG_MIPTREE @@ -310,102 +312,107 @@ intel_miptree_get_image_offset(struct intel_mipmap_tree *mt, } /** - * Upload data for a particular image. + * Copies the image's current data to the given miptree, and associates that + * miptree with the image. */ void -intel_miptree_image_data(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, - GLuint level, - void *src, - GLuint src_row_pitch, - GLuint src_image_pitch) +intel_miptree_copy_teximage(struct intel_context *intel, + struct intel_texture_image *intelImage, + struct intel_mipmap_tree *dst_mt) { - const GLuint depth = dst->level[level].depth; - GLuint i; - - for (i = 0; i < depth; i++) { - GLuint dst_x, dst_y, height, width; - - intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y); - - height = dst->level[level].height; - width = dst->level[level].width; - if (dst->compressed) { - unsigned int align_w, align_h; + struct intel_mipmap_tree *src_mt = intelImage->mt; + int level = intelImage->base.Base.Level; + int face = intelImage->base.Base.Face; + GLuint width = src_mt->level[level].width; + GLuint height = src_mt->level[level].height; + GLuint depth = src_mt->level[level].depth; + int slice; + void *src, *dst; + + if (dst_mt->compressed) { + unsigned int align_w, align_h; + + intel_get_texture_alignment_unit(intelImage->base.Base.TexFormat, + &align_w, &align_h); + height = ALIGN(height, align_h) / align_h; + width = ALIGN(width, align_w); + } - intel_get_texture_alignment_unit(dst->format, &align_w, &align_h); - height = (height + align_h - 1) / align_h; - width = ALIGN(width, align_w); + for (slice = 0; slice < depth; slice++) { + unsigned int dst_x, dst_y, src_x, src_y; + + intel_miptree_get_image_offset(dst_mt, level, face, slice, + &dst_x, &dst_y); + + if (src_mt) { + /* Copy potentially with the blitter: + */ + intel_miptree_get_image_offset(src_mt, level, face, slice, + &src_x, &src_y); + + DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n", + src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp, + dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp, + width, height); + + if (!intelEmitCopyBlit(intel, + dst_mt->region->cpp, + src_mt->region->pitch, src_mt->region->bo, + 0, src_mt->region->tiling, + dst_mt->region->pitch, dst_mt->region->bo, + 0, dst_mt->region->tiling, + src_x, src_y, + dst_x, dst_y, + width, height, + GL_COPY)) { + + fallback_debug("miptree validate blit for %s failed\n", + _mesa_get_format_name(intelImage->base.Base.TexFormat)); + dst = intel_region_map(intel, dst_mt->region); + src = intel_region_map(intel, src_mt->region); + + _mesa_copy_rect(dst, + dst_mt->cpp, + dst_mt->region->pitch, + dst_x, dst_y, + width, height, + src, src_mt->region->pitch, + src_x, src_y); + + intel_region_unmap(intel, dst_mt->region); + intel_region_unmap(intel, src_mt->region); + } + } else { + dst = intel_region_map(intel, dst_mt->region); + + DBG("validate upload mt %p -> mt %p %d,%d/%d (%dx%d)\n", + src, + dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp, + width, height); + + src = intelImage->base.Base.Data; + src += (intelImage->base.Base.RowStride * + intelImage->base.Base.Height * + dst_mt->region->cpp * + slice); + + _mesa_copy_rect(dst, + dst_mt->region->cpp, + dst_mt->region->pitch, + dst_x, dst_y, + width, height, + src, + intelImage->base.Base.RowStride, + 0, 0); + + intel_region_unmap(intel, dst_mt->region); } - - DBG("%s: %d/%d %p/%d -> (%d, %d)/%d (%d, %d)\n", - __FUNCTION__, face, level, - src, src_row_pitch * dst->cpp, - dst_x, dst_y, dst->region->pitch * dst->cpp, - width, height); - - intel_region_data(intel, - dst->region, 0, dst_x, dst_y, - src, - src_row_pitch, - 0, 0, /* source x, y */ - width, height); - - src = (char *)src + src_image_pitch * dst->cpp; } -} - -/** - * Copy mipmap image between trees - */ -void -intel_miptree_image_copy(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, GLuint level, - struct intel_mipmap_tree *src) -{ - GLuint width = src->level[level].width; - GLuint height = src->level[level].height; - GLuint depth = src->level[level].depth; - GLuint src_x, src_y, dst_x, dst_y; - GLuint i; - GLboolean success; - - if (dst->compressed) { - GLuint align_w, align_h; - - intel_get_texture_alignment_unit(dst->format, &align_w, &align_h); - height = (height + 3) / 4; - width = ALIGN(width, align_w); + if (!src_mt) { + _mesa_free_texmemory(intelImage->base.Base.Data); + intelImage->base.Base.Data = NULL; } - intel_prepare_render(intel); - - for (i = 0; i < depth; i++) { - intel_miptree_get_image_offset(src, level, face, i, &src_x, &src_y); - intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y); - success = intel_region_copy(intel, - dst->region, 0, dst_x, dst_y, - src->region, 0, src_x, src_y, - width, height, GL_FALSE, - GL_COPY); - if (!success) { - GLubyte *src_ptr, *dst_ptr; - - src_ptr = intel_region_map(intel, src->region); - dst_ptr = intel_region_map(intel, dst->region); - - _mesa_copy_rect(dst_ptr, - dst->cpp, - dst->region->pitch, - dst_x, dst_y, width, height, - src_ptr, - src->region->pitch, - src_x, src_y); - intel_region_unmap(intel, src->region); - intel_region_unmap(intel, dst->region); - } - } + intel_miptree_reference(&intelImage->mt, dst_mt); } diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 7ca24f9bb60..7c0a3e3caad 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -56,6 +56,7 @@ * temporary system buffers. */ +struct intel_texture_image; /** * Describes the location of each texture image within a texture region. @@ -180,21 +181,10 @@ void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, GLuint level, GLuint img, GLuint x, GLuint y); -/* Upload an image into a tree - */ -void intel_miptree_image_data(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, - GLuint level, - void *src, - GLuint src_row_pitch, GLuint src_image_pitch); - -/* Copy an image between two trees - */ -void intel_miptree_image_copy(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, GLuint level, - struct intel_mipmap_tree *src); +void +intel_miptree_copy_teximage(struct intel_context *intel, + struct intel_texture_image *intelImage, + struct intel_mipmap_tree *dst_mt); /* i915_mipmap_tree.c: */ diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 9cb16328a00..7faf4ca40f5 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -337,37 +337,6 @@ _mesa_copy_rect(GLubyte * dst, } } - -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -void -intel_region_data(struct intel_context *intel, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - const void *src, GLuint src_pitch, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) -{ - _DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - intel_prepare_render(intel); - - _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset, - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - intel_region_unmap(intel, dst); -} - /* Copy rectangular sub-regions. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 61a284aa6ae..e639895ec8f 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -101,16 +101,6 @@ GLubyte *intel_region_map(struct intel_context *intel, void intel_region_unmap(struct intel_context *intel, struct intel_region *ib); - -/* Upload data to a rectangular sub-region - */ -void intel_region_data(struct intel_context *intel, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - const void *src, GLuint src_stride, - GLuint srcx, GLuint srcy, GLuint width, GLuint height); - /* Copy rectangular sub-regions */ GLboolean diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index f227ab8f8b1..a2299ee14d1 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -4,7 +4,9 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" +#include "intel_blit.h" #include "intel_tex.h" +#include "intel_tex_layout.h" #define FILE_DEBUG_FLAG DEBUG_TEXTURE @@ -27,44 +29,6 @@ intel_update_max_level(struct intel_texture_object *intelObj, } } -/** - * Copies the image's contents at its level into the object's miptree, - * and updates the image to point at the object's miptree. - */ -static void -copy_image_data_to_tree(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage) -{ - if (intelImage->mt) { - /* Copy potentially with the blitter: - */ - intel_miptree_image_copy(intel, - intelObj->mt, - intelImage->base.Base.Face, - intelImage->base.Base.Level, intelImage->mt); - } - else { - assert(intelImage->base.Base.Data != NULL); - - /* More straightforward upload. - */ - intel_miptree_image_data(intel, - intelObj->mt, - intelImage->base.Base.Face, - intelImage->base.Base.Level, - intelImage->base.Base.Data, - intelImage->base.Base.RowStride, - intelImage->base.Base.RowStride * - intelImage->base.Base.Height); - _mesa_align_free(intelImage->base.Base.Data); - intelImage->base.Base.Data = NULL; - } - - intel_miptree_reference(&intelImage->mt, intelObj->mt); -} - - /* */ GLuint @@ -148,7 +112,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (intelObj->mt != intelImage->mt && !intelImage->used_as_render_target) { - copy_image_data_to_tree(intel, intelObj, intelImage); + intel_miptree_copy_teximage(intel, intelImage, intelObj->mt); } } } -- 2.30.2