diff --git a/src/mesa/meson.build b/src/mesa/meson.build index c664e9847e2..7b0a920807d 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -364,6 +364,8 @@ files_libmesa = files( 'state_tracker/st_scissor.h', 'state_tracker/st_shader_cache.c', 'state_tracker/st_shader_cache.h', + 'state_tracker/st_texcompress_compute.c', + 'state_tracker/st_texcompress_compute.h', 'state_tracker/st_texture.c', 'state_tracker/st_texture.h', 'state_tracker/st_util.h', diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 18eafd183b8..2ce5337fe85 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -56,6 +56,7 @@ #include "st_program.h" #include "st_sampler_view.h" #include "st_shader_cache.h" +#include "st_texcompress_compute.h" #include "st_texture.h" #include "st_util.h" #include "pipe/p_context.h" @@ -354,6 +355,10 @@ st_destroy_context_priv(struct st_context *st, bool destroy_pipe) st_destroy_drawpix(st); st_destroy_drawtex(st); st_destroy_pbo_helpers(st); + + if (st->transcode_astc) + st_destroy_texcompress_compute(st); + st_destroy_bound_texture_handles(st); st_destroy_bound_image_handles(st); @@ -772,6 +777,17 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe, return NULL; } + if (_mesa_has_compute_shaders(ctx) && + st->transcode_astc && !st_init_texcompress_compute(st)) { + /* Transcoding ASTC to DXT5 using compute shaders can provide a + * significant performance benefit over the CPU path. It isn't strictly + * necessary to fail if we can't use the compute shader path, but it's + * very convenient to do so. This should be rare. + */ + st_destroy_context_priv(st, false); + return NULL; + } + /* This must be done after extensions are initialized to enable persistent * mappings immediately. */ diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 6879f24cbf4..fa0f7c0828e 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -342,6 +342,10 @@ struct st_context bool use_gs; } pbo; + struct { + struct gl_program **progs; + } texcompress_compute; + /** for drawing with st_util_vertex */ struct cso_velems_state util_velems; diff --git a/src/mesa/state_tracker/st_texcompress_compute.c b/src/mesa/state_tracker/st_texcompress_compute.c new file mode 100644 index 00000000000..5090beddd0c --- /dev/null +++ b/src/mesa/state_tracker/st_texcompress_compute.c @@ -0,0 +1,98 @@ +/************************************************************************** + * + * Copyright © 2022 Intel Corporation + * + * 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 without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 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 "main/shaderapi.h" +#include "main/shaderobj.h" + +#include "state_tracker/st_context.h" +#include "state_tracker/st_texcompress_compute.h" + +#include "util/u_string.h" + +enum compute_program_id { + COMPUTE_PROGRAM_COUNT +}; + +static struct gl_program * PRINTFLIKE(3, 4) +get_compute_program(struct st_context *st, + enum compute_program_id prog_id, + const char *source_fmt, ...) +{ + /* Try to get the program from the cache. */ + assert(prog_id < COMPUTE_PROGRAM_COUNT); + if (st->texcompress_compute.progs[prog_id]) + return st->texcompress_compute.progs[prog_id]; + + /* Cache miss. Create the final source string. */ + char *source_str; + va_list ap; + va_start(ap, source_fmt); + int num_printed_bytes = vasprintf(&source_str, source_fmt, ap); + va_end(ap); + if (num_printed_bytes == -1) + return NULL; + + /* Compile and link the shader. Then, destroy the shader string. */ + const char *strings[] = { source_str }; + GLuint program = + _mesa_CreateShaderProgramv_impl(st->ctx, GL_COMPUTE_SHADER, 1, strings); + free(source_str); + + struct gl_shader_program *shProg = + _mesa_lookup_shader_program(st->ctx, program); + if (!shProg) + return NULL; + + if (shProg->data->LinkStatus == LINKING_FAILURE) { + fprintf(stderr, "Linking failed:\n%s\n", shProg->data->InfoLog); + _mesa_reference_shader_program(st->ctx, &shProg, NULL); + return NULL; + } + + /* Cache the program and return it. */ + return st->texcompress_compute.progs[prog_id] = + shProg->_LinkedShaders[MESA_SHADER_COMPUTE]->Program; +} + +bool +st_init_texcompress_compute(struct st_context *st) +{ + st->texcompress_compute.progs = + calloc(COMPUTE_PROGRAM_COUNT, sizeof(struct gl_program *)); + if (!st->texcompress_compute.progs) + return false; + + return true; +} + +void +st_destroy_texcompress_compute(struct st_context *st) +{ + /* The programs in the array are part of the gl_context (in st->ctx).They + * are automatically destroyed when the context is destroyed (via + * _mesa_free_context_data -> ... -> free_shader_program_data_cb). + */ + free(st->texcompress_compute.progs); +} diff --git a/src/mesa/state_tracker/st_texcompress_compute.h b/src/mesa/state_tracker/st_texcompress_compute.h new file mode 100644 index 00000000000..f438d5f3563 --- /dev/null +++ b/src/mesa/state_tracker/st_texcompress_compute.h @@ -0,0 +1,35 @@ +/************************************************************************** + * + * Copyright © 2022 Intel Corporation + * + * 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 without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 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. + * + **************************************************************************/ + +#ifndef ST_TEXCOMPRESS_COMPUTE_H +#define ST_TEXCOMPRESS_COMPUTE_H + +bool +st_init_texcompress_compute(struct st_context *st); + +void +st_destroy_texcompress_compute(struct st_context *st); + +#endif /* ST_TEXCOMPRESS_COMPUTE_H */