summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2016-10-07 21:30:05 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2016-10-07 21:37:48 +0200
commit4841b4e4d858806e0c30df50c6f7b3023d7bbd2f (patch)
tree15455eb3cc6ec7242223cdaaec7a7d1003607b11
parent013fdc5badc78e6517918b19ec5eff781b0c3c6e (diff)
st/glsl_to_tgsi: mark "gaps" in input/output arrays as used
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.
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp32
1 files 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 66ce24c3af..aac80ee778 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2458,9 +2458,9 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
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;
@@ -2474,12 +2474,12 @@ shrink_array_declarations(struct array_decl *arrays, unsigned count,
/* 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;
@@ -2493,12 +2493,12 @@ shrink_array_declarations(struct array_decl *arrays, unsigned count,
/* 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;
@@ -2506,6 +2506,22 @@ shrink_array_declarations(struct array_decl *arrays, unsigned count,
decl->array_size--;
}
+
+ /* When not all entries of an array are accessed, we mark them as uesd
+ * 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);
+ }
}
}
@@ -6631,9 +6647,9 @@ get_mesa_program_tgsi(struct gl_context *ctx,
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. */