[Mesa-dev] [PATCH] mesa: allocate transform_feedback_info::Outputs array dynamically

Paul Berry stereotype441 at gmail.com
Tue Jan 17 11:02:24 PST 2012


On 17 January 2012 09:31, Christoph Bumiller
<e0425955 at student.tuwien.ac.at>wrote:

> The nvc0 gallium driver is advertising 128 MAX_INTERLEAVED_COMPS
> which made it always assert in the linker when TFB was used since
> the Outputs array was smaller than that maximum.
>
> NOTE: This is a candidate for the 8.0 branch.
> ---
>  src/glsl/linker.cpp    |   57
> +++++++++++++++++++++++++++++------------------
>  src/mesa/main/mtypes.h |   32 ++++++++++++++------------
>  2 files changed, 52 insertions(+), 37 deletions(-)
>
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 0d85aee..1a986ef 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -1388,6 +1388,7 @@ public:
>    static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
>    bool assign_location(struct gl_context *ctx, struct gl_shader_program
> *prog,
>                         ir_variable *output_var);
> +   bool accumulate_num_outputs(struct gl_shader_program *prog, unsigned
> *count);
>    bool store(struct gl_context *ctx, struct gl_shader_program *prog,
>               struct gl_transform_feedback_info *info, unsigned buffer,
>              unsigned varying) const;
> @@ -1624,16 +1625,9 @@ tfeedback_decl::assign_location(struct gl_context
> *ctx,
>  }
>
>
> -/**
> - * Update gl_transform_feedback_info to reflect this tfeedback_decl.
> - *
> - * If an error occurs, the error is reported through linker_error() and
> false
> - * is returned.
> - */
>  bool
> -tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program
> *prog,
> -                      struct gl_transform_feedback_info *info,
> -                      unsigned buffer, unsigned varying) const
> +tfeedback_decl::accumulate_num_outputs(struct gl_shader_program *prog,
> +                                       unsigned *count)
>  {
>    if (!this->is_assigned()) {
>       /* From GL_EXT_transform_feedback:
> @@ -1648,6 +1642,27 @@ tfeedback_decl::store(struct gl_context *ctx,
> struct gl_shader_program *prog,
>       return false;
>    }
>
> +   unsigned translated_size = this->size;
> +   if (this->is_clip_distance_mesa)
> +      translated_size = (translated_size + 3) / 4;
> +
> +   *count += translated_size * this->matrix_columns;
> +
> +   return true;
> +}
> +
> +
> +/**
> + * Update gl_transform_feedback_info to reflect this tfeedback_decl.
> + *
> + * If an error occurs, the error is reported through linker_error() and
> false
> + * is returned.
> + */
> +bool
> +tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program
> *prog,
> +                      struct gl_transform_feedback_info *info,
> +                      unsigned buffer, unsigned varying) const
> +{
>    /* From GL_EXT_transform_feedback:
>     *   A program will fail to link if:
>     *
> @@ -1663,19 +1678,6 @@ tfeedback_decl::store(struct gl_context *ctx,
> struct gl_shader_program *prog,
>       return false;
>    }
>
> -   /* Verify that the checks on
> MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS
> -    * and MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS are sufficient to
> prevent
> -    * overflow of info->Outputs[].  In worst case we generate one entry in
> -    * Outputs[] per component so a conservative check is to verify that
> the
> -    * size of the array is greater than or equal to both
> -    * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS and
> -    * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.
> -    */
> -   assert(Elements(info->Outputs) >=
> -          ctx->Const.MaxTransformFeedbackInterleavedComponents);
> -   assert(Elements(info->Outputs) >=
> -          ctx->Const.MaxTransformFeedbackSeparateComponents);
> -
>    unsigned translated_size = this->size;
>    if (this->is_clip_distance_mesa)
>       translated_size = (translated_size + 3) / 4;
> @@ -1976,6 +1978,7 @@ store_tfeedback_info(struct gl_context *ctx, struct
> gl_shader_program *prog,
>       prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
>
>    ralloc_free(prog->LinkedTransformFeedback.Varyings);
> +   ralloc_free(prog->LinkedTransformFeedback.Outputs);
>
>    memset(&prog->LinkedTransformFeedback, 0,
>           sizeof(prog->LinkedTransformFeedback));
> @@ -1988,6 +1991,16 @@ store_tfeedback_info(struct gl_context *ctx, struct
> gl_shader_program *prog,
>                    struct gl_transform_feedback_varying_info,
>                    num_tfeedback_decls);
>
> +   unsigned num_outputs = 0;
> +   for (unsigned i = 0; i < num_tfeedback_decls; ++i)
> +      if (!tfeedback_decls[i].accumulate_num_outputs(prog, &num_outputs))
> +         return false;
> +
> +   prog->LinkedTransformFeedback.Outputs =
> +      rzalloc_array(prog->LinkedTransformFeedback.Outputs,
> +                    struct gl_transform_feedback_output,
> +                    num_outputs);
> +
>

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.

With that change, this patch is:

Reviewed-by: Paul Berry <stereotype441 at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20120117/409c4f27/attachment.htm>


More information about the mesa-dev mailing list