[Mesa-dev] [PATCH 2/3] st/mesa: fix import of EGL images with non-zero level or layer
Nicolai Hähnle
nhaehnle at gmail.com
Fri Oct 6 20:19:00 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
In GL state, textures created from EGL images look like plain 2D textures
with a single level, so we use the existing layer_override facility and
add an analogous level_override one.
Fixes dEQP-EGL.functional.image.create.gles2_cubemap_{positive,negative}_{x,y,z}_rgba_texture
---
src/mesa/state_tracker/st_cb_eglimage.c | 3 ++-
src/mesa/state_tracker/st_cb_texture.c | 2 ++
src/mesa/state_tracker/st_sampler_view.c | 16 ++++++++++------
src/mesa/state_tracker/st_texture.h | 15 ++++++++++++---
src/mesa/state_tracker/st_vdpau.c | 2 ++
5 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index e15b32ff199..bb092a2f6ef 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -219,26 +219,27 @@ st_bind_egl_image(struct gl_context *ctx,
break;
default:
unreachable("bad YUV format!");
}
}
_mesa_init_teximage_fields(ctx, texImage,
stimg->texture->width0, stimg->texture->height0,
1, 0, internalFormat, texFormat);
- /* FIXME create a non-default sampler view from the stimg? */
pipe_resource_reference(&stObj->pt, stimg->texture);
st_texture_release_all_sampler_views(st, stObj);
pipe_resource_reference(&stImage->pt, stObj->pt);
stObj->surface_format = stimg->format;
+ stObj->level_override = stimg->level;
+ stObj->layer_override = stimg->layer;
_mesa_dirty_texobj(ctx, texObj);
}
static void
st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
GLeglImageOES image_handle)
{
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index b0a95ecbc79..25ea52924d2 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -688,20 +688,22 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
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;
assert(!st_texture_image(texImage)->pt);
_mesa_clear_texture_object(ctx, texObj, texImage);
+ stObj->layer_override = 0;
+ stObj->level_override = 0;
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_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c
index fbf0aaeb03a..014b4d26784 100644
--- a/src/mesa/state_tracker/st_sampler_view.c
+++ b/src/mesa/state_tracker/st_sampler_view.c
@@ -372,30 +372,34 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st,
struct st_texture_object *stObj,
enum pipe_format format,
bool glsl130_or_later)
{
/* There is no need to clear this structure (consider CPU overhead). */
struct pipe_sampler_view templ;
unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl130_or_later);
templ.format = format;
- templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
- templ.u.tex.last_level = last_level(stObj);
- assert(templ.u.tex.first_level <= templ.u.tex.last_level);
+ if (stObj->level_override) {
+ templ.u.tex.first_level = templ.u.tex.last_level = stObj->level_override;
+ } else {
+ templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
+ templ.u.tex.last_level = last_level(stObj);
+ }
if (stObj->layer_override) {
templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override;
} else {
templ.u.tex.first_layer = stObj->base.MinLayer;
templ.u.tex.last_layer = last_layer(stObj);
}
assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
+ assert(templ.u.tex.first_level <= templ.u.tex.last_level);
templ.target = gl_target_to_pipe(stObj->base.Target);
templ.swizzle_r = GET_SWZ(swizzle, 0);
templ.swizzle_g = GET_SWZ(swizzle, 1);
templ.swizzle_b = GET_SWZ(swizzle, 2);
templ.swizzle_a = GET_SWZ(swizzle, 3);
return st->pipe->create_sampler_view(st->pipe, stObj->pt, &templ);
}
@@ -412,23 +416,23 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
if (*sv) {
/* Debug check: make sure that the sampler view's parameters are
* what they're supposed to be.
*/
MAYBE_UNUSED struct pipe_sampler_view *view = *sv;
assert(stObj->pt == view->texture);
assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
assert(get_sampler_view_format(st, stObj, samp) == view->format);
assert(gl_target_to_pipe(stObj->base.Target) == view->target);
- assert(stObj->base.MinLevel + stObj->base.BaseLevel ==
- view->u.tex.first_level);
- assert(last_level(stObj) == view->u.tex.last_level);
+ assert(stObj->level_override ||
+ stObj->base.MinLevel + stObj->base.BaseLevel == view->u.tex.first_level);
+ assert(stObj->level_override || last_level(stObj) == view->u.tex.last_level);
assert(stObj->layer_override || stObj->base.MinLayer == view->u.tex.first_layer);
assert(stObj->layer_override || last_layer(stObj) == view->u.tex.last_layer);
assert(!stObj->layer_override ||
(stObj->layer_override == view->u.tex.first_layer &&
stObj->layer_override == view->u.tex.last_layer));
}
else {
/* create new sampler view */
enum pipe_format format = get_sampler_view_format(st, stObj, samp);
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 8448f4c6f02..0cde0c1f409 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -104,26 +104,35 @@ struct st_texture_object
* cannot be reallocated and the format can only be changed with a sampler
* view or a surface.
*/
GLboolean surface_based;
/* If surface_based is true, this format should be used for all sampler
* views and surfaces instead of pt->format.
*/
enum pipe_format surface_format;
+ /* When non-zero, samplers should use this level instead of the level
+ * range specified by the GL state.
+ *
+ * This is used for EGL images, which may correspond to a single level out
+ * of an imported pipe_resources with multiple mip levels.
+ */
+ uint level_override;
+
/* When non-zero, samplers should use this layer instead of the one
* specified by the GL state.
*
- * This is used for VDPAU interop, where imported pipe_resources may be
- * array textures (containing layers with different fields) even though the
- * GL state describes one non-array texture per field.
+ * This is used for EGL images and VDPAU interop, where imported
+ * pipe_resources may be cube, 3D, or array textures (containing layers
+ * with different fields in the case of VDPAU) even though the GL state
+ * describes one non-array texture per field.
*/
uint layer_override;
/** The glsl version of the shader seen during the previous validation */
bool prev_glsl130_or_later;
/** The value of the sampler's sRGBDecode state at the previous validation */
GLenum prev_sRGBDecode;
/**
* Set when the texture images of this texture object might not all be in
diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c
index bb4070eec34..19611e719a1 100644
--- a/src/mesa/state_tracker/st_vdpau.c
+++ b/src/mesa/state_tracker/st_vdpau.c
@@ -229,40 +229,42 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
_mesa_init_teximage_fields(ctx, texImage,
res->width0, res->height0, 1, 0, GL_RGBA,
texFormat);
pipe_resource_reference(&stObj->pt, res);
st_texture_release_all_sampler_views(st, stObj);
pipe_resource_reference(&stImage->pt, res);
stObj->surface_format = res->format;
+ stObj->level_override = 0;
stObj->layer_override = layer_override;
_mesa_dirty_texobj(ctx, texObj);
pipe_resource_reference(&res, NULL);
}
static void
st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access,
GLboolean output, struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
const void *vdpSurface, GLuint index)
{
struct st_context *st = st_context(ctx);
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
pipe_resource_reference(&stObj->pt, NULL);
st_texture_release_all_sampler_views(st, stObj);
pipe_resource_reference(&stImage->pt, NULL);
+ stObj->level_override = 0;
stObj->layer_override = 0;
_mesa_dirty_texobj(ctx, texObj);
st_flush(st, NULL, 0);
}
#endif
void
--
2.11.0
More information about the mesa-dev
mailing list