main: Added entry point for glTransformFeedbackBufferRange
authorMartin Peres <martin.peres@linux.intel.com>
Wed, 21 Jan 2015 10:22:11 +0000 (12:22 +0200)
committerMartin Peres <martin.peres@linux.intel.com>
Wed, 25 Mar 2015 08:05:45 +0000 (10:05 +0200)
v2: review from Laura Ekstrand
- use the refactored code to lookup the objects
- improve some error messages
- factor out the gl method name computation
- better handle the spec differences between the DSA and non-DSA cases
- quote the spec a little more

v3: review from Laura Ekstrand
- use the new name of _mesa_lookup_bufferobj_err
- swap the comments around the offset and size checks

v4: review from Laura Ekstrand
- add more spec quotes
- properly fix the comments around the offset and size checks

v5: review from Laura Ekstrand
- add quotes on the spec citations
- revert some changes in the printf format

v6: review from Laura Ekstrand
- remove a redondant "gl" in a method name

Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Laura Ekstrand <laura@jlekstrand.net>
src/mapi/glapi/gen/ARB_direct_state_access.xml
src/mesa/main/bufferobj.c
src/mesa/main/tests/dispatch_sanity.cpp
src/mesa/main/transformfeedback.c
src/mesa/main/transformfeedback.h

index 02e33cd4a7557f13181706c44ad1b59dafffbcef..2375df4e7005e88c9b69a1fd998ecc253b039ebc 100644 (file)
       <param name="buffer" type="GLuint" />
    </function>
 
+   <function name="TransformFeedbackBufferRange" offset="assign">
+      <param name="xfb" type="GLuint" />
+      <param name="index" type="GLuint" />
+      <param name="buffer" type="GLuint" />
+      <param name="offset" type="GLintptr" />
+      <param name="size" type="GLsizeiptr" />
+   </function>
+
    <!-- Buffer object functions -->
 
    <function name="CreateBuffers" offset="assign">
index e73793638c9a550bf8212761fa06c223621ac1df..c45cec405a0375497e6f9602b847c643bedab7dd 100644 (file)
@@ -3887,7 +3887,8 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
    case GL_TRANSFORM_FEEDBACK_BUFFER:
       _mesa_bind_buffer_range_transform_feedback(ctx,
                                                  ctx->TransformFeedback.CurrentObject,
-                                                 index, bufObj, offset, size);
+                                                 index, bufObj, offset, size,
+                                                 false);
       return;
    case GL_UNIFORM_BUFFER:
       bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
index 315571d6fedba32ad63112b2a8267aa4c8b60f7d..a259272d20acf44ca37c4de0657f91f9909e5383 100644 (file)
@@ -924,6 +924,7 @@ const struct function gl_core_functions_possible[] = {
    /* GL_ARB_direct_state_access */
    { "glCreateTransformFeedbacks", 45, -1 },
    { "glTransformFeedbackBufferBase", 45, -1 },
+   { "glTransformFeedbackBufferRange", 45, -1 },
    { "glCreateBuffers", 45, -1 },
    { "glNamedBufferStorage", 45, -1 },
    { "glNamedBufferData", 45, -1 },
index 1b2bd8d77afe342097bdf11d8d21fb09db1f67a3..e6b9803532a65edd8c84507f21b580e15480db70 100644 (file)
@@ -541,7 +541,8 @@ bind_buffer_range(struct gl_context *ctx,
 /**
  * Specify a buffer object to receive transform feedback results.  Plus,
  * specify the starting offset to place the results, and max size.
- * Called from the glBindBufferRange() function.
+ * Called from the glBindBufferRange() and glTransformFeedbackBufferRange
+ * functions.
  */
 void
 _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
@@ -549,35 +550,74 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
                                            GLuint index,
                                            struct gl_buffer_object *bufObj,
                                            GLintptr offset,
-                                           GLsizeiptr size)
+                                           GLsizeiptr size,
+                                           bool dsa)
 {
+   const char *gl_methd_name;
+   if (dsa)
+      gl_methd_name = "glTransformFeedbackBufferRange";
+   else
+      gl_methd_name = "glBindBufferRange";
+
+
    if (obj->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glBindBufferRange(transform feedback active)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)",
+                  gl_methd_name);
       return;
    }
 
    if (index >= ctx->Const.MaxTransformFeedbackBuffers) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d "
-                  "out of bounds)", index);
+      /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+       * generated if index is greater than or equal to the number of binding
+       * points for transform feedback, as described in section 6.7.1."
+       */
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)",
+                  gl_methd_name, index);
       return;
    }
 
    if (size & 0x3) {
-      /* must a multiple of four */
-      _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
-                  (int) size);
+      /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be a multiple of "
+                  "four)", gl_methd_name, (int) size);
       return;
    }  
 
    if (offset & 0x3) {
-      /* must be multiple of four */
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glBindBufferRange(offset=%d)", (int) offset);
+      /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be a multiple "
+                  "of four)", gl_methd_name, (int) offset);
       return;
-   }  
+   }
+
+   if (offset < 0) {
+      /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+       * generated by BindBufferRange if offset is negative."
+       *
+       * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error
+       * is generated by TransformFeedbackBufferRange if offset is negative."
+       */
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be >= 0)",
+                  gl_methd_name,
+                  (int) offset);
+      return;
+   }
+
+   if (size <= 0 && (dsa || bufObj != ctx->Shared->NullBufferObj)) {
+      /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is
+       * generated by BindBufferRange if buffer is non-zero and size is less
+       * than or equal to zero."
+       *
+       * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error
+       * is generated by TransformFeedbackBufferRange if size is less than or
+       * equal to zero."
+       */
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be > 0)",
+                  gl_methd_name, (int) size);
+      return;
+   }
 
-   bind_buffer_range(ctx, obj, index, bufObj, offset, size, false);
+   bind_buffer_range(ctx, obj, index, bufObj, offset, size, dsa);
 }
 
 
@@ -681,6 +721,30 @@ _mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
    _mesa_bind_buffer_base_transform_feedback(ctx, obj, index, bufObj, true);
 }
 
+void GLAPIENTRY
+_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer,
+                                   GLintptr offset, GLsizeiptr size)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_transform_feedback_object *obj;
+   struct gl_buffer_object *bufObj;
+
+   obj = lookup_transform_feedback_object_err(ctx, xfb,
+                                              "glTransformFeedbackBufferRange");
+   if(!obj) {
+      return;
+   }
+
+   bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer,
+                                              "glTransformFeedbackBufferRange");
+   if(!bufObj) {
+      return;
+   }
+
+   _mesa_bind_buffer_range_transform_feedback(ctx, obj, index, bufObj, offset,
+                                              size, true);
+}
+
 /**
  * Specify a buffer object to receive transform feedback results, plus the
  * offset in the buffer to start placing results.
index aac7433d14b282ae5bb3e8517500cd714c6d7a82..9ec7d384af77c4d9f972f874ea71f3ebbe5d7ff4 100644 (file)
@@ -69,7 +69,7 @@ _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
                                           GLuint index,
                                           struct gl_buffer_object *bufObj,
                                           GLintptr offset,
-                                          GLsizeiptr size);
+                                          GLsizeiptr size, bool dsa);
 
 extern void
 _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
@@ -152,4 +152,8 @@ _mesa_set_transform_feedback_binding(struct gl_context *ctx,
 extern void GLAPIENTRY
 _mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer);
 
+extern void GLAPIENTRY
+_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer,
+                                   GLintptr offset, GLsizeiptr size);
+
 #endif /* TRANSFORM_FEEDBACK_H */