[Mesa-dev] [PATCH 21/37] glsl: basic linking support for xfb qualifiers
Timothy Arceri
timothy.arceri at collabora.com
Tue Mar 15 12:57:11 UTC 2016
This adds the initial infrastructure for enabling transform feedback
mode via in shader qualifiers and adds initial buffer support.
---
src/compiler/glsl/link_varyings.cpp | 22 ++++++++++++++++-----
src/compiler/glsl/link_varyings.h | 5 +++--
src/compiler/glsl/linker.cpp | 38 +++++++++++++++++++++++++++++++------
3 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index 38dee0f..c6985e1 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -781,7 +781,8 @@ tfeedback_decl::get_num_outputs() const
bool
tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
struct gl_transform_feedback_info *info,
- unsigned buffer, const unsigned max_outputs) const
+ unsigned buffer, const unsigned max_outputs,
+ bool has_xfb_qualifiers) const
{
assert(!this->next_buffer_separator);
@@ -924,7 +925,7 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
bool
store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls)
+ tfeedback_decl *tfeedback_decls, bool has_xfb_qualifiers)
{
bool separate_attribs_mode =
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
@@ -951,11 +952,12 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
unsigned num_buffers = 0;
- if (separate_attribs_mode) {
+ if (!has_xfb_qualifiers && separate_attribs_mode) {
/* GL_SEPARATE_ATTRIBS */
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
- num_buffers, num_outputs))
+ num_buffers, num_outputs,
+ has_xfb_qualifiers))
return false;
num_buffers++;
@@ -964,6 +966,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
else {
/* GL_INVERLEAVED_ATTRIBS */
int buffer_stream_id = -1;
+ unsigned buffer =
+ num_tfeedback_decls ? tfeedback_decls[0].get_buffer() : 0;
+
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
if (tfeedback_decls[i].is_next_buffer_separator()) {
num_buffers++;
@@ -986,9 +991,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
return false;
}
+ if (has_xfb_qualifiers) {
+ buffer = tfeedback_decls[i].get_buffer();
+ } else {
+ buffer = num_buffers;
+ }
+
if (!tfeedback_decls[i].store(ctx, prog,
&prog->LinkedTransformFeedback,
- num_buffers, num_outputs))
+ num_buffers, num_outputs,
+ has_xfb_qualifiers))
return false;
}
num_buffers++;
diff --git a/src/compiler/glsl/link_varyings.h b/src/compiler/glsl/link_varyings.h
index 339e9cf..7165ecb 100644
--- a/src/compiler/glsl/link_varyings.h
+++ b/src/compiler/glsl/link_varyings.h
@@ -98,7 +98,7 @@ public:
unsigned get_num_outputs() const;
bool store(struct gl_context *ctx, struct gl_shader_program *prog,
struct gl_transform_feedback_info *info, unsigned buffer,
- const unsigned max_outputs) const;
+ const unsigned max_outputs, bool has_xfb_qualifiers) const;
const tfeedback_candidate *find_candidate(gl_shader_program *prog,
hash_table *tfeedback_candidates);
@@ -301,7 +301,8 @@ remove_unused_shader_inputs_and_outputs(bool is_separate_shader_object,
bool
store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls);
+ tfeedback_decl *tfeedback_decls,
+ bool has_xfb_qualifiers);
bool
assign_varying_locations(struct gl_context *ctx,
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index dcfe7fa..40d216f 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -4232,9 +4232,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
return;
}
- tfeedback_decl *tfeedback_decls = NULL;
- unsigned num_tfeedback_decls = prog->TransformFeedback.NumVarying;
+ unsigned num_tfeedback_decls = 0;
unsigned int num_explicit_uniform_locs = 0;
+ bool has_xfb_qualifiers = false;
+ char **varying_names = NULL;
+ tfeedback_decl *tfeedback_decls = NULL;
void *mem_ctx = ralloc_context(NULL); // temporary linker context
@@ -4544,6 +4546,30 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
+ /* From the ARB_enhanced_layouts spec:
+ *
+ * "If the shader used to record output variables for transform feedback
+ * varyings uses the "xfb_buffer", "xfb_offset", or "xfb_stride" layout
+ * qualifiers, the values specified by TransformFeedbackVaryings are
+ * ignored, and the set of variables captured for transform feedback is
+ * instead derived from the specified layout qualifiers."
+ */
+ for (int i = MESA_SHADER_FRAGMENT - 1; i >= 0; i--) {
+ /* Find last stage before fragment shader */
+ if (prog->_LinkedShaders[i]) {
+ has_xfb_qualifiers =
+ process_xfb_layout_qualifiers(mem_ctx, prog->_LinkedShaders[i],
+ &num_tfeedback_decls,
+ &varying_names);
+ break;
+ }
+ }
+
+ if (!has_xfb_qualifiers) {
+ num_tfeedback_decls = prog->TransformFeedback.NumVarying;
+ varying_names = prog->TransformFeedback.VaryingNames;
+ }
+
if (num_tfeedback_decls != 0) {
/* From GL_EXT_transform_feedback:
* A program will fail to link if:
@@ -4560,10 +4586,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
tfeedback_decls = ralloc_array(mem_ctx, tfeedback_decl,
- prog->TransformFeedback.NumVarying);
+ num_tfeedback_decls);
if (!parse_tfeedback_decls(ctx, prog, mem_ctx, num_tfeedback_decls,
- prog->TransformFeedback.VaryingNames,
- tfeedback_decls))
+ varying_names, tfeedback_decls))
goto done;
}
@@ -4643,7 +4668,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
- if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls))
+ if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls,
+ has_xfb_qualifiers))
goto done;
update_array_sizes(prog);
--
2.5.0
More information about the mesa-dev
mailing list