Update `gpu_data`

This commit is contained in:
Patrick Walton 2020-06-23 13:02:15 -07:00
parent eabe1b239d
commit 58a76f0f16
1 changed files with 324 additions and 71 deletions

View File

@ -13,13 +13,15 @@
use crate::builder::{ALPHA_TILES_PER_LEVEL, ALPHA_TILE_LEVEL_COUNT};
use crate::options::BoundingQuad;
use crate::paint::PaintCompositeOp;
use crate::scene::PathId;
use crate::tile_map::DenseTileMap;
use pathfinder_color::ColorU;
use pathfinder_content::effects::{BlendMode, Filter};
use pathfinder_content::render_target::RenderTargetId;
use pathfinder_geometry::line_segment::{LineSegmentU4, LineSegmentU8};
use pathfinder_geometry::line_segment::{LineSegment2F, LineSegmentU16};
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::transform2d::Transform2F;
use pathfinder_geometry::vector::Vector2I;
use pathfinder_geometry::vector::{Vector2F, Vector2I};
use pathfinder_gpu::TextureSamplingFlags;
use std::fmt::{Debug, Formatter, Result as DebugResult};
use std::sync::Arc;
@ -64,13 +66,18 @@ pub enum RenderCommand {
UploadTextureMetadata(Vec<TextureMetadataEntry>),
// Adds fills to the queue.
AddFills(Vec<FillBatchEntry>),
AddFillsD3D9(Vec<Fill>),
// Flushes the queue of fills.
FlushFills,
FlushFillsD3D9,
// Renders clips to the mask tile.
ClipTiles(Vec<ClipBatch>),
/// Upload a scene to GPU.
///
/// This will only be sent if dicing and binning is done on GPU.
UploadSceneD3D11 {
draw_segments: SegmentsD3D11,
clip_segments: SegmentsD3D11,
},
// Pushes a render target onto the stack. Draw commands go to the render target on top of the
// stack.
@ -79,11 +86,14 @@ pub enum RenderCommand {
// Pops a render target from the stack.
PopRenderTarget,
// Marks that tile compositing is about to begin.
BeginTileDrawing,
// Computes backdrops for tiles, prepares any Z-buffers, and performs clipping.
PrepareClipTilesD3D11(TileBatchDataD3D11),
// Draws a batch of tiles to the render target on top of the stack.
DrawTiles(TileBatch),
DrawTilesD3D9(DrawTileBatchD3D9),
// Draws a batch of tiles to the render target on top of the stack.
DrawTilesD3D11(DrawTileBatchD3D11),
// Presents a rendered frame.
Finish { cpu_build_time: Duration },
@ -103,13 +113,125 @@ pub struct TextureLocation {
pub rect: RectI,
}
/// Information about a batch of tiles to be prepared (postprocessed).
#[derive(Clone, Debug)]
pub struct TileBatch {
pub tiles: Vec<Tile>,
pub struct TileBatchDataD3D11 {
/// The ID of this batch.
///
/// The renderer should not assume that these values are consecutive.
pub batch_id: TileBatchId,
/// The number of paths in this batch.
pub path_count: u32,
/// The number of tiles in this batch.
pub tile_count: u32,
/// The total number of segments in this batch.
pub segment_count: u32,
/// Information needed to prepare the tiles.
pub prepare_info: PrepareTilesInfoD3D11,
/// Where the paths come from (draw or clip).
pub path_source: PathSource,
/// Information about clips applied to paths, if any of the paths have clips.
pub clipped_path_info: Option<ClippedPathInfo>,
}
/// Where a path should come from (draw or clip).
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum PathSource {
Draw,
Clip,
}
/// Information about a batch of tiles to be prepared on GPU.
#[derive(Clone, Debug)]
pub struct PrepareTilesInfoD3D11 {
/// Initial backdrop values for each tile column, packed together.
pub backdrops: Vec<BackdropInfoD3D11>,
/// Mapping from path index to metadata needed to compute propagation on GPU.
///
/// This contains indices into the `tiles` vector.
pub propagate_metadata: Vec<PropagateMetadataD3D11>,
/// Metadata about each path that will be diced (flattened).
pub dice_metadata: Vec<DiceMetadataD3D11>,
/// Sparse information about all the allocated tiles.
pub tile_path_info: Vec<TilePathInfoD3D11>,
/// A transform to apply to the segments.
pub transform: Transform2F,
}
#[derive(Clone, Debug)]
pub struct SegmentsD3D11 {
pub points: Vec<Vector2F>,
pub indices: Vec<SegmentIndicesD3D11>,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct SegmentIndicesD3D11 {
pub first_point_index: u32,
pub flags: u32,
}
/// Information about clips applied to paths in a batch.
#[derive(Clone, Debug)]
pub struct ClippedPathInfo {
/// The ID of the batch containing the clips.
///
/// In the current implementation, this is always 0.
pub clip_batch_id: TileBatchId,
/// The number of paths that have clips.
pub clipped_path_count: u32,
/// The maximum number of clipped tiles.
///
/// This is used to allocate vertex buffers.
pub max_clipped_tile_count: u32,
/// The actual clips, if calculated on CPU.
pub clips: Option<Vec<Clip>>,
}
/// Together with the `TileBatchId`, uniquely identifies a path on the renderer side.
///
/// Generally, `PathIndex(!0)` represents no path.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct PathBatchIndex(pub u32);
/// Unique ID that identifies a batch of tiles.
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct TileBatchId(pub u32);
#[derive(Clone, Debug)]
pub enum DrawTileBatch {
D3D9(DrawTileBatchD3D9),
D3D11(DrawTileBatchD3D11),
}
/// Information needed to draw a batch of tiles in D3D9.
#[derive(Clone, Debug)]
pub struct DrawTileBatchD3D9 {
pub tiles: Vec<TileObjectPrimitive>,
pub clips: Vec<Clip>,
pub z_buffer_data: DenseTileMap<i32>,
/// The color texture to use.
pub color_texture: Option<TileBatchTexture>,
/// The filter to use.
pub filter: Filter,
/// The blend mode to composite these tiles with.
pub blend_mode: BlendMode,
pub tile_page: u16,
}
/// Information needed to draw a batch of tiles in D3D11.
#[derive(Clone, Debug)]
pub struct DrawTileBatchD3D11 {
/// Data for the tile batch.
pub tile_batch_data: TileBatchDataD3D11,
/// The color texture to use.
pub color_texture: Option<TileBatchTexture>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
@ -119,90 +241,198 @@ pub struct TileBatchTexture {
pub composite_op: PaintCompositeOp,
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct TileId(pub i32);
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct FillId(pub i32);
// TODO(pcwalton): Pack better.
#[derive(Clone, Copy, Debug)]
pub struct FillObjectPrimitive {
pub px: LineSegmentU4,
pub subpx: LineSegmentU8,
#[repr(C)]
pub struct TileObjectPrimitive {
pub tile_x: i16,
pub tile_y: i16,
pub alpha_tile_id: AlphaTileId,
pub path_id: PathId,
// TODO(pcwalton): Maybe look the color up based on path ID?
pub color: u16,
pub ctrl: u8,
pub backdrop: i8,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct TileObjectPrimitive {
pub alpha_tile_id: AlphaTileId,
pub struct TileD3D11 {
pub next_tile_id: TileId,
pub first_fill_id: FillId,
pub alpha_tile_id_lo: i16,
pub alpha_tile_id_hi: i8,
pub backdrop_delta: i8,
pub color: u16,
pub ctrl: u8,
pub backdrop: i8,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct AlphaTileD3D11 {
pub alpha_tile_index: AlphaTileId,
pub clip_tile_index: AlphaTileId,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct TilePathInfoD3D11 {
pub tile_min_x: i16,
pub tile_min_y: i16,
pub tile_max_x: i16,
pub tile_max_y: i16,
pub first_tile_index: u32,
// Must match the order in `TileD3D11`.
pub color: u16,
pub ctrl: u8,
pub backdrop: i8,
}
// TODO(pcwalton): Pack better!
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct PropagateMetadataD3D11 {
pub tile_rect: RectI,
pub tile_offset: u32,
pub path_index: PathBatchIndex,
pub z_write: u32,
// This will generally not refer to the same batch as `path_index`.
pub clip_path_index: PathBatchIndex,
pub backdrop_offset: u32,
pub pad0: u32,
pub pad1: u32,
pub pad2: u32,
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct DiceMetadataD3D11 {
pub global_path_id: PathId,
pub first_global_segment_index: u32,
pub first_batch_segment_index: u32,
pub pad: u32,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct TextureMetadataEntry {
pub color_0_transform: Transform2F,
pub color_0_combine_mode: ColorCombineMode,
pub base_color: ColorU,
pub filter: Filter,
pub blend_mode: BlendMode,
}
#[derive(Clone, Copy, Debug, Default)]
pub struct FillBatchEntry {
pub fill: Fill,
pub page: u16,
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub enum ColorCombineMode {
None,
SrcIn,
DestIn,
}
#[derive(Clone, Copy, Debug, Default)]
#[repr(C)]
pub struct Fill {
pub subpx: LineSegmentU8,
pub px: LineSegmentU4,
pub alpha_tile_index: u16,
pub line_segment: LineSegmentU16,
// The meaning of this field depends on whether fills are being done with the GPU rasterizer or
// GPU compute. If raster, this field names the index of the alpha tile that this fill belongs
// to. If compute, this field names the index of the next fill in the singly-linked list of
// fills belonging to this alpha tile.
pub link: u32,
}
#[derive(Clone, Debug)]
pub struct ClipBatch {
pub clips: Vec<Clip>,
pub key: ClipBatchKey,
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct ClipMetadata {
pub draw_tile_rect: RectI,
pub clip_tile_rect: RectI,
pub draw_tile_offset: u32,
pub clip_tile_offset: u32,
pub pad0: u32,
pub pad1: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ClipBatchKey {
pub dest_page: u16,
pub src_page: u16,
pub kind: ClipBatchKind,
}
// Order is significant here.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ClipBatchKind {
Draw,
Clip,
}
#[derive(Clone, Copy, Debug, Default)]
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Clip {
pub dest_u: u8,
pub dest_v: u8,
pub src_u: u8,
pub src_v: u8,
pub backdrop: i8,
pub pad_0: u8,
pub pad_1: u16,
pub dest_tile_id: AlphaTileId,
pub dest_backdrop: i32,
pub src_tile_id: AlphaTileId,
pub src_backdrop: i32,
}
#[derive(Clone, Copy, Debug, Default)]
impl Default for Clip {
#[inline]
fn default() -> Clip {
Clip {
dest_tile_id: AlphaTileId(!0),
dest_backdrop: 0,
src_tile_id: AlphaTileId(!0),
src_backdrop: 0,
}
}
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Tile {
pub tile_x: i16,
pub tile_y: i16,
pub mask_0_u: u8,
pub mask_0_v: u8,
pub mask_0_backdrop: i8,
pub pad: u8,
pub color: u16,
pub ctrl: u16,
pub struct BinSegment {
pub segment: LineSegment2F,
pub path_index: PathId,
pub pad0: u32,
pub pad1: u32,
pub pad2: u32,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct BackdropInfoD3D11 {
pub initial_backdrop: i32,
// Column number, where 0 is the leftmost column in the tile rect.
pub tile_x_offset: i32,
pub path_index: PathBatchIndex,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub(crate) struct MicrolineD3D11 {
from_x_px: i16,
from_y_px: i16,
to_x_px: i16,
to_y_px: i16,
from_x_subpx: u8,
from_y_subpx: u8,
to_x_subpx: u8,
to_y_subpx: u8,
path_index: u32,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub(crate) struct FirstTileD3D11 {
first_tile: i32,
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(C)]
pub struct AlphaTileId(pub u32);
impl PathBatchIndex {
#[inline]
pub fn none() -> PathBatchIndex {
PathBatchIndex(!0)
}
}
impl AlphaTileId {
#[inline]
pub fn new(next_alpha_tile_index: &[AtomicUsize; ALPHA_TILE_LEVEL_COUNT], level: usize)
@ -249,24 +479,40 @@ impl Debug for RenderCommand {
RenderCommand::UploadTextureMetadata(ref metadata) => {
write!(formatter, "UploadTextureMetadata(x{})", metadata.len())
}
RenderCommand::AddFills(ref fills) => {
write!(formatter, "AddFills(x{})", fills.len())
RenderCommand::AddFillsD3D9(ref fills) => {
write!(formatter, "AddFillsD3D9(x{})", fills.len())
}
RenderCommand::FlushFills => write!(formatter, "FlushFills"),
RenderCommand::ClipTiles(ref batches) => {
write!(formatter, "ClipTiles(x{})", batches.len())
RenderCommand::FlushFillsD3D9 => write!(formatter, "FlushFills"),
RenderCommand::UploadSceneD3D11 { ref draw_segments, ref clip_segments } => {
write!(formatter,
"UploadSceneD3D11(DP x{}, DI x{}, CP x{}, CI x{})",
draw_segments.points.len(),
draw_segments.indices.len(),
clip_segments.points.len(),
clip_segments.indices.len())
}
RenderCommand::PrepareClipTilesD3D11(ref batch) => {
let clipped_path_count = match batch.clipped_path_info {
None => 0,
Some(ref clipped_path_info) => clipped_path_info.clipped_path_count,
};
write!(formatter,
"PrepareClipTilesD3D11({:?}, C {})",
batch.batch_id,
clipped_path_count)
}
RenderCommand::PushRenderTarget(render_target_id) => {
write!(formatter, "PushRenderTarget({:?})", render_target_id)
}
RenderCommand::PopRenderTarget => write!(formatter, "PopRenderTarget"),
RenderCommand::BeginTileDrawing => write!(formatter, "BeginTileDrawing"),
RenderCommand::DrawTiles(ref batch) => {
RenderCommand::DrawTilesD3D9(ref batch) => {
write!(formatter, "DrawTilesD3D9(x{:?})", batch.tiles.len())
}
RenderCommand::DrawTilesD3D11(ref batch) => {
write!(formatter,
"DrawTiles(x{}, C0 {:?}, {:?})",
batch.tiles.len(),
batch.color_texture,
batch.blend_mode)
"DrawTilesD3D11({:?}, C0 {:?})",
batch.tile_batch_data.batch_id,
batch.color_texture)
}
RenderCommand::Finish { cpu_build_time } => {
write!(formatter, "Finish({} ms)", cpu_build_time.as_secs_f64() * 1000.0)
@ -274,3 +520,10 @@ impl Debug for RenderCommand {
}
}
}
impl Default for FirstTileD3D11 {
#[inline]
fn default() -> FirstTileD3D11 {
FirstTileD3D11 { first_tile: -1 }
}
}