static void teximage_assign_miptree(radeonContextPtr rmesa, struct gl_texture_object *texObj, struct gl_texture_image *texImage, unsigned face, unsigned level) { radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); /* Since miptree holds only images for levels <BaseLevel..MaxLevel> * don't allocate the miptree if the teximage won't fit. */ if (!image_matches_texture_obj(texObj, texImage, level)) return; /* Try using current miptree, or create new if there isn't any */ if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "%s: texObj %p, texImage %p, face %d, level %d, " "texObj miptree doesn't match, allocated new miptree %p\n", __FUNCTION__, texObj, texImage, face, level, t->mt); } /* Miptree alocation may have failed, * when there was no image for baselevel specified */ if (t->mt) { image->mtface = face; image->mtlevel = level; radeon_miptree_reference(t->mt, &image->mt); } else radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, "%s Failed to allocate miptree.\n", __func__); }
void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLeglImageOES image_handle) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image *radeonImage = get_radeon_texture_image(texImage); __DRIscreen *screen; __DRIimage *image; screen = radeon->dri.screen; image = screen->dri2.image->lookupEGLImage(screen, image_handle, screen->loaderPrivate); if (image == NULL) return; radeonFreeTextureImageBuffer(ctx, texImage); texImage->Width = image->width; texImage->Height = image->height; texImage->Depth = 1; texImage->_BaseFormat = GL_RGBA; texImage->TexFormat = image->format; radeonImage->base.RowStride = image->pitch; texImage->InternalFormat = image->internal_format; if(t->mt) { radeon_miptree_unreference(&t->mt); t->mt = NULL; } /* NOTE: The following is *very* ugly and will probably break. But I don't know how to deal with it, without creating a whole new function like radeon_miptree_from_bo() so I'm going with the easy but error-prone way. */ radeon_try_alloc_miptree(radeon, t); radeon_miptree_reference(t->mt, &radeonImage->mt); if (t->mt == NULL) { radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, "%s Failed to allocate miptree.\n", __func__); return; } /* Particularly ugly: this is guaranteed to break, if image->bo is not of the required size for a miptree. */ radeon_bo_unref(t->mt->bo); radeon_bo_ref(image->bo); t->mt->bo = image->bo; if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base)) fprintf(stderr, "miptree doesn't match image\n"); }
/** * Validate texture mipmap tree. * If individual images are stored in different mipmap trees * use the mipmap tree that has the most of the correct data. */ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_sampler_object *samp, struct gl_texture_object *texObj) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); radeon_mipmap_tree *dst_miptree; if (samp == &texObj->Sampler && (t->validated || t->image_override)) { return GL_TRUE; } calculate_min_max_lod(samp, &t->base, &t->minLod, &t->maxLod); radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", __func__, texObj ,t->minLod, t->maxLod); dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel); radeon_miptree_unreference(&t->mt); if (!dst_miptree) { radeon_try_alloc_miptree(rmesa, t); radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "%s: No matching miptree found, allocated new one %p\n", __func__, t->mt); } else { radeon_miptree_reference(dst_miptree, &t->mt); radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "%s: Using miptree %p\n", __func__, t->mt); } const unsigned faces = _mesa_num_tex_faces(texObj->Target); unsigned face, level; radeon_texture_image *img; /* Validate only the levels that will actually be used during rendering */ for (face = 0; face < faces; ++face) { for (level = t->minLod; level <= t->maxLod; ++level) { img = get_radeon_texture_image(texObj->Image[face][level]); radeon_print(RADEON_TEXTURE, RADEON_TRACE, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt); if (img->mt != t->mt && !img->used_as_render_target) { radeon_print(RADEON_TEXTURE, RADEON_TRACE, "MIGRATING\n"); struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { radeon_firevertices(rmesa); } migrate_image_to_miptree(t->mt, img, face, level); } else radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n"); } } t->validated = GL_TRUE; return GL_TRUE; }