On 17 January 2012 09:31, Christoph Bumiller <span dir="ltr"><<a href="mailto:e0425955@student.tuwien.ac.at">e0425955@student.tuwien.ac.at</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The nvc0 gallium driver is advertising 128 MAX_INTERLEAVED_COMPS<br>
which made it always assert in the linker when TFB was used since<br>
the Outputs array was smaller than that maximum.<br>
<br>
NOTE: This is a candidate for the 8.0 branch.<br>
---<br>
src/glsl/linker.cpp | 57 +++++++++++++++++++++++++++++------------------<br>
src/mesa/main/mtypes.h | 32 ++++++++++++++------------<br>
2 files changed, 52 insertions(+), 37 deletions(-)<br>
<br>
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp<br>
index 0d85aee..1a986ef 100644<br>
--- a/src/glsl/linker.cpp<br>
+++ b/src/glsl/linker.cpp<br>
@@ -1388,6 +1388,7 @@ public:<br>
static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);<br>
bool assign_location(struct gl_context *ctx, struct gl_shader_program *prog,<br>
ir_variable *output_var);<br>
+ bool accumulate_num_outputs(struct gl_shader_program *prog, unsigned *count);<br>
bool store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
struct gl_transform_feedback_info *info, unsigned buffer,<br>
unsigned varying) const;<br>
@@ -1624,16 +1625,9 @@ tfeedback_decl::assign_location(struct gl_context *ctx,<br>
}<br>
<br>
<br>
-/**<br>
- * Update gl_transform_feedback_info to reflect this tfeedback_decl.<br>
- *<br>
- * If an error occurs, the error is reported through linker_error() and false<br>
- * is returned.<br>
- */<br>
bool<br>
-tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
- struct gl_transform_feedback_info *info,<br>
- unsigned buffer, unsigned varying) const<br>
+tfeedback_decl::accumulate_num_outputs(struct gl_shader_program *prog,<br>
+ unsigned *count)<br>
{<br>
if (!this->is_assigned()) {<br>
/* From GL_EXT_transform_feedback:<br>
@@ -1648,6 +1642,27 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
return false;<br>
}<br>
<br>
+ unsigned translated_size = this->size;<br>
+ if (this->is_clip_distance_mesa)<br>
+ translated_size = (translated_size + 3) / 4;<br>
+<br>
+ *count += translated_size * this->matrix_columns;<br>
+<br>
+ return true;<br>
+}<br>
+<br>
+<br>
+/**<br>
+ * Update gl_transform_feedback_info to reflect this tfeedback_decl.<br>
+ *<br>
+ * If an error occurs, the error is reported through linker_error() and false<br>
+ * is returned.<br>
+ */<br>
+bool<br>
+tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
+ struct gl_transform_feedback_info *info,<br>
+ unsigned buffer, unsigned varying) const<br>
+{<br>
/* From GL_EXT_transform_feedback:<br>
* A program will fail to link if:<br>
*<br>
@@ -1663,19 +1678,6 @@ tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,<br>
return false;<br>
}<br>
<br>
- /* Verify that the checks on MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS<br>
- * and MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS are sufficient to prevent<br>
- * overflow of info->Outputs[]. In worst case we generate one entry in<br>
- * Outputs[] per component so a conservative check is to verify that the<br>
- * size of the array is greater than or equal to both<br>
- * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS and<br>
- * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.<br>
- */<br>
- assert(Elements(info->Outputs) >=<br>
- ctx->Const.MaxTransformFeedbackInterleavedComponents);<br>
- assert(Elements(info->Outputs) >=<br>
- ctx->Const.MaxTransformFeedbackSeparateComponents);<br>
-<br>
unsigned translated_size = this->size;<br>
if (this->is_clip_distance_mesa)<br>
translated_size = (translated_size + 3) / 4;<br>
@@ -1976,6 +1978,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,<br>
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;<br>
<br>
ralloc_free(prog->LinkedTransformFeedback.Varyings);<br>
+ ralloc_free(prog->LinkedTransformFeedback.Outputs);<br>
<br>
memset(&prog->LinkedTransformFeedback, 0,<br>
sizeof(prog->LinkedTransformFeedback));<br>
@@ -1988,6 +1991,16 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,<br>
struct gl_transform_feedback_varying_info,<br>
num_tfeedback_decls);<br>
<br>
+ unsigned num_outputs = 0;<br>
+ for (unsigned i = 0; i < num_tfeedback_decls; ++i)<br>
+ if (!tfeedback_decls[i].accumulate_num_outputs(prog, &num_outputs))<br>
+ return false;<br>
+<br>
+ prog->LinkedTransformFeedback.Outputs =<br>
+ rzalloc_array(prog->LinkedTransformFeedback.Outputs,<br>
+ struct gl_transform_feedback_output,<br>
+ num_outputs);<br>
+<br></blockquote><div><br>Can we add an assertion to the bottom of store_tfeedback_info to verify that num_outputs == prog->LinkedTransformFeedback.NumOutputs? That would give me a lot more confidence in this patch.<br>
<br>With that change, this patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div></div>