From: Marek Olšák <marek.ol...@amd.com> Remove handling of buffers from all texture paths. This simplifies things for both buffers and textures.
get_sampler_view_format is also cleaned up not to call util_format_is_depth_and_stencil. --- src/mesa/state_tracker/st_atom_image.c | 29 ++++-- src/mesa/state_tracker/st_atom_texture.c | 5 + src/mesa/state_tracker/st_cb_texture.c | 17 --- src/mesa/state_tracker/st_cb_texture.h | 1 + src/mesa/state_tracker/st_sampler_view.c | 174 ++++++++++++++++++------------- src/mesa/state_tracker/st_sampler_view.h | 3 + 6 files changed, 131 insertions(+), 98 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c index 381eca1..eb873a6 100644 --- a/src/mesa/state_tracker/st_atom_image.c +++ b/src/mesa/state_tracker/st_atom_image.c @@ -29,64 +29,80 @@ #include "program/prog_parameter.h" #include "program/prog_print.h" #include "compiler/glsl/ir_uniform.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" #include "util/u_surface.h" #include "cso_cache/cso_context.h" +#include "st_cb_bufferobjects.h" #include "st_cb_texture.h" #include "st_debug.h" #include "st_texture.h" #include "st_context.h" #include "st_atom.h" #include "st_program.h" #include "st_format.h" /** * Convert a gl_image_unit object to a pipe_image_view object. */ void st_convert_image(const struct st_context *st, const struct gl_image_unit *u, struct pipe_image_view *img) { struct st_texture_object *stObj = st_texture_object(u->TexObj); - img->resource = stObj->pt; img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat); switch (u->Access) { case GL_READ_ONLY: img->access = PIPE_IMAGE_ACCESS_READ; break; case GL_WRITE_ONLY: img->access = PIPE_IMAGE_ACCESS_WRITE; break; case GL_READ_WRITE: img->access = PIPE_IMAGE_ACCESS_READ_WRITE; break; default: unreachable("bad gl_image_unit::Access"); } - if (stObj->pt->target == PIPE_BUFFER) { + if (stObj->base.Target == GL_TEXTURE_BUFFER) { + struct st_buffer_object *stbuf = + st_buffer_object(stObj->base.BufferObject); unsigned base, size; + if (!stbuf || !stbuf->buffer) { + memset(img, 0, sizeof(*img)); + return; + } + struct pipe_resource *buf = stbuf->buffer; + base = stObj->base.BufferOffset; - assert(base < stObj->pt->width0); - size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize); + assert(base < buf->width0); + size = MIN2(buf->width0 - base, (unsigned)stObj->base.BufferSize); + img->resource = stbuf->buffer; img->u.buf.offset = base; img->u.buf.size = size; } else { + if (!st_finalize_texture(st->ctx, st->pipe, u->TexObj, 0) || + !stObj->pt) { + memset(img, 0, sizeof(*img)); + return; + } + + img->resource = stObj->pt; img->u.tex.level = u->Level + stObj->base.MinLevel; if (stObj->pt->target == PIPE_TEXTURE_3D) { if (u->Layered) { img->u.tex.first_layer = 0; img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1; } else { img->u.tex.first_layer = u->_Layer; img->u.tex.last_layer = u->_Layer; } } else { @@ -111,26 +127,23 @@ st_bind_images(struct st_context *st, struct gl_program *prog, struct gl_program_constants *c; if (!prog || !st->pipe->set_shader_images) return; c = &st->ctx->Const.Program[prog->info.stage]; for (i = 0; i < prog->info.num_images; i++) { struct gl_image_unit *u = &st->ctx->ImageUnits[prog->sh.ImageUnits[i]]; - struct st_texture_object *stObj = st_texture_object(u->TexObj); struct pipe_image_view *img = &images[i]; - if (!_mesa_is_image_unit_valid(st->ctx, u) || - !st_finalize_texture(st->ctx, st->pipe, u->TexObj, 0) || - !stObj->pt) { + if (!_mesa_is_image_unit_valid(st->ctx, u)) { memset(img, 0, sizeof(*img)); continue; } st_convert_image(st, u, img); } cso_set_shader_images(st->cso_context, shader_type, 0, prog->info.num_images, images); /* clear out any stale shader images */ if (prog->info.num_images < c->MaxImageUniforms) diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index ddde445..f696f0e 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -63,20 +63,25 @@ update_single_texture(struct st_context *st, struct st_texture_object *stObj; GLboolean retval; samp = _mesa_get_samplerobj(ctx, texUnit); texObj = ctx->Texture.Unit[texUnit]._Current; assert(texObj); stObj = st_texture_object(texObj); + if (unlikely(texObj->Target == GL_TEXTURE_BUFFER)) { + *sampler_view = st_get_buffer_sampler_view_from_stobj(st, stObj); + return; + } + retval = st_finalize_texture(ctx, st->pipe, texObj, 0); if (!retval) { /* out of mem */ *sampler_view = NULL; return; } /* Check a few pieces of state outside the texture object to see if we * need to force revalidation. */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 443bb7b..540519f 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -2462,37 +2462,20 @@ st_finalize_texture(struct gl_context *ctx, * incomplete. In that case, we'll have set stObj->lastLevel before * we get here. */ if (stObj->base.Sampler.MinFilter == GL_LINEAR || stObj->base.Sampler.MinFilter == GL_NEAREST) stObj->lastLevel = stObj->base.BaseLevel; else stObj->lastLevel = stObj->base._MaxLevel; } - if (tObj->Target == GL_TEXTURE_BUFFER) { - struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject); - - if (!st_obj) { - pipe_resource_reference(&stObj->pt, NULL); - st_texture_release_all_sampler_views(st, stObj); - return GL_TRUE; - } - - if (st_obj->buffer != stObj->pt) { - pipe_resource_reference(&stObj->pt, st_obj->buffer); - st_texture_release_all_sampler_views(st, stObj); - } - return GL_TRUE; - - } - firstImage = st_texture_image_const(stObj->base.Image[cubeMapFace][stObj->base.BaseLevel]); assert(firstImage); /* Skip the loop over images in the common case of no images having * changed. But if the GL_BASE_LEVEL or GL_MAX_LEVEL change to something we * haven't looked at, then we do need to look at those new images. */ if (!stObj->needs_validation && stObj->base.BaseLevel >= stObj->validated_first_level && stObj->lastLevel <= stObj->validated_last_level) { diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index f647b16..ed6ed16 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -30,20 +30,21 @@ #define ST_CB_TEXTURE_H #include "main/glheader.h" struct dd_function_table; struct gl_context; struct gl_texture_object; struct pipe_context; struct st_context; +struct st_texture_object; extern enum pipe_texture_target gl_target_to_pipe(GLenum target); unsigned st_get_blit_mask(GLenum srcFormat, GLenum dstFormat); extern GLboolean st_finalize_texture(struct gl_context *ctx, struct pipe_context *pipe, diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index c78a987..f0cf9cb 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -31,20 +31,21 @@ #include "main/macros.h" #include "main/mtypes.h" #include "main/teximage.h" #include "main/texobj.h" #include "program/prog_instruction.h" #include "st_context.h" #include "st_sampler_view.h" #include "st_texture.h" #include "st_format.h" +#include "st_cb_bufferobjects.h" #include "st_cb_texture.h" /** * Try to find a matching sampler view for the given context. * If none is found an empty slot is initialized with a * template and returned instead. */ static struct pipe_sampler_view ** st_texture_get_sampler_view(struct st_context *st, @@ -355,97 +356,71 @@ last_layer(const struct st_texture_object *stObj) /** * Determine the format for the texture sampler view. */ static enum pipe_format get_sampler_view_format(struct st_context *st, const struct st_texture_object *stObj, const struct gl_sampler_object *samp) { enum pipe_format format; - if (stObj->base.Target == GL_TEXTURE_BUFFER) { - format = - st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat); - } - else { - format = - stObj->surface_based ? stObj->surface_format : stObj->pt->format; + GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat; + format = stObj->surface_based ? stObj->surface_format : stObj->pt->format; - if (util_format_is_depth_and_stencil(format)) { - if (stObj->base.StencilSampling) { - format = util_format_stencil_only(format); - } - else { - GLenum baseFormat = _mesa_texture_base_format(&stObj->base); - if (baseFormat == GL_STENCIL_INDEX) { - format = util_format_stencil_only(format); - } - } - } - else { - /* If sRGB decoding is off, use the linear format */ - if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) { - format = util_format_linear(format); - } + if (baseFormat == GL_DEPTH_COMPONENT || + baseFormat == GL_DEPTH_STENCIL || + baseFormat == GL_STENCIL_INDEX) { + if (stObj->base.StencilSampling || baseFormat == GL_STENCIL_INDEX) + format = util_format_stencil_only(format); - /* Use R8_UNORM for video formats */ - switch (format) { - case PIPE_FORMAT_NV12: - case PIPE_FORMAT_IYUV: - format = PIPE_FORMAT_R8_UNORM; - break; - default: - break; - } - } + return format; } + /* If sRGB decoding is off, use the linear format */ + if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) + format = util_format_linear(format); + + /* Use R8_UNORM for video formats */ + switch (format) { + case PIPE_FORMAT_NV12: + case PIPE_FORMAT_IYUV: + format = PIPE_FORMAT_R8_UNORM; + break; + default: + break; + } return format; } static struct pipe_sampler_view * st_create_texture_sampler_view_from_stobj(struct st_context *st, struct st_texture_object *stObj, enum pipe_format format, unsigned glsl_version) { struct pipe_sampler_view templ; unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl_version); u_sampler_view_default_template(&templ, stObj->pt, format); - if (stObj->pt->target == PIPE_BUFFER) { - unsigned base, size; - - base = stObj->base.BufferOffset; - if (base >= stObj->pt->width0) - return NULL; - size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize); - if (!size) - return NULL; - - templ.u.buf.offset = base; - templ.u.buf.size = size; + 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->layer_override) { + templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override; } else { - 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->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); - templ.target = gl_target_to_pipe(stObj->base.Target); + 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); + 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); } @@ -461,42 +436,95 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, return NULL; } sv = st_texture_get_sampler_view(st, stObj); 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, 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; - MAYBE_UNUSED 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->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)); - } + assert(stObj->base.MinLevel + stObj->base.BaseLevel == + view->u.tex.first_level); + assert(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); *sv = st_create_texture_sampler_view_from_stobj(st, stObj, format, glsl_version); } return *sv; } + + +struct pipe_sampler_view * +st_get_buffer_sampler_view_from_stobj(struct st_context *st, + struct st_texture_object *stObj) +{ + struct pipe_sampler_view **sv; + struct st_buffer_object *stBuf = + st_buffer_object(stObj->base.BufferObject); + + if (!stBuf || !stBuf->buffer) + return NULL; + + sv = st_texture_get_sampler_view(st, stObj); + + struct pipe_resource *buf = stBuf->buffer; + struct pipe_sampler_view *view = *sv; + + if (view && view->texture == buf) { + /* Debug check: make sure that the sampler view's parameters are + * what they're supposed to be. + */ + assert(st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat) + == view->format); + assert(view->target == PIPE_BUFFER); + unsigned base = stObj->base.BufferOffset; + MAYBE_UNUSED unsigned size = MIN2(buf->width0 - base, + (unsigned) stObj->base.BufferSize); + assert(view->u.buf.offset == base); + assert(view->u.buf.size == size); + } else { + unsigned base = stObj->base.BufferOffset; + + if (base >= buf->width0) + return NULL; + + unsigned size = buf->width0 - base; + size = MIN2(size, (unsigned)stObj->base.BufferSize); + if (!size) + return NULL; + + /* Create a new sampler view. There is no need to clear the entire + * structure (consider CPU overhead). + */ + struct pipe_sampler_view templ; + + templ.format = + st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat); + templ.target = PIPE_BUFFER; + templ.swizzle_r = PIPE_SWIZZLE_X; + templ.swizzle_g = PIPE_SWIZZLE_Y; + templ.swizzle_b = PIPE_SWIZZLE_Z; + templ.swizzle_a = PIPE_SWIZZLE_W; + templ.u.buf.offset = base; + templ.u.buf.size = size; + + pipe_sampler_view_reference(sv, NULL); + *sv = st->pipe->create_sampler_view(st->pipe, buf, &templ); + } + return *sv; +} diff --git a/src/mesa/state_tracker/st_sampler_view.h b/src/mesa/state_tracker/st_sampler_view.h index 6825ceb..b08ca4a 100644 --- a/src/mesa/state_tracker/st_sampler_view.h +++ b/src/mesa/state_tracker/st_sampler_view.h @@ -68,12 +68,15 @@ st_texture_release_all_sampler_views(struct st_context *st, void st_texture_free_sampler_views(struct st_texture_object *stObj); struct pipe_sampler_view * st_get_texture_sampler_view_from_stobj(struct st_context *st, struct st_texture_object *stObj, const struct gl_sampler_object *samp, unsigned glsl_version); +struct pipe_sampler_view * +st_get_buffer_sampler_view_from_stobj(struct st_context *st, + struct st_texture_object *stObj); #endif /* ST_SAMPLER_VIEW_H */ -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev