From f0ecd36ef8e10c087738c92cf62bad3815366963 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 12 Jun 2017 01:00:04 +0200 Subject: [PATCH] st/mesa: add an entirely separate codepath for setting up buffer views MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. v2: also update st_NewTextureHandle Reviewed-by: Nicolai Hähnle (v1) --- 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 | 22 +-- 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, 134 insertions(+), 100 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c index 5b914637a2a..1c4980173f4 100644 --- a/src/mesa/state_tracker/st_atom_image.c +++ b/src/mesa/state_tracker/st_atom_image.c @@ -36,6 +36,7 @@ #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" @@ -53,7 +54,6 @@ st_convert_image(const struct st_context *st, const struct gl_image_unit *u, { 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) { @@ -70,16 +70,32 @@ st_convert_image(const struct st_context *st, const struct gl_image_unit *u, 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) { @@ -111,11 +127,8 @@ st_convert_image_from_unit(const struct st_context *st, GLuint imgUnit) { struct gl_image_unit *u = &st->ctx->ImageUnits[imgUnit]; - struct st_texture_object *stObj = st_texture_object(u->TexObj); - 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)); return; } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 20cc859c941..b71b73506f8 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -73,6 +73,11 @@ st_update_single_texture(struct st_context *st, 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 */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 317bb5324d0..9798321d4bc 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -2469,23 +2469,6 @@ st_finalize_texture(struct gl_context *ctx, 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); @@ -2923,10 +2906,11 @@ st_NewTextureHandle(struct gl_context *ctx, struct gl_texture_object *texObj, return 0; st_convert_sampler(st, texObj, sampObj, &sampler); + view = st_get_texture_sampler_view_from_stobj(st, stObj, sampObj, 0); + } else { + view = st_get_buffer_sampler_view_from_stobj(st, stObj); } - view = st_get_texture_sampler_view_from_stobj(st, stObj, sampObj, 0); - return pipe->create_texture_handle(pipe, view, &sampler); } diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index f647b16c8dc..ed6ed16fed8 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -37,6 +37,7 @@ 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); diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index c78a987486e..f0cf9cb929a 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -38,6 +38,7 @@ #include "st_sampler_view.h" #include "st_texture.h" #include "st_format.h" +#include "st_cb_bufferobjects.h" #include "st_cb_texture.h" @@ -362,43 +363,31 @@ get_sampler_view_format(struct st_context *st, { 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; } @@ -414,31 +403,17 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st, 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); @@ -468,26 +443,18 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, * 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 */ @@ -500,3 +467,64 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, 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 6825cebdf6d..b08ca4a70f2 100644 --- a/src/mesa/state_tracker/st_sampler_view.h +++ b/src/mesa/state_tracker/st_sampler_view.h @@ -75,5 +75,8 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, 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.30.2