diff options
-rw-r--r-- | src/mesa/state_tracker/st_atom_texture.c | 58 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 52 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_texture.c | 16 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_texture.h | 5 |
4 files changed, 101 insertions, 30 deletions
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index bfa16dc5ac7..45f1f6b02f1 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -370,7 +370,7 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st, static struct pipe_sampler_view * st_get_texture_sampler_view_from_stobj(struct st_context *st, struct st_texture_object *stObj, - enum pipe_format format, + const struct gl_sampler_object *samp, unsigned glsl_version) { struct pipe_sampler_view **sv; @@ -381,34 +381,42 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, sv = st_texture_get_sampler_view(st, stObj); - /* if sampler view has changed dereference it */ if (*sv) { - if (check_sampler_swizzle(st, stObj, *sv, glsl_version) || - (format != (*sv)->format) || - gl_target_to_pipe(stObj->base.Target) != (*sv)->target || - stObj->base.MinLevel + stObj->base.BaseLevel != (*sv)->u.tex.first_level || - last_level(stObj) != (*sv)->u.tex.last_level || - stObj->base.MinLayer != (*sv)->u.tex.first_layer || - last_layer(stObj) != (*sv)->u.tex.last_layer) { - pipe_sampler_view_reference(sv, NULL); + /* Debug check: make sure that the sampler view's parameters are + * what they're supposed to be. + */ + struct pipe_sampler_view *view = *sv; + assert(!check_sampler_swizzle(st, stObj, view, glsl_version)); + assert(get_sampler_view_format(st, stObj, samp) == view->format); + assert(gl_target_to_pipe(stObj->base.Target) == view->target); + if (stObj->base.Target == GL_TEXTURE_BUFFER) { + unsigned base = stObj->base.BufferOffset; + unsigned size = MIN2(stObj->pt->width0 - base, + (unsigned) stObj->base.BufferSize); + assert(view->u.buf.offset == base); + assert(view->u.buf.size == size); + } + else { + assert(stObj->base.MinLevel + stObj->base.BaseLevel == + view->u.tex.first_level); + assert(last_level(stObj) == view->u.tex.last_level); + assert(stObj->base.MinLayer == view->u.tex.first_layer); + assert(last_layer(stObj) == view->u.tex.last_layer); } } + else { + /* create new sampler view */ + enum pipe_format format = get_sampler_view_format(st, stObj, samp); - if (!*sv) { *sv = st_create_texture_sampler_view_from_stobj(st, stObj, format, glsl_version); - } else if ((*sv)->context != st->pipe) { - /* Recreate view in correct context, use existing view as template */ - struct pipe_sampler_view *new_sv = - st->pipe->create_sampler_view(st->pipe, stObj->pt, *sv); - pipe_sampler_view_reference(sv, NULL); - *sv = new_sv; } return *sv; } + static GLboolean update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view, @@ -418,7 +426,6 @@ update_single_texture(struct st_context *st, const struct gl_sampler_object *samp; struct gl_texture_object *texObj; struct st_texture_object *stObj; - enum pipe_format view_format; GLboolean retval; samp = _mesa_get_samplerobj(ctx, texUnit); @@ -437,11 +444,20 @@ update_single_texture(struct st_context *st, return GL_FALSE; } - view_format = get_sampler_view_format(st, stObj, samp); + /* Check a few pieces of state outside the texture object to see if we + * need to force revalidation. + */ + if (stObj->prev_glsl_version != glsl_version || + stObj->prev_sRGBDecode != samp->sRGBDecode) { + + st_texture_release_all_sampler_views(st, stObj); + + stObj->prev_glsl_version = glsl_version; + stObj->prev_sRGBDecode = samp->sRGBDecode; + } *sampler_view = - st_get_texture_sampler_view_from_stobj(st, stObj, view_format, - glsl_version); + st_get_texture_sampler_view_from_stobj(st, stObj, samp, glsl_version); return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index fa360b9fed4..392b2a4b512 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -176,6 +176,8 @@ static void st_FreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *texImage) { + struct st_context *st = st_context(ctx); + struct st_texture_object *stObj = st_texture_object(texImage->TexObject); struct st_texture_image *stImage = st_texture_image(texImage); DBG("%s\n", __func__); @@ -192,6 +194,11 @@ st_FreeTextureImageBuffer(struct gl_context *ctx, free(stImage->etc_data); stImage->etc_data = NULL; } + + /* if the texture image is being deallocated, the structure of the + * texture is changing so we'll likely need a new sampler view. + */ + st_texture_release_all_sampler_views(st, stObj); } bool @@ -2778,6 +2785,7 @@ st_TextureView(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_texture_object *origTexObj) { + struct st_context *st = st_context(ctx); struct st_texture_object *orig = st_texture_object(origTexObj); struct st_texture_object *tex = st_texture_object(texObj); struct gl_texture_image *image = texObj->Image[0][0]; @@ -2805,6 +2813,11 @@ st_TextureView(struct gl_context *ctx, tex->lastLevel = numLevels - 1; + /* free texture sampler views. They need to be recreated when we + * change the texture view parameters. + */ + st_texture_release_all_sampler_views(st, tex); + return GL_TRUE; } @@ -2839,6 +2852,43 @@ st_ClearTexSubImage(struct gl_context *ctx, pipe->clear_texture(pipe, pt, level, &box, clearValue ? clearValue : zeros); } + +/** + * Called via the glTexParam*() function, but only when some texture object + * state has actually changed. + */ +static void +st_TexParameter(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params) +{ + struct st_context *st = st_context(ctx); + struct st_texture_object *stObj = st_texture_object(texObj); + + switch (pname) { + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_DEPTH_TEXTURE_MODE: + case GL_DEPTH_STENCIL_TEXTURE_MODE: + case GL_TEXTURE_SRGB_DECODE_EXT: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_SWIZZLE_RGBA: + case GL_TEXTURE_BUFFER_SIZE: + case GL_TEXTURE_BUFFER_OFFSET: + /* changing any of these texture parameters means we must create + * new sampler views. + */ + st_texture_release_all_sampler_views(st, stObj); + break; + default: + ; /* nothing */ + } +} + + void st_init_texture_functions(struct dd_function_table *functions) { @@ -2871,4 +2921,6 @@ st_init_texture_functions(struct dd_function_table *functions) functions->AllocTextureStorage = st_AllocTextureStorage; functions->TextureView = st_TextureView; functions->ClearTexSubImage = st_ClearTexSubImage; + + functions->TexParameter = st_TexParameter; } diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 42616ca4cb4..32e5b84a5af 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -428,19 +428,17 @@ struct pipe_sampler_view ** st_texture_get_sampler_view(struct st_context *st, struct st_texture_object *stObj) { - struct pipe_sampler_view *used = NULL, **free = NULL; + struct pipe_sampler_view **free = NULL; GLuint i; for (i = 0; i < stObj->num_sampler_views; ++i) { struct pipe_sampler_view **sv = &stObj->sampler_views[i]; /* Is the array entry used ? */ if (*sv) { - /* Yes, check if it's the right one */ - if ((*sv)->context == st->pipe) + /* check if the context matches */ + if ((*sv)->context == st->pipe) { return sv; - - /* Wasn't the right one, but remember it as template */ - used = *sv; + } } else { /* Found a free slot, remember that */ free = sv; @@ -458,9 +456,7 @@ st_texture_get_sampler_view(struct st_context *st, *free = NULL; } - /* Add just any sampler view to be used as a template */ - if (used) - pipe_sampler_view_reference(free, used); + assert(*free == NULL); return free; } @@ -512,4 +508,6 @@ st_texture_free_sampler_views(struct st_texture_object *stObj) * those two headers we can trash the heap. */ FREE(stObj->sampler_views); + stObj->sampler_views = NULL; + stObj->num_sampler_views = 0; } diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index d2c4f3f880c..9c9a05b5605 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -107,6 +107,11 @@ struct st_texture_object * views and surfaces instead of pt->format. */ enum pipe_format surface_format; + + /** The glsl version of the shader seen during the previous validation */ + unsigned prev_glsl_version; + /** The value of the sampler's sRGBDecode state at the previous validation */ + GLenum prev_sRGBDecode; }; |