Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode path_data and draw_data directly as u32 #817

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

DJMcNab
Copy link
Member

@DJMcNab DJMcNab commented Feb 14, 2025

We already assume these are word-aligned, and so this would catch a failure of that assumption very early, if it came up.

A potential alternative is to store path_data as f32 instead, as all values stored are f32. I've not done that for pretty weak reasons, and it should be trivial to change.

A future change would be to encode the full scene encoding as u32. That would be useful for #810, as the current code has an alignment hazard.

We already assume these are word-aligned, and so this would
catch a failure of that assumption much earller.

A future change would be to encode the full scene encoding as u32.
That would be useful for linebender#810, as the current code has an alignment hazard
@DJMcNab DJMcNab requested a review from raphlinus February 14, 2025 14:47
Copy link
Collaborator

@waywardmonkeys waywardmonkeys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if this has a measurable impact on anything or was the only motivation to do with alignment?

On the GPU side, this is already an array<u32>, right?

@@ -331,7 +334,8 @@ impl Encoding {
pub fn encode_color(&mut self, color: impl Into<DrawColor>) {
let color = color.into();
self.draw_tags.push(DrawTag::COLOR);
self.draw_data.extend_from_slice(bytemuck::bytes_of(&color));
let DrawColor { rgba } = color;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, I think.

}
if let Some((x, y)) = self.pending_images[*index].xy {
let xy = (x << 16) | y;
data.extend_from_slice(bytemuck::bytes_of(&xy));
pos = *draw_data_offset + 4;
pos = *draw_data_offset + 1;
} else {
// If we get here, we failed to allocate a slot for this image in the atlas.
// In this case, let's zero out the dimensions so we don't attempt to render
// anything.
// TODO: a better strategy: texture array? downsample large images?
data.extend_from_slice(&[0_u8; 8]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slightly confusing then being u8 still and just required some extra thought.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes... I don't think there's really a cleaner way to express this, because data is still byte-wise. Happy to change it if needed.

@DJMcNab
Copy link
Member Author

DJMcNab commented Feb 14, 2025

Curious if this has a measurable impact on anything or was the only motivation to do with alignment?

I don't expect this to have a measurable impact. It's largely about making the semantics of the encoding match the reality, which is that these values are required to a multiple of 4 bytes (if they're not, things would go extremely badly wrong on the GPU). Separately, this will also make reasoning about alignment easier, if we end up doing the follow-up.

On the GPU side, this is already an array<u32>, right?

Yes, exactly. The scene buffer is always interpreted as an array of 32 bit unsigned integers.

tomcur added a commit that referenced this pull request Feb 20, 2025
(On top of #817 to prevent
conflicts.)

WGSL expects little-endian data, but Vello currently doesn't convert to
little-endian, except for colors: `DrawColor` specifies its endianness
explicitly, with conversion handled by the Color crate. On big-endian
hosts, the other encodings would break.

Whether big-endian hosts are a valid target for Vello, I do not know.
This is opened in part as a place to have that discussion. If this is
desirable, other places will need attention. I have not taken a look
yet.
tomcur added a commit that referenced this pull request Feb 20, 2025
(On top of #817 to prevent
conflicts.)

WGSL expects little-endian data, but Vello currently doesn't convert to
little-endian, except for colors: `DrawColor` specifies its endianness
explicitly, with conversion handled by the Color crate. On big-endian
hosts, the other encodings would break.

Whether big-endian hosts are a valid target for Vello, I do not know.
This is opened in part as a place to have that discussion. If this is
desirable, other places will need attention. I have not taken a look
yet.
tomcur added a commit that referenced this pull request Feb 20, 2025
(On top of #817 to prevent
conflicts.)

WGSL expects little-endian data, but Vello currently doesn't convert to
little-endian, except for colors: `DrawColor` specifies its endianness
explicitly, with conversion handled by the Color crate. On big-endian
hosts, the other encodings would break.

Whether big-endian hosts are a valid target for Vello, I do not know.
This is opened in part as a place to have that discussion. If this is
desirable, other places will need attention. I have not taken a look
yet.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants