[Mesa-dev] [PATCH 09/13] st/glsl_to_tgsi: mark "gaps" in input/output arrays as used
Edward O'Callaghan
funfunctor at folklore1984.net
Sat Oct 8 07:16:51 UTC 2016
On 10/08/2016 06:55 AM, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> In some cases, a shader may have an input/output array but not use some
> entries in the middle. This happens with eON games, for example.
>
> We emit declarations that cover the entire array range even if there are
> some unused gaps. This patch now reflects that in the InputsRead etc.
> fields to ensure the various input/outputMapping arrays are actually
> correct, which will be important when we re-jiggle the way declarations
> are emitted.
> ---
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 32 ++++++++++++++++++++++--------
> 1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 66ce24c..aac80ee 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -2451,68 +2451,84 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
> this->result = st_src_reg(entry->file, entry->index, var->type);
> this->result.array_id = entry->array_id;
> if (this->shader->Stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_in && var->type->is_double())
> this->result.is_double_vertex_input = true;
> if (!native_integers)
> this->result.type = GLSL_TYPE_FLOAT;
> }
>
> static void
> shrink_array_declarations(struct array_decl *arrays, unsigned count,
> - GLbitfield64 usage_mask,
> + GLbitfield64* usage_mask,
> GLbitfield64 double_usage_mask,
> - GLbitfield patch_usage_mask)
> + GLbitfield* patch_usage_mask)
> {
> unsigned i;
> int j;
>
> /* Fix array declarations by removing unused array elements at both ends
> * of the arrays. For example, mat4[3] where only mat[1] is used.
> */
> for (i = 0; i < count; i++) {
> struct array_decl *decl = &arrays[i];
>
> /* Shrink the beginning. */
> for (j = 0; j < (int)decl->array_size; j++) {
> if (decl->mesa_index >= VARYING_SLOT_PATCH0) {
> - if (patch_usage_mask &
> + if (*patch_usage_mask &
> BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j))
> break;
> }
> else {
> - if (usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
> + if (*usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
> break;
> if (double_usage_mask & BITFIELD64_BIT(decl->mesa_index+j-1))
> break;
> }
>
> decl->mesa_index++;
> decl->array_size--;
> j--;
> }
>
> /* Shrink the end. */
> for (j = decl->array_size-1; j >= 0; j--) {
> if (decl->mesa_index >= VARYING_SLOT_PATCH0) {
> - if (patch_usage_mask &
> + if (*patch_usage_mask &
> BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j))
> break;
> }
> else {
> - if (usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
> + if (*usage_mask & BITFIELD64_BIT(decl->mesa_index+j))
> break;
> if (double_usage_mask & BITFIELD64_BIT(decl->mesa_index+j-1))
> break;
> }
>
> decl->array_size--;
> }
> +
> + /* When not all entries of an array are accessed, we mark them as uesd
s/uesd/used/
> + * here anyway, to ensure that the input/output mapping logic doesn't get
> + * confused.
> + *
> + * TODO This happens when an array isn't used via indirect access, which
> + * some game ports do (at least eON-based). There is an optimization
> + * opportunity here by replacing the array declaration with non-array
> + * declarations of those slots that are actually used.
> + */
> + for (j = 1; j < (int)decl->array_size; ++j) {
> + if (decl->mesa_index >= VARYING_SLOT_PATCH0)
> + *patch_usage_mask |= BITFIELD64_BIT(decl->mesa_index - VARYING_SLOT_PATCH0 + j);
> + else
> + *usage_mask |= BITFIELD64_BIT(decl->mesa_index + j);
> + }
> }
> }
>
> void
> glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
> {
> ir_constant *index;
> st_src_reg src;
> int element_size = type_size(ir->type);
> bool is_2D = false;
> @@ -6624,23 +6640,23 @@ get_mesa_program_tgsi(struct gl_context *ctx,
> shader_program->Name);
> _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL);
> _mesa_log("\n\n");
> }
>
> prog->Instructions = NULL;
> prog->NumInstructions = 0;
>
> do_set_program_inouts(shader->ir, prog, shader->Stage);
> shrink_array_declarations(v->input_arrays, v->num_input_arrays,
> - prog->InputsRead, prog->DoubleInputsRead, prog->PatchInputsRead);
> + &prog->InputsRead, prog->DoubleInputsRead, &prog->PatchInputsRead);
> shrink_array_declarations(v->output_arrays, v->num_output_arrays,
> - prog->OutputsWritten, 0ULL, prog->PatchOutputsWritten);
> + &prog->OutputsWritten, 0ULL, &prog->PatchOutputsWritten);
> count_resources(v, prog);
>
> /* The GLSL IR won't be needed anymore. */
> ralloc_free(shader->ir);
> shader->ir = NULL;
>
> /* This must be done before the uniform storage is associated. */
> if (shader->Stage == MESA_SHADER_FRAGMENT &&
> (prog->InputsRead & VARYING_BIT_POS ||
> prog->SystemValuesRead & (1 << SYSTEM_VALUE_FRAG_COORD))) {
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161008/6c3b661a/attachment.sig>
More information about the mesa-dev
mailing list