summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-03-24 17:46:20 +1100
committerTimothy Arceri <[email protected]>2017-03-25 13:39:12 +1100
commit425671f616cc85899535cb84abd7406a9380565e (patch)
tree6ddb6005017470628bac9124f70af0aec209cf60 /src
parentb9e92334f79bff2497fd718d49fe7c53b5f2074c (diff)
mesa/glthread: add custom marshalling for ClearBufferfv()
This is one of the main causes of syncs in Civ6. Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mapi/glapi/gen/GL3x.xml2
-rw-r--r--src/mesa/main/marshal.c74
-rw-r--r--src/mesa/main/marshal.h9
3 files changed, 84 insertions, 1 deletions
diff --git a/src/mapi/glapi/gen/GL3x.xml b/src/mapi/glapi/gen/GL3x.xml
index b603e1f82f6..f38a2876dfe 100644
--- a/src/mapi/glapi/gen/GL3x.xml
+++ b/src/mapi/glapi/gen/GL3x.xml
@@ -129,7 +129,7 @@
<param name="value" type="const GLuint *"/>
</function>
- <function name="ClearBufferfv" es2="3.0">
+ <function name="ClearBufferfv" es2="3.0" marshal="custom">
<param name="buffer" type="GLenum"/>
<param name="drawbuffer" type="GLint"/>
<param name="value" type="const GLfloat *"/>
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
index cdc7fed8a58..03da140d876 100644
--- a/src/mesa/main/marshal.c
+++ b/src/mesa/main/marshal.c
@@ -27,6 +27,8 @@
* thread when automatic code generation isn't appropriate.
*/
+#include "main/enums.h"
+#include "main/macros.h"
#include "marshal.h"
#include "dispatch.h"
#include "marshal_generated.h"
@@ -384,4 +386,76 @@ _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
}
}
+/* ClearBufferfv: marshalled asynchronously */
+struct marshal_cmd_ClearBufferfv
+{
+ struct marshal_cmd_base cmd_base;
+ GLenum buffer;
+ GLint drawbuffer;
+};
+
+void
+_mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
+ const struct marshal_cmd_ClearBufferfv *cmd)
+{
+ const GLenum buffer = cmd->buffer;
+ const GLint drawbuffer = cmd->drawbuffer;
+ const char *variable_data = (const char *) (cmd + 1);
+ const GLfloat *value = (const GLfloat *) variable_data;
+
+ CALL_ClearBufferfv(ctx->CurrentServerDispatch,
+ (buffer, drawbuffer, value));
+}
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ debug_print_marshal("ClearBufferfv");
+
+ size_t size;
+ switch (buffer) {
+ case GL_DEPTH:
+ size = sizeof(GLfloat);
+ break;
+ case GL_COLOR:
+ size = sizeof(GLfloat) * 4;
+ break;
+ default:
+ _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 ClearBufferfv and
+ * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
+ */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)",
+ _mesa_enum_to_string(buffer));
+ return;
+ }
+
+ size_t cmd_size = sizeof(struct marshal_cmd_ClearBufferfv) + size;
+ if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {
+ struct marshal_cmd_ClearBufferfv *cmd =
+ _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_ClearBufferfv,
+ cmd_size);
+ cmd->buffer = buffer;
+ cmd->drawbuffer = drawbuffer;
+ GLfloat *variable_data = (GLfloat *) (cmd + 1);
+ if (buffer == GL_COLOR)
+ COPY_4V(variable_data, value);
+ else
+ *variable_data = *value;
+
+ _mesa_post_marshal_hook(ctx);
+ } else {
+ debug_print_sync("ClearBufferfv");
+ _mesa_glthread_finish(ctx);
+ CALL_ClearBufferfv(ctx->CurrentServerDispatch,
+ (buffer, drawbuffer, value));
+ }
+}
+
#endif
diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
index 4e9a6653b4e..52339aa1db2 100644
--- a/src/mesa/main/marshal.h
+++ b/src/mesa/main/marshal.h
@@ -189,6 +189,7 @@ struct marshal_cmd_Flush;
struct marshal_cmd_BindBuffer;
struct marshal_cmd_BufferData;
struct marshal_cmd_BufferSubData;
+struct marshal_cmd_ClearBufferfv;
void GLAPIENTRY
_mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
@@ -228,4 +229,12 @@ void GLAPIENTRY
_mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
const GLvoid * data);
+void
+_mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
+ const struct marshal_cmd_ClearBufferfv *cmd);
+
+void GLAPIENTRY
+_mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
+ const GLfloat *value);
+
#endif /* MARSHAL_H */