[Xcb] [PATCH] c_client.py: Add padding after full_sequence for certain XGE events.

Kenneth Graunke kenneth at whitecape.org
Sun Dec 29 18:38:37 PST 2013

With the advent of the Present extension, some events (such as
PresentCompleteNotify) now use native 64-bit types on the wire.

For XGE events, we insert an extra "uint32_t full_sequence" field
immediately after the first 32 bytes of data.  Normally, this causes the
subsequent fields to be shifted over by 4 bytes, and the structure to
grow in size by 4 bytes.  Everything works fine.

However, if the field following full_sequence is a uint64_t value, the
compiler may add an extra 4 bytes of padding so that the field is
properly aligned.  This causes the structure to grow by 8 bytes, not 4.
Unfortunately, XCB doesn't realize this; read_packet() then fails to
malloc enough memory to hold the event, and the event handling code uses
the wrong offsets.

To correct this, we check if the field following full_sequence has a
type whose size is 8 bytes.  If so, we add an additional uint32_t field
called "pad_fs" (pad after full_sequence).  This is harmless on 32-bit
architectures, and essential for 64-bit architectures to function.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
 src/c_client.py | 8 ++++++++
 1 file changed, 8 insertions(+)

I've verified that only the xcb_present_complete_notify_event_t struct
gains pad_fs; other events are unaffected.

This fixes vblank synchronization when using DRI3/Present enabled
versions of Mesa, X, and xf86-video-intel.

diff --git a/src/c_client.py b/src/c_client.py
index 99fd307..e8e2600 100644
--- a/src/c_client.py
+++ b/src/c_client.py
@@ -2911,6 +2911,14 @@ def c_event(self, name):
                 full_sequence = Field(tcard32, tcard32.name, 'full_sequence', False, True, True)
                 idx = self.fields.index(field)
                 self.fields.insert(idx + 1, full_sequence)
+                # Adding full_sequence bumps the next field to offset 36, which
+                # is misaligned for native 64-bit types.  If the next field is
+                # an 8 byte value, add an extra 4 byte pad.
+                if idx + 2 < len(self.fields) and self.fields[idx + 2].type.size == 8:
+                    pad_fs = Field(tcard32, tcard32.name, 'pad_fs', False, True, True)
+                    self.fields.insert(idx + 2, pad_fs)
     _c_type_setup(self, name, ('event',))

More information about the Xcb mailing list