diff --git a/src/nouveau/nil/cbindgen.toml b/src/nouveau/nil/cbindgen.toml index ca48d17961a..af0cd99fa16 100644 --- a/src/nouveau/nil/cbindgen.toml +++ b/src/nouveau/nil/cbindgen.toml @@ -33,6 +33,7 @@ renaming_overrides_prefixing = true "SuInfo" = "nil_su_info" "Tiling" = "nil_tiling" "View" = "nil_view" +"ViewAccess" = "nil_view_access" "ViewType" = "nil_view_type" # There's just no good solution for this one diff --git a/src/nouveau/nil/descriptor.rs b/src/nouveau/nil/descriptor.rs index 0081ba15486..1dd966ec110 100644 --- a/src/nouveau/nil/descriptor.rs +++ b/src/nouveau/nil/descriptor.rs @@ -22,11 +22,7 @@ use std::ops::Range; use crate::extent::{units, Extent4D}; use crate::format::Format; -use crate::image::Image; -use crate::image::ImageDim; -use crate::image::SampleLayout; -use crate::image::View; -use crate::image::ViewType; +use crate::image::{Image, ImageDim, SampleLayout, View, ViewAccess, ViewType}; macro_rules! set_enum { ($th:expr, $cls:ident, $field:ident, $enum:ident) => { @@ -922,6 +918,9 @@ impl Descriptor { &mut desc.bits, ); } else if dev.cls_eng3d >= FERMI_A { + // Kepler and earlier doesn't support surface access through + // conventional image descriptors + assert_eq!(view.access, ViewAccess::Texture); nv9097_fill_image_view_desc( image, view, diff --git a/src/nouveau/nil/image.rs b/src/nouveau/nil/image.rs index 933cea1cdd9..1062f324724 100644 --- a/src/nouveau/nil/image.rs +++ b/src/nouveau/nil/image.rs @@ -975,11 +975,26 @@ pub enum ViewType { CubeArray, } +/// An enum describing how an image view will be accessed by the shader. +#[allow(dead_code)] +#[derive(Clone, Debug, Copy, PartialEq)] +#[repr(u8)] +pub enum ViewAccess { + /// This image view will be accessed via texture instructions (tex, etc.) + Texture, + + /// This image view will be accessed as a storage image via surface + /// instructions (suld/sust) + Storage, +} + #[repr(C)] #[derive(Debug, Clone, PartialEq)] pub struct View { pub view_type: ViewType, + pub access: ViewAccess, + /// The format to use in the view /// /// This may differ from the format of the actual isl_surf but must have the diff --git a/src/nouveau/nil/su_info.rs b/src/nouveau/nil/su_info.rs index 03c8f8e5b93..37eb33957b3 100644 --- a/src/nouveau/nil/su_info.rs +++ b/src/nouveau/nil/su_info.rs @@ -6,7 +6,7 @@ use crate::format::Format; use crate::image::ViewType; -use crate::image::{Image, SampleLayout, View}; +use crate::image::{Image, SampleLayout, View, ViewAccess}; use bitview::{BitMutView, SetField}; use nil_rs_bindings::*; @@ -204,6 +204,7 @@ pub extern "C" fn nil_fill_su_info( view: &View, base_address: u64, ) -> SuInfo { + assert_eq!(view.access, ViewAccess::Storage); assert!(view.format.supports_storage(dev)); debug_assert!(image.align_B >= 256); let level = &image.levels[view.base_level as usize]; diff --git a/src/nouveau/vulkan/nvk_image_view.c b/src/nouveau/vulkan/nvk_image_view.c index e179010dbf9..69440ba409c 100644 --- a/src/nouveau/vulkan/nvk_image_view.c +++ b/src/nouveau/vulkan/nvk_image_view.c @@ -188,6 +188,7 @@ nvk_image_view_init(struct nvk_device *dev, if (view->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { + nil_view.access = NIL_VIEW_ACCESS_TEXTURE; const struct nil_descriptor desc = nil_image_view_descriptor(&pdev->info, &nil_image, &nil_view, base_addr); @@ -214,6 +215,8 @@ nvk_image_view_init(struct nvk_device *dev, } if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { + nil_view.access = NIL_VIEW_ACCESS_STORAGE; + /* For storage images, we can't have any cubes */ if (view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE || view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)