<div dir="ltr"><div>Looks good to me.<br><br></div>Reviewed-by: Laura Ekstrand <<a href="mailto:laura@jlekstrand.net">laura@jlekstrand.net</a>><br><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 23, 2015 at 6:47 AM, Martin Peres <span dir="ltr"><<a href="mailto:martin.peres@linux.intel.com" target="_blank">martin.peres@linux.intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">v2: Review from Laura Ekstrand<br>
- give more helpful error messages<br>
- factor the lookup code for the xfb and objBuf<br>
- replace some already-existing tabs with spaces<br>
- add comments to explain the cases where xfb == 0 or buffer == 0<br>
- fix the condition for binding the transform buffer or not<br>
<br>
v3: Review from Laura Ekstrand<br>
- rename _mesa_lookup_bufferobj_err to<br>
_mesa_lookup_transform_feedback_bufferobj_err and make it static to avoid a<br>
future conflict<br>
- make _mesa_lookup_transform_feedback_object_err static<br>
<br>
v4: Review from Laura Ekstrand<br>
- add the pdf page number when quoting the spec<br>
- rename some of the symbols to follow the public/private conventions<br>
<br>
</span>v5: Review from Laura Ekstrand<br>
- properly rename some of the symbols to follow the public/private conventions<br>
- fix some alignments<br>
- add quotes around a spec citation<br>
- add back a newline I accidentally deleted<br>
- add spaces around the ternary operator usages<br>
<span class=""><br>
Signed-off-by: Martin Peres <<a href="mailto:martin.peres@linux.intel.com">martin.peres@linux.intel.com</a>><br>
---<br>
</span> src/mapi/glapi/gen/ARB_direct_state_access.xml | 6 ++<br>
src/mesa/main/bufferobj.c | 9 +-<br>
src/mesa/main/tests/dispatch_sanity.cpp | 1 +<br>
src/mesa/main/transformfeedback.c | 138 +++++++++++++++++++------<br>
src/mesa/main/transformfeedback.h | 10 +-<br>
5 files changed, 129 insertions(+), 35 deletions(-)<br>
<span class=""><br>
diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml b/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
index 15b00c2..35d6906 100644<br>
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
@@ -14,6 +14,12 @@<br>
<param name="ids" type="GLuint *" /><br>
</function><br>
<br>
+ <function name="TransformFeedbackBufferBase" offset="assign"><br>
+ <param name="xfb" type="GLuint" /><br>
+ <param name="index" type="GLuint" /><br>
+ <param name="buffer" type="GLuint" /><br>
+ </function><br>
+<br>
<!-- Texture object functions --><br>
<br>
<function name="CreateTextures" offset="assign"><br>
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c<br>
</span>index b372c68..96d43c8 100644<br>
--- a/src/mesa/main/bufferobj.c<br>
+++ b/src/mesa/main/bufferobj.c<br>
@@ -3575,8 +3575,9 @@ _mesa_BindBufferRange(GLenum target, GLuint index,<br>
<span class=""><br>
switch (target) {<br>
case GL_TRANSFORM_FEEDBACK_BUFFER:<br>
- _mesa_bind_buffer_range_transform_feedback(ctx, index, bufObj,<br>
- offset, size);<br>
+ _mesa_bind_buffer_range_transform_feedback(ctx,<br>
+ ctx->TransformFeedback.CurrentObject,<br>
+ index, bufObj, offset, size);<br>
return;<br>
case GL_UNIFORM_BUFFER:<br>
bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);<br>
</span>@@ -3640,7 +3641,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)<br>
<span class=""><br>
switch (target) {<br>
case GL_TRANSFORM_FEEDBACK_BUFFER:<br>
- _mesa_bind_buffer_base_transform_feedback(ctx, index, bufObj);<br>
+ _mesa_bind_buffer_base_transform_feedback(ctx,<br>
+ ctx->TransformFeedback.CurrentObject,<br>
+ index, bufObj, false);<br>
return;<br>
case GL_UNIFORM_BUFFER:<br>
bind_buffer_base_uniform_buffer(ctx, index, bufObj);<br>
</span>diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp<br>
index c37ce95..3195abb 100644<br>
<span class="">--- a/src/mesa/main/tests/dispatch_sanity.cpp<br>
+++ b/src/mesa/main/tests/dispatch_sanity.cpp<br>
@@ -956,6 +956,7 @@ const struct function gl_core_functions_possible[] = {<br>
<br>
/* GL_ARB_direct_state_access */<br>
{ "glCreateTransformFeedbacks", 45, -1 },<br>
+ { "glTransformFeedbackBufferBase", 45, -1 },<br>
{ "glCreateTextures", 45, -1 },<br>
{ "glTextureStorage1D", 45, -1 },<br>
{ "glTextureStorage2D", 45, -1 },<br>
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c<br>
</span>index 10bb6a1..159fa62 100644<br>
<div><div class="h5">--- a/src/mesa/main/transformfeedback.c<br>
+++ b/src/mesa/main/transformfeedback.c<br>
@@ -514,22 +514,24 @@ _mesa_EndTransformFeedback(void)<br>
* Helper used by BindBufferRange() and BindBufferBase().<br>
*/<br>
static void<br>
-bind_buffer_range(struct gl_context *ctx, GLuint index,<br>
+bind_buffer_range(struct gl_context *ctx,<br>
+ struct gl_transform_feedback_object *obj,<br>
+ GLuint index,<br>
struct gl_buffer_object *bufObj,<br>
- GLintptr offset, GLsizeiptr size)<br>
+ GLintptr offset, GLsizeiptr size,<br>
+ bool dsa)<br>
{<br>
- struct gl_transform_feedback_object *obj =<br>
- ctx->TransformFeedback.CurrentObject;<br>
-<br>
/* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because<br>
* transform feedback buffers can't be changed while transform feedback is<br>
* active.<br>
*/<br>
<br>
- /* The general binding point */<br>
- _mesa_reference_buffer_object(ctx,<br>
- &ctx->TransformFeedback.CurrentBuffer,<br>
- bufObj);<br>
+ if (!dsa) {<br>
+ /* The general binding point */<br>
+ _mesa_reference_buffer_object(ctx,<br>
+ &ctx->TransformFeedback.CurrentBuffer,<br>
+ bufObj);<br>
+ }<br>
<br>
/* The per-attribute binding point */<br>
_mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size);<br>
@@ -543,15 +545,12 @@ bind_buffer_range(struct gl_context *ctx, GLuint index,<br>
*/<br>
void<br>
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,<br>
- GLuint index,<br>
- struct gl_buffer_object *bufObj,<br>
- GLintptr offset,<br>
- GLsizeiptr size)<br>
+ struct gl_transform_feedback_object *obj,<br>
+ GLuint index,<br>
+ struct gl_buffer_object *bufObj,<br>
+ GLintptr offset,<br>
+ GLsizeiptr size)<br>
{<br>
- struct gl_transform_feedback_object *obj;<br>
-<br>
- obj = ctx->TransformFeedback.CurrentObject;<br>
-<br>
if (obj->Active) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
"glBindBufferRange(transform feedback active)");<br>
@@ -559,13 +558,15 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,<br>
}<br>
<br>
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {<br>
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);<br>
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d "<br>
+ "out of bounds)", index);<br>
return;<br>
}<br>
<br>
if (size & 0x3) {<br>
/* must a multiple of four */<br>
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size);<br>
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",<br>
+ (int) size);<br>
return;<br>
}<br>
<br>
@@ -576,38 +577,109 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,<br>
return;<br>
}<br>
<br>
- bind_buffer_range(ctx, index, bufObj, offset, size);<br>
+ bind_buffer_range(ctx, obj, index, bufObj, offset, size, false);<br>
}<br>
<br>
<br>
/**<br>
* Specify a buffer object to receive transform feedback results.<br>
* As above, but start at offset = 0.<br>
- * Called from the glBindBufferBase() function.<br>
+ * Called from the glBindBufferBase() and glTransformFeedbackBufferBase()<br>
+ * functions.<br>
*/<br>
void<br>
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,<br>
- GLuint index,<br>
- struct gl_buffer_object *bufObj)<br>
+ struct gl_transform_feedback_object *obj,<br>
+ GLuint index,<br>
+ struct gl_buffer_object *bufObj,<br>
+ bool dsa)<br>
{<br>
- struct gl_transform_feedback_object *obj;<br>
-<br>
- obj = ctx->TransformFeedback.CurrentObject;<br>
-<br>
if (obj->Active) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
- "glBindBufferBase(transform feedback active)");<br>
+ "%s(transform feedback active)",<br>
</div></div>+ dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase");<br>
<span class=""> return;<br>
}<br>
<br>
if (index >= ctx->Const.MaxTransformFeedbackBuffers) {<br>
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);<br>
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",<br>
</span>+ dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase",<br>
<span class="">+ index);<br>
return;<br>
}<br>
<br>
- bind_buffer_range(ctx, index, bufObj, 0, 0);<br>
+ bind_buffer_range(ctx, obj, index, bufObj, 0, 0, dsa);<br>
}<br>
<br>
+/**<br>
</span>+ * Wrapper around lookup_transform_feedback_object that throws<br>
<span class="">+ * GL_INVALID_OPERATION if id is not in the hash table. After calling<br>
+ * _mesa_error, it returns NULL.<br>
+ */<br>
+static struct gl_transform_feedback_object *<br>
</span><span class="">+lookup_transform_feedback_object_err(struct gl_context *ctx,<br>
+ GLuint xfb, const char* func)<br>
+{<br>
+ struct gl_transform_feedback_object *obj;<br>
+<br>
</span>+ obj = _mesa_lookup_transform_feedback_object(ctx, xfb);<br>
<span class="">+ if (!obj) {<br>
+ _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+ "%s(xfb=%u: non-generated object name)", func, xfb);<br>
+ }<br>
+<br>
+ return obj;<br>
+}<br>
+<br>
+/**<br>
+ * Wrapper around _mesa_lookup_bufferobj that throws GL_INVALID_VALUE if id<br>
+ * is not in the hash table. Specialised version for the<br>
+ * transform-feedback-related functions. After calling _mesa_error, it<br>
+ * returns NULL.<br>
+ */<br>
+static struct gl_buffer_object *<br>
</span><div><div class="h5">+lookup_transform_feedback_bufferobj_err(struct gl_context *ctx,<br>
+ GLuint buffer, const char* func)<br>
+{<br>
+ struct gl_buffer_object *bufObj;<br>
+<br>
+ /* OpenGL 4.5 core profile, 13.2, pdf page 444: buffer must be zero or the<br>
+ * name of an existing buffer object.<br>
+ */<br>
+ if (buffer == 0) {<br>
+ bufObj = ctx->Shared->NullBufferObj;<br>
+ } else {<br>
+ bufObj = _mesa_lookup_bufferobj(ctx, buffer);<br>
+ if (!bufObj) {<br>
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid buffer=%u)", func,<br>
+ buffer);<br>
+ }<br>
+ }<br>
+<br>
+ return bufObj;<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)<br>
+{<br>
+ GET_CURRENT_CONTEXT(ctx);<br>
+ struct gl_transform_feedback_object *obj;<br>
+ struct gl_buffer_object *bufObj;<br>
+<br>
+ obj = lookup_transform_feedback_object_err(ctx, xfb,<br>
+ "glTransformFeedbackBufferBase");<br>
</div></div><span class="">+ if(!obj) {<br>
+ return;<br>
+ }<br>
+<br>
+ bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer,<br>
+ "glTransformFeedbackBufferBase");<br>
+ if(!bufObj) {<br>
+ return;<br>
+ }<br>
+<br>
+ _mesa_bind_buffer_base_transform_feedback(ctx, obj, index, bufObj, true);<br>
+}<br>
<br>
/**<br>
* Specify a buffer object to receive transform feedback results, plus the<br>
@@ -660,7 +732,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,<br>
return;<br>
}<br>
<br>
- bind_buffer_range(ctx, index, bufObj, offset, 0);<br>
+ bind_buffer_range(ctx, obj, index, bufObj, offset, 0, false);<br>
}<br>
<br>
<br>
</span>@@ -817,6 +889,10 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index,<br>
struct gl_transform_feedback_object *<br>
_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)<br>
<span class=""> {<br>
+ /* OpenGL 4.5 core profile, 13.2 pdf page 444: "xfb must be zero, indicating<br>
+ * the default transform feedback object, or the name of an existing<br>
+ * transform feedback object."<br>
+ */<br>
</span><span class=""> if (name == 0) {<br>
return ctx->TransformFeedback.DefaultObject;<br>
}<br>
</span>diff --git a/src/mesa/main/transformfeedback.h b/src/mesa/main/transformfeedback.h<br>
index 9de1fef..aac7433 100644<br>
<span class="">--- a/src/mesa/main/transformfeedback.h<br>
+++ b/src/mesa/main/transformfeedback.h<br>
@@ -65,6 +65,7 @@ _mesa_EndTransformFeedback(void);<br>
<br>
extern void<br>
_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,<br>
+ struct gl_transform_feedback_object *obj,<br>
GLuint index,<br>
struct gl_buffer_object *bufObj,<br>
GLintptr offset,<br>
</span>@@ -72,8 +73,10 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,<br>
<span class=""><br>
extern void<br>
_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,<br>
+ struct gl_transform_feedback_object *obj,<br>
GLuint index,<br>
- struct gl_buffer_object *bufObj);<br>
</span>+ struct gl_buffer_object *bufObj,<br>
+ bool dsa);<br>
<span class=""><br>
extern void GLAPIENTRY<br>
_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,<br>
</span>@@ -144,4 +147,9 @@ _mesa_set_transform_feedback_binding(struct gl_context *ctx,<br>
<span class=""> tfObj->RequestedSize[index] = size;<br>
}<br>
<br>
+/*** GL_ARB_direct_state_access ***/<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer);<br>
+<br>
#endif /* TRANSFORM_FEEDBACK_H */<br>
</span><span class="">--<br>
2.3.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
</span><a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div></div></div></div>