From c95e92b14d69c114b79d941c7e8902a0ea62c287 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Mon, 14 Mar 2016 10:32:17 +1100 Subject: [PATCH] glsl: handle varyings that are not written to but have an xfb_offset Reviewed-by: Dave Airlie --- src/compiler/glsl/link_varyings.cpp | 34 ++++++++++++++++++++--------- src/compiler/glsl/link_varyings.h | 8 +++++++ 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; -- 2.30.2