wgpu: Avoid panics when attempting to create a texture larger than the device supports
This commit is contained in:
parent
ef4a955e65
commit
cebe11ee38
|
@ -107,7 +107,8 @@ fn take_screenshot(
|
|||
.unwrap_or_else(|| movie.height().to_pixels());
|
||||
let height = (height * size.scale).round() as u32;
|
||||
|
||||
let target = TextureTarget::new(&descriptors.device, (width, height));
|
||||
let target = TextureTarget::new(&descriptors.device, (width, height))
|
||||
.map_err(|e| anyhow!(e.to_string()))?;
|
||||
let player = PlayerBuilder::new()
|
||||
.with_renderer(
|
||||
WgpuRenderBackend::new(descriptors, target).map_err(|e| anyhow!(e.to_string()))?,
|
||||
|
|
|
@ -395,7 +395,7 @@ impl WgpuRenderBackend<target::TextureTarget> {
|
|||
power_preference,
|
||||
trace_path,
|
||||
))?;
|
||||
let target = target::TextureTarget::new(&descriptors.device, size);
|
||||
let target = target::TextureTarget::new(&descriptors.device, size)?;
|
||||
Self::new(Arc::new(descriptors), target)
|
||||
}
|
||||
|
||||
|
@ -406,6 +406,18 @@ impl WgpuRenderBackend<target::TextureTarget> {
|
|||
|
||||
impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||
pub fn new(descriptors: Arc<Descriptors>, target: T) -> Result<Self, Error> {
|
||||
if target.width() > descriptors.limits.max_texture_dimension_2d
|
||||
|| target.height() > descriptors.limits.max_texture_dimension_2d
|
||||
{
|
||||
return Err(format!(
|
||||
"Render target texture cannot be larger than {}px on either dimension (requested {} x {})",
|
||||
descriptors.limits.max_texture_dimension_2d,
|
||||
target.width(),
|
||||
target.height()
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let extent = wgpu::Extent3d {
|
||||
width: target.width(),
|
||||
height: target.height(),
|
||||
|
@ -772,6 +784,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
|||
impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||
fn set_viewport_dimensions(&mut self, width: u32, height: u32) {
|
||||
// Avoid panics from creating 0-sized framebuffers.
|
||||
// TODO: find a way to bubble an error when the size is too large
|
||||
let width = std::cmp::max(width, 1);
|
||||
let height = std::cmp::max(height, 1);
|
||||
|
||||
|
@ -1370,6 +1383,18 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
}
|
||||
|
||||
fn register_bitmap(&mut self, bitmap: Bitmap) -> Result<BitmapHandle, Error> {
|
||||
if bitmap.width() > self.descriptors.limits.max_texture_dimension_2d
|
||||
|| bitmap.height() > self.descriptors.limits.max_texture_dimension_2d
|
||||
{
|
||||
return Err(format!(
|
||||
"Bitmap texture cannot be larger than {}px on either dimension (requested {} x {})",
|
||||
self.descriptors.limits.max_texture_dimension_2d,
|
||||
bitmap.width(),
|
||||
bitmap.height()
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
let bitmap = bitmap.to_rgba();
|
||||
let extent = wgpu::Extent3d {
|
||||
width: bitmap.width(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#[cfg(not(target_family = "wasm"))]
|
||||
use crate::utils::BufferDimensions;
|
||||
use crate::Error;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait RenderTargetFrame: Debug {
|
||||
|
@ -130,7 +131,18 @@ impl RenderTargetFrame for TextureTargetFrame {
|
|||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
impl TextureTarget {
|
||||
pub fn new(device: &wgpu::Device, size: (u32, u32)) -> Self {
|
||||
pub fn new(device: &wgpu::Device, size: (u32, u32)) -> Result<Self, Error> {
|
||||
if size.0 > device.limits().max_texture_dimension_2d
|
||||
|| size.1 > device.limits().max_texture_dimension_2d
|
||||
{
|
||||
return Err(format!(
|
||||
"Texture target cannot be larger than {}px on either dimension (requested {} x {})",
|
||||
device.limits().max_texture_dimension_2d,
|
||||
size.0,
|
||||
size.1
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let buffer_dimensions = BufferDimensions::new(size.0 as usize, size.1 as usize);
|
||||
let size = wgpu::Extent3d {
|
||||
width: size.0,
|
||||
|
@ -156,13 +168,13 @@ impl TextureTarget {
|
|||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
Self {
|
||||
Ok(Self {
|
||||
size,
|
||||
texture,
|
||||
format,
|
||||
buffer,
|
||||
buffer_dimensions,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn capture(&self, device: &wgpu::Device) -> Option<image::RgbaImage> {
|
||||
|
@ -204,6 +216,7 @@ impl RenderTarget for TextureTarget {
|
|||
type Frame = TextureTargetFrame;
|
||||
|
||||
fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) {
|
||||
// TODO: find a way to bubble an error when the size is too large
|
||||
self.size.width = width;
|
||||
self.size.height = height;
|
||||
|
||||
|
|
|
@ -1232,7 +1232,7 @@ fn run_swf(
|
|||
movie.width().to_pixels() as u32,
|
||||
movie.height().to_pixels() as u32,
|
||||
),
|
||||
);
|
||||
)?;
|
||||
|
||||
builder = builder
|
||||
.with_renderer(WgpuRenderBackend::new(Arc::new(descriptors), target)?)
|
||||
|
|
Loading…
Reference in New Issue