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.
pub fn add_prim_to_batch(
&mut self,
prim_instance: &PrimitiveInstance,
extra_prim_gpu_address: Option<GpuCacheAddress>,
cmd: &PrimitiveCommand,
prim_spatial_node_index: SpatialNodeIndex,
ctx: &RenderTargetContext,
gpu_cache: &mut GpuCache,
@ -827,8 +826,19 @@ impl BatchBuilder {
root_spatial_node_index: SpatialNodeIndex,
surface_spatial_node_index: SpatialNodeIndex,
z_generator: &mut ZBufferIdGenerator,
prim_instances: &[PrimitiveInstance],
_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 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
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
@ -3869,23 +3909,22 @@ impl CommandBuffer {
/// Add a primitive to the command buffer
pub fn add_prim(
&mut self,
prim_instance_index: PrimitiveInstanceIndex,
prim_cmd: &PrimitiveCommand,
spatial_node_index: SpatialNodeIndex,
gpu_address: Option<GpuCacheAddress>,
) {
if self.current_spatial_node_index != spatial_node_index {
self.commands.push(Command::set_spatial_node(spatial_node_index));
self.current_spatial_node_index = spatial_node_index;
}
match gpu_address {
Some(gpu_address) => {
match *prim_cmd {
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::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>(
&self,
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 cmd_iter = self.commands.iter();
@ -3904,7 +3943,8 @@ impl CommandBuffer {
match command {
Command::CMD_DRAW_SIMPLE_PRIM => {
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 => {
current_spatial_node_index = SpatialNodeIndex(param);
@ -3916,7 +3956,11 @@ impl CommandBuffer {
u: (data.0 >> 16) 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!();

View file

@ -790,12 +790,9 @@ pub fn build_render_pass(
let mut batch_builder = BatchBuilder::new(batcher);
cmd_buffer.iter_prims(&mut |prim_instance_index, spatial_node_index, gpu_address| {
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
cmd_buffer.iter_prims(&mut |cmd, spatial_node_index| {
batch_builder.add_prim_to_batch(
prim_instance,
gpu_address,
cmd,
spatial_node_index,
ctx,
gpu_cache,
@ -805,6 +802,7 @@ pub fn build_render_pass(
pic_task.raster_spatial_node_index,
pic_task.surface_spatial_node_index,
z_generator,
prim_instances,
&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::{ImageRendering, ColorDepth, YuvRangedColorSpace, YuvFormat, AlphaType};
use api::units::*;
use crate::batch::PrimitiveCommand;
use crate::box_shadow::BLUR_SAMPLE_SCALE;
use crate::clip::{ClipStore, ClipChainInstance, ClipLeafId, ClipNodeId, ClipTreeBuilder};
use crate::spatial_tree::{SpatialTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace};
@ -5882,11 +5883,15 @@ impl PicturePrimitive {
for child in list {
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.gpu_address
);
frame_state.surface_builder.push_prim(
&prim_cmd,
child.anchor.spatial_node_index,
&child_prim_instance.vis,
Some(child.gpu_address),
frame_state.cmd_buffers,
);
}

View file

@ -12,6 +12,7 @@ use api::{BoxShadowClipMode, BorderStyle, ClipMode};
use api::units::*;
use euclid::Scale;
use smallvec::SmallVec;
use crate::batch::PrimitiveCommand;
use crate::image_tiling::{self, Repetition};
use crate::border::{get_max_scale_for_border, build_border_instances};
use crate::clip::{ClipStore};
@ -71,7 +72,7 @@ pub fn prepare_primitives(
PrimitiveInstanceIndex(prim_instance_index as u32),
);
if prepare_prim_for_render(
if let Some(ref prim_cmd) = prepare_prim_for_render(
store,
prim_instance_index,
cluster,
@ -85,14 +86,10 @@ pub fn prepare_primitives(
tile_caches,
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(
PrimitiveInstanceIndex(prim_instance_index as u32),
prim_cmd,
cluster.spatial_node_index,
&prim_instance.vis,
None,
&prim_instances[prim_instance_index].vis,
frame_state.cmd_buffers,
);
@ -122,7 +119,7 @@ fn prepare_prim_for_render(
scratch: &mut PrimitiveScratchBuffer,
tile_caches: &mut FastHashMap<SliceId, Box<TileCacheInstance>>,
prim_instances: &mut Vec<PrimitiveInstance>,
) -> bool {
) -> Option<PrimitiveCommand> {
profile_scope!("prepare_prim_for_render");
// If we have dependencies, we need to prepare them first, in order
@ -173,7 +170,7 @@ fn prepare_prim_for_render(
);
}
None => {
return false;
return None;
}
}
}
@ -200,12 +197,13 @@ fn prepare_prim_for_render(
data_stores,
scratch,
) {
return false;
return None;
}
}
prepare_interned_prim_for_render(
Some(prepare_interned_prim_for_render(
store,
PrimitiveInstanceIndex(prim_instance_index as u32),
prim_instance,
cluster,
plane_split_anchor,
@ -214,9 +212,7 @@ fn prepare_prim_for_render(
frame_state,
data_stores,
scratch,
);
true
))
}
/// 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.
fn prepare_interned_prim_for_render(
store: &mut PrimitiveStore,
prim_instance_index: PrimitiveInstanceIndex,
prim_instance: &mut PrimitiveInstance,
cluster: &mut PrimitiveCluster,
plane_split_anchor: PlaneSplitAnchor,
@ -232,7 +229,7 @@ fn prepare_interned_prim_for_render(
frame_state: &mut FrameBuildingState,
data_stores: &mut DataStores,
scratch: &mut PrimitiveScratchBuffer,
) {
) -> PrimitiveCommand {
let prim_spatial_node_index = cluster.spatial_node_index;
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 cmd_buffer = cmd_buffers.get(pic_task.cmd_buffer_index);
cmd_buffer.iter_prims(&mut |prim_instance_index, spatial_node_index, gpu_address| {
let prim_instance = &prim_instances[prim_instance_index.0 as usize];
cmd_buffer.iter_prims(&mut |cmd, spatial_node_index| {
batch_builder.add_prim_to_batch(
prim_instance,
gpu_address,
cmd,
spatial_node_index,
ctx,
gpu_cache,
@ -314,6 +311,7 @@ impl RenderTarget for ColorRenderTarget {
pic_task.raster_spatial_node_index,
pic_task.surface_spatial_node_index,
z_generator,
prim_instances,
&mut gpu_buffer_builder,
);
});

View file

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