diff options
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 17 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex.h | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_image.c | 125 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.c | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_validate.c | 27 |
6 files changed, 126 insertions, 61 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 2ced6ac86b2..a3409274fb7 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -56,7 +56,8 @@ static struct intel_mipmap_tree * intel_miptree_create_internal(struct intel_context *intel, GLenum target, GLenum internal_format, - GLuint levels, + GLuint first_level, + GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint cpp, GLuint compress_byte, @@ -65,14 +66,15 @@ intel_miptree_create_internal(struct intel_context *intel, GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); - DBG("%s target %s format %s levels %d <-- %p\n", __FUNCTION__, + DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), _mesa_lookup_enum_by_nr(internal_format), - levels, mt); + first_level, last_level, mt); mt->target = target_to_target(target); mt->internal_format = internal_format; - mt->levels = levels; + mt->first_level = first_level; + mt->last_level = last_level; mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; @@ -104,7 +106,8 @@ intel_miptree_create(struct intel_context *intel, GLenum target, GLenum base_format, GLenum internal_format, - GLuint levels, + GLuint first_level, + GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint cpp, GLuint compress_byte, @@ -123,7 +126,7 @@ intel_miptree_create(struct intel_context *intel, } mt = intel_miptree_create_internal(intel, target, internal_format, - levels, width0, + first_level, last_level, width0, height0, depth0, cpp, compress_byte, tiling); /* @@ -161,7 +164,7 @@ intel_miptree_create_for_region(struct intel_context *intel, struct intel_mipmap_tree *mt; mt = intel_miptree_create_internal(intel, target, internal_format, - 1, + 0, 0, region->width, region->height, 1, region->cpp, compress_byte, I915_TILING_NONE); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 4bb90bf4ac6..760a8bce601 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -93,7 +93,8 @@ struct intel_mipmap_tree GLenum target; GLenum internal_format; - GLuint levels; + GLuint first_level; + GLuint last_level; GLuint width0, height0, depth0; /**< Level zero image dimensions */ GLuint cpp; @@ -123,7 +124,8 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLenum target, GLenum base_format, GLenum internal_format, - GLuint levels, + GLuint first_level, + GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 7c76bd48c60..6552ed0d332 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -65,10 +65,4 @@ void intel_tex_unmap_images(struct intel_context *intel, int intel_compressed_num_bytes(GLuint mesaFormat); -struct intel_mipmap_tree * -intel_miptree_create_for_teximage(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage, - GLboolean expect_accelerated_upload); - #endif diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 3b173bc257e..450c3ceee6f 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -45,12 +45,24 @@ logbase2(int n) return log2; } -struct intel_mipmap_tree * -intel_miptree_create_for_teximage(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage, - GLboolean expect_accelerated_upload) + +/* Otherwise, store it in memory if (Border != 0) or (any dimension == + * 1). + * + * Otherwise, if max_level >= level >= min_level, create tree with + * space for textures from min_level down to max_level. + * + * Otherwise, create tree with space for textures from (level + * 0)..(1x1). Consider pruning this tree at a validation if the + * saving is worth it. + */ +static void +guess_and_alloc_mipmap_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage, + GLboolean expect_accelerated_upload) { + GLuint firstLevel; GLuint lastLevel; GLuint width = intelImage->base.Width; GLuint height = intelImage->base.Height; @@ -61,11 +73,28 @@ intel_miptree_create_for_teximage(struct intel_context *intel, DBG("%s\n", __FUNCTION__); if (intelImage->base.Border) - return NULL; + return; + + if (intelImage->level > intelObj->base.BaseLevel && + (intelImage->base.Width == 1 || + (intelObj->base.Target != GL_TEXTURE_1D && + intelImage->base.Height == 1) || + (intelObj->base.Target == GL_TEXTURE_3D && + intelImage->base.Depth == 1))) + return; + + /* If this image disrespects BaseLevel, allocate from level zero. + * Usually BaseLevel == 0, so it's unlikely to happen. + */ + if (intelImage->level < intelObj->base.BaseLevel) + firstLevel = 0; + else + firstLevel = intelObj->base.BaseLevel; + /* Figure out image dimensions at start level. */ - for (i = intelImage->level; i > 0; i--) { + for (i = intelImage->level; i > firstLevel; i--) { width <<= 1; if (height != 1) height <<= 1; @@ -80,29 +109,34 @@ intel_miptree_create_for_teximage(struct intel_context *intel, */ if ((intelObj->base.MinFilter == GL_NEAREST || intelObj->base.MinFilter == GL_LINEAR) && - intelImage->level == 0) { - lastLevel = 0; + intelImage->level == firstLevel && + (intel->gen < 4 || firstLevel == 0)) { + lastLevel = firstLevel; } else { - lastLevel = logbase2(MAX2(MAX2(width, height), depth)); + lastLevel = firstLevel + logbase2(MAX2(MAX2(width, height), depth)); } + assert(!intelObj->mt); if (_mesa_is_format_compressed(intelImage->base.TexFormat)) comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); - return intel_miptree_create(intel, - intelObj->base.Target, - intelImage->base._BaseFormat, - intelImage->base.InternalFormat, - lastLevel + 1, - width, - height, - depth, - texelBytes, - comp_byte, - expect_accelerated_upload); + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + intelImage->base._BaseFormat, + intelImage->base.InternalFormat, + firstLevel, + lastLevel, + width, + height, + depth, + texelBytes, + comp_byte, + expect_accelerated_upload); + + DBG("%s - success\n", __FUNCTION__); } @@ -310,23 +344,41 @@ intelTexImage(struct gl_context * ctx, texImage->Data = NULL; } - if (intelObj->mt && intel_miptree_match_image(intelObj->mt, - &intelImage->base)) { - intel_miptree_reference(&intelImage->mt, intelObj->mt); - } else { - intel_miptree_release(intel, &intelImage->mt); - intelImage->mt = intel_miptree_create_for_teximage(intel, intelObj, - intelImage, - pixels == NULL); - if (!intelImage->mt) { + if (!intelObj->mt) { + guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); + if (!intelObj->mt) { DBG("guess_and_alloc_mipmap_tree: failed\n"); } + } + + assert(!intelImage->mt); + + if (intelObj->mt && + intel_miptree_match_image(intelObj->mt, &intelImage->base)) { + + intel_miptree_reference(&intelImage->mt, intelObj->mt); + assert(intelImage->mt); + } else if (intelImage->base.Border == 0) { + int comp_byte = 0; + GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); + GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat); + if (_mesa_is_format_compressed(intelImage->base.TexFormat)) { + comp_byte = + intel_compressed_num_bytes(intelImage->base.TexFormat); + } - /* Speculatively set up the object with this miptree so that the - * later levels can just load into the miptree we just made. + /* Didn't fit in the object miptree, but it's suitable for inclusion in + * a miptree, so create one just for our level and store it in the image. + * It'll get moved into the object miptree at validate time. */ - if (!intelObj->mt && intelImage->mt) - intel_miptree_reference(&intelObj->mt, intelImage->mt); + intelImage->mt = intel_miptree_create(intel, target, + baseFormat, + internalFormat, + level, level, + width, height, depth, + texelBytes, + comp_byte, pixels == NULL); + } /* PBO fastpaths: @@ -345,7 +397,10 @@ intelTexImage(struct gl_context * ctx, * performance (in particular when intel_region_cow() is * required). */ - if (intelImage->mt->levels == 1) { + if (intelObj->mt == intelImage->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level) { + if (try_pbo_zcopy(intel, intelImage, unpack, internalFormat, width, height, format, type, pixels)) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index 540ef36a415..d39733b6c5a 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -86,7 +86,7 @@ void i945_miptree_layout_2d(struct intel_context *intel, * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (mt->levels > 1) { + if (mt->first_level != mt->last_level) { GLuint mip1_width; if (mt->compressed) { @@ -104,7 +104,7 @@ void i945_miptree_layout_2d(struct intel_context *intel, mt->total_height = 0; - for (level = 0; level < mt->levels; level++) { + for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { GLuint img_height; intel_miptree_set_level_info(mt, level, nr_images, x, y, width, @@ -123,7 +123,7 @@ void i945_miptree_layout_2d(struct intel_context *intel, /* Layout_below: step right after second mipmap. */ - if (level == 1) { + if (level == mt->first_level + 1) { x += ALIGN(width, align_w); } else { diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index 31c0a83ae34..ab8aba31fe0 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -104,7 +104,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (firstImage->mt && firstImage->mt != intelObj->mt && - firstImage->mt->levels >= intelObj->_MaxLevel) { + firstImage->mt->first_level <= tObj->BaseLevel && + firstImage->mt->last_level >= intelObj->_MaxLevel) { if (intelObj->mt) intel_miptree_release(intel, &intelObj->mt); @@ -131,10 +132,11 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) if (intelObj->mt && (intelObj->mt->target != intelObj->base.Target || intelObj->mt->internal_format != firstImage->base.InternalFormat || - intelObj->mt->levels <= intelObj->_MaxLevel || - intelObj->mt->width0 != firstImage->mt->width0 || - intelObj->mt->height0 != firstImage->mt->height0 || - intelObj->mt->depth0 != firstImage->mt->depth0 || + intelObj->mt->first_level != tObj->BaseLevel || + intelObj->mt->last_level != intelObj->_MaxLevel || + intelObj->mt->width0 != firstImage->base.Width || + intelObj->mt->height0 != firstImage->base.Height || + intelObj->mt->depth0 != firstImage->base.Depth || intelObj->mt->cpp != cpp || intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) { intel_miptree_release(intel, &intelObj->mt); @@ -144,9 +146,18 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) /* May need to create a new tree: */ if (!intelObj->mt) { - intelObj->mt = intel_miptree_create_for_teximage(intel, intelObj, - firstImage, - GL_TRUE); + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + firstImage->base._BaseFormat, + firstImage->base.InternalFormat, + tObj->BaseLevel, + intelObj->_MaxLevel, + firstImage->base.Width, + firstImage->base.Height, + firstImage->base.Depth, + cpp, + comp_byte, + GL_TRUE); } /* Pull in any images not in the object's tree: |