X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fintel%2Fintel_mipmap_tree.c;h=cb5a341050b646061f2daf671cf7b96a9b1d46c0;hb=70be48dff6bb68c61285641e4d976bfd53e0f00c;hp=4f5101a312870ff7df302238d0feca45a8035d88;hpb=5d2413fca4c252ec5c7880fa7f983b5df3d762ba;p=mesa.git diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 4f5101a3128..cb5a341050b 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -28,7 +28,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "intel_chipset.h" +#include "intel_tex_layout.h" #ifndef I915 #include "brw_state.h" #endif @@ -36,6 +36,7 @@ #define FILE_DEBUG_FLAG DEBUG_MIPTREE + static GLenum target_to_target(GLenum target) { @@ -52,6 +53,7 @@ target_to_target(GLenum target) } } + static struct intel_mipmap_tree * intel_miptree_create_internal(struct intel_context *intel, GLenum target, @@ -84,7 +86,7 @@ intel_miptree_create_internal(struct intel_context *intel, mt->pitch = 0; #ifdef I915 - if (IS_945(intel->intelScreen->deviceID)) + if (intel->is_945) ok = i945_miptree_layout(intel, mt, tiling); else ok = i915_miptree_layout(intel, mt, tiling); @@ -101,6 +103,7 @@ intel_miptree_create_internal(struct intel_context *intel, return mt; } + struct intel_mipmap_tree * intel_miptree_create(struct intel_context *intel, GLenum target, @@ -118,7 +121,7 @@ intel_miptree_create(struct intel_context *intel, if (intel->use_texture_tiling && compress_byte == 0 && intel->intelScreen->kernel_exec_fencing) { - if (IS_965(intel->intelScreen->deviceID) && + if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT || base_format == GL_DEPTH_STENCIL_EXT)) tiling = I915_TILING_Y; @@ -134,8 +137,10 @@ intel_miptree_create(struct intel_context *intel, /* * pitch == 0 || height == 0 indicates the null texture */ - if (!mt || !mt->pitch || !mt->total_height) + if (!mt || !mt->pitch || !mt->total_height) { + free(mt); return NULL; + } mt->region = intel_region_alloc(intel, tiling, @@ -153,6 +158,7 @@ intel_miptree_create(struct intel_context *intel, return mt; } + struct intel_mipmap_tree * intel_miptree_create_for_region(struct intel_context *intel, GLenum target, @@ -190,7 +196,8 @@ intel_miptree_create_for_region(struct intel_context *intel, intel_region_reference(&mt->region, region); return mt; - } +} + /** * intel_miptree_pitch_align: @@ -204,7 +211,6 @@ intel_miptree_create_for_region(struct intel_context *intel, * Given @pitch, compute a larger value which accounts for * any necessary alignment required by the device */ - int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, uint32_t tiling, @@ -217,16 +223,12 @@ int intel_miptree_pitch_align (struct intel_context *intel, if (!mt->compressed) { int pitch_align; - if (intel->ttm) { - /* XXX: Align pitch to multiple of 64 bytes for now to allow - * render-to-texture to work in all cases. This should probably be - * replaced at some point by some scheme to only do this when really - * necessary. - */ - pitch_align = 64; - } else { - pitch_align = 4; - } + /* XXX: Align pitch to multiple of 64 bytes for now to allow + * render-to-texture to work in all cases. This should probably be + * replaced at some point by some scheme to only do this when really + * necessary. + */ + pitch_align = 64; if (tiling == I915_TILING_X) pitch_align = 512; @@ -250,6 +252,7 @@ int intel_miptree_pitch_align (struct intel_context *intel, return pitch; } + void intel_miptree_reference(struct intel_mipmap_tree **dst, struct intel_mipmap_tree *src) @@ -259,6 +262,7 @@ intel_miptree_reference(struct intel_mipmap_tree **dst, DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount); } + void intel_miptree_release(struct intel_context *intel, struct intel_mipmap_tree **mt) @@ -287,9 +291,10 @@ intel_miptree_release(struct intel_context *intel, intel_region_release(&((*mt)->region)); - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) - if ((*mt)->level[i].image_offset) - free((*mt)->level[i].image_offset); + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + free((*mt)->level[i].x_offset); + free((*mt)->level[i].y_offset); + } free(*mt); } @@ -297,33 +302,31 @@ intel_miptree_release(struct intel_context *intel, } - - -/* Can the image be pulled into a unified mipmap tree. This mirrors +/** + * Can the image be pulled into a unified mipmap tree? This mirrors * the completeness test in a lot of ways. * * Not sure whether I want to pass gl_texture_image here. */ GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, - struct gl_texture_image *image, - GLuint face, GLuint level) + struct gl_texture_image *image) { - /* Images with borders are never pulled into mipmap trees. - */ - if (image->Border || - ((image->_BaseFormat == GL_DEPTH_COMPONENT) && - ((image->TexObject->WrapS == GL_CLAMP_TO_BORDER) || - (image->TexObject->WrapT == GL_CLAMP_TO_BORDER)))) + GLboolean isCompressed = _mesa_is_format_compressed(image->TexFormat); + struct intel_texture_image *intelImage = intel_texture_image(image); + GLuint level = intelImage->level; + + /* Images with borders are never pulled into mipmap trees. */ + if (image->Border) return GL_FALSE; if (image->InternalFormat != mt->internal_format || - image->IsCompressed != mt->compressed) + isCompressed != mt->compressed) return GL_FALSE; - if (!image->IsCompressed && + if (!isCompressed && !mt->compressed && - image->TexFormat->TexelBytes != mt->cpp) + _mesa_get_format_bytes(image->TexFormat) != mt->cpp) return GL_FALSE; /* Test image dimensions against the base level image adjusted for @@ -350,82 +353,59 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt, mt->level[level].height = h; mt->level[level].depth = d; mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; + mt->level[level].level_x = x; + mt->level[level].level_y = y; mt->level[level].nr_images = nr_images; DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, level, w, h, d, x, y, mt->level[level].level_offset); - /* Not sure when this would happen, but anyway: - */ - if (mt->level[level].image_offset) { - free(mt->level[level].image_offset); - mt->level[level].image_offset = NULL; - } - assert(nr_images); + assert(!mt->level[level].x_offset); - mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint)); - mt->level[level].image_offset[0] = 0; + mt->level[level].x_offset = malloc(nr_images * sizeof(GLuint)); + mt->level[level].x_offset[0] = mt->level[level].level_x; + mt->level[level].y_offset = malloc(nr_images * sizeof(GLuint)); + mt->level[level].y_offset[0] = mt->level[level].level_y; } -void -intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt, - GLuint level, GLuint img, - GLuint x, GLuint y, - GLuint offset) -{ - if (img == 0 && level == 0) - assert(x == 0 && y == 0); - - assert(img < mt->level[level].nr_images); - - mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp + offset; - - DBG("%s level %d img %d pos %d,%d image_offset %x\n", - __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); -} - void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, GLuint level, GLuint img, GLuint x, GLuint y) { - intel_miptree_set_image_offset_ex(mt, level, img, x, y, 0); -} + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + assert(img < mt->level[level].nr_images); -/* Although we use the image_offset[] array to store relative offsets - * to cube faces, Mesa doesn't know anything about this and expects - * each cube face to be treated as a separate image. - * - * These functions present that view to mesa: - */ -const GLuint * -intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level) -{ - static const GLuint zero = 0; + mt->level[level].x_offset[img] = mt->level[level].level_x + x; + mt->level[level].y_offset[img] = mt->level[level].level_y + y; - if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1) - return &zero; - else - return mt->level[level].image_offset; + DBG("%s level %d img %d pos %d,%d\n", + __FUNCTION__, level, img, + mt->level[level].x_offset[img], mt->level[level].y_offset[img]); } -GLuint -intel_miptree_image_offset(struct intel_mipmap_tree *mt, - GLuint face, GLuint level) +void +intel_miptree_get_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint face, GLuint depth, + GLuint *x, GLuint *y) { - if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) - return (mt->level[level].level_offset + - mt->level[level].image_offset[face]); - else - return mt->level[level].level_offset; + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) { + *x = mt->level[level].x_offset[face]; + *y = mt->level[level].y_offset[face]; + } else if (mt->target == GL_TEXTURE_3D) { + *x = mt->level[level].x_offset[depth]; + *y = mt->level[level].y_offset[depth]; + } else { + *x = mt->level[level].x_offset[0]; + *y = mt->level[level].y_offset[0]; + } } - - /** * Map a teximage in a mipmap tree. * \param row_stride returns row stride in bytes @@ -441,6 +421,7 @@ intel_miptree_image_map(struct intel_context * intel, GLuint level, GLuint * row_stride, GLuint * image_offsets) { + GLuint x, y; DBG("%s \n", __FUNCTION__); if (row_stride) @@ -449,19 +430,26 @@ intel_miptree_image_map(struct intel_context * intel, if (mt->target == GL_TEXTURE_3D) { int i; - for (i = 0; i < mt->level[level].depth; i++) - image_offsets[i] = mt->level[level].image_offset[i] / mt->cpp; + for (i = 0; i < mt->level[level].depth; i++) { + + intel_miptree_get_image_offset(mt, level, face, i, + &x, &y); + image_offsets[i] = x + y * mt->pitch; + } + + return intel_region_map(intel, mt->region); } else { assert(mt->level[level].depth == 1); - assert(mt->target == GL_TEXTURE_CUBE_MAP || - mt->level[level].image_offset[0] == 0); + intel_miptree_get_image_offset(mt, level, face, 0, + &x, &y); image_offsets[0] = 0; - } - return (intel_region_map(intel, mt->region) + - intel_miptree_image_offset(mt, face, level)); + return intel_region_map(intel, mt->region) + + (x + y * mt->pitch) * mt->cpp; + } } + void intel_miptree_image_unmap(struct intel_context *intel, struct intel_mipmap_tree *mt) @@ -471,8 +459,8 @@ intel_miptree_image_unmap(struct intel_context *intel, } - -/* Upload data for a particular image. +/** + * Upload data for a particular image. */ void intel_miptree_image_data(struct intel_context *intel, @@ -483,21 +471,21 @@ intel_miptree_image_data(struct intel_context *intel, GLuint src_row_pitch, GLuint src_image_pitch) { - GLuint depth = dst->level[level].depth; - GLuint dst_offset = intel_miptree_image_offset(dst, face, level); - const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + const GLuint depth = dst->level[level].depth; GLuint i; - GLuint height = 0; DBG("%s: %d/%d\n", __FUNCTION__, face, level); for (i = 0; i < depth; i++) { + GLuint dst_x, dst_y, height; + + intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y); + height = dst->level[level].height; if(dst->compressed) height = (height + 3) / 4; + intel_region_data(intel, - dst->region, - dst_offset + dst_depth_offset[i], /* dst_offset */ - 0, 0, /* dstx, dsty */ + dst->region, 0, dst_x, dst_y, src, src_row_pitch, 0, 0, /* source x, y */ @@ -507,8 +495,9 @@ intel_miptree_image_data(struct intel_context *intel, } } -extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *); -/* Copy mipmap image between trees + +/** + * Copy mipmap image between trees */ void intel_miptree_image_copy(struct intel_context *intel, @@ -519,38 +508,37 @@ intel_miptree_image_copy(struct intel_context *intel, GLuint width = src->level[level].width; GLuint height = src->level[level].height; GLuint depth = src->level[level].depth; - GLuint dst_offset = intel_miptree_image_offset(dst, face, level); - GLuint src_offset = intel_miptree_image_offset(src, face, level); - const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); - const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); + 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->internal_format, &align_w, &align_h); + intel_get_texture_alignment_unit(dst->internal_format, + &align_w, &align_h); height = (height + 3) / 4; width = ALIGN(width, align_w); } 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, dst_offset + dst_depth_offset[i], - 0, 0, - src->region, src_offset + src_depth_offset[i], - 0, 0, width, height, GL_COPY); + dst->region, 0, dst_x, dst_y, + src->region, 0, src_x, src_y, width, height, + 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_offset + dst_depth_offset[i], + _mesa_copy_rect(dst_ptr + dst->cpp * (dst_x + dst_y * dst->pitch), dst->cpp, dst->pitch, 0, 0, width, height, - src_ptr + src_offset + src_depth_offset[i], + src_ptr + src->cpp * (src_x + src_y * src->pitch), src->pitch, 0, 0); intel_region_unmap(intel, src->region);