diff --git a/src/nouveau/nil/image.rs b/src/nouveau/nil/image.rs index 55dcad71925..596bd7cb65c 100644 --- a/src/nouveau/nil/image.rs +++ b/src/nouveau/nil/image.rs @@ -10,6 +10,8 @@ use crate::Minify; use nil_rs_bindings::*; use nvidia_headers::classes::{cl9097, clc597}; +use std::panic; + pub const MAX_LEVELS: usize = 16; pub type ImageUsageFlags = u8; @@ -186,24 +188,40 @@ pub struct Image { impl Image { #[no_mangle] - pub extern "C" fn nil_image_new( + pub extern "C" fn nil_image_init( dev: &nil_rs_bindings::nv_device_info, + image_out: *mut Self, info: &ImageInitInfo, - ) -> Self { - Self::new(dev, std::slice::from_ref(info), 0) + ) -> bool { + panic::catch_unwind(|| { + let image = Self::new(dev, std::slice::from_ref(info), 0); + unsafe { + assert!(!image_out.is_null()); + image_out.write(image); + } + }) + .is_ok() } #[no_mangle] - pub extern "C" fn nil_image_new_planar( + pub extern "C" fn nil_image_init_planar( dev: &nil_rs_bindings::nv_device_info, + image_out: *mut Self, info: *const ImageInitInfo, plane: usize, plane_count: usize, - ) -> Self { - assert!(plane < plane_count); - let infos = unsafe { std::slice::from_raw_parts(info, plane_count) }; - - Self::new(dev, infos, plane) + ) -> bool { + panic::catch_unwind(|| { + assert!(plane < plane_count); + let infos = + unsafe { std::slice::from_raw_parts(info, plane_count) }; + let image = Self::new(dev, infos, plane); + unsafe { + assert!(!image_out.is_null()); + image_out.write(image); + } + }) + .is_ok() } fn new_linear( diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index e036605aa8f..45efc576418 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -861,8 +861,12 @@ nvk_image_init(struct nvk_device *dev, .samples = image->vk.samples, .usage = usage & ~NIL_IMAGE_USAGE_LINEAR_BIT, }; - image->linear_tiled_shadow.nil = - nil_image_new(&pdev->info, &tiled_shadow_nil_info); + bool ok = nil_image_init(&pdev->info, + &image->linear_tiled_shadow.nil, + &tiled_shadow_nil_info); + if (!ok) + return vk_errorf(dev, VK_ERROR_UNKNOWN, + "Invalid image creation parameters"); } } @@ -903,13 +907,22 @@ nvk_image_init(struct nvk_device *dev, if (usage & NIL_IMAGE_USAGE_VIDEO_BIT) { assert(!image->disjoint); for (uint8_t plane = 0; plane < image->plane_count; plane++) { - image->planes[plane].nil = - nil_image_new_planar(&pdev->info, nil_info, plane, image->plane_count); + bool ok = nil_image_init_planar(&pdev->info, + &image->planes[plane].nil, + nil_info, plane, + image->plane_count); + if (!ok) + return vk_errorf(dev, VK_ERROR_UNKNOWN, + "Invalid image creation parameters"); } } else { for (uint8_t plane = 0; plane < image->plane_count; plane++) { - image->planes[plane].nil = - nil_image_new(&pdev->info, &nil_info[plane]); + bool ok = nil_image_init(&pdev->info, + &image->planes[plane].nil, + &nil_info[plane]); + if (!ok) + return vk_errorf(dev, VK_ERROR_UNKNOWN, + "Invalid image creation parameters"); } } @@ -929,8 +942,12 @@ nvk_image_init(struct nvk_device *dev, .usage = usage, }; - image->stencil_copy_temp.nil = - nil_image_new(&pdev->info, &stencil_nil_info); + bool ok = nil_image_init(&pdev->info, + &image->stencil_copy_temp.nil, + &stencil_nil_info); + if (!ok) + return vk_errorf(dev, VK_ERROR_UNKNOWN, + "Invalid image creation parameters"); } return VK_SUCCESS;