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:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user