Update naga with new image API

This commit is contained in:
Dzmitry Malyshau 2020-09-10 17:45:54 -04:00
parent f6f7210b63
commit 6a3c106cc4
4 changed files with 109 additions and 46 deletions

2
Cargo.lock generated
View File

@ -836,7 +836,7 @@ dependencies = [
[[package]] [[package]]
name = "naga" name = "naga"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/gfx-rs/naga?rev=bd9efe5915e548b9a2ec1f3d3e9296c90b31e69a#bd9efe5915e548b9a2ec1f3d3e9296c90b31e69a" source = "git+https://github.com/gfx-rs/naga?rev=b278e10ea7c144b2387585c4e81c1d86db8e2def#b278e10ea7c144b2387585c4e81c1d86db8e2def"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"fxhash", "fxhash",

View File

@ -40,8 +40,8 @@ gfx-memory = "0.2"
[dependencies.naga] [dependencies.naga]
version = "0.2" version = "0.2"
git = "https://github.com/gfx-rs/naga" git = "https://github.com/gfx-rs/naga"
rev = "bd9efe5915e548b9a2ec1f3d3e9296c90b31e69a" rev = "b278e10ea7c144b2387585c4e81c1d86db8e2def"
features = ["spirv-in", "spirv-out"] features = ["spirv-in", "spirv-out", "wgsl-in"]
[dependencies.wgt] [dependencies.wgt]
path = "../wgpu-types" path = "../wgpu-types"

View File

@ -2726,7 +2726,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.with_label(&desc.label)); .with_label(&desc.label));
} }
if rasterization_state.polygon_mode != wgt::PolygonMode::Fill if rasterization_state.polygon_mode != wgt::PolygonMode::Fill
&& !device.features.contains(wgt::Features::NON_FILL_POLYGON_MODE) && !device
.features
.contains(wgt::Features::NON_FILL_POLYGON_MODE)
{ {
return Err(pipeline::CreateRenderPipelineError::MissingFeature( return Err(pipeline::CreateRenderPipelineError::MissingFeature(
wgt::Features::NON_FILL_POLYGON_MODE, wgt::Features::NON_FILL_POLYGON_MODE,
@ -2819,7 +2821,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
module, module,
group_layouts, group_layouts,
&entry_point_name, &entry_point_name,
naga::ShaderStage::Vertex, flag,
interface, interface,
) )
.map_err(|error| { .map_err(|error| {
@ -2868,7 +2870,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
module, module,
group_layouts, group_layouts,
&entry_point_name, &entry_point_name,
naga::ShaderStage::Fragment, flag,
interface, interface,
) )
.map_err(|error| { .map_err(|error| {
@ -3172,6 +3174,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
) )
})?; })?;
let flag = wgt::ShaderStage::COMPUTE;
if let Some(ref module) = shader_module.module { if let Some(ref module) = shader_module.module {
let group_layouts = match desc.layout { let group_layouts = match desc.layout {
Some(pipeline_layout_id) => Device::get_introspection_bind_group_layouts( Some(pipeline_layout_id) => Device::get_introspection_bind_group_layouts(
@ -3193,14 +3196,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
module, module,
group_layouts, group_layouts,
&entry_point_name, &entry_point_name,
naga::ShaderStage::Compute, flag,
interface, interface,
) )
.map_err(pipeline::CreateComputePipelineError::Stage)?; .map_err(pipeline::CreateComputePipelineError::Stage)?;
} else if desc.layout.is_none() { } else if desc.layout.is_none() {
Err(pipeline::ImplicitLayoutError::ReflectionError( Err(pipeline::ImplicitLayoutError::ReflectionError(flag))?
wgt::ShaderStage::COMPUTE,
))?
} }
let shader = hal::pso::EntryPoint::<B> { let shader = hal::pso::EntryPoint::<B> {

View File

@ -79,8 +79,8 @@ pub enum BindingError {
WrongSamplerComparison, WrongSamplerComparison,
#[error("derived bind group layout type is not consistent between stages")] #[error("derived bind group layout type is not consistent between stages")]
InconsistentlyDerivedType, InconsistentlyDerivedType,
#[error("texture format {0:?} isn't recognized")] #[error("texture format {0:?} is not supported for storage use")]
UnknownStorageFormat(wgt::TextureFormat), BadStorageFormat(wgt::TextureFormat),
} }
#[derive(Clone, Debug, Error)] #[derive(Clone, Debug, Error)]
@ -96,8 +96,8 @@ pub enum InputError {
pub enum StageError { pub enum StageError {
#[error("shader module is invalid")] #[error("shader module is invalid")]
InvalidModule, InvalidModule,
#[error("unable to find an entry point matching the {0:?} execution model")] #[error("unable to find an entry point at {0:?} stage")]
MissingEntryPoint(naga::ShaderStage), MissingEntryPoint(wgt::ShaderStage),
#[error("error matching global binding at index {binding} in set {set} against the pipeline layout: {error}")] #[error("error matching global binding at index {binding} in set {set} against the pipeline layout: {error}")]
Binding { Binding {
set: u32, set: u32,
@ -170,6 +170,70 @@ fn get_aligned_type_size(
} }
} }
fn map_storage_format_to_naga(format: wgt::TextureFormat) -> Option<naga::StorageFormat> {
use naga::StorageFormat as Sf;
use wgt::TextureFormat as Tf;
// Using the table in https://gpuweb.github.io/gpuweb/#plain-color-formats
Some(match format {
Tf::R32Uint => Sf::R32Uint,
Tf::R32Sint => Sf::R32Sint,
Tf::R32Float => Sf::R32Float,
Tf::Rgba8Unorm => Sf::Rgba8Unorm,
Tf::Rgba8Snorm => Sf::Rgba8Snorm,
Tf::Rgba8Uint => Sf::Rgba8Uint,
Tf::Rgba8Sint => Sf::Rgba8Sint,
Tf::Rg32Uint => Sf::Rg32Uint,
Tf::Rg32Sint => Sf::Rg32Sint,
Tf::Rg32Float => Sf::Rg32Float,
Tf::Rgba16Uint => Sf::Rgba16Uint,
Tf::Rgba16Sint => Sf::Rgba16Sint,
Tf::Rgba16Float => Sf::Rgba16Float,
Tf::Rgba32Uint => Sf::Rgba32Uint,
Tf::Rgba32Sint => Sf::Rgba32Sint,
Tf::Rgba32Float => Sf::Rgba32Float,
_ => return None,
})
}
fn map_storage_format_from_naga(format: naga::StorageFormat) -> wgt::TextureFormat {
use naga::StorageFormat as Sf;
use wgt::TextureFormat as Tf;
match format {
Sf::R8Unorm => Tf::R8Unorm,
Sf::R8Snorm => Tf::R8Snorm,
Sf::R8Uint => Tf::R8Uint,
Sf::R8Sint => Tf::R8Sint,
Sf::R16Uint => Tf::R16Uint,
Sf::R16Sint => Tf::R16Sint,
Sf::R16Float => Tf::R16Float,
Sf::Rg8Unorm => Tf::Rg8Unorm,
Sf::Rg8Snorm => Tf::Rg8Snorm,
Sf::Rg8Uint => Tf::Rg8Uint,
Sf::Rg8Sint => Tf::Rg8Sint,
Sf::R32Uint => Tf::R32Uint,
Sf::R32Sint => Tf::R32Sint,
Sf::R32Float => Tf::R32Float,
Sf::Rg16Uint => Tf::Rg16Uint,
Sf::Rg16Sint => Tf::Rg16Sint,
Sf::Rg16Float => Tf::Rg16Float,
Sf::Rgba8Unorm => Tf::Rgba8Unorm,
Sf::Rgba8Snorm => Tf::Rgba8Snorm,
Sf::Rgba8Uint => Tf::Rgba8Uint,
Sf::Rgba8Sint => Tf::Rgba8Sint,
Sf::Rgb10a2Unorm => Tf::Rgb10a2Unorm,
Sf::Rg11b10Float => Tf::Rg11b10Float,
Sf::Rg32Uint => Tf::Rg32Uint,
Sf::Rg32Sint => Tf::Rg32Sint,
Sf::Rg32Float => Tf::Rg32Float,
Sf::Rgba16Uint => Tf::Rgba16Uint,
Sf::Rgba16Sint => Tf::Rgba16Sint,
Sf::Rgba16Float => Tf::Rgba16Float,
Sf::Rgba32Uint => Tf::Rgba32Uint,
Sf::Rgba32Sint => Tf::Rgba32Sint,
Sf::Rgba32Float => Tf::Rgba32Float,
}
}
fn check_binding_use( fn check_binding_use(
module: &naga::Module, module: &naga::Module,
var: &naga::GlobalVariable, var: &naga::GlobalVariable,
@ -259,7 +323,7 @@ fn check_binding_use(
} }
} }
} }
let expected_class = match entry.ty { let (expected_class, usage) = match entry.ty {
BindingType::SampledTexture { BindingType::SampledTexture {
dimension: _, dimension: _,
component_type, component_type,
@ -279,29 +343,28 @@ fn check_binding_use(
shader: kind, shader: kind,
}); });
} }
if multisampled { let class = if multisampled {
naga::ImageClass::Multisampled naga::ImageClass::Multisampled
} else if comparison { } else if comparison {
naga::ImageClass::Depth naga::ImageClass::Depth
} else { } else {
naga::ImageClass::Sampled naga::ImageClass::Sampled
} };
(class, naga::GlobalUse::LOAD)
} }
BindingType::StorageTexture { BindingType::StorageTexture {
readonly, readonly,
format, format,
dimension: _, dimension: _,
} => { } => {
let naga_format = match format { let naga_format = map_storage_format_to_naga(format)
wgt::TextureFormat::Rgba32Float => naga::StorageFormat::Rgba32f, .ok_or(BindingError::BadStorageFormat(format))?;
_ => return Err(BindingError::UnknownStorageFormat(format)), let usage = if readonly {
}; naga::GlobalUse::LOAD
let access = if readonly {
naga::StorageAccess::LOAD
} else { } else {
naga::StorageAccess::STORE naga::GlobalUse::STORE
}; };
naga::ImageClass::Storage(naga_format, access) (naga::ImageClass::Storage(naga_format), usage)
} }
_ => return Err(BindingError::WrongType), _ => return Err(BindingError::WrongType),
}; };
@ -311,14 +374,7 @@ fn check_binding_use(
shader: class, shader: class,
}); });
} }
Ok(match class { Ok(usage)
naga::ImageClass::Storage(_, access)
if access.contains(naga::StorageAccess::STORE) =>
{
naga::GlobalUse::STORE
}
_ => naga::GlobalUse::LOAD,
})
} }
_ => Err(BindingError::WrongType), _ => Err(BindingError::WrongType),
} }
@ -747,7 +803,7 @@ fn derive_binding_type(
naga::StorageClass::StorageBuffer => BindingType::StorageBuffer { naga::StorageClass::StorageBuffer => BindingType::StorageBuffer {
dynamic, dynamic,
min_binding_size: wgt::BufferSize::new(actual_size), min_binding_size: wgt::BufferSize::new(actual_size),
readonly: !usage.contains(naga::GlobalUse::STORE), //TODO: clarify readonly: !usage.contains(naga::GlobalUse::STORE),
}, },
_ => return Err(BindingError::WrongType), _ => return Err(BindingError::WrongType),
} }
@ -789,12 +845,16 @@ fn derive_binding_type(
component_type: wgt::TextureComponentType::DepthComparison, component_type: wgt::TextureComponentType::DepthComparison,
multisampled: false, multisampled: false,
}, },
naga::ImageClass::Storage(format, access) => BindingType::StorageTexture { naga::ImageClass::Storage(format) => BindingType::StorageTexture {
dimension, dimension,
format: match format { format: {
naga::StorageFormat::Rgba32f => wgt::TextureFormat::Rgba32Float, let f = map_storage_format_from_naga(format);
let original = map_storage_format_to_naga(f)
.ok_or(BindingError::BadStorageFormat(f))?;
debug_assert_eq!(format, original);
f
}, },
readonly: !access.contains(naga::StorageAccess::STORE), readonly: !usage.contains(naga::GlobalUse::STORE),
}, },
} }
} }
@ -806,7 +866,7 @@ pub fn check_stage<'a>(
module: &'a naga::Module, module: &'a naga::Module,
mut group_layouts: IntrospectionBindGroupLayouts, mut group_layouts: IntrospectionBindGroupLayouts,
entry_point_name: &str, entry_point_name: &str,
stage: naga::ShaderStage, stage_bit: wgt::ShaderStage,
inputs: StageInterface<'a>, inputs: StageInterface<'a>,
) -> Result<StageInterface<'a>, StageError> { ) -> Result<StageInterface<'a>, StageError> {
// Since a shader module can have multiple entry points with the same name, // Since a shader module can have multiple entry points with the same name,
@ -814,13 +874,15 @@ pub fn check_stage<'a>(
let entry_point = module let entry_point = module
.entry_points .entry_points
.iter() .iter()
.find(|entry_point| entry_point.name == entry_point_name && entry_point.stage == stage) .find(|entry_point| {
.ok_or(StageError::MissingEntryPoint(stage))?; entry_point.name == entry_point_name
let stage_bit = match stage { && stage_bit.contains(match entry_point.stage {
naga::ShaderStage::Vertex => wgt::ShaderStage::VERTEX, naga::ShaderStage::Vertex { .. } => wgt::ShaderStage::VERTEX,
naga::ShaderStage::Fragment => wgt::ShaderStage::FRAGMENT, naga::ShaderStage::Fragment { .. } => wgt::ShaderStage::FRAGMENT,
naga::ShaderStage::Compute => wgt::ShaderStage::COMPUTE, naga::ShaderStage::Compute { .. } => wgt::ShaderStage::COMPUTE,
}; })
})
.ok_or(StageError::MissingEntryPoint(stage_bit))?;
let function = &module.functions[entry_point.function]; let function = &module.functions[entry_point.function];
let mut outputs = StageInterface::default(); let mut outputs = StageInterface::default();