[Mesa-dev] [PATCH v5 3/3] mapi/glthread: generate asynchronous code for PBO transfer
Gregory Hainaut
gregory.hainaut at gmail.com
Wed Apr 19 16:54:56 UTC 2017
Improve speed on PCSX2
v2:
Add ppbo/ubpo status in XML file
Disable variable parameter (as the pointer would be a fixed offset)
v3:
split buffer tracking into separate patches.
use 'goto fallback_to_sync' when asynchronous transfer isn't supported
v4:
add Nicolai comment to explain why ppbo isn't impacted by the variable_params
issue
Signed-off-by: Gregory Hainaut <gregory.hainaut at gmail.com>
---
src/mapi/glapi/gen/ARB_direct_state_access.xml | 16 +++++++--------
src/mapi/glapi/gen/ARB_robustness.xml | 2 +-
src/mapi/glapi/gen/gl_API.dtd | 10 +++++----
src/mapi/glapi/gen/gl_API.xml | 28 +++++++++++++-------------
src/mapi/glapi/gen/gl_marshal.py | 23 ++++++++++++++++++++-
src/mapi/glapi/gen/marshal_XML.py | 21 ++++++++++++++-----
6 files changed, 67 insertions(+), 33 deletions(-)
diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml b/src/mapi/glapi/gen/ARB_direct_state_access.xml
index 566f157..d842ebd 100644
--- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
+++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
@@ -367,79 +367,79 @@
<function name="TextureStorage3DMultisample">
<param name="texture" type="GLuint" />
<param name="samples" type="GLsizei" />
<param name="internalformat" type="GLenum" />
<param name="width" type="GLsizei" />
<param name="height" type="GLsizei" />
<param name="depth" type="GLsizei" />
<param name="fixedsamplelocations" type="GLboolean" />
</function>
- <function name="TextureSubImage1D">
+ <function name="TextureSubImage1D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="type" type="GLenum" />
<param name="pixels" type="const GLvoid *" />
</function>
- <function name="TextureSubImage2D">
+ <function name="TextureSubImage2D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="yoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="height" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="type" type="GLenum" />
<param name="pixels" type="const GLvoid *" />
</function>
- <function name="TextureSubImage3D">
+ <function name="TextureSubImage3D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="yoffset" type="GLint" />
<param name="zoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="height" type="GLsizei" />
<param name="depth" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="type" type="GLenum" />
<param name="pixels" type="const GLvoid *" />
</function>
- <function name="CompressedTextureSubImage1D">
+ <function name="CompressedTextureSubImage1D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="imageSize" type="GLsizei" />
<param name="data" type="const GLvoid *" />
</function>
- <function name="CompressedTextureSubImage2D">
+ <function name="CompressedTextureSubImage2D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="yoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="height" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="imageSize" type="GLsizei" />
<param name="data" type="const GLvoid *" />
</function>
- <function name="CompressedTextureSubImage3D">
+ <function name="CompressedTextureSubImage3D" marshal="upbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="xoffset" type="GLint" />
<param name="yoffset" type="GLint" />
<param name="zoffset" type="GLint" />
<param name="width" type="GLsizei" />
<param name="height" type="GLsizei" />
<param name="depth" type="GLsizei" />
<param name="format" type="GLenum" />
<param name="imageSize" type="GLsizei" />
@@ -516,30 +516,30 @@
<function name="GenerateTextureMipmap">
<param name="texture" type="GLuint" />
</function>
<function name="BindTextureUnit">
<param name="unit" type="GLuint" />
<param name="texture" type="GLuint" />
</function>
- <function name="GetTextureImage">
+ <function name="GetTextureImage" marshal="ppbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="format" type="GLenum" />
<param name="type" type="GLenum" />
<param name="bufSize" type="GLsizei" />
<param name="pixels" type="GLvoid *" />
</function>
- <function name="GetCompressedTextureImage">
+ <function name="GetCompressedTextureImage" marshal="ppbo">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="bufSize" type="GLsizei" />
<param name="pixels" type="GLvoid *" />
</function>
<function name="GetTextureLevelParameterfv">
<param name="texture" type="GLuint" />
<param name="level" type="GLint" />
<param name="pname" type="GLenum" />
diff --git a/src/mapi/glapi/gen/ARB_robustness.xml b/src/mapi/glapi/gen/ARB_robustness.xml
index 9b2f2f0..6e1ac09 100644
--- a/src/mapi/glapi/gen/ARB_robustness.xml
+++ b/src/mapi/glapi/gen/ARB_robustness.xml
@@ -75,21 +75,21 @@
<function name="GetnTexImageARB">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="bufSize" type="GLsizei"/>
<param name="img" type="GLvoid *" output="true"/>
</function>
- <function name="ReadnPixelsARB">
+ <function name="ReadnPixelsARB" marshal="ppbo">
<param name="x" type="GLint"/>
<param name="y" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="bufSize" type="GLsizei"/>
<param name="data" type="GLvoid *" output="true"/>
</function>
diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd
index b464250..447b03a 100644
--- a/src/mapi/glapi/gen/gl_API.dtd
+++ b/src/mapi/glapi/gen/gl_API.dtd
@@ -115,28 +115,30 @@ param:
img_send_null - boolean flag to determine if blank pixel data should
be sent when a NULL pointer is passed. This is only used by
TexImage1D and TexImage2D.
img_null_flag - boolean flag to determine if an extra flag is used to
determine if a NULL pixel pointer was passed. This is used by
TexSubImage1D, TexSubImage2D, TexImage3D and others.
img_pad_dimensions - boolean flag to determine if dimension data and
offset data should be padded to the next even number of dimensions.
For example, this will insert an empty "height" field after the
"width" field in the protocol for TexImage1D.
- marshal - One of "sync", "async", "draw", or "custom", defaulting to
- async unless one of the arguments is something we know we can't
- codegen for. If "sync", we finish any queued glthread work and call
+ marshal - One of "sync", "async", "draw", "ppbo", "upbo" or "custom",
+ defaulting to async unless one of the arguments is something we know we
+ can't codegen for. If "sync", we finish any queued glthread work and call
the Mesa implementation directly. If "async", we queue the function
call to be performed by glthread. If "custom", the prototype will be
generated but a custom implementation will be present in marshal.c.
If "draw", it will follow the "async" rules except that "indices" are
- ignored (since they may come from a VBO).
+ ignored (since they may come from a VBO). If "ppbo"/"upbo", it will
+ follow the "async" rules when a pack/unpack pixel buffer is bound
+ otherwise it will follow the "sync" rules.
marshal_fail - an expression that, if it evaluates true, causes glthread
to switch back to the Mesa implementation and call it directly. Used
to disable glthread for GL compatibility interactions that we don't
want to track state for.
glx:
rop - Opcode value for "render" commands
sop - Opcode value for "single" commands
vendorpriv - Opcode value for vendor private (or vendor private with
reply) commands
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index ad841a1..f436a95 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -2142,33 +2142,33 @@
<glx rop="107"/>
</function>
<function name="TexParameteriv" es1="1.1" es2="2.0">
<param name="target" type="GLenum"/>
<param name="pname" type="GLenum"/>
<param name="params" type="const GLint *" variable_param="pname"/>
<glx rop="108"/>
</function>
- <function name="TexImage1D">
+ <function name="TexImage1D" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="pixels" type="const GLvoid *" img_width="width" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/>
<glx rop="109" large="true"/>
</function>
- <function name="TexImage2D" es1="1.0" es2="2.0">
+ <function name="TexImage2D" marshal="upbo" es1="1.0" es2="2.0">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/>
<glx rop="110" large="true"/>
@@ -2633,21 +2633,21 @@
<function name="CopyPixels" deprecated="3.1">
<param name="x" type="GLint"/>
<param name="y" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="type" type="GLenum"/>
<glx rop="172"/>
</function>
- <function name="ReadPixels" es1="1.0" es2="2.0">
+ <function name="ReadPixels" marshal="ppbo" es1="1.0" es2="2.0">
<param name="x" type="GLint"/>
<param name="y" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="pixels" type="GLvoid *" output="true" img_width="width" img_height="height" img_format="format" img_type="type" img_target="0"/>
<glx sop="111"/>
</function>
@@ -3286,33 +3286,33 @@
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="yoffset" type="GLint"/>
<param name="x" type="GLint"/>
<param name="y" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<glx rop="4122"/>
</function>
- <function name="TexSubImage1D">
+ <function name="TexSubImage1D" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="UNUSED" type="GLuint" padding="true"/>
<param name="pixels" type="const GLvoid *" img_width="width" img_xoff="xoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/>
<glx rop="4099" large="true"/>
</function>
- <function name="TexSubImage2D" es1="1.0" es2="2.0">
+ <function name="TexSubImage2D" marshal="upbo" es1="1.0" es2="2.0">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="yoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="UNUSED" type="GLuint" padding="true"/>
<param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_xoff="xoffset" img_yoff="yoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/>
@@ -3998,35 +3998,35 @@
<function name="ResetHistogram" deprecated="3.1">
<param name="target" type="GLenum"/>
<glx rop="4112"/>
</function>
<function name="ResetMinmax" deprecated="3.1">
<param name="target" type="GLenum"/>
<glx rop="4113"/>
</function>
- <function name="TexImage3D" es2="3.0">
+ <function name="TexImage3D" marshal="upbo" es2="3.0">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="depth" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
<param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/>
<glx rop="4114" large="true"/>
</function>
- <function name="TexSubImage3D" es2="3.0">
+ <function name="TexSubImage3D" marshal="upbo" es2="3.0">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="yoffset" type="GLint"/>
<param name="zoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="depth" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="type" type="GLenum"/>
@@ -4494,96 +4494,96 @@
<param name="m" type="const GLdouble *"/>
<glx handcode="true"/>
</function>
<function name="SampleCoverage" es1="1.0" es2="2.0">
<param name="value" type="GLclampf"/>
<param name="invert" type="GLboolean"/>
<glx rop="229"/>
</function>
- <function name="CompressedTexImage3D" es2="3.0" marshal="sync">
+ <function name="CompressedTexImage3D" es2="3.0" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="depth" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="216" handcode="client"/>
</function>
- <function name="CompressedTexImage2D" es1="1.0" es2="2.0" marshal="sync">
+ <function name="CompressedTexImage2D" es1="1.0" es2="2.0" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="215" handcode="client"/>
</function>
- <function name="CompressedTexImage1D" marshal="sync">
+ <function name="CompressedTexImage1D" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="border" type="GLint"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="214" handcode="client"/>
</function>
- <function name="CompressedTexSubImage3D" es2="3.0" marshal="sync">
+ <function name="CompressedTexSubImage3D" es2="3.0" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="yoffset" type="GLint"/>
<param name="zoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="depth" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="219" handcode="client"/>
</function>
- <function name="CompressedTexSubImage2D" es1="1.0" es2="2.0" marshal="sync">
+ <function name="CompressedTexSubImage2D" es1="1.0" es2="2.0" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="yoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="218" handcode="client"/>
</function>
- <function name="CompressedTexSubImage1D" marshal="sync">
+ <function name="CompressedTexSubImage1D" marshal="upbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="xoffset" type="GLint"/>
<param name="width" type="GLsizei"/>
<param name="format" type="GLenum"/>
<param name="imageSize" type="GLsizei" counter="true"/>
<param name="data" type="const GLvoid *" count="imageSize"/>
<glx rop="217" handcode="client"/>
</function>
- <function name="GetCompressedTexImage">
+ <function name="GetCompressedTexImage" marshal="ppbo">
<param name="target" type="GLenum"/>
<param name="level" type="GLint"/>
<param name="img" type="GLvoid *" output="true"/>
<glx sop="160" handcode="true"/>
</function>
</category>
<category name="1.4">
<enum name="BLEND_DST_RGB" count="1" value="0x80C8">
<size name="Get" mode="get"/>
diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py
index 51475e1..713ea02 100644
--- a/src/mapi/glapi/gen/gl_marshal.py
+++ b/src/mapi/glapi/gen/gl_marshal.py
@@ -168,24 +168,30 @@ class PrintCode(gl_XML.gl_print_base):
p.size_string(), p.get_base_type_string(),
p.name, p.counter))
out('};')
def print_async_unmarshal(self, func):
out('static inline void')
out(('_mesa_unmarshal_{0}(struct gl_context *ctx, '
'const struct marshal_cmd_{0} *cmd)').format(func.name))
out('{')
with indent():
+ flavor = func.marshal_flavor()
for p in func.fixed_params:
if p.count:
out('const {0} * {1} = cmd->{1};'.format(
p.get_base_type_string(), p.name))
+ elif p.is_pointer() and flavor == 'ppbo':
+ # Data is written to destination user pointer (if no PBO
+ # are bound) therefore the pointer must be non-const
+ out('{0} * {1} = cmd->{1};'.format(
+ p.get_base_type_string(), p.name))
else:
out('const {0} {1} = cmd->{1};'.format(
p.type_string(), p.name))
if func.variable_params:
for p in func.variable_params:
out('const {0} * {1};'.format(
p.get_base_type_string(), p.name))
out('const char *variable_data = (const char *) (cmd + 1);')
for p in func.variable_params:
out('{0} = (const {1} *) variable_data;'.format(
@@ -242,20 +248,35 @@ class PrintCode(gl_XML.gl_print_base):
if func.marshal_fail:
out('if ({0}) {{'.format(func.marshal_fail))
with indent():
out('_mesa_glthread_finish(ctx);')
out('_mesa_glthread_restore_dispatch(ctx);')
self.print_sync_dispatch(func)
out('return;')
out('}')
+ flavor = func.marshal_flavor()
+ if flavor == "upbo":
+ need_fallback_sync = True
+ out('if (!ctx->GLThread->pixel_unpack_buffer_bound) {')
+ with indent():
+ out('goto fallback_to_sync;')
+ out('}')
+
+ if flavor == "ppbo":
+ need_fallback_sync = True
+ out('if (!ctx->GLThread->pixel_pack_buffer_bound) {')
+ with indent():
+ out('goto fallback_to_sync;')
+ out('}')
+
out('if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {')
with indent():
self.print_async_dispatch(func)
out('return;')
out('}')
out('')
if need_fallback_sync:
out('fallback_to_sync:')
with indent():
@@ -321,21 +342,21 @@ class PrintCode(gl_XML.gl_print_base):
out('}')
out('')
out('')
def printBody(self, api):
async_funcs = []
for func in api.functionIterateAll():
flavor = func.marshal_flavor()
if flavor in ('skip', 'custom'):
continue
- elif flavor == 'async':
+ elif flavor == 'async' or flavor == 'ppbo' or flavor == 'upbo':
self.print_async_body(func)
async_funcs.append(func)
elif flavor == 'sync':
self.print_sync_body(func)
self.print_unmarshal_dispatch_cmd(api)
self.print_create_marshal_table(api)
def show_usage():
print 'Usage: %s [-f input_file_name]' % sys.argv[0]
diff --git a/src/mapi/glapi/gen/marshal_XML.py b/src/mapi/glapi/gen/marshal_XML.py
index 80f7f54..3750bc8 100644
--- a/src/mapi/glapi/gen/marshal_XML.py
+++ b/src/mapi/glapi/gen/marshal_XML.py
@@ -38,35 +38,46 @@ class marshal_item_factory(gl_XML.gl_item_factory):
class marshal_function(gl_XML.gl_function):
def process_element(self, element):
# Do normal processing.
super(marshal_function, self).process_element(element)
# Only do further processing when we see the canonical
# function name.
if element.get('name') != self.name:
return
+ # Store the "marshal" attribute, if present.
+ self.marshal = element.get('marshal')
+ self.marshal_fail = element.get('marshal_fail')
+
# Classify fixed and variable parameters.
self.fixed_params = []
self.variable_params = []
for p in self.parameters:
if p.is_padding:
continue
- if p.is_variable_length():
+ if self.marshal == "upbo" and p.is_pointer():
+ # There are some texture upload functions (the
+ # CompressedTexImage family) which provide an imageSize together
+ # with the image pointer. The default marshaling behavior is to
+ # copy the contents of image to a variable length section, which
+ # is incorrect when image refers to a pixel buffer.
+ #
+ # This ensures that the pointer is marshaled as is. The non-PBO
+ # case is always synchronous and so does not use marshaling
+ # anyway.
+ self.fixed_params.append(p)
+ elif p.is_variable_length():
self.variable_params.append(p)
else:
self.fixed_params.append(p)
- # Store the "marshal" attribute, if present.
- self.marshal = element.get('marshal')
- self.marshal_fail = element.get('marshal_fail')
-
def marshal_flavor(self):
"""Find out how this function should be marshalled between
client and server threads."""
# If a "marshal" attribute was present, that overrides any
# determination that would otherwise be made by this function.
if self.marshal not in (None, 'draw'):
return self.marshal
if self.exec_flavor == 'skip':
# Functions marked exec="skip" are not yet implemented in
--
2.1.4
More information about the mesa-dev
mailing list