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());
|
.unwrap_or_else(|| movie.height().to_pixels());
|
||||||
let height = (height * size.scale).round() as u32;
|
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()
|
let player = PlayerBuilder::new()
|
||||||
.with_renderer(
|
.with_renderer(
|
||||||
WgpuRenderBackend::new(descriptors, target).map_err(|e| anyhow!(e.to_string()))?,
|
WgpuRenderBackend::new(descriptors, target).map_err(|e| anyhow!(e.to_string()))?,
|
||||||
|
|
|
@ -395,7 +395,7 @@ impl WgpuRenderBackend<target::TextureTarget> {
|
||||||
power_preference,
|
power_preference,
|
||||||
trace_path,
|
trace_path,
|
||||||
))?;
|
))?;
|
||||||
let target = target::TextureTarget::new(&descriptors.device, size);
|
let target = target::TextureTarget::new(&descriptors.device, size)?;
|
||||||
Self::new(Arc::new(descriptors), target)
|
Self::new(Arc::new(descriptors), target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,6 +406,18 @@ impl WgpuRenderBackend<target::TextureTarget> {
|
||||||
|
|
||||||
impl<T: RenderTarget> WgpuRenderBackend<T> {
|
impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
pub fn new(descriptors: Arc<Descriptors>, target: T) -> Result<Self, Error> {
|
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 {
|
let extent = wgpu::Extent3d {
|
||||||
width: target.width(),
|
width: target.width(),
|
||||||
height: target.height(),
|
height: target.height(),
|
||||||
|
@ -772,6 +784,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
fn set_viewport_dimensions(&mut self, width: u32, height: u32) {
|
fn set_viewport_dimensions(&mut self, width: u32, height: u32) {
|
||||||
// Avoid panics from creating 0-sized framebuffers.
|
// 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 width = std::cmp::max(width, 1);
|
||||||
let height = std::cmp::max(height, 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> {
|
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 bitmap = bitmap.to_rgba();
|
||||||
let extent = wgpu::Extent3d {
|
let extent = wgpu::Extent3d {
|
||||||
width: bitmap.width(),
|
width: bitmap.width(),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
use crate::utils::BufferDimensions;
|
use crate::utils::BufferDimensions;
|
||||||
|
use crate::Error;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait RenderTargetFrame: Debug {
|
pub trait RenderTargetFrame: Debug {
|
||||||
|
@ -130,7 +131,18 @@ impl RenderTargetFrame for TextureTargetFrame {
|
||||||
|
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
impl TextureTarget {
|
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 buffer_dimensions = BufferDimensions::new(size.0 as usize, size.1 as usize);
|
||||||
let size = wgpu::Extent3d {
|
let size = wgpu::Extent3d {
|
||||||
width: size.0,
|
width: size.0,
|
||||||
|
@ -156,13 +168,13 @@ impl TextureTarget {
|
||||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
|
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
});
|
});
|
||||||
Self {
|
Ok(Self {
|
||||||
size,
|
size,
|
||||||
texture,
|
texture,
|
||||||
format,
|
format,
|
||||||
buffer,
|
buffer,
|
||||||
buffer_dimensions,
|
buffer_dimensions,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capture(&self, device: &wgpu::Device) -> Option<image::RgbaImage> {
|
pub fn capture(&self, device: &wgpu::Device) -> Option<image::RgbaImage> {
|
||||||
|
@ -204,6 +216,7 @@ impl RenderTarget for TextureTarget {
|
||||||
type Frame = TextureTargetFrame;
|
type Frame = TextureTargetFrame;
|
||||||
|
|
||||||
fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) {
|
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.width = width;
|
||||||
self.size.height = height;
|
self.size.height = height;
|
||||||
|
|
||||||
|
|
|
@ -1232,7 +1232,7 @@ fn run_swf(
|
||||||
movie.width().to_pixels() as u32,
|
movie.width().to_pixels() as u32,
|
||||||
movie.height().to_pixels() as u32,
|
movie.height().to_pixels() as u32,
|
||||||
),
|
),
|
||||||
);
|
)?;
|
||||||
|
|
||||||
builder = builder
|
builder = builder
|
||||||
.with_renderer(WgpuRenderBackend::new(Arc::new(descriptors), target)?)
|
.with_renderer(WgpuRenderBackend::new(Arc::new(descriptors), target)?)
|
||||||
|
|
Loading…
Reference in New Issue