glthread: add marshal_call_after and remove custom glFlush and glEnable code

Instead of implementing marshalling manually, this XML property allows us
to insert additional code into code-generated functions.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3948>
This commit is contained in:
Marek Olšák
2020-02-20 18:15:42 -05:00
committed by Marge Bot
parent 4970199d11
commit d510e652d4
6 changed files with 15 additions and 95 deletions

View File

@@ -42,6 +42,7 @@
marshal NMTOKEN #IMPLIED
marshal_fail CDATA #IMPLIED>
marshal_count CDATA #IMPLIED>
marshal_call_after CDATA #IMPLIED>
<!ATTLIST size name NMTOKEN #REQUIRED
count NMTOKEN #IMPLIED
mode (get | set) "set">
@@ -137,6 +138,7 @@ param:
want to track state for.
marshal_count - same as count, but variable_param is ignored. Used by
glthread.
marshal_call_after - insert the string at the end of the marshal function
glx:
rop - Opcode value for "render" commands

View File

@@ -2377,7 +2377,8 @@
<glx rop="138" handcode="client"/>
</function>
<function name="Enable" es1="1.0" es2="2.0" marshal="custom">
<function name="Enable" es1="1.0" es2="2.0"
marshal_call_after='if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) _mesa_glthread_disable(ctx, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)");'>
<param name="cap" type="GLenum"/>
<glx rop="139" handcode="client"/>
</function>
@@ -2386,14 +2387,8 @@
<glx sop="108" handcode="true"/>
</function>
<!-- TODO: Flush is marshalled synchronously as a temporary hack
since we don't yet have a hook into SwapBuffers.
NOTE: when we remove this hack, we'll still have to handle Flush
specially to ensure that it causes all previous commands to get
delivered to the server thread.
-->
<function name="Flush" es1="1.0" es2="2.0" marshal="custom">
<function name="Flush" es1="1.0" es2="2.0"
marshal_call_after="_mesa_glthread_flush_batch(ctx);">
<glx sop="142" handcode="true"/>
</function>

View File

@@ -78,13 +78,16 @@ class PrintCode(gl_XML.gl_print_base):
def printRealFooter(self):
pass
def print_sync_call(self, func):
def print_sync_call(self, func, unmarshal = 0):
call = 'CALL_{0}(ctx->CurrentServerDispatch, ({1}))'.format(
func.name, func.get_called_parameter_string())
if func.return_type == 'void':
out('{0};'.format(call))
if func.marshal_call_after and not unmarshal:
out(func.marshal_call_after);
else:
out('return {0};'.format(call))
assert not func.marshal_call_after
def print_sync_dispatch(self, func):
self.print_sync_call(func)
@@ -132,6 +135,9 @@ class PrintCode(gl_XML.gl_print_base):
if not func.fixed_params and not func.variable_params:
out('(void) cmd;')
if func.marshal_call_after:
out(func.marshal_call_after);
# Uncomment this if you want to call _mesa_glthread_finish for debugging
#out('_mesa_glthread_finish(ctx);')
@@ -208,7 +214,7 @@ class PrintCode(gl_XML.gl_print_base):
out('variable_data += {0};'.format(p.size_string(False, marshal = 1)))
i += 1
self.print_sync_call(func)
self.print_sync_call(func, unmarshal = 1)
out('}')
def validate_count_or_fallback(self, func):

View File

@@ -58,6 +58,7 @@ class marshal_function(gl_XML.gl_function):
# Store the "marshal" attribute, if present.
self.marshal = element.get('marshal')
self.marshal_fail = element.get('marshal_fail')
self.marshal_call_after = element.get('marshal_call_after')
def marshal_flavor(self):
"""Find out how this function should be marshalled between

View File

@@ -43,74 +43,6 @@ _mesa_post_marshal_hook(struct gl_context *ctx)
_mesa_glthread_finish(ctx);
}
struct marshal_cmd_Flush
{
struct marshal_cmd_base cmd_base;
};
void
_mesa_unmarshal_Flush(struct gl_context *ctx,
const struct marshal_cmd_Flush *cmd)
{
CALL_Flush(ctx->CurrentServerDispatch, ());
}
void GLAPIENTRY
_mesa_marshal_Flush(void)
{
GET_CURRENT_CONTEXT(ctx);
struct marshal_cmd_Flush *cmd =
_mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Flush,
sizeof(struct marshal_cmd_Flush));
(void) cmd;
_mesa_post_marshal_hook(ctx);
/* Flush() needs to be handled specially. In addition to telling the
* background thread to flush, we need to ensure that our own buffer is
* submitted to the background thread so that it will complete in a finite
* amount of time.
*/
_mesa_glthread_flush_batch(ctx);
}
/* Enable: marshalled asynchronously */
struct marshal_cmd_Enable
{
struct marshal_cmd_base cmd_base;
GLenum cap;
};
void
_mesa_unmarshal_Enable(struct gl_context *ctx,
const struct marshal_cmd_Enable *cmd)
{
const GLenum cap = cmd->cap;
CALL_Enable(ctx->CurrentServerDispatch, (cap));
}
void GLAPIENTRY
_mesa_marshal_Enable(GLenum cap)
{
GET_CURRENT_CONTEXT(ctx);
struct marshal_cmd_Enable *cmd;
debug_print_marshal("Enable");
if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) {
_mesa_glthread_disable(ctx, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)");
} else {
cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Enable,
sizeof(*cmd));
cmd->cap = cap;
_mesa_post_marshal_hook(ctx);
return;
}
_mesa_glthread_finish(ctx);
debug_print_sync_fallback("Enable");
CALL_Enable(ctx->CurrentServerDispatch, (cap));
}
struct marshal_cmd_ShaderSource
{

View File

@@ -175,22 +175,13 @@ _mesa_glthread_is_compat_bind_vertex_array(const struct gl_context *ctx)
return ctx->API != API_OPENGL_CORE;
}
struct marshal_cmd_Enable;
struct marshal_cmd_ShaderSource;
struct marshal_cmd_Flush;
struct marshal_cmd_BindBuffer;
struct marshal_cmd_BufferData;
struct marshal_cmd_BufferSubData;
struct marshal_cmd_NamedBufferData;
struct marshal_cmd_NamedBufferSubData;
void
_mesa_unmarshal_Enable(struct gl_context *ctx,
const struct marshal_cmd_Enable *cmd);
void GLAPIENTRY
_mesa_marshal_Enable(GLenum cap);
void GLAPIENTRY
_mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
const GLchar * const *string, const GLint *length);
@@ -199,13 +190,6 @@ void
_mesa_unmarshal_ShaderSource(struct gl_context *ctx,
const struct marshal_cmd_ShaderSource *cmd);
void GLAPIENTRY
_mesa_marshal_Flush(void);
void
_mesa_unmarshal_Flush(struct gl_context *ctx,
const struct marshal_cmd_Flush *cmd);
void GLAPIENTRY
_mesa_marshal_BindBuffer(GLenum target, GLuint buffer);