GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) { struct gl_context *ctx = &intel->ctx; struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit); GLuint face, i; GLuint nr_faces = 0; struct intel_texture_image *firstImage; /* We know/require this is true by now: */ assert(intelObj->base._Complete); /* What levels must the tree include at a minimum? */ intel_update_max_level(intel, intelObj, sampler); firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]); /* Fallback case: */ if (firstImage->base.Border) { if (intelObj->mt) { intel_miptree_release(intel, &intelObj->mt); } return GL_FALSE; } /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. * * For pre-gen4, we have to match first_level == tObj->BaseLevel, * because we don't have the control that gen4 does to make min/mag * determination happen at a nonzero (hardware) baselevel. Because * of that, we just always relayout on baselevel change. */ if (intelObj->mt && (intelObj->mt->target != intelObj->base.Target || intelObj->mt->format != firstImage->base.TexFormat || 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)) { intel_miptree_release(intel, &intelObj->mt); } /* May need to create a new tree: */ if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->base.TexFormat, tObj->BaseLevel, intelObj->_MaxLevel, firstImage->base.Width, firstImage->base.Height, firstImage->base.Depth, GL_TRUE); if (!intelObj->mt) return GL_FALSE; } /* Pull in any images not in the object's tree: */ nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; for (face = 0; face < nr_faces; face++) { for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) { struct intel_texture_image *intelImage = intel_texture_image(intelObj->base.Image[face][i]); /* skip too small size mipmap */ if (intelImage == NULL) break; /* Need to import images in main memory or held in other trees. * If it's a render target, then its data isn't needed to be in * the object tree (otherwise we'd be FBO incomplete), and we need * to keep track of the image's MT as needing to be pulled in still, * or we'll lose the rendering that's done to it. */ if (intelObj->mt != intelImage->mt && !intelImage->used_as_render_target) { copy_image_data_to_tree(intel, intelObj, intelImage); } } } return GL_TRUE; }
GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) { struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); int comp_byte = 0; int cpp; GLuint face, i; GLuint nr_faces = 0; struct intel_texture_image *firstImage; /* We know/require this is true by now: */ assert(intelObj->base._Complete); /* What levels must the tree include at a minimum? */ intel_calculate_first_last_level(intelObj); firstImage = intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]); /* Fallback case: */ if (firstImage->base.Border) { if (intelObj->mt) { intel_miptree_release(intel, &intelObj->mt); } return GL_FALSE; } /* If both firstImage and intelObj have a tree which can contain * all active images, favour firstImage. Note that because of the * completeness requirement, we know that the image dimensions * will match. */ if (firstImage->mt && firstImage->mt != intelObj->mt && firstImage->mt->first_level <= intelObj->firstLevel && firstImage->mt->last_level >= intelObj->lastLevel) { if (intelObj->mt) intel_miptree_release(intel, &intelObj->mt); intel_miptree_reference(&intelObj->mt, firstImage->mt); } if (firstImage->base.IsCompressed) { comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); cpp = comp_byte; } else cpp = firstImage->base.TexFormat->TexelBytes; /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. * * XXX: For some layouts (eg i945?), the test might have to be * first_level == firstLevel, as the tree isn't valid except at the * original start level. Hope to get around this by * programming minLod, maxLod, baseLevel into the hardware and * leaving the tree alone. */ if (intelObj->mt && (intelObj->mt->target != intelObj->base.Target || intelObj->mt->internal_format != firstImage->base.InternalFormat || intelObj->mt->first_level != intelObj->firstLevel || intelObj->mt->last_level != intelObj->lastLevel || 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 != firstImage->base.IsCompressed)) { intel_miptree_release(intel, &intelObj->mt); } /* May need to create a new tree: */ if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->base.InternalFormat, intelObj->firstLevel, intelObj->lastLevel, firstImage->base.Width, firstImage->base.Height, firstImage->base.Depth, cpp, comp_byte, GL_TRUE); } /* Pull in any images not in the object's tree: */ nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; for (face = 0; face < nr_faces; face++) { for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { struct intel_texture_image *intelImage = intel_texture_image(intelObj->base.Image[face][i]); /* Need to import images in main memory or held in other trees. */ if (intelObj->mt != intelImage->mt) { copy_image_data_to_tree(intel, intelObj, intelImage); } } } return GL_TRUE; }
GLuint intel_finalize_mipmap_tree( struct intel_context *intel, struct gl_texture_object *tObj ) { struct intel_texture_object *intelObj = intel_texture_object(tObj); GLuint face, i; GLuint nr_faces = 0; struct gl_texture_image *firstImage; GLuint cpp = 0; if( tObj == intel->frame_buffer_texobj ) return GL_FALSE; /* We know/require this is true by now: */ assert(intelObj->base.Complete); /* What levels must the tree include at a minimum? */ if (intelObj->dirty) { intel_calculate_first_last_level( intelObj ); /* intel_miptree_destroy(intel, intelObj->mt); */ /* intelObj->mt = NULL; */ } firstImage = intelObj->base.Image[0][intelObj->firstLevel]; /* Fallback case: */ if (firstImage->Border || ((firstImage->_BaseFormat == GL_DEPTH_COMPONENT) && ((tObj->WrapS == GL_CLAMP_TO_BORDER) || (tObj->WrapT == GL_CLAMP_TO_BORDER)))) { if (intelObj->mt) { intel_miptree_destroy(intel, intelObj->mt); intelObj->mt = NULL; /* Set all images dirty: */ intel_texture_invalidate(intelObj); } return GL_FALSE; } if (firstImage->IsCompressed) { cpp = intel_compressed_num_bytes(firstImage->TexFormat->MesaFormat); } else { cpp = firstImage->TexFormat->TexelBytes; } /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. */ if (intelObj->mt && (intelObj->mt->target != intelObj->base.Target || intelObj->mt->internal_format != firstImage->InternalFormat || intelObj->mt->first_level != intelObj->firstLevel || intelObj->mt->last_level != intelObj->lastLevel || intelObj->mt->width0 != firstImage->Width || intelObj->mt->height0 != firstImage->Height || intelObj->mt->depth0 != firstImage->Depth || intelObj->mt->cpp != cpp || intelObj->mt->compressed != firstImage->IsCompressed)) { intel_miptree_destroy(intel, intelObj->mt); intelObj->mt = NULL; /* Set all images dirty: */ intel_texture_invalidate(intelObj); } /* May need to create a new tree: */ if (!intelObj->mt) { intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->InternalFormat, intelObj->firstLevel, intelObj->lastLevel, firstImage->Width, firstImage->Height, firstImage->Depth, cpp, firstImage->IsCompressed); /* Tell the buffer manager that we will manage the backing * store, but we still want it to do fencing for us. */ bmBufferSetInvalidateCB(intel, intelObj->mt->region->buffer, intel_texture_invalidate_cb, intelObj, GL_FALSE); } /* Pull in any images not in the object's tree: */ if (intelObj->dirty) { nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; for (face = 0; face < nr_faces; face++) { if (intelObj->dirty_images[face]) { for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { struct gl_texture_image *texImage = intelObj->base.Image[face][i]; /* Need to import images in main memory or held in other trees. */ if (intelObj->dirty_images[face] & (1<<i) && texImage) { if (INTEL_DEBUG & DEBUG_TEXTURE) _mesa_printf("copy data from image %d (%p) into object miptree\n", i, texImage->Data); if (!copy_image_data_to_tree(intel, intelObj, texImage, face, i)) return GL_FALSE; } } } } /* Only clear the dirty flags if everything went ok: */ for (face = 0; face < nr_faces; face++) { intelObj->dirty_images[face] = 0; } intelObj->dirty = 0; } return GL_TRUE; }