Bug 1791336 - Extend command buffer infrastructure for future primitive types r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D157611
This commit is contained in:
Glenn Watson 2022-09-19 20:12:11 +00:00
parent cc6395c43d
commit fb47df18ef
6 changed files with 91 additions and 52 deletions

View file

@ -816,8 +816,7 @@ impl BatchBuilder {
// in that picture are being drawn into the same target. // in that picture are being drawn into the same target.
pub fn add_prim_to_batch( pub fn add_prim_to_batch(
&mut self, &mut self,
prim_instance: &PrimitiveInstance, cmd: &PrimitiveCommand,
extra_prim_gpu_address: Option<GpuCacheAddress>,
prim_spatial_node_index: SpatialNodeIndex, prim_spatial_node_index: SpatialNodeIndex,
ctx: &RenderTargetContext, ctx: &RenderTargetContext,
gpu_cache: &mut GpuCache, gpu_cache: &mut GpuCache,
@ -827,8 +826,19 @@ impl BatchBuilder {
root_spatial_node_index: SpatialNodeIndex, root_spatial_node_index: SpatialNodeIndex,
surface_spatial_node_index: SpatialNodeIndex, surface_spatial_node_index: SpatialNodeIndex,
z_generator: &mut ZBufferIdGenerator, z_generator: &mut ZBufferIdGenerator,
prim_instances: &[PrimitiveInstance],
_gpu_buffer_builder: &mut GpuBufferBuilder, _gpu_buffer_builder: &mut GpuBufferBuilder,
) { ) {
let (prim_instance_index, extra_prim_gpu_address) = match cmd {
PrimitiveCommand::Simple { prim_instance_index } => {
(prim_instance_index, None)
}
PrimitiveCommand::Complex { prim_instance_index, gpu_address } => {
(prim_instance_index, Some(*gpu_address))
}
};
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
let is_anti_aliased = ctx.data_stores.prim_has_anti_aliasing(prim_instance); let is_anti_aliased = ctx.data_stores.prim_has_anti_aliasing(prim_instance);
let brush_flags = if is_anti_aliased { let brush_flags = if is_anti_aliased {
@ -3769,6 +3779,36 @@ impl<'a, 'rc> RenderTargetContext<'a, 'rc> {
} }
} }
pub enum PrimitiveCommand {
Simple {
prim_instance_index: PrimitiveInstanceIndex,
},
Complex {
prim_instance_index: PrimitiveInstanceIndex,
gpu_address: GpuCacheAddress,
},
}
impl PrimitiveCommand {
pub fn simple(
prim_instance_index: PrimitiveInstanceIndex,
) -> Self {
PrimitiveCommand::Simple {
prim_instance_index,
}
}
pub fn complex(
prim_instance_index: PrimitiveInstanceIndex,
gpu_address: GpuCacheAddress,
) -> Self {
PrimitiveCommand::Complex {
prim_instance_index,
gpu_address,
}
}
}
// A tightly packed command stored in a command buffer // A tightly packed command stored in a command buffer
#[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))] #[cfg_attr(feature = "replay", derive(Deserialize))]
@ -3869,23 +3909,22 @@ impl CommandBuffer {
/// Add a primitive to the command buffer /// Add a primitive to the command buffer
pub fn add_prim( pub fn add_prim(
&mut self, &mut self,
prim_instance_index: PrimitiveInstanceIndex, prim_cmd: &PrimitiveCommand,
spatial_node_index: SpatialNodeIndex, spatial_node_index: SpatialNodeIndex,
gpu_address: Option<GpuCacheAddress>,
) { ) {
if self.current_spatial_node_index != spatial_node_index { if self.current_spatial_node_index != spatial_node_index {
self.commands.push(Command::set_spatial_node(spatial_node_index)); self.commands.push(Command::set_spatial_node(spatial_node_index));
self.current_spatial_node_index = spatial_node_index; self.current_spatial_node_index = spatial_node_index;
} }
match gpu_address { match *prim_cmd {
Some(gpu_address) => { PrimitiveCommand::Simple { prim_instance_index } => {
self.commands.push(Command::draw_simple_prim(prim_instance_index));
}
PrimitiveCommand::Complex { prim_instance_index, gpu_address } => {
self.commands.push(Command::draw_complex_prim(prim_instance_index)); 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.u as u32) << 16 | gpu_address.v as u32));
} }
None => {
self.commands.push(Command::draw_simple_prim(prim_instance_index));
}
} }
} }
@ -3893,7 +3932,7 @@ impl CommandBuffer {
pub fn iter_prims<F>( pub fn iter_prims<F>(
&self, &self,
f: &mut F, f: &mut F,
) where F: FnMut(PrimitiveInstanceIndex, SpatialNodeIndex, Option<GpuCacheAddress>) { ) where F: FnMut(&PrimitiveCommand, SpatialNodeIndex) {
let mut current_spatial_node_index = SpatialNodeIndex::INVALID; let mut current_spatial_node_index = SpatialNodeIndex::INVALID;
let mut cmd_iter = self.commands.iter(); let mut cmd_iter = self.commands.iter();
@ -3904,7 +3943,8 @@ impl CommandBuffer {
match command { match command {
Command::CMD_DRAW_SIMPLE_PRIM => { Command::CMD_DRAW_SIMPLE_PRIM => {
let prim_instance_index = PrimitiveInstanceIndex(param); let prim_instance_index = PrimitiveInstanceIndex(param);
f(prim_instance_index, current_spatial_node_index, None); let cmd = PrimitiveCommand::simple(prim_instance_index);
f(&cmd, current_spatial_node_index);
} }
Command::CMD_SET_SPATIAL_NODE => { Command::CMD_SET_SPATIAL_NODE => {
current_spatial_node_index = SpatialNodeIndex(param); current_spatial_node_index = SpatialNodeIndex(param);
@ -3916,7 +3956,11 @@ impl CommandBuffer {
u: (data.0 >> 16) as u16, u: (data.0 >> 16) as u16,
v: (data.0 & 0xffff) as u16, v: (data.0 & 0xffff) as u16,
}; };
f(prim_instance_index, current_spatial_node_index, Some(gpu_address)); let cmd = PrimitiveCommand::complex(
prim_instance_index,
gpu_address,
);
f(&cmd, current_spatial_node_index);
} }
_ => { _ => {
unreachable!(); unreachable!();

View file

@ -790,12 +790,9 @@ pub fn build_render_pass(
let mut batch_builder = BatchBuilder::new(batcher); let mut batch_builder = BatchBuilder::new(batcher);
cmd_buffer.iter_prims(&mut |prim_instance_index, spatial_node_index, gpu_address| { cmd_buffer.iter_prims(&mut |cmd, spatial_node_index| {
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
batch_builder.add_prim_to_batch( batch_builder.add_prim_to_batch(
prim_instance, cmd,
gpu_address,
spatial_node_index, spatial_node_index,
ctx, ctx,
gpu_cache, gpu_cache,
@ -805,6 +802,7 @@ pub fn build_render_pass(
pic_task.raster_spatial_node_index, pic_task.raster_spatial_node_index,
pic_task.surface_spatial_node_index, pic_task.surface_spatial_node_index,
z_generator, z_generator,
prim_instances,
&mut gpu_buffer_builder, &mut gpu_buffer_builder,
); );
}); });

View file

@ -99,6 +99,7 @@ use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, RasterSpace};
use api::{DebugFlags, ImageKey, ColorF, ColorU, PrimitiveFlags}; use api::{DebugFlags, ImageKey, ColorF, ColorU, PrimitiveFlags};
use api::{ImageRendering, ColorDepth, YuvRangedColorSpace, YuvFormat, AlphaType}; use api::{ImageRendering, ColorDepth, YuvRangedColorSpace, YuvFormat, AlphaType};
use api::units::*; use api::units::*;
use crate::batch::PrimitiveCommand;
use crate::box_shadow::BLUR_SAMPLE_SCALE; use crate::box_shadow::BLUR_SAMPLE_SCALE;
use crate::clip::{ClipStore, ClipChainInstance, ClipLeafId, ClipNodeId, ClipTreeBuilder}; use crate::clip::{ClipStore, ClipChainInstance, ClipLeafId, ClipNodeId, ClipTreeBuilder};
use crate::spatial_tree::{SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace}; use crate::spatial_tree::{SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace};
@ -5882,11 +5883,15 @@ impl PicturePrimitive {
for child in list { for child in list {
let child_prim_instance = &prim_instances[child.anchor.instance_index.0 as usize]; let child_prim_instance = &prim_instances[child.anchor.instance_index.0 as usize];
frame_state.surface_builder.push_prim( let prim_cmd = PrimitiveCommand::complex(
child.anchor.instance_index, child.anchor.instance_index,
child.gpu_address
);
frame_state.surface_builder.push_prim(
&prim_cmd,
child.anchor.spatial_node_index, child.anchor.spatial_node_index,
&child_prim_instance.vis, &child_prim_instance.vis,
Some(child.gpu_address),
frame_state.cmd_buffers, frame_state.cmd_buffers,
); );
} }

View file

@ -12,6 +12,7 @@ use api::{BoxShadowClipMode, BorderStyle, ClipMode};
use api::units::*; use api::units::*;
use euclid::Scale; use euclid::Scale;
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::batch::PrimitiveCommand;
use crate::image_tiling::{self, Repetition}; use crate::image_tiling::{self, Repetition};
use crate::border::{get_max_scale_for_border, build_border_instances}; use crate::border::{get_max_scale_for_border, build_border_instances};
use crate::clip::{ClipStore}; use crate::clip::{ClipStore};
@ -71,7 +72,7 @@ pub fn prepare_primitives(
PrimitiveInstanceIndex(prim_instance_index as u32), PrimitiveInstanceIndex(prim_instance_index as u32),
); );
if prepare_prim_for_render( if let Some(ref prim_cmd) = prepare_prim_for_render(
store, store,
prim_instance_index, prim_instance_index,
cluster, cluster,
@ -85,14 +86,10 @@ pub fn prepare_primitives(
tile_caches, tile_caches,
prim_instances, prim_instances,
) { ) {
// First check for coarse visibility (if this primitive was completely off-screen)
let prim_instance = &mut prim_instances[prim_instance_index];
frame_state.surface_builder.push_prim( frame_state.surface_builder.push_prim(
PrimitiveInstanceIndex(prim_instance_index as u32), prim_cmd,
cluster.spatial_node_index, cluster.spatial_node_index,
&prim_instance.vis, &prim_instances[prim_instance_index].vis,
None,
frame_state.cmd_buffers, frame_state.cmd_buffers,
); );
@ -122,7 +119,7 @@ fn prepare_prim_for_render(
scratch: &mut PrimitiveScratchBuffer, scratch: &mut PrimitiveScratchBuffer,
tile_caches: &mut FastHashMap<SliceId, Box<TileCacheInstance>>, tile_caches: &mut FastHashMap<SliceId, Box<TileCacheInstance>>,
prim_instances: &mut Vec<PrimitiveInstance>, prim_instances: &mut Vec<PrimitiveInstance>,
) -> bool { ) -> Option<PrimitiveCommand> {
profile_scope!("prepare_prim_for_render"); profile_scope!("prepare_prim_for_render");
// If we have dependencies, we need to prepare them first, in order // If we have dependencies, we need to prepare them first, in order
@ -173,7 +170,7 @@ fn prepare_prim_for_render(
); );
} }
None => { None => {
return false; return None;
} }
} }
} }
@ -200,12 +197,13 @@ fn prepare_prim_for_render(
data_stores, data_stores,
scratch, scratch,
) { ) {
return false; return None;
} }
} }
prepare_interned_prim_for_render( Some(prepare_interned_prim_for_render(
store, store,
PrimitiveInstanceIndex(prim_instance_index as u32),
prim_instance, prim_instance,
cluster, cluster,
plane_split_anchor, plane_split_anchor,
@ -214,9 +212,7 @@ fn prepare_prim_for_render(
frame_state, frame_state,
data_stores, data_stores,
scratch, scratch,
); ))
true
} }
/// Prepare an interned primitive for rendering, by requesting /// Prepare an interned primitive for rendering, by requesting
@ -224,6 +220,7 @@ fn prepare_prim_for_render(
/// prepare_prim_for_render_inner call for old style primitives. /// prepare_prim_for_render_inner call for old style primitives.
fn prepare_interned_prim_for_render( fn prepare_interned_prim_for_render(
store: &mut PrimitiveStore, store: &mut PrimitiveStore,
prim_instance_index: PrimitiveInstanceIndex,
prim_instance: &mut PrimitiveInstance, prim_instance: &mut PrimitiveInstance,
cluster: &mut PrimitiveCluster, cluster: &mut PrimitiveCluster,
plane_split_anchor: PlaneSplitAnchor, plane_split_anchor: PlaneSplitAnchor,
@ -232,7 +229,7 @@ fn prepare_interned_prim_for_render(
frame_state: &mut FrameBuildingState, frame_state: &mut FrameBuildingState,
data_stores: &mut DataStores, data_stores: &mut DataStores,
scratch: &mut PrimitiveScratchBuffer, scratch: &mut PrimitiveScratchBuffer,
) { ) -> PrimitiveCommand {
let prim_spatial_node_index = cluster.spatial_node_index; let prim_spatial_node_index = cluster.spatial_node_index;
let device_pixel_scale = frame_state.surfaces[pic_context.surface_index.0].device_pixel_scale; let device_pixel_scale = frame_state.surfaces[pic_context.surface_index.0].device_pixel_scale;
@ -812,7 +809,9 @@ fn prepare_interned_prim_for_render(
} }
} }
} }
}; }
PrimitiveCommand::simple(prim_instance_index)
} }

View file

@ -299,12 +299,9 @@ impl RenderTarget for ColorRenderTarget {
let mut batch_builder = BatchBuilder::new(alpha_batch_builder); let mut batch_builder = BatchBuilder::new(alpha_batch_builder);
let cmd_buffer = cmd_buffers.get(pic_task.cmd_buffer_index); let cmd_buffer = cmd_buffers.get(pic_task.cmd_buffer_index);
cmd_buffer.iter_prims(&mut |prim_instance_index, spatial_node_index, gpu_address| { cmd_buffer.iter_prims(&mut |cmd, spatial_node_index| {
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
batch_builder.add_prim_to_batch( batch_builder.add_prim_to_batch(
prim_instance, cmd,
gpu_address,
spatial_node_index, spatial_node_index,
ctx, ctx,
gpu_cache, gpu_cache,
@ -314,6 +311,7 @@ impl RenderTarget for ColorRenderTarget {
pic_task.raster_spatial_node_index, pic_task.raster_spatial_node_index,
pic_task.surface_spatial_node_index, pic_task.surface_spatial_node_index,
z_generator, z_generator,
prim_instances,
&mut gpu_buffer_builder, &mut gpu_buffer_builder,
); );
}); });

View file

@ -3,10 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::units::*; use api::units::*;
use crate::batch::{CommandBufferBuilderKind, CommandBufferList, CommandBufferBuilder, CommandBufferIndex}; use crate::batch::{CommandBufferBuilderKind, CommandBufferList, CommandBufferBuilder, CommandBufferIndex, PrimitiveCommand};
use crate::internal_types::FastHashMap; use crate::internal_types::FastHashMap;
use crate::picture::{SurfaceInfo, SurfaceIndex, TileKey, SubSliceIndex}; use crate::picture::{SurfaceInfo, SurfaceIndex, TileKey, SubSliceIndex};
use crate::prim_store::{PrimitiveInstanceIndex, PictureIndex}; use crate::prim_store::{PictureIndex};
use crate::render_task_graph::{RenderTaskId, RenderTaskGraphBuilder}; use crate::render_task_graph::{RenderTaskId, RenderTaskGraphBuilder};
use crate::spatial_tree::SpatialNodeIndex; use crate::spatial_tree::SpatialNodeIndex;
use crate::render_target::ResolveOp; use crate::render_target::ResolveOp;
@ -156,11 +156,10 @@ impl CommandBufferTargets {
/// Push a new primitive in to the command buffer builder /// Push a new primitive in to the command buffer builder
fn push_prim( fn push_prim(
&mut self, &mut self,
prim_instance_index: PrimitiveInstanceIndex, prim_cmd: &PrimitiveCommand,
spatial_node_index: SpatialNodeIndex, spatial_node_index: SpatialNodeIndex,
tile_rect: crate::picture::TileRect, tile_rect: crate::picture::TileRect,
sub_slice_index: SubSliceIndex, sub_slice_index: SubSliceIndex,
gpu_address: Option<crate::gpu_cache::GpuCacheAddress>,
cmd_buffers: &mut CommandBufferList, cmd_buffers: &mut CommandBufferList,
) { ) {
match self { match self {
@ -175,9 +174,8 @@ impl CommandBufferTargets {
}; };
if let Some(cmd_buffer_index) = tiles.get(&key) { if let Some(cmd_buffer_index) = tiles.get(&key) {
cmd_buffers.get_mut(*cmd_buffer_index).add_prim( cmd_buffers.get_mut(*cmd_buffer_index).add_prim(
prim_instance_index, prim_cmd,
spatial_node_index, spatial_node_index,
gpu_address,
); );
} }
} }
@ -186,9 +184,8 @@ impl CommandBufferTargets {
CommandBufferTargets::Simple { cmd_buffer_index, .. } => { CommandBufferTargets::Simple { cmd_buffer_index, .. } => {
// For simple builders, just add the prim // For simple builders, just add the prim
cmd_buffers.get_mut(*cmd_buffer_index).add_prim( cmd_buffers.get_mut(*cmd_buffer_index).add_prim(
prim_instance_index, prim_cmd,
spatial_node_index, spatial_node_index,
gpu_address,
); );
} }
} }
@ -355,10 +352,9 @@ impl SurfaceBuilder {
// Push a primitive to the current cmd buffer target(s) // Push a primitive to the current cmd buffer target(s)
pub fn push_prim( pub fn push_prim(
&mut self, &mut self,
prim_instance_index: PrimitiveInstanceIndex, prim_cmd: &PrimitiveCommand,
spatial_node_index: SpatialNodeIndex, spatial_node_index: SpatialNodeIndex,
vis: &PrimitiveVisibility, vis: &PrimitiveVisibility,
gpu_address: Option<crate::gpu_cache::GpuCacheAddress>,
cmd_buffers: &mut CommandBufferList, cmd_buffers: &mut CommandBufferList,
) { ) {
match vis.state { match vis.state {
@ -367,11 +363,10 @@ impl SurfaceBuilder {
} }
VisibilityState::Visible { tile_rect, sub_slice_index, .. } => { VisibilityState::Visible { tile_rect, sub_slice_index, .. } => {
self.current_cmd_buffers.push_prim( self.current_cmd_buffers.push_prim(
prim_instance_index, prim_cmd,
spatial_node_index, spatial_node_index,
tile_rect, tile_rect,
sub_slice_index, sub_slice_index,
gpu_address,
cmd_buffers, cmd_buffers,
) )
} }