commit 3910e404dc48a9ca593e3f1e098afed4c3c87260
parent 63601d9a9d3ba32092e3f41674a8a6b1ad9a60fc
Author: Nicolas Silva <nical@fastmail.com>
Date: Wed, 19 Nov 2025 09:40:34 +0000
Bug 1996818 - Store gpu addresses as a u32. r=gw
This also makes things a fair bit simpler, but the main motivation is that it makes it possible to put a GpuBufferAddress directly in some gpu data.
Differential Revision: https://phabricator.services.mozilla.com/D270856
Diffstat:
3 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/gfx/wr/webrender/src/command_buffer.rs b/gfx/wr/webrender/src/command_buffer.rs
@@ -239,11 +239,11 @@ impl CommandBuffer {
}
PrimitiveCommand::Complex { prim_instance_index, gpu_address } => {
self.commands.push(Command::draw_complex_prim(prim_instance_index));
- self.commands.push(Command::data((gpu_address.u as u32) << 16 | gpu_address.v as u32));
+ self.commands.push(Command::data(gpu_address.as_u32()));
}
PrimitiveCommand::Instance { prim_instance_index, gpu_buffer_address } => {
self.commands.push(Command::draw_instance(prim_instance_index));
- self.commands.push(Command::data((gpu_buffer_address.u as u32) << 16 | gpu_buffer_address.v as u32));
+ self.commands.push(Command::data(gpu_buffer_address.as_u32()));
}
PrimitiveCommand::Quad { pattern, pattern_input, prim_instance_index, gpu_buffer_address, transform_id, quad_flags, edge_flags, src_color_task_id } => {
self.commands.push(Command::draw_quad(prim_instance_index));
@@ -251,7 +251,7 @@ impl CommandBuffer {
self.commands.push(Command::data(pattern_input.0 as u32));
self.commands.push(Command::data(pattern_input.1 as u32));
self.commands.push(Command::data(src_color_task_id.index));
- self.commands.push(Command::data((gpu_buffer_address.u as u32) << 16 | gpu_buffer_address.v as u32));
+ self.commands.push(Command::data(gpu_buffer_address.as_u32()));
self.commands.push(Command::data(transform_id.0));
self.commands.push(Command::data((quad_flags.bits() as u32) << 16 | edge_flags.bits() as u32));
}
@@ -284,10 +284,7 @@ impl CommandBuffer {
Command::CMD_DRAW_COMPLEX_PRIM => {
let prim_instance_index = PrimitiveInstanceIndex(param);
let data = cmd_iter.next().unwrap();
- let gpu_address = GpuBufferAddress {
- u: (data.0 >> 16) as u16,
- v: (data.0 & 0xffff) as u16,
- };
+ let gpu_address = GpuBufferAddress::from_u32(data.0);
let cmd = PrimitiveCommand::complex(
prim_instance_index,
gpu_address,
@@ -307,10 +304,7 @@ impl CommandBuffer {
let bits = cmd_iter.next().unwrap().0;
let quad_flags = QuadFlags::from_bits((bits >> 16) as u8).unwrap();
let edge_flags = EdgeAaSegmentMask::from_bits((bits & 0xff) as u8).unwrap();
- let gpu_buffer_address = GpuBufferAddress {
- u: (data.0 >> 16) as u16,
- v: (data.0 & 0xffff) as u16,
- };
+ let gpu_buffer_address = GpuBufferAddress::from_u32(data.0);
let cmd = PrimitiveCommand::quad(
pattern,
pattern_input,
@@ -327,10 +321,7 @@ impl CommandBuffer {
Command::CMD_DRAW_INSTANCE => {
let prim_instance_index = PrimitiveInstanceIndex(param);
let data = cmd_iter.next().unwrap();
- let gpu_buffer_address = GpuBufferAddress {
- u: (data.0 >> 16) as u16,
- v: (data.0 & 0xffff) as u16,
- };
+ let gpu_buffer_address = GpuBufferAddress::from_u32(data.0);
let cmd = PrimitiveCommand::instance(
prim_instance_index,
gpu_buffer_address,
diff --git a/gfx/wr/webrender/src/renderer/gpu_buffer.rs b/gfx/wr/webrender/src/renderer/gpu_buffer.rs
@@ -11,6 +11,8 @@
*/
+use std::i32;
+
use crate::gpu_types::UvRectKind;
use crate::internal_types::{FrameMemory, FrameVec};
use crate::renderer::MAX_VERTEX_TEXTURE_WIDTH;
@@ -70,24 +72,44 @@ pub struct GpuBufferBlockI {
data: [i32; 4],
}
+// TODO(gw): Temporarily encode GPU Cache addresses as a single int.
+// In the future, we can change the PrimitiveInstanceData struct
+// to use 2x u16 for the vertex attribute instead of an i32.
+#[repr(transparent)]
#[derive(Copy, Debug, Clone, MallocSizeOf, Eq, PartialEq)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
-pub struct GpuBufferAddress {
- pub u: u16,
- pub v: u16,
-}
+pub struct GpuBufferAddress(u32);
impl GpuBufferAddress {
+ pub fn new(u: u16, v: u16) -> Self {
+ GpuBufferAddress(
+ v as u32 * MAX_VERTEX_TEXTURE_WIDTH as u32 + u as u32
+ )
+ }
+
+ pub fn as_u32(self) -> u32 {
+ self.0
+ }
+
+ pub fn from_u32(val: u32) -> Self {
+ GpuBufferAddress(val)
+ }
+
#[allow(dead_code)]
pub fn as_int(self) -> i32 {
- // TODO(gw): Temporarily encode GPU Cache addresses as a single int.
- // In the future, we can change the PrimitiveInstanceData struct
- // to use 2x u16 for the vertex attribute instead of an i32.
- self.v as i32 * MAX_VERTEX_TEXTURE_WIDTH as i32 + self.u as i32
+ self.0 as i32
+ }
+
+ #[allow(dead_code)]
+ pub fn uv(self) -> (u16, u16) {
+ (
+ (self.0 as usize % MAX_VERTEX_TEXTURE_WIDTH) as u16,
+ (self.0 as usize / MAX_VERTEX_TEXTURE_WIDTH) as u16,
+ )
}
- pub const INVALID: GpuBufferAddress = GpuBufferAddress { u: !0, v: !0 };
+ pub const INVALID: GpuBufferAddress = GpuBufferAddress(u32::MAX - 1);
}
impl GpuBufferBlockF {
@@ -260,10 +282,7 @@ impl<'a, T> GpuBufferWriter<'a, T> where T: Texel {
pub fn finish(self) -> GpuBufferAddress {
assert!(self.buffer.len() <= self.index + self.max_block_count);
- GpuBufferAddress {
- u: (self.index % MAX_VERTEX_TEXTURE_WIDTH) as u16,
- v: (self.index / MAX_VERTEX_TEXTURE_WIDTH) as u16,
- }
+ GpuBufferAddress(self.index as u32)
}
}
@@ -307,10 +326,7 @@ impl<T> GpuBufferBuilderImpl<T> where T: Texel + std::convert::From<DeviceIntRec
self.data.extend_from_slice(blocks);
- GpuBufferAddress {
- u: (index % MAX_VERTEX_TEXTURE_WIDTH) as u16,
- v: (index / MAX_VERTEX_TEXTURE_WIDTH) as u16,
- }
+ GpuBufferAddress(index as u32)
}
/// Begin writing a specific number of blocks
@@ -346,10 +362,7 @@ impl<T> GpuBufferBuilderImpl<T> where T: Texel + std::convert::From<DeviceIntRec
self.data.push(Default::default());
}
- GpuBufferAddress {
- u: (index % MAX_VERTEX_TEXTURE_WIDTH) as u16,
- v: (index / MAX_VERTEX_TEXTURE_WIDTH) as u16,
- }
+ GpuBufferAddress(index as u32)
}
pub fn finalize(
diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs
@@ -4956,7 +4956,7 @@ impl Renderer {
.insert(DeferredResolveIndex(i as u32), texture);
let addr = deferred_resolve.address;
- let index = addr.u as usize + addr.v as usize * MAX_VERTEX_TEXTURE_WIDTH;
+ let index = addr.as_u32() as usize;
gpu_buffer.data[index] = image.uv.to_array().into();
gpu_buffer.data[index + 1] = [0f32; 4].into();
}