mesa/marshal: add marshalling for glClearBuffer*

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>
This commit is contained in:
Grigori Goronzy 2017-07-09 03:27:12 +02:00
parent 8036198c0f
commit 1ad24faa11
3 changed files with 163 additions and 5 deletions

View File

@ -117,13 +117,13 @@
<!-- 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 *"/>
@ -135,7 +135,7 @@
<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"/>

View 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));
}
}

View 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 */