wgpu: Fixed panic when rendering texture to itself, by always rendering to an intermediary
This commit is contained in:
parent
68343369a3
commit
c85910b46d
|
@ -402,9 +402,7 @@ mod wrapper {
|
|||
}
|
||||
|
||||
pub fn render(&self, smoothing: bool, context: &mut RenderContext<'_, 'gc>) {
|
||||
// if try_write fails,
|
||||
// this is caused by recursive render attempt. TODO: support this.
|
||||
if let Ok(mut inner_bitmap_data) = self.0.try_write(context.gc_context) {
|
||||
let mut inner_bitmap_data = self.0.write(context.gc_context);
|
||||
if inner_bitmap_data.disposed() {
|
||||
return;
|
||||
}
|
||||
|
@ -416,14 +414,9 @@ mod wrapper {
|
|||
.bitmap_handle(context.renderer)
|
||||
.expect("Missing bitmap handle");
|
||||
|
||||
context.commands.render_bitmap(
|
||||
handle,
|
||||
context.transform_stack.transform(),
|
||||
smoothing,
|
||||
);
|
||||
} else {
|
||||
//this is caused by recursive render attempt. TODO: support this.
|
||||
}
|
||||
context
|
||||
.commands
|
||||
.render_bitmap(handle, context.transform_stack.transform(), smoothing);
|
||||
}
|
||||
|
||||
pub fn is_point_in_bounds(&self, x: i32, y: i32) -> bool {
|
||||
|
|
|
@ -111,7 +111,6 @@ impl Surface {
|
|||
|
||||
let mut buffers = vec![draw_encoder.finish()];
|
||||
|
||||
if let RenderTargetMode::FreshBuffer(_) = render_target_mode {
|
||||
let mut copy_encoder =
|
||||
descriptors
|
||||
.device
|
||||
|
@ -131,7 +130,6 @@ impl Surface {
|
|||
&mut copy_encoder,
|
||||
);
|
||||
buffers.push(copy_encoder.finish());
|
||||
}
|
||||
|
||||
buffers.insert(0, uniform_encoder.finish());
|
||||
uniform_buffer.finish();
|
||||
|
|
|
@ -28,6 +28,7 @@ impl ResolveBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn new_manual(texture: Arc<wgpu::Texture>) -> Self {
|
||||
Self {
|
||||
texture: PoolOrArcTexture::Manual((
|
||||
|
@ -69,6 +70,7 @@ pub struct FrameBuffer {
|
|||
/// (when doing an offscreen render to a BitmapData texture)
|
||||
pub enum PoolOrArcTexture {
|
||||
Pool(PoolEntry<(wgpu::Texture, wgpu::TextureView), AlwaysCompatible>),
|
||||
#[allow(dead_code)]
|
||||
Manual((Arc<wgpu::Texture>, wgpu::TextureView)),
|
||||
}
|
||||
|
||||
|
@ -98,6 +100,7 @@ impl FrameBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn new_manual(texture: Arc<wgpu::Texture>, size: wgpu::Extent3d) -> Self {
|
||||
Self {
|
||||
texture: PoolOrArcTexture::Manual((
|
||||
|
@ -232,11 +235,6 @@ impl CommandTarget {
|
|||
|
||||
let whole_frame_bind_group = OnceCell::new();
|
||||
|
||||
let (frame_buffer, resolve_buffer) = match &render_target_mode {
|
||||
// In `FreshBuffer` mode, get a new frame buffer (and resolve buffer, if necessary)
|
||||
// from the pool. They will be cleared with the provided clear color
|
||||
// in `color_attachments`
|
||||
RenderTargetMode::FreshBuffer(_) => {
|
||||
let frame_buffer = make_pooled_frame_buffer();
|
||||
let resolve_buffer = if sample_count > 1 {
|
||||
Some(ResolveBuffer::new(
|
||||
|
@ -252,18 +250,9 @@ impl CommandTarget {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
(frame_buffer, resolve_buffer)
|
||||
}
|
||||
// In `ExistingTexture` mode, we will use an existing texture
|
||||
// as either the frame buffer or resolve buffer.
|
||||
RenderTargetMode::ExistingTexture(texture) => {
|
||||
if sample_count > 1 {
|
||||
// The exising texture always has a sample count of 1,
|
||||
// so we need to create a new texture for the multisampled frame
|
||||
// buffer. Our existing texture will be used as the resolve buffer,
|
||||
// which is downsampled from the frame buffer.
|
||||
let frame_buffer = make_pooled_frame_buffer();
|
||||
|
||||
if let RenderTargetMode::ExistingTexture(texture) = &render_target_mode {
|
||||
if sample_count > 1 {
|
||||
// Both our frame buffer and resolve buffer need to start out
|
||||
// in the same state, so copy our existing texture to the freshly
|
||||
// allocated frame buffer. We cannot use `copy_texture_to_texture`,
|
||||
|
@ -280,18 +269,14 @@ impl CommandTarget {
|
|||
sample_count,
|
||||
encoder,
|
||||
);
|
||||
|
||||
(
|
||||
frame_buffer,
|
||||
Some(ResolveBuffer::new_manual(texture.clone())),
|
||||
)
|
||||
} else {
|
||||
// If multisampling is disabled, we don't need a resolve buffer.
|
||||
// We can just use our existing texture as the frame buffer.
|
||||
(FrameBuffer::new_manual(texture.clone(), size), None)
|
||||
encoder.copy_texture_to_texture(
|
||||
texture.as_image_copy(),
|
||||
frame_buffer.texture().as_image_copy(),
|
||||
size,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Self {
|
||||
frame_buffer,
|
||||
|
|
Loading…
Reference in New Issue