Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ rand = "0.10.0"
[target.'cfg(target_os = "linux")'.dev-dependencies]
processing_glfw = { workspace = true, features = ["wayland"] }

[[example]]
name = "test"
path = "examples/test.rs"

[patch."https://github.com/bevyengine/bevy"]
bevy = { git = "https://github.com/processing/bevy", branch = "main" }

Expand Down
1 change: 1 addition & 0 deletions crates/processing_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ half = "2.7"
crossbeam-channel = "0.5"
processing_core = { workspace = true }
processing_midi = { workspace = true }
wgpu = { version = "29.0.1", default-features = false }

[build-dependencies]
wesl = { workspace = true, features = ["package"] }
Expand Down
59 changes: 58 additions & 1 deletion crates/processing_render/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use bevy::{
render::{
RenderApp,
render_resource::{
CommandEncoderDescriptor, Extent3d, MapMode, Origin3d, PollType, TexelCopyBufferInfo,
CommandEncoderDescriptor, Extent3d, LoadOp, MapMode, Operations, Origin3d, PollType,
RenderPassColorAttachment, RenderPassDescriptor, StoreOp, TexelCopyBufferInfo,
TexelCopyBufferLayout, TexelCopyTextureInfo, Texture, TextureFormat, TextureUsages,
},
renderer::{RenderDevice, RenderQueue},
Expand All @@ -36,6 +37,8 @@ use crate::{
};
use processing_core::error::{ProcessingError, Result};

pub const DEFAULT_CLEAR_COLOR: Color = Color::srgba_u8(208, 208, 208, 255);

pub struct GraphicsPlugin;

impl Plugin for GraphicsPlugin {
Expand Down Expand Up @@ -483,6 +486,60 @@ pub fn end_draw(app: &mut App, entity: Entity) -> Result<()> {
present(app, entity)
}

/// Do some work on the GPU to ensure that the render target texture is initialized and can be read
/// from/written to.
///
/// This is necessary on some platforms (notably macOS) to avoid issues with the first few frames of
/// rendering being corrupted or not appearing at all.
///
// TODO: why is metal particularly affected by this? can we remove this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a bevy issue we can track related to this? if so can we ref the issue here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, although I was able to create a reproduction in Bevy. I should try to create a reproduction in raw wgpu to confirm. It's a bit tricky because our "sketch" requirements (i.e. load semantics on the color attachment plus first frame transient raster) are very unusual for graphical applications. I tried to dig into the xcode debugger but was having trouble reproducing under instrumentation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also possible this is just a M1/M2 thing...

pub fn warmup(app: &mut App, entity: Entity) -> Result<()> {
let main_texture = {
let render_world = app.sub_app_mut(RenderApp).world_mut();
let mut query = render_world.query::<(&MainEntity, &ViewTarget)>();
let mut found = None;
for (main_entity, vt) in query.iter(render_world) {
if **main_entity == entity {
found = Some(vt.main_texture().clone());
break;
}
}
found.ok_or(ProcessingError::GraphicsNotFound)?
};

let render_app = app.sub_app(RenderApp);
let render_device = render_app.world().resource::<RenderDevice>();
let render_queue = render_app.world().resource::<RenderQueue>();

let view = main_texture.create_view(&bevy::render::render_resource::TextureViewDescriptor {
label: Some("processing_warmup_view"),
..Default::default()
});
let mut encoder = render_device.create_command_encoder(&CommandEncoderDescriptor {
label: Some("processing_warmup_encoder"),
});
{
let _pass = encoder.begin_render_pass(&RenderPassDescriptor {
label: Some("processing_warmup_clear"),
color_attachments: &[Some(RenderPassColorAttachment {
view: &view,
depth_slice: None,
resolve_target: None,
ops: Operations {
load: LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
}
render_queue.submit([encoder.finish()]);
Ok(())
}

pub fn record_command(
In((graphics_entity, cmd)): In<(Entity, DrawCommand)>,
mut graphics_query: Query<&mut CommandBuffer>,
Expand Down
21 changes: 17 additions & 4 deletions crates/processing_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use processing_core::config::*;
use processing_core::error;

use crate::geometry::{AttributeFormat, AttributeValue};
use crate::graphics::flush;
use crate::graphics::{DEFAULT_CLEAR_COLOR, flush};
use crate::image::gpu_image;
use crate::render::command::DrawCommand;

Expand Down Expand Up @@ -254,13 +254,26 @@ pub fn graphics_create(
height: u32,
texture_format: TextureFormat,
) -> error::Result<Entity> {
app_mut(|app| {
app.world_mut()
app_mut(|app| -> error::Result<Entity> {
let entity = app
.world_mut()
.run_system_cached_with(
graphics::create,
(width, height, surface_entity, texture_format),
)
.unwrap()
.unwrap()?;

app.update();
#[cfg(target_os = "macos")]
graphics::warmup(app, entity)?;

app.world_mut()
.run_system_cached_with(
graphics::record_command,
(entity, DrawCommand::BackgroundColor(DEFAULT_CLEAR_COLOR)),
)
.unwrap()?;
Ok(entity)
})
}

Expand Down
Loading