summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2016-02-24 16:27:03 +1100
committerTimothy Arceri <[email protected]>2016-03-31 12:51:21 +1100
commit0822517936d473f4889b07606e131e1dc3199644 (patch)
treef9eb129a04d63c741faf73b18d2098d72fae6adf /src/compiler/glsl
parent707fd3972f3c2e16c710cd7ce819d0c5439c28fd (diff)
glsl: add helper to process xfb qualifiers during linking
This function checks for any xfb_* qualifiers which will enable transform feedback mode and cause any API defined xfb varyings to be ignored. It also counts the number of varyings that have a xfb_offset qualifier and finally it calls the create_xfb_varying_names() helper to generate the names of varyings to be caputured. Reviewed-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/link_varyings.cpp66
-rw-r--r--src/compiler/glsl/link_varyings.h5
2 files changed, 71 insertions, 0 deletions
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index dae6fb216c7..b000012e429 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -106,6 +106,72 @@ create_xfb_varying_names(void *mem_ctx, const glsl_type *t, char **name,
}
}
+bool
+process_xfb_layout_qualifiers(void *mem_ctx, const gl_shader *sh,
+ unsigned *num_tfeedback_decls,
+ char ***varying_names)
+{
+ bool has_xfb_qualifiers = false;
+
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
+ if (!var || var->data.mode != ir_var_shader_out)
+ continue;
+
+ /* From the ARB_enhanced_layouts spec:
+ *
+ * "Any shader making any static use (after preprocessing) of any of
+ * these *xfb_* qualifiers will cause the shader to be in a
+ * transform feedback capturing mode and hence responsible for
+ * describing the transform feedback setup. This mode will capture
+ * any output selected by *xfb_offset*, directly or indirectly, to
+ * a transform feedback buffer."
+ */
+ if (var->data.explicit_xfb_buffer || var->data.explicit_xfb_stride) {
+ has_xfb_qualifiers = true;
+ }
+
+ if (var->data.explicit_xfb_offset) {
+ *num_tfeedback_decls += var->type->varying_count();
+ has_xfb_qualifiers = true;
+ }
+ }
+
+ if (*num_tfeedback_decls == 0)
+ return has_xfb_qualifiers;
+
+ unsigned i = 0;
+ *varying_names = ralloc_array(mem_ctx, char *, *num_tfeedback_decls);
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *var = node->as_variable();
+ if (!var || var->data.mode != ir_var_shader_out)
+ continue;
+
+ if (var->data.explicit_xfb_offset) {
+ char *name;
+ const glsl_type *type, *member_type;
+
+ if (var->data.from_named_ifc_block) {
+ type = var->get_interface_type();
+ /* Find the member type before it was altered by lowering */
+ member_type =
+ type->fields.structure[type->field_index(var->name)].type;
+ name = ralloc_strdup(NULL, type->without_array()->name);
+ } else {
+ type = var->type;
+ member_type = NULL;
+ name = ralloc_strdup(NULL, var->name);
+ }
+ create_xfb_varying_names(mem_ctx, type, &name, strlen(name), &i,
+ var->name, member_type, varying_names);
+ ralloc_free(name);
+ }
+ }
+
+ assert(i == *num_tfeedback_decls);
+ return has_xfb_qualifiers;
+}
+
/**
* Validate the types and qualifiers of an output from one stage against the
* matching input to another stage.
diff --git a/src/compiler/glsl/link_varyings.h b/src/compiler/glsl/link_varyings.h
index b2812614ecc..8d504f6f0dc 100644
--- a/src/compiler/glsl/link_varyings.h
+++ b/src/compiler/glsl/link_varyings.h
@@ -268,6 +268,11 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
const void *mem_ctx, unsigned num_names,
char **varying_names, tfeedback_decl *decls);
+bool
+process_xfb_layout_qualifiers(void *mem_ctx, const gl_shader *sh,
+ unsigned *num_tfeedback_decls,
+ char ***varying_names);
+
void
remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object,
gl_shader *sh,