1use std::i32;
11
12use crate::gpu_types::UvRectKind;
13use crate::internal_types::{FrameId, FrameMemory, FrameVec, TextureSource, TextureSourceExternal};
14use crate::renderer::MAX_VERTEX_TEXTURE_WIDTH;
15use crate::util::ScaleOffset;
16use api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceRect, LayoutRect, PictureRect};
17use api::{PremultipliedColorF, ImageFormat};
18use crate::device::Texel;
19use crate::render_task::{RenderTaskLocation, StaticRenderTaskSurface};
20use crate::render_task_graph::{RenderTaskGraph, RenderTaskId};
21
22pub struct GpuBufferBuilder {
23 pub i32: GpuBufferBuilderI,
24 pub f32: GpuBufferBuilderF,
25}
26
27pub type GpuBufferF = GpuBuffer<GpuBufferBlockF>;
28pub type GpuBufferBuilderF = GpuBufferBuilderImpl<GpuBufferBlockF>;
29
30pub type GpuBufferI = GpuBuffer<GpuBufferBlockI>;
31pub type GpuBufferBuilderI = GpuBufferBuilderImpl<GpuBufferBlockI>;
32
33pub type GpuBufferWriterF<'l> = GpuBufferWriter<'l, GpuBufferBlockF>;
34pub type GpuBufferWriterI<'l> = GpuBufferWriter<'l, GpuBufferBlockI>;
35
36unsafe impl Texel for GpuBufferBlockF {
37 fn image_format() -> ImageFormat { ImageFormat::RGBAF32 }
38}
39
40unsafe impl Texel for GpuBufferBlockI {
41 fn image_format() -> ImageFormat { ImageFormat::RGBAI32 }
42}
43
44impl Default for GpuBufferBlockF {
45 fn default() -> Self {
46 GpuBufferBlockF::EMPTY
47 }
48}
49
50impl Default for GpuBufferBlockI {
51 fn default() -> Self {
52 GpuBufferBlockI::EMPTY
53 }
54}
55
56#[derive(Copy, Clone, Debug, MallocSizeOf)]
58#[cfg_attr(feature = "capture", derive(Serialize))]
59#[cfg_attr(feature = "replay", derive(Deserialize))]
60pub struct GpuBufferBlockF {
61 data: [f32; 4],
62}
63
64#[derive(Copy, Clone, Debug, MallocSizeOf)]
66#[cfg_attr(feature = "capture", derive(Serialize))]
67#[cfg_attr(feature = "replay", derive(Deserialize))]
68pub struct GpuBufferBlockI {
69 data: [i32; 4],
70}
71
72#[repr(transparent)]
85#[derive(Copy, Clone, MallocSizeOf, Eq, PartialEq)]
86#[cfg_attr(feature = "capture", derive(Serialize))]
87#[cfg_attr(feature = "replay", derive(Deserialize))]
88pub struct GpuBufferHandle(u32);
89
90impl GpuBufferHandle {
91 pub const INVALID: GpuBufferHandle = GpuBufferHandle(u32::MAX - 1);
92 const EPOCH_MASK: u32 = 0xFC000000; fn new(addr: u32, epoch: u32) -> Self {
95 Self(addr | epoch)
96 }
97
98 pub fn address_unchecked(&self) -> GpuBufferAddress {
99 GpuBufferAddress(self.0 & !Self::EPOCH_MASK)
100 }
101}
102
103impl std::fmt::Debug for GpuBufferHandle {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 let addr = self.0 & !Self::EPOCH_MASK;
106 let epoch = (self.0 & Self::EPOCH_MASK) >> 26;
107 write!(f, "#{addr}@{epoch}")
108 }
109}
110
111#[repr(transparent)]
115#[derive(Copy, Clone, MallocSizeOf, Eq, PartialEq)]
116#[cfg_attr(feature = "capture", derive(Serialize))]
117#[cfg_attr(feature = "replay", derive(Deserialize))]
118pub struct GpuBufferAddress(u32);
119
120impl GpuBufferAddress {
121 pub fn new(u: u16, v: u16) -> Self {
122 GpuBufferAddress(
123 v as u32 * MAX_VERTEX_TEXTURE_WIDTH as u32 + u as u32
124 )
125 }
126
127 pub fn is_valid(&self) -> bool {
128 *self != Self::INVALID
129 }
130
131 pub fn as_u32(self) -> u32 {
132 self.0
133 }
134
135 pub fn from_u32(val: u32) -> Self {
136 GpuBufferAddress(val)
137 }
138
139 #[allow(dead_code)]
140 pub fn as_int(self) -> i32 {
141 self.0 as i32
142 }
143
144 #[allow(dead_code)]
145 pub fn uv(self) -> (u16, u16) {
146 (
147 (self.0 as usize % MAX_VERTEX_TEXTURE_WIDTH) as u16,
148 (self.0 as usize / MAX_VERTEX_TEXTURE_WIDTH) as u16,
149 )
150 }
151
152 pub const INVALID: GpuBufferAddress = GpuBufferAddress(u32::MAX - 1);
153}
154
155impl std::fmt::Debug for GpuBufferAddress {
156 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
157 if *self == Self::INVALID {
158 write!(f, "<invalid>")
159 } else {
160 write!(f, "#{}", self.0)
161 }
162 }
163}
164
165impl GpuBufferBlockF {
166 pub const EMPTY: Self = GpuBufferBlockF { data: [0.0; 4] };
167}
168
169impl GpuBufferBlockI {
170 pub const EMPTY: Self = GpuBufferBlockI { data: [0; 4] };
171}
172
173impl Into<GpuBufferBlockF> for LayoutRect {
174 fn into(self) -> GpuBufferBlockF {
175 GpuBufferBlockF {
176 data: [
177 self.min.x,
178 self.min.y,
179 self.max.x,
180 self.max.y,
181 ],
182 }
183 }
184}
185
186impl Into<GpuBufferBlockF> for crate::quad::LayoutOrDeviceRect {
187 fn into(self) -> GpuBufferBlockF {
188 GpuBufferBlockF {
189 data: [
190 self.min.x,
191 self.min.y,
192 self.max.x,
193 self.max.y,
194 ],
195 }
196 }
197}
198
199impl Into<GpuBufferBlockF> for ScaleOffset {
200 fn into(self) -> GpuBufferBlockF {
201 GpuBufferBlockF {
202 data: [
203 self.scale.x,
204 self.scale.y,
205 self.offset.x,
206 self.offset.y,
207 ],
208 }
209 }
210}
211
212impl Into<GpuBufferBlockF> for PictureRect {
213 fn into(self) -> GpuBufferBlockF {
214 GpuBufferBlockF {
215 data: [
216 self.min.x,
217 self.min.y,
218 self.max.x,
219 self.max.y,
220 ],
221 }
222 }
223}
224
225impl Into<GpuBufferBlockF> for DeviceRect {
226 fn into(self) -> GpuBufferBlockF {
227 GpuBufferBlockF {
228 data: [
229 self.min.x,
230 self.min.y,
231 self.max.x,
232 self.max.y,
233 ],
234 }
235 }
236}
237
238impl Into<GpuBufferBlockF> for PremultipliedColorF {
239 fn into(self) -> GpuBufferBlockF {
240 GpuBufferBlockF {
241 data: [
242 self.r,
243 self.g,
244 self.b,
245 self.a,
246 ],
247 }
248 }
249}
250
251impl From<DeviceIntRect> for GpuBufferBlockF {
252 fn from(rect: DeviceIntRect) -> Self {
253 GpuBufferBlockF {
254 data: [
255 rect.min.x as f32,
256 rect.min.y as f32,
257 rect.max.x as f32,
258 rect.max.y as f32,
259 ],
260 }
261 }
262}
263
264impl From<DeviceIntRect> for GpuBufferBlockI {
265 fn from(rect: DeviceIntRect) -> Self {
266 GpuBufferBlockI {
267 data: [
268 rect.min.x,
269 rect.min.y,
270 rect.max.x,
271 rect.max.y,
272 ],
273 }
274 }
275}
276
277impl Into<GpuBufferBlockF> for [f32; 4] {
278 fn into(self) -> GpuBufferBlockF {
279 GpuBufferBlockF {
280 data: self,
281 }
282 }
283}
284
285impl Into<GpuBufferBlockI> for [i32; 4] {
286 fn into(self) -> GpuBufferBlockI {
287 GpuBufferBlockI {
288 data: self,
289 }
290 }
291}
292
293pub trait GpuBufferDataF {
294 const NUM_BLOCKS: usize;
295 fn write(&self, writer: &mut GpuBufferWriterF);
296}
297
298pub trait GpuBufferDataI {
299 const NUM_BLOCKS: usize;
300 fn write(&self, writer: &mut GpuBufferWriterI);
301}
302
303impl GpuBufferDataF for [f32; 4] {
304 const NUM_BLOCKS: usize = 1;
305 fn write(&self, writer: &mut GpuBufferWriterF) {
306 writer.push_one(*self);
307 }
308}
309
310impl GpuBufferDataI for [i32; 4] {
311 const NUM_BLOCKS: usize = 1;
312 fn write(&self, writer: &mut GpuBufferWriterI) {
313 writer.push_one(*self);
314 }
315}
316
317struct DeferredBlock {
319 task_id: RenderTaskId,
320 index: usize,
321}
322
323pub struct GpuBufferWriter<'a, T> {
325 buffer: &'a mut FrameVec<T>,
326 deferred: &'a mut Vec<DeferredBlock>,
327 index: usize,
328 max_block_count: usize,
329 epoch: u32,
330}
331
332impl<'a, T> GpuBufferWriter<'a, T> where T: Texel {
333 fn new(
334 buffer: &'a mut FrameVec<T>,
335 deferred: &'a mut Vec<DeferredBlock>,
336 index: usize,
337 max_block_count: usize,
338 epoch: u32,
339 ) -> Self {
340 GpuBufferWriter {
341 buffer,
342 deferred,
343 index,
344 max_block_count,
345 epoch,
346 }
347 }
348
349 pub fn push_one<B>(&mut self, block: B) where B: Into<T> {
351 self.buffer.push(block.into());
352 }
353
354 pub fn push_render_task(&mut self, task_id: RenderTaskId) {
357 if task_id != RenderTaskId::INVALID {
358 self.deferred.push(DeferredBlock {
359 task_id,
360 index: self.buffer.len(),
361 });
362 }
363
364 self.buffer.push(T::default());
365 }
366
367 pub fn finish(self) -> GpuBufferAddress {
369 assert!(self.buffer.len() <= self.index + self.max_block_count);
370
371 GpuBufferAddress(self.index as u32)
372 }
373
374 pub fn finish_with_handle(self) -> GpuBufferHandle {
376 assert!(self.buffer.len() <= self.index + self.max_block_count);
377 assert_eq!(self.index & (GpuBufferHandle::EPOCH_MASK as usize), 0);
378
379 GpuBufferHandle::new(self.index as u32, self.epoch)
380 }
381}
382
383impl<'a> GpuBufferWriterF<'a> {
384 pub fn push<Data: GpuBufferDataF>(&mut self, data: &Data) {
385 let _start_index = self.buffer.len();
386 data.write(self);
387 debug_assert_eq!(self.buffer.len() - _start_index, Data::NUM_BLOCKS);
388 }
389}
390
391impl<'a> GpuBufferWriterI<'a> {
392 pub fn push<Data: GpuBufferDataI>(&mut self, data: &Data) {
393 data.write(self);
394 }
395}
396
397impl<'a, T> Drop for GpuBufferWriter<'a, T> {
398 fn drop(&mut self) {
399 assert!(self.buffer.len() <= self.index + self.max_block_count, "Attempt to write too many GpuBuffer blocks");
400 }
401}
402
403pub struct GpuBufferBuilderImpl<T> {
404 data: FrameVec<T>,
407 deferred: Vec<DeferredBlock>,
410
411 epoch: u32,
412}
413
414impl<T> GpuBufferBuilderImpl<T> where T: Texel + std::convert::From<DeviceIntRect> {
415 pub fn new(memory: &FrameMemory, capacity: usize, frame_id: FrameId) -> Self {
416 let epoch = ((frame_id.as_u64() % 62) as u32 + 1) << 26;
419 GpuBufferBuilderImpl {
420 data: memory.new_vec_with_capacity(capacity),
421 deferred: Vec::new(),
422 epoch,
423 }
424 }
425
426 #[allow(dead_code)]
427 pub fn push_blocks(
428 &mut self,
429 blocks: &[T],
430 ) -> GpuBufferAddress {
431 assert!(blocks.len() <= MAX_VERTEX_TEXTURE_WIDTH);
432
433 ensure_row_capacity(&mut self.data, blocks.len());
434
435 let index = self.data.len();
436
437 self.data.extend_from_slice(blocks);
438
439 GpuBufferAddress(index as u32 | self.epoch)
440 }
441
442 pub fn write_blocks(
444 &mut self,
445 max_block_count: usize,
446 ) -> GpuBufferWriter<T> {
447 assert!(max_block_count <= MAX_VERTEX_TEXTURE_WIDTH);
448
449 ensure_row_capacity(&mut self.data, max_block_count);
450
451 let index = self.data.len();
452
453 GpuBufferWriter::new(
454 &mut self.data,
455 &mut self.deferred,
456 index,
457 max_block_count,
458 self.epoch,
459 )
460 }
461
462 pub fn reserve_renderer_deferred_blocks(&mut self, block_count: usize) -> GpuBufferHandle {
465 ensure_row_capacity(&mut self.data, block_count);
466
467 let index = self.data.len();
468
469 self.data.reserve(block_count);
470 for _ in 0 ..block_count {
471 self.data.push(Default::default());
472 }
473
474 GpuBufferHandle::new(index as u32, self.epoch)
475 }
476
477 pub fn finalize(
478 mut self,
479 render_tasks: &RenderTaskGraph,
480 ) -> GpuBuffer<T> {
481 finish_row(&mut self.data);
482
483 let len = self.data.len();
484 assert!(len % MAX_VERTEX_TEXTURE_WIDTH == 0);
485
486 let mut deferred_uv_copies = Vec::new();
491 for block in self.deferred.drain(..) {
492 let render_task = &render_tasks[block.task_id];
493
494 if let RenderTaskLocation::Static {
500 surface: StaticRenderTaskSurface::ReadOnly {
501 source: TextureSource::External(TextureSourceExternal { normalized_uvs, .. }),
502 },
503 ..
504 } = render_task.location {
505 let uv_scale = if normalized_uvs {
509 let size = render_task.get_target_rect().size();
510 [size.width as f32, size.height as f32]
511 } else {
512 [1.0, 1.0]
513 };
514 deferred_uv_copies.push(DeferredUvCopy {
515 src: render_task.get_texture_address().as_u32(),
516 dst: block.index as u32,
517 uv_scale,
518 });
519 continue;
520 }
521
522 let mut target_rect = render_task.get_target_rect();
523 if block.task_id.has_sub_rect() {
524 let sub = &render_tasks.sub_rects[block.task_id.sub_rect_index as usize];
525 target_rect = sub.sub_rect
526 .translate(target_rect.min.to_vector())
527 .intersection_unchecked(&target_rect);
528 }
529
530 let uv_rect = match render_task.uv_rect_kind() {
531 UvRectKind::Rect => {
532 target_rect
533 }
534 UvRectKind::Quad { top_left, bottom_right, .. } => {
535 let size = target_rect.size();
536
537 DeviceIntRect::new(
538 DeviceIntPoint::new(
539 target_rect.min.x + (top_left.x * size.width as f32).round() as i32,
540 target_rect.min.y + (top_left.y * size.height as f32).round() as i32,
541 ),
542 DeviceIntPoint::new(
543 target_rect.min.x + (bottom_right.x * size.width as f32).round() as i32,
544 target_rect.min.y + (bottom_right.y * size.height as f32).round() as i32,
545 ),
546 )
547 }
548 };
549
550 self.data[block.index] = uv_rect.into();
551 }
552
553 GpuBuffer {
554 data: self.data,
555 size: DeviceIntSize::new(MAX_VERTEX_TEXTURE_WIDTH as i32, (len / MAX_VERTEX_TEXTURE_WIDTH) as i32),
556 format: T::image_format(),
557 deferred_uv_copies,
558 epoch: self.epoch,
559 }
560 }
561
562 pub fn resolve_handle(&self, handle: GpuBufferHandle) -> GpuBufferAddress {
563 if handle == GpuBufferHandle::INVALID {
564 return GpuBufferAddress::INVALID;
565 }
566
567 let epoch = handle.0 & GpuBufferHandle::EPOCH_MASK;
568 assert!(self.epoch == epoch);
569
570 GpuBufferAddress(handle.0 & !GpuBufferHandle::EPOCH_MASK)
571 }
572
573 #[allow(unused)]
575 pub fn check_handle(&self, handle: GpuBufferHandle) {
576 if handle == GpuBufferHandle::INVALID {
577 return;
578 }
579 let epoch = handle.0 & GpuBufferHandle::EPOCH_MASK;
580 assert!(self.epoch == epoch);
581 }
582}
583
584impl GpuBufferBuilderF {
585 pub fn push<D>(&mut self, data: &D) -> GpuBufferAddress
586 where D: GpuBufferDataF
587 {
588 let mut writer = self.write_blocks(D::NUM_BLOCKS);
589 data.write(&mut writer);
590
591 writer.finish()
592 }
593}
594
595impl GpuBufferBuilderI {
596 pub fn push<D>(&mut self, data: &D) -> GpuBufferAddress
597 where D: GpuBufferDataI
598 {
599 let mut writer = self.write_blocks(D::NUM_BLOCKS);
600 data.write(&mut writer);
601
602 writer.finish()
603 }
604}
605
606fn ensure_row_capacity<T: Default>(data: &mut FrameVec<T>, cap: usize) {
607 if (data.len() % MAX_VERTEX_TEXTURE_WIDTH) + cap > MAX_VERTEX_TEXTURE_WIDTH {
608 finish_row(data);
609 }
610}
611
612fn finish_row<T: Default>(data: &mut FrameVec<T>) {
613 let required_len = (data.len() + MAX_VERTEX_TEXTURE_WIDTH-1) & !(MAX_VERTEX_TEXTURE_WIDTH-1);
614 for _ in 0 .. required_len - data.len() {
615 data.push(T::default());
616 }
617}
618
619#[cfg_attr(feature = "capture", derive(Serialize))]
630#[cfg_attr(feature = "replay", derive(Deserialize))]
631#[derive(Clone, Copy, Debug)]
632pub struct DeferredUvCopy {
633 pub src: u32,
634 pub dst: u32,
635 pub uv_scale: [f32; 2],
640}
641
642#[cfg_attr(feature = "capture", derive(Serialize))]
643#[cfg_attr(feature = "replay", derive(Deserialize))]
644pub struct GpuBuffer<T> {
645 pub data: FrameVec<T>,
646 pub size: DeviceIntSize,
647 pub format: ImageFormat,
648 pub deferred_uv_copies: Vec<DeferredUvCopy>,
649 epoch: u32,
650}
651
652impl GpuBuffer<GpuBufferBlockF> {
653 pub fn apply_deferred_uv_copies(&mut self) {
656 for i in 0 .. self.deferred_uv_copies.len() {
657 let copy = self.deferred_uv_copies[i];
658 let mut uv = self.data[copy.src as usize].data;
660 uv[0] *= copy.uv_scale[0];
661 uv[1] *= copy.uv_scale[1];
662 uv[2] *= copy.uv_scale[0];
663 uv[3] *= copy.uv_scale[1];
664 self.data[copy.dst as usize] = uv.into();
665 }
666 }
667}
668
669impl<T> GpuBuffer<T> {
670 pub fn is_empty(&self) -> bool {
671 self.data.is_empty()
672 }
673
674 pub fn resolve_handle(&self, handle: GpuBufferHandle) -> GpuBufferAddress {
675 if handle == GpuBufferHandle::INVALID {
676 return GpuBufferAddress::INVALID;
677 }
678
679 let epoch = handle.0 & GpuBufferHandle::EPOCH_MASK;
680 assert!(self.epoch == epoch);
681
682 GpuBufferAddress(handle.0 & !GpuBufferHandle::EPOCH_MASK)
683 }
684}
685
686#[test]
687fn test_gpu_buffer_sizing_push() {
688 let frame_memory = FrameMemory::fallback();
689 let render_task_graph = RenderTaskGraph::new_for_testing();
690 let mut builder = GpuBufferBuilderF::new(&frame_memory, 0, FrameId::first());
691
692 let row = vec![GpuBufferBlockF::EMPTY; MAX_VERTEX_TEXTURE_WIDTH];
693 builder.push_blocks(&row);
694
695 builder.push_blocks(&[GpuBufferBlockF::EMPTY]);
696 builder.push_blocks(&[GpuBufferBlockF::EMPTY]);
697
698 let buffer = builder.finalize(&render_task_graph);
699 assert_eq!(buffer.data.len(), MAX_VERTEX_TEXTURE_WIDTH * 2);
700}
701
702#[test]
703fn test_gpu_buffer_sizing_writer() {
704 let frame_memory = FrameMemory::fallback();
705 let render_task_graph = RenderTaskGraph::new_for_testing();
706 let mut builder = GpuBufferBuilderF::new(&frame_memory, 0, FrameId::first());
707
708 let mut writer = builder.write_blocks(MAX_VERTEX_TEXTURE_WIDTH);
709 for _ in 0 .. MAX_VERTEX_TEXTURE_WIDTH {
710 writer.push_one(GpuBufferBlockF::EMPTY);
711 }
712 writer.finish();
713
714 let mut writer = builder.write_blocks(1);
715 writer.push_one(GpuBufferBlockF::EMPTY);
716 writer.finish();
717
718 let mut writer = builder.write_blocks(1);
719 writer.push_one(GpuBufferBlockF::EMPTY);
720 writer.finish();
721
722 let buffer = builder.finalize(&render_task_graph);
723 assert_eq!(buffer.data.len(), MAX_VERTEX_TEXTURE_WIDTH * 2);
724}