Skip to content

Commit a53af7a

Browse files
committed
Reliably clear to default clear color.
1 parent e3ceaa5 commit a53af7a

3 files changed

Lines changed: 77 additions & 5 deletions

File tree

crates/processing_render/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ half = "2.7"
2222
crossbeam-channel = "0.5"
2323
processing_core = { workspace = true }
2424
processing_midi = { workspace = true }
25+
wgpu = { version = "29.0.1", default-features = false }
2526

2627
[build-dependencies]
2728
wesl = { workspace = true, features = ["package"] }

crates/processing_render/src/graphics.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use bevy::{
1515
render::{
1616
RenderApp,
1717
render_resource::{
18-
CommandEncoderDescriptor, Extent3d, MapMode, Origin3d, PollType, TexelCopyBufferInfo,
18+
CommandEncoderDescriptor, Extent3d, LoadOp, MapMode, Operations, Origin3d, PollType,
19+
RenderPassColorAttachment, RenderPassDescriptor, StoreOp, TexelCopyBufferInfo,
1920
TexelCopyBufferLayout, TexelCopyTextureInfo, Texture, TextureFormat, TextureUsages,
2021
},
2122
renderer::{RenderDevice, RenderQueue},
@@ -36,6 +37,8 @@ use crate::{
3637
};
3738
use processing_core::error::{ProcessingError, Result};
3839

40+
pub const DEFAULT_CLEAR_COLOR: Color = Color::srgba_u8(208, 208, 208, 255);
41+
3942
pub struct GraphicsPlugin;
4043

4144
impl Plugin for GraphicsPlugin {
@@ -483,6 +486,61 @@ pub fn end_draw(app: &mut App, entity: Entity) -> Result<()> {
483486
present(app, entity)
484487
}
485488

489+
490+
/// Do some work on the GPU to ensure that the render target texture is initialized and can be read
491+
/// from/written to.
492+
///
493+
/// This is necessary on some platforms (notably macOS) to avoid issues with the first few frames of
494+
/// rendering being corrupted or not appearing at all.
495+
///
496+
// TODO: why is metal particularly affected by this? can we remove this?
497+
pub fn warmup(app: &mut App, entity: Entity) -> Result<()> {
498+
let main_texture = {
499+
let render_world = app.sub_app_mut(RenderApp).world_mut();
500+
let mut query = render_world.query::<(&MainEntity, &ViewTarget)>();
501+
let mut found = None;
502+
for (main_entity, vt) in query.iter(render_world) {
503+
if **main_entity == entity {
504+
found = Some(vt.main_texture().clone());
505+
break;
506+
}
507+
}
508+
found.ok_or(ProcessingError::GraphicsNotFound)?
509+
};
510+
511+
let render_app = app.sub_app(RenderApp);
512+
let render_device = render_app.world().resource::<RenderDevice>();
513+
let render_queue = render_app.world().resource::<RenderQueue>();
514+
515+
let view = main_texture.create_view(&bevy::render::render_resource::TextureViewDescriptor {
516+
label: Some("processing_warmup_view"),
517+
..Default::default()
518+
});
519+
let mut encoder = render_device.create_command_encoder(&CommandEncoderDescriptor {
520+
label: Some("processing_warmup_encoder"),
521+
});
522+
{
523+
let _pass = encoder.begin_render_pass(&RenderPassDescriptor {
524+
label: Some("processing_warmup_clear"),
525+
color_attachments: &[Some(RenderPassColorAttachment {
526+
view: &view,
527+
depth_slice: None,
528+
resolve_target: None,
529+
ops: Operations {
530+
load: LoadOp::Clear(wgpu::Color::TRANSPARENT),
531+
store: StoreOp::Store,
532+
},
533+
})],
534+
depth_stencil_attachment: None,
535+
timestamp_writes: None,
536+
occlusion_query_set: None,
537+
multiview_mask: None,
538+
});
539+
}
540+
render_queue.submit([encoder.finish()]);
541+
Ok(())
542+
}
543+
486544
pub fn record_command(
487545
In((graphics_entity, cmd)): In<(Entity, DrawCommand)>,
488546
mut graphics_query: Query<&mut CommandBuffer>,

crates/processing_render/src/lib.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use processing_core::config::*;
2727
use processing_core::error;
2828

2929
use crate::geometry::{AttributeFormat, AttributeValue};
30-
use crate::graphics::flush;
30+
use crate::graphics::{DEFAULT_CLEAR_COLOR, flush};
3131
use crate::image::gpu_image;
3232
use crate::render::command::DrawCommand;
3333

@@ -254,13 +254,26 @@ pub fn graphics_create(
254254
height: u32,
255255
texture_format: TextureFormat,
256256
) -> error::Result<Entity> {
257-
app_mut(|app| {
258-
app.world_mut()
257+
app_mut(|app| -> error::Result<Entity> {
258+
let entity = app
259+
.world_mut()
259260
.run_system_cached_with(
260261
graphics::create,
261262
(width, height, surface_entity, texture_format),
262263
)
263-
.unwrap()
264+
.unwrap()?;
265+
266+
app.update();
267+
#[cfg(target_os = "macos")]
268+
graphics::warmup(app, entity)?;
269+
270+
app.world_mut()
271+
.run_system_cached_with(
272+
graphics::record_command,
273+
(entity, DrawCommand::BackgroundColor(DEFAULT_CLEAR_COLOR)),
274+
)
275+
.unwrap()?;
276+
Ok(entity)
264277
})
265278
}
266279

0 commit comments

Comments
 (0)