[Mesa-dev] [PATCH 1/3] st/mesa: fix switching from surface-based to non-surface-based textures
Nicolai Hähnle
nhaehnle at gmail.com
Fri Oct 6 20:18:59 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
This can happen with surface-based texture objects derived from EGL
images, since those aren't immutable.
Fixes tests in dEQP-EGL.functional.sharing.gles2.multithread.random.images.teximage2d.* and others
---
src/mesa/main/texobj.c | 11 +++++++----
src/mesa/main/texobj.h | 3 ++-
src/mesa/state_tracker/st_cb_eglimage.c | 2 +-
src/mesa/state_tracker/st_cb_texture.c | 3 ++-
src/mesa/state_tracker/st_manager.c | 2 +-
src/mesa/state_tracker/st_vdpau.c | 2 +-
6 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index b703da01bef..1978898b8b9 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -464,40 +464,43 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
COPY_4V(dest->Swizzle, src->Swizzle);
dest->_Swizzle = src->_Swizzle;
dest->_IsHalfFloat = src->_IsHalfFloat;
dest->_IsFloat = src->_IsFloat;
dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits;
}
/**
- * Free all texture images of the given texture object.
+ * Free all texture images of the given texture objectm, except for
+ * \p retainTexImage.
*
* \param ctx GL context.
- * \param t texture object.
+ * \param texObj texture object.
+ * \param retainTexImage a texture image that will \em not be freed.
*
* \sa _mesa_clear_texture_image().
*/
void
_mesa_clear_texture_object(struct gl_context *ctx,
- struct gl_texture_object *texObj)
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *retainTexImage)
{
GLuint i, j;
if (texObj->Target == 0)
return;
for (i = 0; i < MAX_FACES; i++) {
for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
struct gl_texture_image *texImage = texObj->Image[i][j];
- if (texImage)
+ if (texImage && texImage != retainTexImage)
_mesa_clear_texture_image(ctx, texImage);
}
}
}
/**
* Check if the given texture object is valid by examining its Target field.
* For debugging only.
*/
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 71cc8ffba2e..e67ce3ff9df 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -74,21 +74,22 @@ _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target);
extern void
_mesa_delete_texture_object( struct gl_context *ctx,
struct gl_texture_object *obj );
extern void
_mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
extern void
_mesa_clear_texture_object(struct gl_context *ctx,
- struct gl_texture_object *obj);
+ struct gl_texture_object *obj,
+ struct gl_texture_image *retainTexImage);
extern void
_mesa_reference_texobj_(struct gl_texture_object **ptr,
struct gl_texture_object *tex);
static inline void
_mesa_reference_texobj(struct gl_texture_object **ptr,
struct gl_texture_object *tex)
{
if (*ptr != tex)
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index cca2c026097..e15b32ff199 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -191,21 +191,21 @@ st_bind_egl_image(struct gl_context *ctx,
UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
internalFormat = GL_RGBA;
else
internalFormat = GL_RGB;
stObj = st_texture_object(texObj);
stImage = st_texture_image(texImage);
/* switch to surface based */
if (!stObj->surface_based) {
- _mesa_clear_texture_object(ctx, texObj);
+ _mesa_clear_texture_object(ctx, texObj, NULL);
stObj->surface_based = GL_TRUE;
}
texFormat = st_pipe_format_to_mesa_format(stimg->format);
/* TODO RequiredTextureImageUnits should probably be reset back
* to 1 somewhere if different texture is bound??
*/
if (texFormat == MESA_FORMAT_NONE) {
switch (stimg->format) {
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index b5006b05a7b..b0a95ecbc79 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -686,21 +686,22 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
{
struct gl_texture_object *texObj = texImage->TexObject;
struct st_texture_object *stObj = st_texture_object(texObj);
/* switch to "normal" */
if (stObj->surface_based) {
const GLenum target = texObj->Target;
const GLuint level = texImage->Level;
mesa_format texFormat;
- _mesa_clear_texture_object(ctx, texObj);
+ assert(!st_texture_image(texImage)->pt);
+ _mesa_clear_texture_object(ctx, texObj, texImage);
pipe_resource_reference(&stObj->pt, NULL);
/* oops, need to init this image again */
texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
texImage->InternalFormat, format,
type);
_mesa_init_teximage_fields(ctx, texImage,
texImage->Width, texImage->Height,
texImage->Depth, texImage->Border,
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 50bc3c33c62..aef87ea8b75 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -687,21 +687,21 @@ st_context_teximage(struct st_context_iface *stctxi,
return FALSE;
}
texObj = _mesa_get_current_tex_object(ctx, target);
_mesa_lock_texture(ctx, texObj);
stObj = st_texture_object(texObj);
/* switch to surface based */
if (!stObj->surface_based) {
- _mesa_clear_texture_object(ctx, texObj);
+ _mesa_clear_texture_object(ctx, texObj, NULL);
stObj->surface_based = GL_TRUE;
}
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
stImage = st_texture_image(texImage);
if (tex) {
mesa_format texFormat = st_pipe_format_to_mesa_format(pipe_format);
if (util_format_has_alpha(tex->format))
internalFormat = GL_RGBA;
diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c
index 02738153085..bb4070eec34 100644
--- a/src/mesa/state_tracker/st_vdpau.c
+++ b/src/mesa/state_tracker/st_vdpau.c
@@ -214,21 +214,21 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
/* do we have different screen objects ? */
if (res->screen != st->pipe->screen) {
_mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV");
pipe_resource_reference(&res, NULL);
return;
}
/* switch to surface based */
if (!stObj->surface_based) {
- _mesa_clear_texture_object(ctx, texObj);
+ _mesa_clear_texture_object(ctx, texObj, NULL);
stObj->surface_based = GL_TRUE;
}
texFormat = st_pipe_format_to_mesa_format(res->format);
_mesa_init_teximage_fields(ctx, texImage,
res->width0, res->height0, 1, 0, GL_RGBA,
texFormat);
pipe_resource_reference(&stObj->pt, res);
--
2.11.0
More information about the mesa-dev
mailing list