mesa/marshal: add marshalling for glClearBuffer*
authorGrigori Goronzy <greg@chown.ath.cx>
Sun, 9 Jul 2017 01:27:12 +0000 (03:27 +0200)
committerGrigori Goronzy <greg@chown.ath.cx>
Fri, 14 Jul 2017 19:20:31 +0000 (21:20 +0200)
Add async marshalling/unmarshalling for all glClearBuffer variants.
These entry points are commonly used in general and Alien Isolation
specifically uses glClearBufferiv. Slightly reduces the number of
thread synchronizations with glthread in that game.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/mapi/glapi/gen/GL3x.xml
src/mesa/main/marshal.c
src/mesa/main/marshal.h

index 24490da7e32cf37e25a864976528aeea5eb47578..7c86e8fc51aed5f90a60a231cd024fa55588d41c 100644 (file)
 
   <!-- These functions are unique to GL3 -->
 
-  <function name="ClearBufferiv" es2="3.0">
+  <function name="ClearBufferiv" es2="3.0" marshal="custom">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="value" type="const GLint *"/>
   </function>
 
-  <function name="ClearBufferuiv" es2="3.0">
+  <function name="ClearBufferuiv" es2="3.0" marshal="custom">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="value" type="const GLuint *"/>
     <param name="value" type="const GLfloat *"/>
   </function>
 
-  <function name="ClearBufferfi" es2="3.0">
+  <function name="ClearBufferfi" es2="3.0" marshal="custom">
     <param name="buffer" type="GLenum"/>
     <param name="drawbuffer" type="GLint"/>
     <param name="depth" type="GLfloat"/>
index 5499bc41ae1a9a6f61703032f3d88f89cdd55871..391b6e746c2b1c33182e0d1586cc0a725ec2a7de 100644 (file)
@@ -516,7 +516,7 @@ _mesa_marshal_NamedBufferSubData(GLuint buffer, GLintptr offset,
    }
 }
 
-/* ClearBufferfv: marshalled asynchronously */
+/* ClearBuffer* (all variants): marshalled asynchronously */
 struct marshal_cmd_ClearBuffer
 {
    struct marshal_cmd_base cmd_base;
@@ -537,6 +537,46 @@ _mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
                       (buffer, drawbuffer, value));
 }
 
+void
+_mesa_unmarshal_ClearBufferiv(struct gl_context *ctx,
+                              const struct marshal_cmd_ClearBuffer *cmd)
+{
+   const GLenum buffer = cmd->buffer;
+   const GLint drawbuffer = cmd->drawbuffer;
+   const char *variable_data = (const char *) (cmd + 1);
+   const GLint *value = (const GLint *) variable_data;
+
+   CALL_ClearBufferiv(ctx->CurrentServerDispatch,
+                      (buffer, drawbuffer, value));
+}
+
+void
+_mesa_unmarshal_ClearBufferuiv(struct gl_context *ctx,
+                               const struct marshal_cmd_ClearBuffer *cmd)
+{
+   const GLenum buffer = cmd->buffer;
+   const GLint drawbuffer = cmd->drawbuffer;
+   const char *variable_data = (const char *) (cmd + 1);
+   const GLuint *value = (const GLuint *) variable_data;
+
+   CALL_ClearBufferuiv(ctx->CurrentServerDispatch,
+                       (buffer, drawbuffer, value));
+}
+
+void
+_mesa_unmarshal_ClearBufferfi(struct gl_context *ctx,
+                              const struct marshal_cmd_ClearBuffer *cmd)
+{
+   const GLenum buffer = cmd->buffer;
+   const GLint drawbuffer = cmd->drawbuffer;
+   const char *variable_data = (const char *) (cmd + 1);
+   const GLfloat *depth = (const GLfloat *) variable_data;
+   const GLint *stencil = (const GLint *) (variable_data + 4);
+
+   CALL_ClearBufferfi(ctx->CurrentServerDispatch,
+                      (buffer, drawbuffer, *depth, *stencil));
+}
+
 static inline size_t buffer_to_size(GLenum buffer)
 {
    switch (buffer) {
@@ -607,3 +647,94 @@ _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
                          (buffer, drawbuffer, value));
    }
 }
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferiv(GLenum buffer, GLint drawbuffer,
+                            const GLint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   debug_print_marshal("ClearBufferiv");
+
+   if (!(buffer == GL_STENCIL || buffer == GL_COLOR)) {
+      _mesa_glthread_finish(ctx);
+
+      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
+       * of the OpenGL 4.5 spec states:
+       *
+       *    "An INVALID_ENUM error is generated by ClearBufferiv and
+       *     ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
+       */
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)",
+                  _mesa_enum_to_string(buffer));
+   }
+
+   size_t size = buffer_to_size(buffer);
+   if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferiv, buffer,
+                                 drawbuffer, (GLuint *)value, size)) {
+      debug_print_sync("ClearBufferiv");
+      _mesa_glthread_finish(ctx);
+      CALL_ClearBufferiv(ctx->CurrentServerDispatch,
+                         (buffer, drawbuffer, value));
+   }
+}
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferuiv(GLenum buffer, GLint drawbuffer,
+                             const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   debug_print_marshal("ClearBufferuiv");
+
+   if (buffer != GL_COLOR) {
+      _mesa_glthread_finish(ctx);
+
+      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
+       * of the OpenGL 4.5 spec states:
+       *
+       *    "An INVALID_ENUM error is generated by ClearBufferuiv and
+       *     ClearNamedFramebufferuiv if buffer is not COLOR."
+       */
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)",
+                  _mesa_enum_to_string(buffer));
+   }
+
+   if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferuiv, buffer,
+                                 drawbuffer, (GLuint *)value, 4)) {
+      debug_print_sync("ClearBufferuiv");
+      _mesa_glthread_finish(ctx);
+      CALL_ClearBufferuiv(ctx->CurrentServerDispatch,
+                         (buffer, drawbuffer, value));
+   }
+}
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferfi(GLenum buffer, GLint drawbuffer,
+                            const GLfloat depth, const GLint stencil)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   debug_print_marshal("ClearBufferfi");
+
+   if (buffer != GL_DEPTH_STENCIL) {
+      _mesa_glthread_finish(ctx);
+
+      /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
+       * of the OpenGL 4.5 spec states:
+       *
+       *    "An INVALID_ENUM error is generated by ClearBufferfi and
+       *     ClearNamedFramebufferfi if buffer is not DEPTH_STENCIL."
+       */
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)",
+                  _mesa_enum_to_string(buffer));
+   }
+
+   fi_type value[2];
+   value[0].f = depth;
+   value[1].i = stencil;
+   if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferfi, buffer,
+                                 drawbuffer, (GLuint *)value, 2)) {
+      debug_print_sync("ClearBufferfi");
+      _mesa_glthread_finish(ctx);
+      CALL_ClearBufferfi(ctx->CurrentServerDispatch,
+                         (buffer, drawbuffer, depth, stencil));
+   }
+}
index 1567e7bea428da9259f27aecf4c2673a963993e7..f2dc8429a1a127ab8b225335db31e8502326e16b 100644 (file)
@@ -183,7 +183,10 @@ struct marshal_cmd_BufferSubData;
 struct marshal_cmd_NamedBufferData;
 struct marshal_cmd_NamedBufferSubData;
 struct marshal_cmd_ClearBuffer;
-#define marshal_cmd_ClearBufferfv marshal_cmd_ClearBuffer
+#define marshal_cmd_ClearBufferfv   marshal_cmd_ClearBuffer
+#define marshal_cmd_ClearBufferiv   marshal_cmd_ClearBuffer
+#define marshal_cmd_ClearBufferuiv  marshal_cmd_ClearBuffer
+#define marshal_cmd_ClearBufferfi   marshal_cmd_ClearBuffer
 
 void
 _mesa_unmarshal_Enable(struct gl_context *ctx,
@@ -254,4 +257,28 @@ void GLAPIENTRY
 _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
                             const GLfloat *value);
 
+void GLAPIENTRY
+_mesa_unmarshal_ClearBufferiv(struct gl_context *ctx,
+                              const struct marshal_cmd_ClearBuffer *cmd);
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferiv(GLenum buffer, GLint drawbuffer,
+                            const GLint *value);
+
+void GLAPIENTRY
+_mesa_unmarshal_ClearBufferuiv(struct gl_context *ctx,
+                               const struct marshal_cmd_ClearBuffer *cmd);
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferuiv(GLenum buffer, GLint drawbuffer,
+                             const GLuint *value);
+
+void GLAPIENTRY
+_mesa_unmarshal_ClearBufferfi(struct gl_context *ctx,
+                              const struct marshal_cmd_ClearBuffer *cmd);
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferfi(GLenum buffer, GLint drawbuffer,
+                            const GLfloat depth, const GLint stencil);
+
 #endif /* MARSHAL_H */