示例#1
0
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__);
}
示例#2
0
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;
}