From 79abf6a17e429fae79555c2960771d60f486b829 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Sun, 5 Dec 2021 13:40:30 +1100 Subject: [PATCH] mesa: move _mesa_ensure_and_associate_uniform_storage() to uniform_query.cpp This is where all the other functions that handle uniform storage live. Reviewed-by: Dave Airlie Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/mesa/main/uniform_query.cpp | 171 +++++++++++++++++++++++ src/mesa/main/uniforms.h | 5 + src/mesa/program/ir_to_mesa.cpp | 170 ---------------------- src/mesa/program/ir_to_mesa.h | 4 - src/mesa/state_tracker/st_shader_cache.c | 2 +- 5 files changed, 177 insertions(+), 175 deletions(-) diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index 700d6afc1ac..36faccf4257 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -922,6 +922,177 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, } +static void +associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog) +{ + struct gl_program_parameter_list *params = prog->Parameters; + gl_shader_stage shader_type = prog->info.stage; + + _mesa_disallow_parameter_storage_realloc(params); + + /* After adding each uniform to the parameter list, connect the storage for + * the parameter with the tracking structure used by the API for the + * uniform. + */ + unsigned last_location = unsigned(~0); + for (unsigned i = 0; i < params->NumParameters; i++) { + if (params->Parameters[i].Type != PROGRAM_UNIFORM) + continue; + + unsigned location = params->Parameters[i].UniformStorageIndex; + + struct gl_uniform_storage *storage = + &shader_program->data->UniformStorage[location]; + + /* Do not associate any uniform storage to built-in uniforms */ + if (storage->builtin) + continue; + + if (location != last_location) { + enum gl_uniform_driver_format format = uniform_native; + unsigned columns = 0; + + int dmul; + if (ctx->Const.PackedDriverUniformStorage && !prog->info.is_arb_asm) { + dmul = storage->type->vector_elements * sizeof(float); + } else { + dmul = 4 * sizeof(float); + } + + switch (storage->type->base_type) { + case GLSL_TYPE_UINT64: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_UINT: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_UINT8: + assert(ctx->Const.NativeIntegers); + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_INT64: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_INT: + case GLSL_TYPE_INT16: + case GLSL_TYPE_INT8: + format = + (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; + columns = 1; + break; + case GLSL_TYPE_DOUBLE: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: + format = uniform_native; + columns = storage->type->matrix_columns; + break; + case GLSL_TYPE_BOOL: + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_TEXTURE: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_SUBROUTINE: + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_ATOMIC_UINT: + case GLSL_TYPE_ARRAY: + case GLSL_TYPE_VOID: + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_ERROR: + case GLSL_TYPE_INTERFACE: + case GLSL_TYPE_FUNCTION: + assert(!"Should not get here."); + break; + } + + unsigned pvo = params->Parameters[i].ValueOffset; + _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul, + format, + ¶ms->ParameterValues[pvo]); + + /* When a bindless sampler/image is bound to a texture/image unit, we + * have to overwrite the constant value by the resident handle + * directly in the constant buffer before the next draw. One solution + * is to keep track a pointer to the base of the data. + */ + if (storage->is_bindless && (prog->sh.NumBindlessSamplers || + prog->sh.NumBindlessImages)) { + unsigned array_elements = MAX2(1, storage->array_elements); + + for (unsigned j = 0; j < array_elements; ++j) { + unsigned unit = storage->opaque[shader_type].index + j; + + if (storage->type->without_array()->is_sampler()) { + assert(unit >= 0 && unit < prog->sh.NumBindlessSamplers); + prog->sh.BindlessSamplers[unit].data = + ¶ms->ParameterValues[pvo] + 4 * j; + } else if (storage->type->without_array()->is_image()) { + assert(unit >= 0 && unit < prog->sh.NumBindlessImages); + prog->sh.BindlessImages[unit].data = + ¶ms->ParameterValues[pvo] + 4 * j; + } + } + } + + /* After attaching the driver's storage to the uniform, propagate any + * data from the linker's backing store. This will cause values from + * initializers in the source code to be copied over. + */ + unsigned array_elements = MAX2(1, storage->array_elements); + if (ctx->Const.PackedDriverUniformStorage && !prog->info.is_arb_asm && + (storage->is_bindless || !storage->type->contains_opaque())) { + const int dmul = storage->type->is_64bit() ? 2 : 1; + const unsigned components = + storage->type->vector_elements * + storage->type->matrix_columns; + + for (unsigned s = 0; s < storage->num_driver_storage; s++) { + gl_constant_value *uni_storage = (gl_constant_value *) + storage->driver_storage[s].data; + memcpy(uni_storage, storage->storage, + sizeof(storage->storage[0]) * components * + array_elements * dmul); + } + } else { + _mesa_propagate_uniforms_to_driver_storage(storage, 0, + array_elements); + } + + last_location = location; + } + } +} + + +void +_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog, unsigned required_space) +{ + /* Avoid reallocation of the program parameter list, because the uniform + * storage is only associated with the original parameter list. + */ + _mesa_reserve_parameter_storage(prog->Parameters, required_space, + required_space); + + /* This has to be done last. Any operation the can cause + * prog->ParameterValues to get reallocated (e.g., anything that adds a + * program constant) has to happen before creating this linkage. + */ + associate_uniform_storage(ctx, shader_program, prog); +} + + /** * Return printable string for a given GLSL_TYPE_x */ diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index e20dd5acd6b..0433d6eae62 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -495,6 +495,11 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, unsigned array_index, unsigned count); +void +_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog, unsigned required_space); + extern void _mesa_update_shader_textures_used(struct gl_shader_program *shProg, struct gl_program *prog); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 7110c746c95..f971ae71918 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -53,176 +53,6 @@ #include "program/prog_parameter.h" -static void -associate_uniform_storage(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_program *prog) -{ - struct gl_program_parameter_list *params = prog->Parameters; - gl_shader_stage shader_type = prog->info.stage; - - _mesa_disallow_parameter_storage_realloc(params); - - /* After adding each uniform to the parameter list, connect the storage for - * the parameter with the tracking structure used by the API for the - * uniform. - */ - unsigned last_location = unsigned(~0); - for (unsigned i = 0; i < params->NumParameters; i++) { - if (params->Parameters[i].Type != PROGRAM_UNIFORM) - continue; - - unsigned location = params->Parameters[i].UniformStorageIndex; - - struct gl_uniform_storage *storage = - &shader_program->data->UniformStorage[location]; - - /* Do not associate any uniform storage to built-in uniforms */ - if (storage->builtin) - continue; - - if (location != last_location) { - enum gl_uniform_driver_format format = uniform_native; - unsigned columns = 0; - - int dmul; - if (ctx->Const.PackedDriverUniformStorage && !prog->info.is_arb_asm) { - dmul = storage->type->vector_elements * sizeof(float); - } else { - dmul = 4 * sizeof(float); - } - - switch (storage->type->base_type) { - case GLSL_TYPE_UINT64: - if (storage->type->vector_elements > 2) - dmul *= 2; - FALLTHROUGH; - case GLSL_TYPE_UINT: - case GLSL_TYPE_UINT16: - case GLSL_TYPE_UINT8: - assert(ctx->Const.NativeIntegers); - format = uniform_native; - columns = 1; - break; - case GLSL_TYPE_INT64: - if (storage->type->vector_elements > 2) - dmul *= 2; - FALLTHROUGH; - case GLSL_TYPE_INT: - case GLSL_TYPE_INT16: - case GLSL_TYPE_INT8: - format = - (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; - columns = 1; - break; - case GLSL_TYPE_DOUBLE: - if (storage->type->vector_elements > 2) - dmul *= 2; - FALLTHROUGH; - case GLSL_TYPE_FLOAT: - case GLSL_TYPE_FLOAT16: - format = uniform_native; - columns = storage->type->matrix_columns; - break; - case GLSL_TYPE_BOOL: - format = uniform_native; - columns = 1; - break; - case GLSL_TYPE_SAMPLER: - case GLSL_TYPE_TEXTURE: - case GLSL_TYPE_IMAGE: - case GLSL_TYPE_SUBROUTINE: - format = uniform_native; - columns = 1; - break; - case GLSL_TYPE_ATOMIC_UINT: - case GLSL_TYPE_ARRAY: - case GLSL_TYPE_VOID: - case GLSL_TYPE_STRUCT: - case GLSL_TYPE_ERROR: - case GLSL_TYPE_INTERFACE: - case GLSL_TYPE_FUNCTION: - assert(!"Should not get here."); - break; - } - - unsigned pvo = params->Parameters[i].ValueOffset; - _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul, - format, - ¶ms->ParameterValues[pvo]); - - /* When a bindless sampler/image is bound to a texture/image unit, we - * have to overwrite the constant value by the resident handle - * directly in the constant buffer before the next draw. One solution - * is to keep track a pointer to the base of the data. - */ - if (storage->is_bindless && (prog->sh.NumBindlessSamplers || - prog->sh.NumBindlessImages)) { - unsigned array_elements = MAX2(1, storage->array_elements); - - for (unsigned j = 0; j < array_elements; ++j) { - unsigned unit = storage->opaque[shader_type].index + j; - - if (storage->type->without_array()->is_sampler()) { - assert(unit >= 0 && unit < prog->sh.NumBindlessSamplers); - prog->sh.BindlessSamplers[unit].data = - ¶ms->ParameterValues[pvo] + 4 * j; - } else if (storage->type->without_array()->is_image()) { - assert(unit >= 0 && unit < prog->sh.NumBindlessImages); - prog->sh.BindlessImages[unit].data = - ¶ms->ParameterValues[pvo] + 4 * j; - } - } - } - - /* After attaching the driver's storage to the uniform, propagate any - * data from the linker's backing store. This will cause values from - * initializers in the source code to be copied over. - */ - unsigned array_elements = MAX2(1, storage->array_elements); - if (ctx->Const.PackedDriverUniformStorage && !prog->info.is_arb_asm && - (storage->is_bindless || !storage->type->contains_opaque())) { - const int dmul = storage->type->is_64bit() ? 2 : 1; - const unsigned components = - storage->type->vector_elements * - storage->type->matrix_columns; - - for (unsigned s = 0; s < storage->num_driver_storage; s++) { - gl_constant_value *uni_storage = (gl_constant_value *) - storage->driver_storage[s].data; - memcpy(uni_storage, storage->storage, - sizeof(storage->storage[0]) * components * - array_elements * dmul); - } - } else { - _mesa_propagate_uniforms_to_driver_storage(storage, 0, - array_elements); - } - - last_location = location; - } - } -} - -void -_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_program *prog, unsigned required_space) -{ - /* Avoid reallocation of the program parameter list, because the uniform - * storage is only associated with the original parameter list. - */ - _mesa_reserve_parameter_storage(prog->Parameters, required_space, - required_space); - - /* This has to be done last. Any operation the can cause - * prog->ParameterValues to get reallocated (e.g., anything that adds a - * program constant) has to happen before creating this linkage. - */ - associate_uniform_storage(ctx, shader_program, prog); -} - - extern "C" { /** diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h index 6da66fdce8a..081458ae4b2 100644 --- a/src/mesa/program/ir_to_mesa.h +++ b/src/mesa/program/ir_to_mesa.h @@ -39,10 +39,6 @@ struct gl_program_parameter_list; void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog); -void -_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_program *prog, unsigned required_space); #ifdef __cplusplus } diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c index a69e137f8b1..b24569f01de 100644 --- a/src/mesa/state_tracker/st_shader_cache.c +++ b/src/mesa/state_tracker/st_shader_cache.c @@ -29,8 +29,8 @@ #include "compiler/glsl/program.h" #include "compiler/nir/nir.h" #include "compiler/nir/nir_serialize.h" +#include "main/uniforms.h" #include "pipe/p_shader_tokens.h" -#include "program/ir_to_mesa.h" #include "tgsi/tgsi_parse.h" #include "util/u_memory.h"