diff --git a/src/back/msl/writer.rs b/src/back/msl/writer.rs index 819a4f15f..97da4de05 100644 --- a/src/back/msl/writer.rs +++ b/src/back/msl/writer.rs @@ -2428,7 +2428,7 @@ fn test_stack_size() { let stack_size = addresses.end - addresses.start; // check the size (in debug only) // last observed macOS value: 17664 - if stack_size < 17000 || stack_size > 19000 { + if stack_size < 14000 || stack_size > 19000 { panic!("`put_expression` stack size {} has changed!", stack_size); } } @@ -2443,7 +2443,7 @@ fn test_stack_size() { let stack_size = addresses.end - addresses.start; // check the size (in debug only) // last observed macOS value: 13600 - if stack_size < 12000 || stack_size > 14500 { + if stack_size < 11000 || stack_size > 14500 { panic!("`put_block` stack size {} has changed!", stack_size); } } diff --git a/src/back/spv/writer.rs b/src/back/spv/writer.rs index 763cd0a6a..176f5f491 100644 --- a/src/back/spv/writer.rs +++ b/src/back/spv/writer.rs @@ -283,7 +283,7 @@ pub struct Writer { logical_layout: LogicalLayout, id_gen: IdGenerator, capabilities: crate::FastHashSet, - strict_capabilities: bool, + forbidden_caps: Option<&'static [spirv::Capability]>, debugs: Vec, annotations: Vec, flags: WriterFlags, @@ -313,19 +313,22 @@ impl Writer { let gl450_ext_inst_id = id_gen.next(); let void_type = id_gen.next(); + let (capabilities, forbidden_caps) = match options.capabilities { + Some(ref caps) => (caps.clone(), None), + None => { + let mut caps = crate::FastHashSet::default(); + caps.insert(spirv::Capability::Shader); + let forbidden: &[_] = &[spirv::Capability::Kernel]; + (caps, Some(forbidden)) + } + }; + Ok(Writer { physical_layout: PhysicalLayout::new(raw_version), logical_layout: LogicalLayout::default(), id_gen, - capabilities: match options.capabilities { - Some(ref caps) => caps.clone(), - None => { - let mut caps = crate::FastHashSet::default(); - caps.insert(spirv::Capability::Shader); - caps - } - }, - strict_capabilities: options.capabilities.is_some(), + capabilities, + forbidden_caps, debugs: vec![], annotations: vec![], flags: options.flags, @@ -344,20 +347,21 @@ impl Writer { } fn check(&mut self, capabilities: &[spirv::Capability]) -> Result<(), Error> { - if self.strict_capabilities { - if capabilities.is_empty() - || capabilities - .iter() - .any(|cap| self.capabilities.contains(cap)) - { - Ok(()) - } else { - Err(Error::MissingCapabilities(capabilities.to_vec())) - } - } else { - self.capabilities.extend(capabilities); - Ok(()) + if capabilities.is_empty() + || capabilities + .iter() + .any(|cap| self.capabilities.contains(cap)) + { + return Ok(()); } + if let Some(forbidden) = self.forbidden_caps { + // take the first allowed capability, blindly + if let Some(&cap) = capabilities.iter().find(|cap| !forbidden.contains(cap)) { + self.capabilities.insert(cap); + return Ok(()); + } + } + Err(Error::MissingCapabilities(capabilities.to_vec())) } fn get_type_id( @@ -887,7 +891,15 @@ impl Writer { let kind = match class { crate::ImageClass::Sampled { kind, multi: _ } => kind, crate::ImageClass::Depth => crate::ScalarKind::Float, - crate::ImageClass::Storage(format) => format.into(), + crate::ImageClass::Storage(format) => { + let required_caps: &[_] = match dim { + crate::ImageDimension::D1 => &[spirv::Capability::Image1D], + crate::ImageDimension::Cube => &[spirv::Capability::ImageCubeArray], + _ => &[], + }; + self.check(required_caps)?; + format.into() + } }; let local_type = LocalType::Value { vector_size: None, @@ -895,9 +907,9 @@ impl Writer { width: 4, pointer_class: None, }; - let type_id = self.get_type_id(arena, LookupType::Local(local_type))?; let dim = map_dim(dim); self.check(dim.required_capabilities())?; + let type_id = self.get_type_id(arena, LookupType::Local(local_type))?; Instruction::type_image(id, type_id, dim, arrayed, class) } crate::TypeInner::Sampler { comparison: _ } => Instruction::type_sampler(id), @@ -2212,6 +2224,8 @@ impl Writer { } }; + self.check(&[spirv::Capability::ImageQuery])?; + match query { Iq::Size { level } => { let dim_coords = match dim { @@ -2248,6 +2262,7 @@ impl Writer { (spirv::Op::ImageQuerySizeLod, Some(level_id)) } }; + // The ID of the vector returned by SPIR-V, which contains the dimensions // as well as the layer count. let id_extended = self.id_gen.next(); diff --git a/tests/in/access.param.ron b/tests/in/access.param.ron index e8c788d60..f7084220b 100644 --- a/tests/in/access.param.ron +++ b/tests/in/access.param.ron @@ -1,6 +1,5 @@ ( spv_version: (1, 1), - spv_capabilities: [ Shader, Image1D, Sampled1D ], spv_debug: true, spv_adjust_coordinate_space: false, msl_custom: true, diff --git a/tests/in/boids.param.ron b/tests/in/boids.param.ron index 16021ec3b..25413d0c4 100644 --- a/tests/in/boids.param.ron +++ b/tests/in/boids.param.ron @@ -1,6 +1,5 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_debug: true, spv_adjust_coordinate_space: false, msl_custom: true, diff --git a/tests/in/collatz.param.ron b/tests/in/collatz.param.ron index 42c8480e4..6da4b84fd 100644 --- a/tests/in/collatz.param.ron +++ b/tests/in/collatz.param.ron @@ -1,5 +1,4 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_debug: true, ) diff --git a/tests/in/control-flow.param.ron b/tests/in/control-flow.param.ron index d6269ab62..bd7d7cc3e 100644 --- a/tests/in/control-flow.param.ron +++ b/tests/in/control-flow.param.ron @@ -1,4 +1,3 @@ ( spv_version: (1, 1), - spv_capabilities: [ Shader ], ) diff --git a/tests/in/empty.param.ron b/tests/in/empty.param.ron index d6269ab62..bd7d7cc3e 100644 --- a/tests/in/empty.param.ron +++ b/tests/in/empty.param.ron @@ -1,4 +1,3 @@ ( spv_version: (1, 1), - spv_capabilities: [ Shader ], ) diff --git a/tests/in/extra.param.ron b/tests/in/extra.param.ron index 1767cbe3f..a0c5c775e 100644 --- a/tests/in/extra.param.ron +++ b/tests/in/extra.param.ron @@ -1,5 +1,4 @@ ( god_mode: true, spv_version: (1, 0), - spv_capabilities: [ Shader ], ) diff --git a/tests/in/image.param.ron b/tests/in/image.param.ron index 703113755..aca18ab38 100644 --- a/tests/in/image.param.ron +++ b/tests/in/image.param.ron @@ -1,5 +1,4 @@ ( spv_version: (1, 1), - spv_capabilities: [ Shader, ImageQuery, Image1D, Sampled1D ], spv_debug: true, ) diff --git a/tests/in/operators.param.ron b/tests/in/operators.param.ron index 553f5e75f..8b306e5b7 100644 --- a/tests/in/operators.param.ron +++ b/tests/in/operators.param.ron @@ -1,4 +1,3 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], ) diff --git a/tests/in/quad-glsl.param.ron b/tests/in/quad-glsl.param.ron index c073cf1a5..a049e71aa 100644 --- a/tests/in/quad-glsl.param.ron +++ b/tests/in/quad-glsl.param.ron @@ -1,6 +1,5 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_debug: true, spv_adjust_coordinate_space: true, ) diff --git a/tests/in/quad.param.ron b/tests/in/quad.param.ron index c073cf1a5..a049e71aa 100644 --- a/tests/in/quad.param.ron +++ b/tests/in/quad.param.ron @@ -1,6 +1,5 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_debug: true, spv_adjust_coordinate_space: true, ) diff --git a/tests/in/shadow.param.ron b/tests/in/shadow.param.ron index c6b43089b..63926c63c 100644 --- a/tests/in/shadow.param.ron +++ b/tests/in/shadow.param.ron @@ -1,6 +1,5 @@ ( spv_version: (1, 2), - spv_capabilities: [ Shader ], spv_debug: true, spv_adjust_coordinate_space: true, ) diff --git a/tests/in/skybox.param.ron b/tests/in/skybox.param.ron index d4510ffcb..9a5bf7d2b 100644 --- a/tests/in/skybox.param.ron +++ b/tests/in/skybox.param.ron @@ -1,7 +1,6 @@ ( spv_flow_dump_prefix: "", spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_debug: false, spv_adjust_coordinate_space: false, msl_custom: true, diff --git a/tests/in/standard.param.ron b/tests/in/standard.param.ron index 1eb59329e..d6d9d69be 100644 --- a/tests/in/standard.param.ron +++ b/tests/in/standard.param.ron @@ -1,5 +1,4 @@ ( spv_version: (1, 0), - spv_capabilities: [ Shader ], spv_adjust_coordinate_space: false, ) diff --git a/tests/out/access.spvasm b/tests/out/access.spvasm index 894968b5f..2f5c21665 100644 --- a/tests/out/access.spvasm +++ b/tests/out/access.spvasm @@ -2,9 +2,7 @@ ; Version: 1.1 ; Generator: rspirv ; Bound: 49 -OpCapability Image1D OpCapability Shader -OpCapability Sampled1D OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 diff --git a/tests/out/image.spvasm b/tests/out/image.spvasm index e0cac29d4..08d1f5a8e 100644 --- a/tests/out/image.spvasm +++ b/tests/out/image.spvasm @@ -2,10 +2,9 @@ ; Version: 1.1 ; Generator: rspirv ; Bound: 127 -OpCapability ImageQuery OpCapability Image1D OpCapability Shader -OpCapability Sampled1D +OpCapability ImageQuery %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %43 "main" %40 diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 8882f9600..b7410e416 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -26,6 +26,7 @@ struct Parameters { #[cfg_attr(not(feature = "spv-out"), allow(dead_code))] spv_version: (u8, u8), #[cfg_attr(not(feature = "spv-out"), allow(dead_code))] + #[serde(default)] spv_capabilities: naga::FastHashSet, #[cfg_attr(not(feature = "spv-out"), allow(dead_code))] #[serde(default)] @@ -139,7 +140,11 @@ fn check_output_spv( let options = spv::Options { lang_version: params.spv_version, flags, - capabilities: Some(params.spv_capabilities.clone()), + capabilities: if params.spv_capabilities.is_empty() { + None + } else { + Some(params.spv_capabilities.clone()) + }, }; let spv = spv::write_vec(module, info, &options).unwrap();