/** * @param for_bo Indicates that the caller is * intel_miptree_create_for_bo(). If true, then do not create * \c stencil_mt. */ struct intel_mipmap_tree * intel_miptree_create_layout(struct intel_context *intel, GLenum target, mesa_format format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, bool for_bo) { struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); if (!mt) return NULL; DBG("%s target %s format %s level %d..%d <-- %p\n", __func__, _mesa_enum_to_string(target), _mesa_get_format_name(format), first_level, last_level, mt); mt->target = target_to_target(target); mt->format = format; mt->first_level = first_level; mt->last_level = last_level; mt->logical_width0 = width0; mt->logical_height0 = height0; mt->logical_depth0 = depth0; /* The cpp is bytes per (1, blockheight)-sized block for compressed * textures. This is why you'll see divides by blockheight all over */ unsigned bw, bh; _mesa_get_format_block_size(format, &bw, &bh); assert(_mesa_get_format_bytes(mt->format) % bw == 0); mt->cpp = _mesa_get_format_bytes(mt->format) / bw; mt->compressed = _mesa_is_format_compressed(format); mt->refcount = 1; if (target == GL_TEXTURE_CUBE_MAP) { assert(depth0 == 1); depth0 = 6; } mt->physical_width0 = width0; mt->physical_height0 = height0; mt->physical_depth0 = depth0; intel_get_texture_alignment_unit(intel, mt->format, &mt->align_w, &mt->align_h); (void) intel; if (intel->is_945) i945_miptree_layout(mt); else i915_miptree_layout(mt); return mt; }
struct intel_mipmap_tree * intel_miptree_create(struct intel_context *intel, GLenum target, GLenum internal_format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint cpp, GLuint compress_byte) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); mt->target = target_to_target(target); mt->internal_format = internal_format; mt->first_level = first_level; mt->last_level = last_level; mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; mt->cpp = compress_byte ? compress_byte : cpp; mt->compressed = compress_byte ? 1 : 0; mt->refcount = 1; switch (intel->intelScreen->deviceID) { case PCI_CHIP_I945_G: case PCI_CHIP_I945_GM: ok = i945_miptree_layout(mt); break; case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: case PCI_CHIP_I830_M: case PCI_CHIP_I855_GM: case PCI_CHIP_I865_G: default: /* All the i830 chips and the i915 use this layout: */ ok = i915_miptree_layout(mt); break; } if (ok) mt->region = intel_region_alloc(intel->intelScreen, mt->cpp, mt->pitch, mt->total_height); if (!mt->region) { free(mt); return NULL; } return mt; }
/** * 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. */ bool intel_miptree_match_image(struct intel_mipmap_tree *mt, struct gl_texture_image *image) { struct intel_texture_image *intelImage = intel_texture_image(image); GLuint level = intelImage->base.Base.Level; int width, height, depth; /* glTexImage* choose the texture object based on the target passed in, and * objects can't change targets over their lifetimes, so this should be * true. */ assert(target_to_target(image->TexObject->Target) == mt->target); mesa_format mt_format = mt->format; if (image->TexFormat != mt_format) return false; intel_miptree_get_dimensions_for_image(image, &width, &height, &depth); if (mt->target == GL_TEXTURE_CUBE_MAP) depth = 6; /* Test image dimensions against the base level image adjusted for * minification. This will also catch images not present in the * tree, changed targets, etc. */ if (mt->target == GL_TEXTURE_2D_MULTISAMPLE || mt->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { /* nonzero level here is always bogus */ assert(level == 0); if (width != mt->logical_width0 || height != mt->logical_height0 || depth != mt->logical_depth0) { return false; } } else { /* all normal textures, renderbuffers, etc */ if (width != mt->level[level].width || height != mt->level[level].height || depth != mt->level[level].depth) { return false; } } return true; }
static struct intel_mipmap_tree * intel_miptree_create_internal(struct intel_context *intel, GLenum target, GLenum internal_format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, GLuint cpp, GLuint compress_byte, uint32_t tiling) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); 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), first_level, last_level, mt); mt->target = target_to_target(target); mt->internal_format = internal_format; mt->first_level = first_level; mt->last_level = last_level; mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; mt->cpp = compress_byte ? compress_byte : cpp; mt->compressed = compress_byte ? 1 : 0; mt->refcount = 1; #ifdef I915 if (intel->is_945) ok = i945_miptree_layout(intel, mt, tiling); else ok = i915_miptree_layout(intel, mt, tiling); #else ok = brw_miptree_layout(intel, mt, tiling); #endif if (!ok) { free(mt); DBG("%s not okay - returning NULL\n", __FUNCTION__); return NULL; } return mt; }