X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_texture.c;h=a2a310daab4cfe640209edb8ac57441c09bbe58c;hb=500b0735c0caa293d22fb3728cb76d267a016834;hp=7da111f39f3bf6016a050d6e8ebfe6ceadaa7044;hpb=b6b915afa45da8e0da3ad315f523051ae1b5d836;p=mesa.git diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 7da111f39f3..a2a310daab4 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 VMware, Inc. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include @@ -37,10 +37,11 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_rect.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "tgsi/tgsi_from_mesa.h" #define DBG if(0) printf @@ -55,14 +56,14 @@ struct pipe_resource * st_texture_create(struct st_context *st, enum pipe_texture_target target, - enum pipe_format format, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, + enum pipe_format format, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint layers, GLuint nr_samples, - GLuint bind ) + GLuint bind) { struct pipe_resource pt, *newtex; struct pipe_screen *screen = st->pipe->screen; @@ -78,7 +79,7 @@ st_texture_create(struct st_context *st, (int) target, util_format_name(format), last_level); assert(format); - assert(screen->is_format_supported(screen, format, target, 0, + assert(screen->is_format_supported(screen, format, target, 0, 0, PIPE_BIND_SAMPLER_VIEW)); memset(&pt, 0, sizeof(pt)); @@ -94,6 +95,7 @@ st_texture_create(struct st_context *st, /* only set this for OpenGL textures, not renderbuffers */ pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY; pt.nr_samples = nr_samples; + pt.nr_storage_samples = nr_samples; newtex = screen->resource_create(screen, &pt); @@ -205,9 +207,9 @@ st_texture_match_image(struct st_context *st, unsigned ptWidth; uint16_t ptHeight, ptDepth, ptLayers; - /* Images with borders are never pulled into mipmap textures. + /* Images with borders are never pulled into mipmap textures. */ - if (image->Border) + if (image->Border) return GL_FALSE; /* Check if this image's format matches the established texture's format. @@ -315,6 +317,7 @@ st_texture_image_unmap(struct st_context *st, *transfer = NULL; } + /** * For debug only: get/print center pixel in the src resource. */ @@ -412,8 +415,8 @@ st_create_color_map_texture(struct gl_context *ctx) /* find an RGBA texture format */ format = st_choose_format(st, GL_RGBA, GL_NONE, GL_NONE, - PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, - FALSE); + PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW, + false, false); /* create texture for color map/table */ pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0, @@ -422,6 +425,86 @@ st_create_color_map_texture(struct gl_context *ctx) } +/** + * Destroy bound texture handles for the given stage. + */ +static void +st_destroy_bound_texture_handles_per_stage(struct st_context *st, + enum pipe_shader_type shader) +{ + struct st_bound_handles *bound_handles = &st->bound_texture_handles[shader]; + struct pipe_context *pipe = st->pipe; + unsigned i; + + if (likely(!bound_handles->num_handles)) + return; + + for (i = 0; i < bound_handles->num_handles; i++) { + uint64_t handle = bound_handles->handles[i]; + + pipe->make_texture_handle_resident(pipe, handle, false); + pipe->delete_texture_handle(pipe, handle); + } + free(bound_handles->handles); + bound_handles->handles = NULL; + bound_handles->num_handles = 0; +} + + +/** + * Destroy all bound texture handles in the context. + */ +void +st_destroy_bound_texture_handles(struct st_context *st) +{ + unsigned i; + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + st_destroy_bound_texture_handles_per_stage(st, i); + } +} + + +/** + * Destroy bound image handles for the given stage. + */ +static void +st_destroy_bound_image_handles_per_stage(struct st_context *st, + enum pipe_shader_type shader) +{ + struct st_bound_handles *bound_handles = &st->bound_image_handles[shader]; + struct pipe_context *pipe = st->pipe; + unsigned i; + + if (likely(!bound_handles->num_handles)) + return; + + for (i = 0; i < bound_handles->num_handles; i++) { + uint64_t handle = bound_handles->handles[i]; + + pipe->make_image_handle_resident(pipe, handle, GL_READ_WRITE, false); + pipe->delete_image_handle(pipe, handle); + } + free(bound_handles->handles); + bound_handles->handles = NULL; + bound_handles->num_handles = 0; +} + + +/** + * Destroy all bound image handles in the context. + */ +void +st_destroy_bound_image_handles(struct st_context *st) +{ + unsigned i; + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + st_destroy_bound_image_handles_per_stage(st, i); + } +} + + /** * Create a texture handle from a texture unit. */ @@ -429,19 +512,19 @@ static GLuint64 st_create_texture_handle_from_unit(struct st_context *st, struct gl_program *prog, GLuint texUnit) { - struct gl_context *ctx = st->ctx; - struct gl_texture_object *texObj; struct pipe_context *pipe = st->pipe; struct pipe_sampler_view *view; - struct pipe_sampler_state sampler; + struct pipe_sampler_state sampler = {0}; - if (!st_update_single_texture(st, &view, texUnit, prog->sh.data->Version)) + /* TODO: Clarify the interaction of ARB_bindless_texture and EXT_texture_sRGB_decode */ + st_update_single_texture(st, &view, texUnit, prog->sh.data->Version >= 130, true); + if (!view) return 0; - st_convert_sampler_from_unit(st, &sampler, texUnit); + if (view->target != PIPE_BUFFER) + st_convert_sampler_from_unit(st, &sampler, texUnit); - texObj = ctx->Texture.Unit[texUnit]._Current; - assert(texObj); + assert(st->ctx->Texture.Unit[texUnit]._Current); return pipe->create_texture_handle(pipe, view, &sampler); } @@ -457,7 +540,101 @@ st_create_image_handle_from_unit(struct st_context *st, struct pipe_context *pipe = st->pipe; struct pipe_image_view img; - st_convert_image_from_unit(st, &img, imgUnit); + st_convert_image_from_unit(st, &img, imgUnit, GL_READ_WRITE); return pipe->create_image_handle(pipe, &img); } + + +/** + * Make all bindless samplers bound to texture units resident in the context. + */ +void +st_make_bound_samplers_resident(struct st_context *st, + struct gl_program *prog) +{ + enum pipe_shader_type shader = pipe_shader_type_from_mesa(prog->info.stage); + struct st_bound_handles *bound_handles = &st->bound_texture_handles[shader]; + struct pipe_context *pipe = st->pipe; + GLuint64 handle; + int i; + + /* Remove previous bound texture handles for this stage. */ + st_destroy_bound_texture_handles_per_stage(st, shader); + + if (likely(!prog->sh.HasBoundBindlessSampler)) + return; + + for (i = 0; i < prog->sh.NumBindlessSamplers; i++) { + struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i]; + + if (!sampler->bound) + continue; + + /* Request a new texture handle from the driver and make it resident. */ + handle = st_create_texture_handle_from_unit(st, prog, sampler->unit); + if (!handle) + continue; + + pipe->make_texture_handle_resident(st->pipe, handle, true); + + /* Overwrite the texture unit value by the resident handle before + * uploading the constant buffer. + */ + *(uint64_t *)sampler->data = handle; + + /* Store the handle in the context. */ + bound_handles->handles = (uint64_t *) + realloc(bound_handles->handles, + (bound_handles->num_handles + 1) * sizeof(uint64_t)); + bound_handles->handles[bound_handles->num_handles] = handle; + bound_handles->num_handles++; + } +} + + +/** + * Make all bindless images bound to image units resident in the context. + */ +void +st_make_bound_images_resident(struct st_context *st, + struct gl_program *prog) +{ + enum pipe_shader_type shader = pipe_shader_type_from_mesa(prog->info.stage); + struct st_bound_handles *bound_handles = &st->bound_image_handles[shader]; + struct pipe_context *pipe = st->pipe; + GLuint64 handle; + int i; + + /* Remove previous bound image handles for this stage. */ + st_destroy_bound_image_handles_per_stage(st, shader); + + if (likely(!prog->sh.HasBoundBindlessImage)) + return; + + for (i = 0; i < prog->sh.NumBindlessImages; i++) { + struct gl_bindless_image *image = &prog->sh.BindlessImages[i]; + + if (!image->bound) + continue; + + /* Request a new image handle from the driver and make it resident. */ + handle = st_create_image_handle_from_unit(st, prog, image->unit); + if (!handle) + continue; + + pipe->make_image_handle_resident(st->pipe, handle, GL_READ_WRITE, true); + + /* Overwrite the image unit value by the resident handle before uploading + * the constant buffer. + */ + *(uint64_t *)image->data = handle; + + /* Store the handle in the context. */ + bound_handles->handles = (uint64_t *) + realloc(bound_handles->handles, + (bound_handles->num_handles + 1) * sizeof(uint64_t)); + bound_handles->handles[bound_handles->num_handles] = handle; + bound_handles->num_handles++; + } +}