[Mesa-dev] [PATCH v2 23/82] glsl: Do not do CSE for expressions involving SSBO loads
Jordan Justen
jordan.l.justen at intel.com
Thu Jun 18 11:35:15 PDT 2015
On 2015-06-17 22:57:27, Iago Toral wrote:
> On Wed, 2015-06-17 at 17:20 -0700, Jordan Justen wrote:
> > I wanted to question whether this was required, based on this text
> > from the extension spec:
> >
> > "The ability to write to buffer objects creates the potential for
> > multiple independent shader invocations to read and write the same
> > underlying memory. The same issue exists with the
> > ARB_shader_image_load_store extension provided in OpenGL 4.2, which
> > can write to texture objects and buffers. In both cases, the
> > specification makes few guarantees related to the relative order of
> > memory reads and writes performed by the shader invocations."
> >
> > But I'm not sure if we can reconcile CSE with 'memoryBarrier' and
> > 'barrier'. curro, any thoughts from image load/store?
>
> I think the problem is within the same thread, that text above talks
> about multiple invocations reading from and writing to the same
> location, but within the same invocation, the order of reads and writes
> must be preserved:
>
> "Buffer variable memory reads and writes within a single shader
> invocation are processed in order. However, the order of reads and
> writes performed in one invocation relative to those performed by
> another invocation is largely undefined."
>
> For example, if X is a shader storage buffer variable and we have code
> like this with just one invocation:
>
> ssbo_store(X, 1);
> a = ssbo_load(X) + 1 // a = 2
> ssbo_store(X, 2);
> b = ssbo_load(X) + 1; // b = 3
>
> CSE could mess it up like this:
>
> ssbo_store(X, 1);
> tmp = ssbo_load(X) + 1 // tmp = 2
> a = tmp;
> ssbo_store(X, 2);
> b = tmp;
>
> which would be incorrect. I think I wrote this patch after seeing
> something like this happening. The CSE pass clearly states that it does
> not support write variables after all.
>
> Also, notice the same would apply if there are multiple invocations but
> the shader code used something like gl_VertexID or gl_FragCoord to make
> each invocation read from/write to a different address within the SSBO
> buffer (I imagine this is the usual way to operate with SSBOs). In these
> cases, even if we have multiple invocations, keeping the relative order
> of reads and writes within each one is necessary.
Ok. Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>
> >
> > On 2015-06-03 00:01:13, Iago Toral Quiroga wrote:
> > > SSBOs are read/write and this CSE pass only handles read-only variables.
> > > ---
> > > src/glsl/opt_cse.cpp | 33 ++++++++++++++++++++++++++++++++-
> > > 1 file changed, 32 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/src/glsl/opt_cse.cpp b/src/glsl/opt_cse.cpp
> > > index 4b8e9a0..a05ab46 100644
> > > --- a/src/glsl/opt_cse.cpp
> > > +++ b/src/glsl/opt_cse.cpp
> > > @@ -245,6 +245,28 @@ contains_rvalue(ir_rvalue *haystack, ir_rvalue *needle)
> > > }
> > >
> > > static bool
> > > +expression_contains_ssbo_load(ir_expression *expr)
> > > +{
> > > + if (expr->operation == ir_binop_ssbo_load)
> > > + return true;
> > > +
> > > + for (unsigned i = 0; i < expr->get_num_operands(); i++) {
> > > + ir_rvalue *op = expr->operands[i];
> > > + if (op->ir_type == ir_type_expression &&
> > > + expression_contains_ssbo_load(op->as_expression())) {
> > > + return true;
> > > + } else if (op->ir_type == ir_type_swizzle) {
> > > + ir_swizzle *swizzle = op->as_swizzle();
> > > + ir_expression *val = swizzle->val->as_expression();
> > > + if (val && expression_contains_ssbo_load(val))
> > > + return true;
> > > + }
> > > + }
> > > +
> > > + return false;
> > > +}
> > > +
> > > +static bool
> > > is_cse_candidate(ir_rvalue *ir)
> > > {
> > > /* Our temporary variable assignment generation isn't ready to handle
> > > @@ -260,7 +282,16 @@ is_cse_candidate(ir_rvalue *ir)
> > > * to variable-index array dereferences at some point.
> > > */
> > > switch (ir->ir_type) {
> > > - case ir_type_expression:
> > > + case ir_type_expression: {
> > > + /* Skip expressions involving SSBO loads, since these operate on
> > > + * read-write variables, meaning that the same ssbo_load expression
> > > + * may return a different value if the underlying buffer storage
> > > + * is written in between.
> > > + */
> > > + if (expression_contains_ssbo_load(ir->as_expression()))
> > > + return false;
> > > + }
> > > + break;
> > > case ir_type_texture:
> > > break;
> > > default:
> > > --
> > > 1.9.1
> > >
> > > _______________________________________________
> > > mesa-dev mailing list
> > > mesa-dev at lists.freedesktop.org
> > > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> >
>
>
More information about the mesa-dev
mailing list