On 15 December 2012 14:56, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 12/15/2012 01:27 PM, Paul Berry wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
On 14 December 2012 13:01, Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a><br></div><div><div class="h5">
<mailto:<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.<u></u>com</a>>> wrote:<br>
<br>
     From the GL 4.3 spec, section 6.7.1 (Indexed Buffer Object Limits and<br>
    Binding Queries):<br>
<br>
         To query the starting offset or size of the range of a buffer<br>
         object binding in an indexed array, call GetInteger64i v with<br>
         target set to respectively the starting offset or binding size<br>
         name from table 6.5 for that array. index must be in the range<br>
         zero to the number of bind points supported minus one. If the<br>
         starting offset or size was not specified when the buffer object<br>
         was bound (e.g. if it was bound with BindBufferBase), or if no<br>
         buffer object is bound to the target array at index, zero is<br>
         returned.<br>
<br>
    Similar language exists in the EXT_transform_feedback spec and in the<br>
    GLES3 spec.<br>
<br>
    Previously, if a buffer object was bound by glBindBufferBase(), the<br>
    GL_TRANSFORM_FEEDBACK_BUFFER_<u></u>SIZE query returned the size of the<br>
    buffer.<br>
<br>
    Fixes GLES3 conformance tests<br>
    transform_feedback_{builtin_<u></u>type,state_variables}.test.<br>
<br>
<br>
NAK this patch.  After some more careful re-reading of the GL and GLES<br>
specs, I believe it implements the wrong behaviour.  I'm thinking in<br>
particular of this text (the last two paragraphs of section 2.9.1 of the<br>
GLES 3 spec):<br>
<br>
"BindBufferBase binds the entire buffer, even when the size of the<br>
buffer is changed after the binding is established. It is equivalent to<br>
calling BindBufferRange with offset zero, while size is determined by<br>
the size of the bound buffer at the time the binding is used.<br>
<br>
"Regardless of the size specified with BindBufferRange, or indirectly<br>
with BindBufferBase, the GL will never read or write beyond the end of a<br>
bound buffer. In some cases this constraint may result in visibly<br>
different behavior when a buffer overflow would otherwise result, such<br>
as described for transform feedback operations in section 2.14.2."<br>
<br>
In the context of transform feedback, I interpret the phrase "at the<br>
time the binding is used" to mean "at the time BeginTransformFeedback is<br>
called."  Mesa's current behaviour isn't consistent with the above two<br>
paragraphs: it records the size of the buffer at the time BindBufferBase<br>
is called, which means that if the buffer is grown after it's bound (but<br>
before it's used), the entire buffer won't be used.  Worse yet, in the<br>
absence of extra checking by the driver, if the buffer is shrunk after<br>
it's bound, there's a danger of transform feedback results overflowing<br>
past the end of the buffer.<br>
</div></div></blockquote>
<br>
I think your new interpretation is correct.  Can we come up with a piglit test that would expose the buffer-growth-after-bind bug?  I'm curious to see what other drivers do...<br></blockquote><div><br></div><div>Yeah, that should be easy enough.  We ought to be able to use a PRIMITIVES_WRITTEN query to detect if the driver tried to write past the end of the buffer.  I'll add it to my list of things to do Monday.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
I'm working on a replacement patch.<br>
<br>
    ---<br>
      src/mesa/main/get.c               |  2 +-<br>
      src/mesa/main/mtypes.h            |  7 +++++++<br>
      src/mesa/main/<u></u>transformfeedback.c | 10 ++++++----<br>
      3 files changed, 14 insertions(+), 5 deletions(-)<br>
<br>
    diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c<br>
    index f3dbda2..2348486 100644<br>
    --- a/src/mesa/main/get.c<br>
    +++ b/src/mesa/main/get.c<br>
    @@ -1574,7 +1574,7 @@ find_value_indexed(const char *func, GLenum<br>
    pname, GLuint index, union value *v)<br>
              goto invalid_value;<br>
            if (!ctx->Extensions.EXT_<u></u>transform_feedback)<br>
              goto invalid_enum;<br>
    -      v->value_int64 =<br>
    ctx->TransformFeedback.<u></u>CurrentObject->Size[index];<br>
    +      v->value_int64 =<br>
    ctx->TransformFeedback.<u></u>CurrentObject->QuerySize[<u></u>index];<br>
            return TYPE_INT64;<br>
<br>
         case GL_TRANSFORM_FEEDBACK_BUFFER_<u></u>BINDING:<br>
    diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h<br>
    index 18ab2db..333b2c9 100644<br>
    --- a/src/mesa/main/mtypes.h<br>
    +++ b/src/mesa/main/mtypes.h<br>
    @@ -1827,6 +1827,13 @@ struct gl_transform_feedback_object<br>
         GLintptr Offset[MAX_FEEDBACK_BUFFERS];<br>
         /** Max data to put into dest buffer (in bytes) */<br>
         GLsizeiptr Size[MAX_FEEDBACK_BUFFERS];<br>
    +   /**<br>
    +    * Size that should be returned from<br>
    GL_TRANSFORM_FEEDBACK_BUFFER_<u></u>SIZE<br>
    +    * queries.  If the transform feedback buffer was set up with<br>
    +    * glBindBufferBase() or glBindBufferOffsetEXT().  If it was set<br>
    up with<br>
    +    * glBindBufferRange() it is equal to ActualSize.<br>
    +    */<br>
    +   GLsizeiptr QuerySize[MAX_FEEDBACK_<u></u>BUFFERS];<br>
      };<br>
<br>
<br>
    diff --git a/src/mesa/main/<u></u>transformfeedback.c<br>
    b/src/mesa/main/<u></u>transformfeedback.c<br>
    index 7d500bc..092c343 100644<br>
    --- a/src/mesa/main/<u></u>transformfeedback.c<br>
    +++ b/src/mesa/main/<u></u>transformfeedback.c<br>
    @@ -383,7 +383,8 @@ _mesa_EndTransformFeedback(<u></u>void)<br>
      static void<br>
      bind_buffer_range(struct gl_context *ctx, GLuint index,<br>
                        struct gl_buffer_object *bufObj,<br>
    -                  GLintptr offset, GLsizeiptr size)<br>
    +                  GLintptr offset, GLsizeiptr size,<br>
    +                  GLsizeiptr query_size)<br>
      {<br>
         struct gl_transform_feedback_object *obj =<br>
            ctx->TransformFeedback.<u></u>CurrentObject;<br>
    @@ -407,6 +408,7 @@ bind_buffer_range(struct gl_context *ctx, GLuint<br>
    index,<br>
<br>
         obj->Offset[index] = offset;<br>
         obj->Size[index] = size;<br>
    +   obj->QuerySize[index] = query_size;<br>
      }<br>
<br>
<br>
    @@ -450,7 +452,7 @@<br>
    _mesa_bind_buffer_range_<u></u>transform_feedback(struct gl_context *ctx,<br>
            return;<br>
         }<br>
<br>
    -   bind_buffer_range(ctx, index, bufObj, offset, size);<br>
    +   bind_buffer_range(ctx, index, bufObj, offset, size, size);<br>
      }<br>
<br>
<br>
    @@ -485,7 +487,7 @@ _mesa_bind_buffer_base_<u></u>transform_feedback(struct<br>
    gl_context *ctx,<br>
          */<br>
         size = bufObj->Size & ~0x3;<br>
<br>
    -   bind_buffer_range(ctx, index, bufObj, 0, size);<br>
    +   bind_buffer_range(ctx, index, bufObj, 0, size, 0);<br>
      }<br>
<br>
<br>
    @@ -546,7 +548,7 @@ _mesa_BindBufferOffsetEXT(<u></u>GLenum target, GLuint<br>
    index, GLuint buffer,<br>
          */<br>
         size = (bufObj->Size - offset) & ~0x3;<br>
<br>
    -   bind_buffer_range(ctx, index, bufObj, offset, size);<br>
    +   bind_buffer_range(ctx, index, bufObj, offset, size, 0);<br>
      }<br>
<br>
<br>
    --<br>
    1.8.0.2<br>
<br>
<br>
<br>
<br></div></div>
______________________________<u></u>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/<u></u>mailman/listinfo/mesa-dev</a><br>
</blockquote>
<br>
</blockquote></div><br></div>