Linux DRM Buffer Sharing: Carry the Format Modifier Alongside the FourCC

An embedded graphics producer and display consumer both report the same FourCC, yet the imported image is rejected or interpreted incorrectly. Matching the pixel-format name is only part of the buffer contract. Tiling or compression can change how those pixels are stored, and the format modifier carries that additional layout identity.

The rules here come from the Linux v6.12 DRM format header and framebuffer metadata definition. They describe the upstream ABI, not the supported format list of a particular GPU, display controller or vendor BSP. No allocation, import or scanout operation was performed.

Negotiate a pair rather than a FourCC alone

The format header defines a FourCC and modifier together as a description of the buffer’s format and data layout. A modifier can affect more than row addressing: it may change the number of planes or the required allocation size.

For a hypothetical pipeline, suppose the producer offers one FourCC with a tiled modifier while the consumer accepts that FourCC only with DRM_FORMAT_MOD_LINEAR. The FourCC names match, but the supported pairs do not intersect. Removing the modifier from the exported descriptor does not transform the producer’s bytes into linear storage.

Higher-level components should treat modifier values as opaque tokens that can be compared and intersected. A generic integration layer should not decode a vendor’s bit fields and invent a conversion based on their apparent meaning. The allocator and driver-specific implementation remain responsible for producing the selected layout.

Preserve whether the modifier was explicit

There are three different descriptor states worth recording: no explicit modifier, explicitly linear storage, and an explicit tiled or compressed layout. Reducing those states to one numeric field can lose important information.

In drm_mode_fb_cmd2, the flag DRM_MODE_FB_MODIFIERS enables interpretation of the modifier[] entries. Without that flag, those entries are ignored. The format header explicitly warns that omitting modifier information allows driver-internal layout information to participate and can result in a tiled framebuffer.

By contrast, an explicitly supplied DRM_FORMAT_MOD_LINEAR is a linear-layout statement. Its numeric value is zero. Therefore, “the modifier field contains zero” is insufficient evidence of explicit linear storage unless the accompanying API state establishes that a modifier was actually provided.

The deprecated name DRM_FORMAT_MOD_NONE also has value zero and means linear. Despite the name, it does not mean implicit layout. Preserve an explicit-modifier-present state in the application descriptor instead of trying to infer presence from whether the number is nonzero.

Three descriptor states distinguish implicit layout, explicitly supplied linear modifier value zero and an explicit non-linear modifier token.
Original buffer-contract worksheet. Modifier presence is separate from its numeric value, and layout identity must survive the handoff.

Carry each plane’s metadata without guessing it

The framebuffer structure records dimensions, FourCC, per-plane handles, pitches, offsets and modifier entries. Those fields should come from the negotiated producer allocation and the receiving API’s contract. A visible width is not a replacement for a returned pitch, and a format name is not a universal allocation-size formula.

The same buffer handle may appear in more than one plane entry. That can describe distinct regions in shared storage; it does not prove that the plane array is redundant. Conversely, different handles should not be collapsed because the color format happens to have a familiar contiguous arrangement elsewhere.

Although the structure provides a modifier array, the modifier must be identical across the used planes. A layout whose planes have different storage roles needs an appropriate single modifier describing the complete arrangement. Mixing unrelated modifier tokens plane by plane is not the ABI’s representation of that arrangement.

Unused entries must be zero, but the converse inference is invalid for offsets and modifiers: zero is a valid used offset, and zero is the linear modifier. Determine used entries from the actual format and allocation contract rather than scanning for the first zero value.

Keep compatibility checks at the right level

Build a proposed import worksheet with one row per buffer and explicit fields for producer, consumer, dimensions, FourCC, modifier presence, modifier value and each used plane’s storage metadata. Compare the supported pairs before attempting to reason about individual pixel addresses.

Matching the pair is still not proof that every import or display operation will succeed. Driver support, handle importability, alignment, size restrictions and the intended usage remain part of the qualified path. A successful GPU import is also not a guarantee that the same allocation is suitable for direct scanout.

If the pair is incompatible, choose a layout supported by both sides or an explicitly supported conversion or copy path. Simply relabeling a tiled allocation as linear is not such a path. Likewise, a CPU row-stride loop is appropriate only when its assumed layout is actually the selected one.

Test the lost-presence bug directly

A descriptor-only fixture should include explicit linear with value zero, implicit layout with no supplied modifier, and an explicit non-linear token. Verify that serialization and reconstruction preserve all three states, including used planes with zero offsets.

Then test rejection of a pair unsupported by the proposed consumer and of mismatched modifier entries across used planes. These are proposed metadata checks, not a claim of device compatibility. Their purpose is to keep the producer’s layout identity intact until the actual driver-qualified import decision can be made.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *