st/mesa: store state that affects sampler views per context

This fixes sequences like:

1. Context 1 samples from texture with sRGB decode enabled
2. Context 2 samples from texture with sRGB decode disabled
3. Context 1 samples from texture with sRGB decode disabled

Previously, step 3 would see the prev_sRGBDecode value from context 2
and would incorrectly use the old sampler view with sRGB decode enabled.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
Nicolai Hähnle
2017-10-05 14:08:04 +02:00
parent e484805352
commit bce3055c69
4 changed files with 44 additions and 41 deletions

View File

@@ -170,8 +170,8 @@ st_convert_sampler(const struct st_context *st,
swizzle is per-texture, not per context. */ swizzle is per-texture, not per context. */
/* XXX: clean that up to not use the sampler view at all */ /* XXX: clean that up to not use the sampler view at all */
for (unsigned i = 0; i < stobj->num_sampler_views; ++i) { for (unsigned i = 0; i < stobj->num_sampler_views; ++i) {
if (stobj->sampler_views[i]) { if (stobj->sampler_views[i].view) {
sv = stobj->sampler_views[i]; sv = stobj->sampler_views[i].view;
break; break;
} }
} }

View File

@@ -84,18 +84,6 @@ st_update_single_texture(struct st_context *st,
return; return;
} }
/* Check a few pieces of state outside the texture object to see if we
* need to force revalidation.
*/
if (stObj->prev_glsl130_or_later != glsl130_or_later ||
stObj->prev_sRGBDecode != samp->sRGBDecode) {
st_texture_release_all_sampler_views(st, stObj);
stObj->prev_glsl130_or_later = glsl130_or_later;
stObj->prev_sRGBDecode = samp->sRGBDecode;
}
if (texObj->TargetIndex == TEXTURE_EXTERNAL_INDEX && if (texObj->TargetIndex == TEXTURE_EXTERNAL_INDEX &&
stObj->pt->screen->resource_changed) stObj->pt->screen->resource_changed)
stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt); stObj->pt->screen->resource_changed(stObj->pt->screen, stObj->pt);

View File

@@ -47,19 +47,19 @@
* If none is found an empty slot is initialized with a * If none is found an empty slot is initialized with a
* template and returned instead. * template and returned instead.
*/ */
static struct pipe_sampler_view ** static struct st_sampler_view *
st_texture_get_sampler_view(struct st_context *st, st_texture_get_sampler_view(struct st_context *st,
struct st_texture_object *stObj) struct st_texture_object *stObj)
{ {
struct pipe_sampler_view **free = NULL; struct st_sampler_view *free = NULL;
GLuint i; GLuint i;
for (i = 0; i < stObj->num_sampler_views; ++i) { for (i = 0; i < stObj->num_sampler_views; ++i) {
struct pipe_sampler_view **sv = &stObj->sampler_views[i]; struct st_sampler_view *sv = &stObj->sampler_views[i];
/* Is the array entry used ? */ /* Is the array entry used ? */
if (*sv) { if (sv->view) {
/* check if the context matches */ /* check if the context matches */
if ((*sv)->context == st->pipe) { if (sv->view->context == st->pipe) {
return sv; return sv;
} }
} else { } else {
@@ -73,13 +73,13 @@ st_texture_get_sampler_view(struct st_context *st,
if (!free) { if (!free) {
/* Haven't even found a free one, resize the array */ /* Haven't even found a free one, resize the array */
unsigned new_size = (stObj->num_sampler_views + 1) * unsigned new_size = (stObj->num_sampler_views + 1) *
sizeof(struct pipe_sampler_view *); sizeof(struct st_sampler_view);
stObj->sampler_views = realloc(stObj->sampler_views, new_size); stObj->sampler_views = realloc(stObj->sampler_views, new_size);
free = &stObj->sampler_views[stObj->num_sampler_views++]; free = &stObj->sampler_views[stObj->num_sampler_views++];
*free = NULL; free->view = NULL;
} }
assert(*free == NULL); assert(free->view == NULL);
return free; return free;
} }
@@ -96,7 +96,7 @@ st_texture_release_sampler_view(struct st_context *st,
GLuint i; GLuint i;
for (i = 0; i < stObj->num_sampler_views; ++i) { for (i = 0; i < stObj->num_sampler_views; ++i) {
struct pipe_sampler_view **sv = &stObj->sampler_views[i]; struct pipe_sampler_view **sv = &stObj->sampler_views[i].view;
if (*sv && (*sv)->context == st->pipe) { if (*sv && (*sv)->context == st->pipe) {
pipe_sampler_view_reference(sv, NULL); pipe_sampler_view_reference(sv, NULL);
@@ -118,7 +118,7 @@ st_texture_release_all_sampler_views(struct st_context *st,
/* XXX This should use sampler_views[i]->pipe, not st->pipe */ /* XXX This should use sampler_views[i]->pipe, not st->pipe */
for (i = 0; i < stObj->num_sampler_views; ++i) for (i = 0; i < stObj->num_sampler_views; ++i)
pipe_sampler_view_release(st->pipe, &stObj->sampler_views[i]); pipe_sampler_view_release(st->pipe, &stObj->sampler_views[i].view);
} }
@@ -410,15 +410,19 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
const struct gl_sampler_object *samp, const struct gl_sampler_object *samp,
bool glsl130_or_later) bool glsl130_or_later)
{ {
struct pipe_sampler_view **sv; struct st_sampler_view *sv;
struct pipe_sampler_view *view;
sv = st_texture_get_sampler_view(st, stObj); sv = st_texture_get_sampler_view(st, stObj);
view = sv->view;
if (*sv) { if (view &&
sv->glsl130_or_later == glsl130_or_later &&
sv->sRGBDecode == samp->sRGBDecode) {
/* Debug check: make sure that the sampler view's parameters are /* Debug check: make sure that the sampler view's parameters are
* what they're supposed to be. * what they're supposed to be.
*/ */
MAYBE_UNUSED struct pipe_sampler_view *view = *sv; MAYBE_UNUSED struct pipe_sampler_view *view = sv->view;
assert(stObj->pt == view->texture); assert(stObj->pt == view->texture);
assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later)); assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
assert(get_sampler_view_format(st, stObj, samp) == view->format); assert(get_sampler_view_format(st, stObj, samp) == view->format);
@@ -436,12 +440,15 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
/* create new sampler view */ /* create new sampler view */
enum pipe_format format = get_sampler_view_format(st, stObj, samp); enum pipe_format format = get_sampler_view_format(st, stObj, samp);
*sv = st_create_texture_sampler_view_from_stobj(st, stObj, sv->glsl130_or_later = glsl130_or_later;
format, glsl130_or_later); sv->sRGBDecode = samp->sRGBDecode;
pipe_sampler_view_release(st->pipe, &sv->view);
view = sv->view =
st_create_texture_sampler_view_from_stobj(st, stObj, format, glsl130_or_later);
} }
return *sv; return view;
} }
@@ -449,7 +456,7 @@ struct pipe_sampler_view *
st_get_buffer_sampler_view_from_stobj(struct st_context *st, st_get_buffer_sampler_view_from_stobj(struct st_context *st,
struct st_texture_object *stObj) struct st_texture_object *stObj)
{ {
struct pipe_sampler_view **sv; struct st_sampler_view *sv;
struct st_buffer_object *stBuf = struct st_buffer_object *stBuf =
st_buffer_object(stObj->base.BufferObject); st_buffer_object(stObj->base.BufferObject);
@@ -459,7 +466,7 @@ st_get_buffer_sampler_view_from_stobj(struct st_context *st,
sv = st_texture_get_sampler_view(st, stObj); sv = st_texture_get_sampler_view(st, stObj);
struct pipe_resource *buf = stBuf->buffer; struct pipe_resource *buf = stBuf->buffer;
struct pipe_sampler_view *view = *sv; struct pipe_sampler_view *view = sv->view;
if (view && view->texture == buf) { if (view && view->texture == buf) {
/* Debug check: make sure that the sampler view's parameters are /* Debug check: make sure that the sampler view's parameters are
@@ -499,8 +506,8 @@ st_get_buffer_sampler_view_from_stobj(struct st_context *st,
templ.u.buf.offset = base; templ.u.buf.offset = base;
templ.u.buf.size = size; templ.u.buf.size = size;
pipe_sampler_view_reference(sv, NULL); pipe_sampler_view_release(st->pipe, &sv->view);
*sv = st->pipe->create_sampler_view(st->pipe, buf, &templ); view = sv->view = st->pipe->create_sampler_view(st->pipe, buf, &templ);
} }
return *sv; return view;
} }

View File

@@ -48,6 +48,19 @@ struct st_texture_image_transfer {
}; };
/**
* Container for one context's validated sampler view.
*/
struct st_sampler_view {
struct pipe_sampler_view *view;
/** The glsl version of the shader seen during validation */
bool glsl130_or_later;
/** The value of the sampler's sRGBDecode state during validation */
GLenum sRGBDecode;
};
/** /**
* Subclass of gl_texure_image. * Subclass of gl_texure_image.
*/ */
@@ -98,7 +111,7 @@ struct st_texture_object
/* Array of sampler views (one per context) attached to this texture /* Array of sampler views (one per context) attached to this texture
* object. Created lazily on first binding in context. * object. Created lazily on first binding in context.
*/ */
struct pipe_sampler_view **sampler_views; struct st_sampler_view *sampler_views;
/* True if this texture comes from the window system. Such a texture /* True if this texture comes from the window system. Such a texture
* cannot be reallocated and the format can only be changed with a sampler * cannot be reallocated and the format can only be changed with a sampler
@@ -129,11 +142,6 @@ struct st_texture_object
*/ */
uint layer_override; 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 * Set when the texture images of this texture object might not all be in
* the pipe_resource *pt above. * the pipe_resource *pt above.