Here's the current code:

      for (UINT i = 0; i < ctx->num_vertex_buffers; i++) {
         uint32_t size, pitch, elems, partial_inbounds;
         const uint8_t *p_data;
         struct pipe_vertex_buffer *vb = &ctx->vertex_buffer[i];

         pitch = vb->stride;
         if (!vb->user_buffer) {
            /* VBO
             * size is based on buffer->width0 rather than info.max_index
             * to prevent having to validate VBO on each draw */
            size = vb->buffer->width0;
            elems = size / pitch;
            partial_inbounds = size % pitch;

            p_data = swr_resource_data(vb->buffer) + vb->buffer_offset;
         } else {
            /* Client buffer
             * client memory is one-time use, re-trigger SWR_NEW_VERTEX to
             * revalidate on each draw */
            post_update_dirty_flags |= SWR_NEW_VERTEX;

            uint32_t base;
            swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems,
&base, &size);
            partial_inbounds = 0;

            /* Copy only needed vertices to scratch space */
            size = AlignUp(size, 4);
            const void *ptr = (const uint8_t *) vb->user_buffer + base;
            memcpy(scratch, ptr, size);
            ptr = scratch;
            scratch += size;
            p_data = (const uint8_t *)ptr - base;
         }

         swrVertexBuffers[i] = {0};
         swrVertexBuffers[i].index = i;
         swrVertexBuffers[i].pitch = pitch;
         swrVertexBuffers[i].pData = p_data;
         swrVertexBuffers[i].size = size;
         swrVertexBuffers[i].maxVertex = elems;
         swrVertexBuffers[i].partialInboundsSize = partial_inbounds;
      }

You're modifying only the client buffer case. The VBO case
(!vb->user_buffer) is not adjusted in any way. Your patch changes the
base vertex passed in no matter what (and remember - I'm 99% sure it's
possible to mix VBO and non-VBO in the same draw). So it stands to
reason that now VBO-based draws with base vertex set will now be done
so incorrectly when min_index != 0.

I think the solution to your problem is to include a minVertex in the
vertex buffer definition, and clamp the range on that in the vertex
jit.

Cheers,

  -ilia

On Tue, Jan 31, 2017 at 12:32 PM, Kyriazis, George
<[email protected]> wrote:
> Ilia,
>
> The problem is the following: This occurs only with index buffers that do not 
> contain vertex index 0.  The vertex fetcher operates in blocks of 8 vertices. 
>  Consequently, the last batch of 8 could access elements outside the range of 
> the index buffer.  There is a chance that those elements will be outside 
> range / non valid.  The 1st phase of the vertex fetcher replaces invalid 
> indices with 0 (in later phases, the actual vertex fetch operation is 
> masked).  Vertex index 0 is outside the range of the copied index buffer, and 
> we SEGV accessing indices with 0 index.  The BaseVertex offset gets added to 
> every index in the index buffer, so the 0 index will now point to the real 
> beginning of the (copied) index buffer, instead of unallocated memory.
>
> VBOs should be similar to DrawElement calls where we don't access client 
> memory directly (ie. we copy the appropriate vertex and index buffers, which 
> is the case that this fixes).  What do you think?
>
> Thanks,
>
> George
>
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]] On Behalf Of Ilia
>> Mirkin
>> Sent: Tuesday, January 31, 2017 11:17 AM
>> To: Kyriazis, George <[email protected]>
>> Cc: [email protected]
>> Subject: Re: [Mesa-dev] [PATCH] [swr] fix index buffers with non-zero
>> indices
>>
>> What's the problem being fixed exactly? We're passing what is effectively
>> the zero index to the core, and the core shouldn't ever access data outside 
>> of
>> [min, max] + bias.
>>
>> That said, what you have is probably a cleaner implementation. However I'm
>> a bit concerned about how it will function with VBO's rather than client-side
>> arrays. I don't think min_index is guaranteed to be zero in that case, e.g. 
>> it
>> could be set via glDrawRangeElements[BaseVertex].
>>
>> So you're effectively mixing a zero-based pointer for VBO and a min-based
>> pointer for client-side arrays. I don't think this can work... perhaps you 
>> need
>> to add a minVertex in addition to the maxVertex?
>>
>> Cheers,
>>
>>   -ilia
>>
>> On Tue, Jan 31, 2017 at 11:38 AM, George Kyriazis
>> <[email protected]> wrote:
>> > Fix issue with index buffers that do not contain 0 index.  Use core
>> > BaseVertex functionality to offset index buffer indices, instead of
>> > offsetting vertex buffer to point before the buffer origin.
>> > ---
>> >  src/gallium/drivers/swr/swr_draw.cpp  | 2 +-
>> > src/gallium/drivers/swr/swr_state.cpp | 2 +-
>> >  2 files changed, 2 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/src/gallium/drivers/swr/swr_draw.cpp
>> > b/src/gallium/drivers/swr/swr_draw.cpp
>> > index c4d5e5c..88000e5 100644
>> > --- a/src/gallium/drivers/swr/swr_draw.cpp
>> > +++ b/src/gallium/drivers/swr/swr_draw.cpp
>> > @@ -200,7 +200,7 @@ swr_draw_vbo(struct pipe_context *pipe, const
>> struct pipe_draw_info *info)
>> >                                info->count,
>> >                                info->instance_count,
>> >                                info->start,
>> > -                              info->index_bias,
>> > +                              info->index_bias - info->min_index,
>> >                                info->start_instance);
>> >     else
>> >        SwrDrawInstanced(ctx->swrContext, diff --git
>> > a/src/gallium/drivers/swr/swr_state.cpp
>> > b/src/gallium/drivers/swr/swr_state.cpp
>> > index f1f4963..f03f814 100644
>> > --- a/src/gallium/drivers/swr/swr_state.cpp
>> > +++ b/src/gallium/drivers/swr/swr_state.cpp
>> > @@ -1133,7 +1133,7 @@ swr_update_derived(struct pipe_context *pipe,
>> >              memcpy(scratch, ptr, size);
>> >              ptr = scratch;
>> >              scratch += size;
>> > -            p_data = (const uint8_t *)ptr - base;
>> > +            p_data = (const uint8_t *)ptr;
>> >           }
>> >
>> >           swrVertexBuffers[i] = {0};
>> > --
>> > 2.7.4
>> >
>> > _______________________________________________
>> > mesa-dev mailing list
>> > [email protected]
>> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to