summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/link_varyings.cpp34
-rw-r--r--src/compiler/glsl/link_varyings.h8
2 files changed, 32 insertions, 10 deletions
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index c5c392d6140..ce6ff0863f0 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -738,14 +738,26 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
unsigned num_components = this->num_components();
while (num_components > 0) {
unsigned output_size = MIN2(num_components, 4 - location_frac);
- assert(info->NumOutputs < max_outputs);
- info->Outputs[info->NumOutputs].ComponentOffset = location_frac;
- info->Outputs[info->NumOutputs].OutputRegister = location;
- info->Outputs[info->NumOutputs].NumComponents = output_size;
- info->Outputs[info->NumOutputs].StreamId = stream_id;
- info->Outputs[info->NumOutputs].OutputBuffer = buffer;
- info->Outputs[info->NumOutputs].DstOffset = xfb_offset;
- ++info->NumOutputs;
+ assert((info->NumOutputs == 0 && max_outputs == 0) ||
+ info->NumOutputs < max_outputs);
+
+ /* From the ARB_enhanced_layouts spec:
+ *
+ * "If such a block member or variable is not written during a shader
+ * invocation, the buffer contents at the assigned offset will be
+ * undefined. Even if there are no static writes to a variable or
+ * member that is assigned a transform feedback offset, the space is
+ * still allocated in the buffer and still affects the stride."
+ */
+ if (this->is_varying_written()) {
+ info->Outputs[info->NumOutputs].ComponentOffset = location_frac;
+ info->Outputs[info->NumOutputs].OutputRegister = location;
+ info->Outputs[info->NumOutputs].NumComponents = output_size;
+ info->Outputs[info->NumOutputs].StreamId = stream_id;
+ info->Outputs[info->NumOutputs].OutputBuffer = buffer;
+ info->Outputs[info->NumOutputs].DstOffset = xfb_offset;
+ ++info->NumOutputs;
+ }
info->Buffers[buffer].Stream = this->stream_id;
xfb_offset += output_size;
@@ -936,8 +948,10 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
num_tfeedback_decls);
unsigned num_outputs = 0;
- for (unsigned i = 0; i < num_tfeedback_decls; ++i)
- num_outputs += tfeedback_decls[i].get_num_outputs();
+ for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
+ if (tfeedback_decls[i].is_varying_written())
+ num_outputs += tfeedback_decls[i].get_num_outputs();
+ }
prog->LinkedTransformFeedback.Outputs =
rzalloc_array(prog,
diff --git a/src/compiler/glsl/link_varyings.h b/src/compiler/glsl/link_varyings.h
index 7919a8d5cd5..9ea79f04fa8 100644
--- a/src/compiler/glsl/link_varyings.h
+++ b/src/compiler/glsl/link_varyings.h
@@ -108,6 +108,14 @@ public:
return this->next_buffer_separator;
}
+ bool is_varying_written() const
+ {
+ if (this->next_buffer_separator || this->skip_components)
+ return false;
+
+ return this->matched_candidate->toplevel_var->data.assigned;
+ }
+
bool is_varying() const
{
return !this->next_buffer_separator && !this->skip_components;