On 01/07/2016 05:22 PM, Ian Romanick wrote: > On 01/07/2016 04:33 PM, Nicolai Hähnle wrote: >> From: Nicolai Hähnle <nicolai.haeh...@amd.com> >> >> Reduced code duplication should make the code more maintainable. >> --- >> src/mesa/main/bufferobj.c | 169 >> +++++++++++++++------------------------------- >> 1 file changed, 56 insertions(+), 113 deletions(-) >> >> diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c >> index a1e47d6..f529536 100644 >> --- a/src/mesa/main/bufferobj.c >> +++ b/src/mesa/main/bufferobj.c >> @@ -3522,84 +3522,18 @@ unbind_xfb_buffers(struct gl_context *ctx, >> } >> >> static void >> -bind_xfb_buffers_base(struct gl_context *ctx, >> - GLuint first, GLsizei count, >> - const GLuint *buffers) >> -{ >> - struct gl_transform_feedback_object *tfObj = >> - ctx->TransformFeedback.CurrentObject; >> - GLint i; >> - >> - if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, >> - "glBindBuffersBase")) >> - return; >> - >> - /* Assume that at least one binding will be changed */ >> - FLUSH_VERTICES(ctx, 0); >> - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; >> - >> - if (!buffers) { >> - /* The ARB_multi_bind spec says: >> - * >> - * "If <buffers> is NULL, all bindings from <first> through >> - * <first>+<count>-1 are reset to their unbound (zero) state." >> - */ >> - unbind_xfb_buffers(ctx, tfObj, first, count); >> - return; >> - } >> - >> - /* Note that the error semantics for multi-bind commands differ from >> - * those of other GL commands. >> - * >> - * The Issues section in the ARB_multi_bind spec says: >> - * >> - * "(11) Typically, OpenGL specifies that if an error is generated by >> a >> - * command, that command has no effect. This is somewhat >> - * unfortunate for multi-bind commands, because it would >> require a >> - * first pass to scan the entire list of bound objects for >> errors >> - * and then a second pass to actually perform the bindings. >> - * Should we have different error semantics? >> - * >> - * RESOLVED: Yes. In this specification, when the parameters for >> - * one of the <count> binding points are invalid, that binding >> point >> - * is not updated and an error will be generated. However, other >> - * binding points in the same command will be updated if their >> - * parameters are valid and no other error occurs." >> - */ >> - >> - _mesa_begin_bufferobj_lookups(ctx); >> - >> - for (i = 0; i < count; i++) { >> - struct gl_buffer_object * const boundBufObj = tfObj->Buffers[first + >> i]; >> - struct gl_buffer_object *bufObj; >> - >> - if (boundBufObj && boundBufObj->Name == buffers[i]) >> - bufObj = boundBufObj; >> - else >> - bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, >> - "glBindBuffersBase"); >> - >> - if (bufObj) >> - _mesa_set_transform_feedback_binding(ctx, tfObj, first + i, >> - bufObj, 0, 0); >> - } >> - >> - _mesa_end_bufferobj_lookups(ctx); >> -} >> - >> -static void >> -bind_xfb_buffers_range(struct gl_context *ctx, >> - GLuint first, GLsizei count, >> - const GLuint *buffers, >> - const GLintptr *offsets, >> - const GLsizeiptr *sizes) >> +bind_xfb_buffers(struct gl_context *ctx, >> + GLuint first, GLsizei count, >> + const GLuint *buffers, >> + const GLintptr *offsets, >> + const GLsizeiptr *sizes, >> + const char *caller) >> { >> struct gl_transform_feedback_object *tfObj = >> ctx->TransformFeedback.CurrentObject; >> GLint i; >> > > Code later assumes that offsets and sizes are either both NULL or both > non-NULL. An assertion like > > assert((offsets == NULL) == (sizes == NULL)); > > would be good.
It looks like the other patches in this series could use the same assertion. It also occurs to me that a buggy application could get... unexpected behavior by calling glBindBuffersRange(target, first, count, buffers, NULL, NULL); Previous to this series a callee of _mesa_BindBuffersRange would segfault (which is allowed by the spec... and should be expected). After this series, passing NULL for offsets will cause it behave like glBindBuffers. I /think/ that's also allowed, but it is a bit more surprising. It would also be more difficult to debug. I guess I'm not sure what the "right" thing to do is. It's probably okay as is, but there's a nagging voice in the back of mind telling me otherwise... > Assuming this passes a full piglit run, with that change this patch is > > Reviewed-by: Ian Romanick <ian.d.roman...@intel.com> > >> - if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, >> - "glBindBuffersRange")) >> + if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, caller)) >> return; >> >> /* Assume that at least one binding will be changed */ >> @@ -3644,55 +3578,64 @@ bind_xfb_buffers_range(struct gl_context *ctx, >> const GLuint index = first + i; >> struct gl_buffer_object * const boundBufObj = tfObj->Buffers[index]; >> struct gl_buffer_object *bufObj; >> + GLintptr offset = 0; >> + GLsizeiptr size = 0; >> >> - if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes)) >> - continue; >> + if (offsets) { >> + offset = offsets[i]; >> + size = sizes[i]; >> >> - /* The ARB_multi_bind spec says: >> - * >> - * "An INVALID_VALUE error is generated by BindBuffersRange if any >> - * pair of values in <offsets> and <sizes> does not respectively >> - * satisfy the constraints described for those parameters for the >> - * specified target, as described in section 6.7.1 (per >> binding)." >> - * >> - * Section 6.7.1 refers to table 6.5, which says: >> - * >> - * >> "┌───────────────────────────────────────────────────────────────┐ >> - * │ Transform feedback array bindings (see sec. 13.2.2) >> │ >> - * >> ├───────────────────────┬───────────────────────────────────────┤ >> - * │ ... │ ... >> │ >> - * │ offset restriction │ multiple of 4 >> │ >> - * │ ... │ ... >> │ >> - * │ size restriction │ multiple of 4 >> │ >> - * >> └───────────────────────┴───────────────────────────────────────┘" >> - */ >> - if (offsets[i] & 0x3) { >> - _mesa_error(ctx, GL_INVALID_VALUE, >> - "glBindBuffersRange(offsets[%u]=%" PRId64 >> - " is misaligned; it must be a multiple of 4 when " >> - "target=GL_TRANSFORM_FEEDBACK_BUFFER)", >> - i, (int64_t) offsets[i]); >> - continue; >> - } >> + if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes)) >> + continue; >> >> - if (sizes[i] & 0x3) { >> - _mesa_error(ctx, GL_INVALID_VALUE, >> - "glBindBuffersRange(sizes[%u]=%" PRId64 >> - " is misaligned; it must be a multiple of 4 when " >> - "target=GL_TRANSFORM_FEEDBACK_BUFFER)", >> - i, (int64_t) sizes[i]); >> - continue; >> + /* The ARB_multi_bind spec says: >> + * >> + * "An INVALID_VALUE error is generated by BindBuffersRange if >> any >> + * pair of values in <offsets> and <sizes> does not >> respectively >> + * satisfy the constraints described for those parameters for >> the >> + * specified target, as described in section 6.7.1 (per >> binding)." >> + * >> + * Section 6.7.1 refers to table 6.5, which says: >> + * >> + * >> "┌───────────────────────────────────────────────────────────────┐ >> + * │ Transform feedback array bindings (see sec. 13.2.2) >> │ >> + * >> ├───────────────────────┬───────────────────────────────────────┤ >> + * │ ... │ ... >> │ >> + * │ offset restriction │ multiple of 4 >> │ >> + * │ ... │ ... >> │ >> + * │ size restriction │ multiple of 4 >> │ >> + * >> └───────────────────────┴───────────────────────────────────────┘" >> + */ >> + if (offsets[i] & 0x3) { >> + _mesa_error(ctx, GL_INVALID_VALUE, >> + "glBindBuffersRange(offsets[%u]=%" PRId64 >> + " is misaligned; it must be a multiple of 4 when " >> + "target=GL_TRANSFORM_FEEDBACK_BUFFER)", >> + i, (int64_t) offsets[i]); >> + continue; >> + } >> + >> + if (sizes[i] & 0x3) { >> + _mesa_error(ctx, GL_INVALID_VALUE, >> + "glBindBuffersRange(sizes[%u]=%" PRId64 >> + " is misaligned; it must be a multiple of 4 when " >> + "target=GL_TRANSFORM_FEEDBACK_BUFFER)", >> + i, (int64_t) sizes[i]); >> + continue; >> + } >> + >> + offset = offsets[i]; >> + size = sizes[i]; >> } >> >> if (boundBufObj && boundBufObj->Name == buffers[i]) >> bufObj = boundBufObj; >> else >> - bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, >> - "glBindBuffersRange"); >> + bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, >> caller); >> >> if (bufObj) >> _mesa_set_transform_feedback_binding(ctx, tfObj, index, bufObj, >> - offsets[i], sizes[i]); >> + offset, size); >> } >> >> _mesa_end_bufferobj_lookups(ctx); >> @@ -4053,7 +3996,7 @@ _mesa_BindBuffersRange(GLenum target, GLuint first, >> GLsizei count, >> >> switch (target) { >> case GL_TRANSFORM_FEEDBACK_BUFFER: >> - bind_xfb_buffers_range(ctx, first, count, buffers, offsets, sizes); >> + bind_xfb_buffers(ctx, first, count, buffers, offsets, sizes, >> "glBindBuffersRange"); >> return; >> case GL_UNIFORM_BUFFER: >> bind_uniform_buffers_range(ctx, first, count, buffers, offsets, >> sizes); >> @@ -4086,7 +4029,7 @@ _mesa_BindBuffersBase(GLenum target, GLuint first, >> GLsizei count, >> >> switch (target) { >> case GL_TRANSFORM_FEEDBACK_BUFFER: >> - bind_xfb_buffers_base(ctx, first, count, buffers); >> + bind_xfb_buffers(ctx, first, count, buffers, NULL, NULL, >> "glBindBuffersBase"); >> return; >> case GL_UNIFORM_BUFFER: >> bind_uniform_buffers_base(ctx, first, count, buffers); >> > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev