mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
[naga spv-out] Add f16 io polyfill (#7884)
This commit is contained in:
parent
2996c926d4
commit
4b5e38ab49
@ -104,6 +104,7 @@ This allows using precompiled shaders without manually checking which backend's
|
||||
|
||||
- Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950).
|
||||
- If the shader source contains control characters, Naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049).
|
||||
- Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884).
|
||||
|
||||
#### DX12
|
||||
|
||||
|
||||
@ -237,7 +237,7 @@ impl Writer {
|
||||
}
|
||||
};
|
||||
|
||||
body.push(Instruction::store(res_member.id, member_value_id, None));
|
||||
self.store_io_with_f16_polyfill(body, res_member.id, member_value_id);
|
||||
|
||||
match res_member.built_in {
|
||||
Some(crate::BuiltIn::Position { .. })
|
||||
|
||||
104
naga/src/back/spv/f16_polyfill.rs
Normal file
104
naga/src/back/spv/f16_polyfill.rs
Normal file
@ -0,0 +1,104 @@
|
||||
/*!
|
||||
This module provides functionality for polyfilling `f16` input/output variables
|
||||
when the `StorageInputOutput16` capability is not available or disabled.
|
||||
|
||||
It works by:
|
||||
|
||||
1. Declaring `f16` I/O variables as `f32` in SPIR-V
|
||||
2. Converting between `f16` and `f32` at runtime using `OpFConvert`
|
||||
3. Maintaining mappings to track which variables need conversion
|
||||
*/
|
||||
|
||||
use crate::back::spv::{Instruction, LocalType, NumericType, Word};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Manages `f16` I/O polyfill state and operations.
|
||||
#[derive(Default)]
|
||||
pub(in crate::back::spv) struct F16IoPolyfill {
|
||||
use_native: bool,
|
||||
io_var_to_f32_type: crate::FastHashMap<Word, Word>,
|
||||
}
|
||||
|
||||
impl F16IoPolyfill {
|
||||
pub fn new(use_storage_input_output_16: bool) -> Self {
|
||||
Self {
|
||||
use_native: use_storage_input_output_16,
|
||||
io_var_to_f32_type: crate::FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn needs_polyfill(&self, ty_inner: &crate::TypeInner) -> bool {
|
||||
use crate::{ScalarKind as Sk, TypeInner};
|
||||
|
||||
!self.use_native
|
||||
&& match *ty_inner {
|
||||
TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => true,
|
||||
TypeInner::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float && scalar.width == 2 =>
|
||||
{
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_io_var(&mut self, variable_id: Word, f32_type_id: Word) {
|
||||
self.io_var_to_f32_type.insert(variable_id, f32_type_id);
|
||||
}
|
||||
|
||||
pub fn get_f32_io_type(&self, variable_id: Word) -> Option<Word> {
|
||||
self.io_var_to_f32_type.get(&variable_id).copied()
|
||||
}
|
||||
|
||||
pub fn emit_f16_to_f32_conversion(
|
||||
f16_value_id: Word,
|
||||
f32_type_id: Word,
|
||||
converted_id: Word,
|
||||
body: &mut Vec<Instruction>,
|
||||
) {
|
||||
body.push(Instruction::unary(
|
||||
spirv::Op::FConvert,
|
||||
f32_type_id,
|
||||
converted_id,
|
||||
f16_value_id,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn emit_f32_to_f16_conversion(
|
||||
f32_value_id: Word,
|
||||
f16_type_id: Word,
|
||||
converted_id: Word,
|
||||
body: &mut Vec<Instruction>,
|
||||
) {
|
||||
body.push(Instruction::unary(
|
||||
spirv::Op::FConvert,
|
||||
f16_type_id,
|
||||
converted_id,
|
||||
f32_value_id,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn create_polyfill_type(ty_inner: &crate::TypeInner) -> Option<LocalType> {
|
||||
use crate::{ScalarKind as Sk, TypeInner};
|
||||
|
||||
match *ty_inner {
|
||||
TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => {
|
||||
Some(LocalType::Numeric(NumericType::Scalar(crate::Scalar::F32)))
|
||||
}
|
||||
TypeInner::Vector { size, scalar } if scalar.kind == Sk::Float && scalar.width == 2 => {
|
||||
Some(LocalType::Numeric(NumericType::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar::F32,
|
||||
}))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::back::spv::recyclable::Recyclable for F16IoPolyfill {
|
||||
fn recycle(mut self) -> Self {
|
||||
self.io_var_to_f32_type = self.io_var_to_f32_type.recycle();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ Backend for [SPIR-V][spv] (Standard Portable Intermediate Representation).
|
||||
*/
|
||||
|
||||
mod block;
|
||||
mod f16_polyfill;
|
||||
mod helpers;
|
||||
mod image;
|
||||
mod index;
|
||||
@ -745,6 +746,7 @@ pub struct Writer {
|
||||
bounds_check_policies: BoundsCheckPolicies,
|
||||
zero_initialize_workgroup_memory: ZeroInitializeWorkgroupMemoryMode,
|
||||
force_loop_bounding: bool,
|
||||
use_storage_input_output_16: bool,
|
||||
void_type: Word,
|
||||
//TODO: convert most of these into vectors, addressable by handle indices
|
||||
lookup_type: crate::FastHashMap<LookupType, Word>,
|
||||
@ -771,6 +773,10 @@ pub struct Writer {
|
||||
|
||||
ray_get_committed_intersection_function: Option<Word>,
|
||||
ray_get_candidate_intersection_function: Option<Word>,
|
||||
|
||||
/// F16 I/O polyfill manager for handling `f16` input/output variables
|
||||
/// when `StorageInputOutput16` capability is not available.
|
||||
io_f16_polyfills: f16_polyfill::F16IoPolyfill,
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
@ -853,6 +859,10 @@ pub struct Options<'a> {
|
||||
/// to think the number of iterations is bounded.
|
||||
pub force_loop_bounding: bool,
|
||||
|
||||
/// Whether to use the `StorageInputOutput16` capability for `f16` shader I/O.
|
||||
/// When false, `f16` I/O is polyfilled using `f32` types with conversions.
|
||||
pub use_storage_input_output_16: bool,
|
||||
|
||||
pub debug_info: Option<DebugInfo<'a>>,
|
||||
}
|
||||
|
||||
@ -872,6 +882,7 @@ impl Default for Options<'_> {
|
||||
bounds_check_policies: BoundsCheckPolicies::default(),
|
||||
zero_initialize_workgroup_memory: ZeroInitializeWorkgroupMemoryMode::Polyfill,
|
||||
force_loop_bounding: true,
|
||||
use_storage_input_output_16: true,
|
||||
debug_info: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +78,7 @@ impl Writer {
|
||||
bounds_check_policies: options.bounds_check_policies,
|
||||
zero_initialize_workgroup_memory: options.zero_initialize_workgroup_memory,
|
||||
force_loop_bounding: options.force_loop_bounding,
|
||||
use_storage_input_output_16: options.use_storage_input_output_16,
|
||||
void_type,
|
||||
lookup_type: crate::FastHashMap::default(),
|
||||
lookup_function: crate::FastHashMap::default(),
|
||||
@ -92,6 +93,9 @@ impl Writer {
|
||||
temp_list: Vec::new(),
|
||||
ray_get_committed_intersection_function: None,
|
||||
ray_get_candidate_intersection_function: None,
|
||||
io_f16_polyfills: super::f16_polyfill::F16IoPolyfill::new(
|
||||
options.use_storage_input_output_16,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
@ -125,6 +129,7 @@ impl Writer {
|
||||
bounds_check_policies: self.bounds_check_policies,
|
||||
zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory,
|
||||
force_loop_bounding: self.force_loop_bounding,
|
||||
use_storage_input_output_16: self.use_storage_input_output_16,
|
||||
capabilities_available: take(&mut self.capabilities_available),
|
||||
binding_map: take(&mut self.binding_map),
|
||||
|
||||
@ -151,6 +156,7 @@ impl Writer {
|
||||
temp_list: take(&mut self.temp_list).recycle(),
|
||||
ray_get_candidate_intersection_function: None,
|
||||
ray_get_committed_intersection_function: None,
|
||||
io_f16_polyfills: take(&mut self.io_f16_polyfills).recycle(),
|
||||
};
|
||||
|
||||
*self = fresh;
|
||||
@ -726,10 +732,11 @@ impl Writer {
|
||||
binding,
|
||||
)?;
|
||||
iface.varying_ids.push(varying_id);
|
||||
let id = self.id_gen.next();
|
||||
prelude
|
||||
.body
|
||||
.push(Instruction::load(argument_type_id, id, varying_id, None));
|
||||
let id = self.load_io_with_f16_polyfill(
|
||||
&mut prelude.body,
|
||||
varying_id,
|
||||
argument_type_id,
|
||||
);
|
||||
|
||||
if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) {
|
||||
local_invocation_id = Some(id);
|
||||
@ -754,10 +761,8 @@ impl Writer {
|
||||
binding,
|
||||
)?;
|
||||
iface.varying_ids.push(varying_id);
|
||||
let id = self.id_gen.next();
|
||||
prelude
|
||||
.body
|
||||
.push(Instruction::load(type_id, id, varying_id, None));
|
||||
let id =
|
||||
self.load_io_with_f16_polyfill(&mut prelude.body, varying_id, type_id);
|
||||
constituent_ids.push(id);
|
||||
|
||||
if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) {
|
||||
@ -1220,8 +1225,10 @@ impl Writer {
|
||||
.insert(spirv::Capability::StorageBuffer16BitAccess);
|
||||
self.capabilities_used
|
||||
.insert(spirv::Capability::UniformAndStorageBuffer16BitAccess);
|
||||
self.capabilities_used
|
||||
.insert(spirv::Capability::StorageInputOutput16);
|
||||
if self.use_storage_input_output_16 {
|
||||
self.capabilities_used
|
||||
.insert(spirv::Capability::StorageInputOutput16);
|
||||
}
|
||||
}
|
||||
Instruction::type_float(id, bits)
|
||||
}
|
||||
@ -1905,8 +1912,26 @@ impl Writer {
|
||||
ty: Handle<crate::Type>,
|
||||
binding: &crate::Binding,
|
||||
) -> Result<Word, Error> {
|
||||
use crate::TypeInner;
|
||||
|
||||
let id = self.id_gen.next();
|
||||
let pointer_type_id = self.get_handle_pointer_type_id(ty, class);
|
||||
let ty_inner = &ir_module.types[ty].inner;
|
||||
let needs_polyfill = self.needs_f16_polyfill(ty_inner);
|
||||
|
||||
let pointer_type_id = if needs_polyfill {
|
||||
let f32_value_local =
|
||||
super::f16_polyfill::F16IoPolyfill::create_polyfill_type(ty_inner)
|
||||
.expect("needs_polyfill returned true but create_polyfill_type returned None");
|
||||
|
||||
let f32_type_id = self.get_localtype_id(f32_value_local);
|
||||
let ptr_id = self.get_pointer_type_id(f32_type_id, class);
|
||||
self.io_f16_polyfills.register_io_var(id, f32_type_id);
|
||||
|
||||
ptr_id
|
||||
} else {
|
||||
self.get_handle_pointer_type_id(ty, class)
|
||||
};
|
||||
|
||||
Instruction::variable(pointer_type_id, id, class, None)
|
||||
.to_words(&mut self.logical_layout.declarations);
|
||||
|
||||
@ -2089,8 +2114,9 @@ impl Writer {
|
||||
// > shader, must be decorated Flat
|
||||
if class == spirv::StorageClass::Input && stage == crate::ShaderStage::Fragment {
|
||||
let is_flat = match ir_module.types[ty].inner {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
TypeInner::Scalar(scalar) | TypeInner::Vector { scalar, .. } => match scalar
|
||||
.kind
|
||||
{
|
||||
Sk::Uint | Sk::Sint | Sk::Bool => true,
|
||||
Sk::Float => false,
|
||||
Sk::AbstractInt | Sk::AbstractFloat => {
|
||||
@ -2112,6 +2138,49 @@ impl Writer {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
/// Load an IO variable, converting from `f32` to `f16` if polyfill is active.
|
||||
/// Returns the id of the loaded value matching `target_type_id`.
|
||||
pub(super) fn load_io_with_f16_polyfill(
|
||||
&mut self,
|
||||
body: &mut Vec<Instruction>,
|
||||
varying_id: Word,
|
||||
target_type_id: Word,
|
||||
) -> Word {
|
||||
let tmp = self.id_gen.next();
|
||||
if let Some(f32_ty) = self.io_f16_polyfills.get_f32_io_type(varying_id) {
|
||||
body.push(Instruction::load(f32_ty, tmp, varying_id, None));
|
||||
let converted = self.id_gen.next();
|
||||
super::f16_polyfill::F16IoPolyfill::emit_f32_to_f16_conversion(
|
||||
tmp,
|
||||
target_type_id,
|
||||
converted,
|
||||
body,
|
||||
);
|
||||
converted
|
||||
} else {
|
||||
body.push(Instruction::load(target_type_id, tmp, varying_id, None));
|
||||
tmp
|
||||
}
|
||||
}
|
||||
|
||||
/// Store an IO variable, converting from `f16` to `f32` if polyfill is active.
|
||||
pub(super) fn store_io_with_f16_polyfill(
|
||||
&mut self,
|
||||
body: &mut Vec<Instruction>,
|
||||
varying_id: Word,
|
||||
value_id: Word,
|
||||
) {
|
||||
if let Some(f32_ty) = self.io_f16_polyfills.get_f32_io_type(varying_id) {
|
||||
let converted = self.id_gen.next();
|
||||
super::f16_polyfill::F16IoPolyfill::emit_f16_to_f32_conversion(
|
||||
value_id, f32_ty, converted, body,
|
||||
);
|
||||
body.push(Instruction::store(varying_id, converted, None));
|
||||
} else {
|
||||
body.push(Instruction::store(varying_id, value_id, None));
|
||||
}
|
||||
}
|
||||
|
||||
fn write_global_variable(
|
||||
&mut self,
|
||||
ir_module: &crate::Module,
|
||||
@ -2585,6 +2654,10 @@ impl Writer {
|
||||
self.decorate(id, spirv::Decoration::NonUniform, &[]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn needs_f16_polyfill(&self, ty_inner: &crate::TypeInner) -> bool {
|
||||
self.io_f16_polyfills.needs_polyfill(ty_inner)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
13
naga/tests/in/wgsl/f16-native.toml
Normal file
13
naga/tests/in/wgsl/f16-native.toml
Normal file
@ -0,0 +1,13 @@
|
||||
targets = "SPIRV"
|
||||
god_mode = true
|
||||
|
||||
[spv]
|
||||
debug = true
|
||||
version = [1, 1]
|
||||
use_storage_input_output_16 = true
|
||||
capabilities = ["Float16"]
|
||||
|
||||
[bounds_check_policies]
|
||||
index = "ReadZeroSkipWrite"
|
||||
buffer = "ReadZeroSkipWrite"
|
||||
image = "ReadZeroSkipWrite"
|
||||
79
naga/tests/in/wgsl/f16-native.wgsl
Normal file
79
naga/tests/in/wgsl/f16-native.wgsl
Normal file
@ -0,0 +1,79 @@
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn test_direct(
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = scalar_f32 + 1.0;
|
||||
output.vec2_f16 = vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct F16IO {
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_struct(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_copy_input(input_original: F16IO) -> F16IO {
|
||||
var input = input_original;
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_return_partial(input_original: F16IO) -> @location(0) f16 {
|
||||
var input = input_original;
|
||||
input.scalar_f16 = 0.0h;
|
||||
return input.scalar_f16;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_component_access(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.vec2_f16.x = input.vec2_f16.y;
|
||||
output.vec2_f16.y = input.vec2_f16.x;
|
||||
return output;
|
||||
}
|
||||
13
naga/tests/in/wgsl/f16-polyfill.toml
Normal file
13
naga/tests/in/wgsl/f16-polyfill.toml
Normal file
@ -0,0 +1,13 @@
|
||||
targets = "SPIRV"
|
||||
god_mode = true
|
||||
|
||||
[spv]
|
||||
debug = true
|
||||
version = [1, 1]
|
||||
use_storage_input_output_16 = false
|
||||
capabilities = ["Float16"]
|
||||
|
||||
[bounds_check_policies]
|
||||
index = "ReadZeroSkipWrite"
|
||||
buffer = "ReadZeroSkipWrite"
|
||||
image = "ReadZeroSkipWrite"
|
||||
79
naga/tests/in/wgsl/f16-polyfill.wgsl
Normal file
79
naga/tests/in/wgsl/f16-polyfill.wgsl
Normal file
@ -0,0 +1,79 @@
|
||||
enable f16;
|
||||
|
||||
@fragment
|
||||
fn test_direct(
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = scalar_f32 + 1.0;
|
||||
output.vec2_f16 = vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct F16IO {
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_struct(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_copy_input(input_original: F16IO) -> F16IO {
|
||||
var input = input_original;
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_return_partial(input_original: F16IO) -> @location(0) f16 {
|
||||
var input = input_original;
|
||||
input.scalar_f16 = 0.0h;
|
||||
return input.scalar_f16;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_component_access(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.vec2_f16.x = input.vec2_f16.y;
|
||||
output.vec2_f16.y = input.vec2_f16.x;
|
||||
return output;
|
||||
}
|
||||
@ -91,7 +91,7 @@ struct SpirvInParameters {
|
||||
adjust_coordinate_space: bool,
|
||||
}
|
||||
|
||||
#[derive(Default, serde::Deserialize)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
struct SpirvOutParameters {
|
||||
version: SpvOutVersion,
|
||||
@ -101,11 +101,29 @@ struct SpirvOutParameters {
|
||||
force_point_size: bool,
|
||||
clamp_frag_depth: bool,
|
||||
separate_entry_points: bool,
|
||||
use_storage_input_output_16: bool,
|
||||
#[cfg(all(feature = "deserialize", spv_out))]
|
||||
#[serde(deserialize_with = "deserialize_binding_map")]
|
||||
binding_map: naga::back::spv::BindingMap,
|
||||
}
|
||||
|
||||
impl Default for SpirvOutParameters {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
version: SpvOutVersion::default(),
|
||||
capabilities: naga::FastHashSet::default(),
|
||||
debug: false,
|
||||
adjust_coordinate_space: false,
|
||||
force_point_size: false,
|
||||
clamp_frag_depth: false,
|
||||
separate_entry_points: false,
|
||||
use_storage_input_output_16: true,
|
||||
#[cfg(all(feature = "deserialize", spv_out))]
|
||||
binding_map: naga::back::spv::BindingMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
struct WgslOutParameters {
|
||||
@ -617,6 +635,7 @@ fn write_output_spv(
|
||||
binding_map: params.binding_map.clone(),
|
||||
zero_initialize_workgroup_memory: spv::ZeroInitializeWorkgroupMemoryMode::Polyfill,
|
||||
force_loop_bounding: true,
|
||||
use_storage_input_output_16: params.use_storage_input_output_16,
|
||||
debug_info,
|
||||
};
|
||||
|
||||
|
||||
@ -6,6 +6,9 @@ Test SPIR-V backend capability checks.
|
||||
|
||||
use spirv::Capability as Ca;
|
||||
|
||||
#[cfg(spv_out)]
|
||||
use rspirv::binary::Disassemble;
|
||||
|
||||
fn capabilities_used(source: &str) -> naga::FastIndexSet<Ca> {
|
||||
use naga::back::spv;
|
||||
use naga::valid;
|
||||
@ -213,3 +216,135 @@ fn int64() {
|
||||
fn float16() {
|
||||
require(&[Ca::Float16], "enable f16; fn f(x: f16) { }");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f16_io_capabilities() {
|
||||
let source = r#"
|
||||
enable f16;
|
||||
|
||||
struct VertexOutput {
|
||||
@location(0) color: vec3<f16>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn main(input: VertexOutput) -> @location(0) vec4<f16> {
|
||||
return vec4<f16>(input.color, f16(1.0));
|
||||
}
|
||||
"#;
|
||||
|
||||
use naga::back::spv;
|
||||
use naga::valid;
|
||||
|
||||
let module = naga::front::wgsl::parse_str(source).unwrap();
|
||||
let info = valid::Validator::new(valid::ValidationFlags::all(), valid::Capabilities::all())
|
||||
.validate(&module)
|
||||
.unwrap();
|
||||
|
||||
// Test native path: use_storage_input_output_16 = true
|
||||
let options_native = spv::Options {
|
||||
use_storage_input_output_16: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut words_native = vec![];
|
||||
let mut writer_native = spv::Writer::new(&options_native).unwrap();
|
||||
writer_native
|
||||
.write(&module, &info, None, &None, &mut words_native)
|
||||
.unwrap();
|
||||
let caps_native = writer_native.get_capabilities_used();
|
||||
|
||||
// Should include `StorageInputOutput16` for native `f16` I/O
|
||||
assert!(caps_native.contains(&Ca::StorageInputOutput16));
|
||||
|
||||
// Test polyfill path: use_storage_input_output_16 = false
|
||||
let options_polyfill = spv::Options {
|
||||
use_storage_input_output_16: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut words_polyfill = vec![];
|
||||
let mut writer_polyfill = spv::Writer::new(&options_polyfill).unwrap();
|
||||
writer_polyfill
|
||||
.write(&module, &info, None, &None, &mut words_polyfill)
|
||||
.unwrap();
|
||||
let caps_polyfill = writer_polyfill.get_capabilities_used();
|
||||
|
||||
// Should not include `StorageInputOutput16` when polyfilled
|
||||
assert!(!caps_polyfill.contains(&Ca::StorageInputOutput16));
|
||||
|
||||
// But should still include the basic `f16` capabilities
|
||||
assert!(caps_polyfill.contains(&Ca::Float16));
|
||||
}
|
||||
|
||||
#[cfg(spv_out)]
|
||||
#[test]
|
||||
fn f16_io_polyfill_codegen() {
|
||||
let source = r#"
|
||||
enable f16;
|
||||
|
||||
struct F16IO {
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn main(input: F16IO) -> F16IO {
|
||||
var output = input;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.vec2_f16.x = input.vec2_f16.y;
|
||||
return output;
|
||||
}
|
||||
"#;
|
||||
|
||||
use naga::{back::spv, valid};
|
||||
|
||||
let module = naga::front::wgsl::parse_str(source).unwrap();
|
||||
let info = valid::Validator::new(valid::ValidationFlags::all(), valid::Capabilities::all())
|
||||
.validate(&module)
|
||||
.unwrap();
|
||||
|
||||
// Test Native Path
|
||||
let options_native = spv::Options {
|
||||
use_storage_input_output_16: true,
|
||||
..Default::default()
|
||||
};
|
||||
let mut words_native = vec![];
|
||||
let mut writer_native = spv::Writer::new(&options_native).unwrap();
|
||||
writer_native
|
||||
.write(&module, &info, None, &None, &mut words_native)
|
||||
.unwrap();
|
||||
let caps_native = writer_native.get_capabilities_used();
|
||||
let dis_native = rspirv::dr::load_words(words_native).unwrap().disassemble();
|
||||
|
||||
// Native path must request the capability and must NOT have conversions.
|
||||
assert!(caps_native.contains(&Ca::StorageInputOutput16));
|
||||
assert!(!dis_native.contains("OpFConvert"));
|
||||
|
||||
// Test Polyfill Path
|
||||
let options_polyfill = spv::Options {
|
||||
use_storage_input_output_16: false,
|
||||
..Default::default()
|
||||
};
|
||||
let mut words_polyfill = vec![];
|
||||
let mut writer_polyfill = spv::Writer::new(&options_polyfill).unwrap();
|
||||
writer_polyfill
|
||||
.write(&module, &info, None, &None, &mut words_polyfill)
|
||||
.unwrap();
|
||||
let caps_polyfill = writer_polyfill.get_capabilities_used();
|
||||
let dis_polyfill = rspirv::dr::load_words(words_polyfill)
|
||||
.unwrap()
|
||||
.disassemble();
|
||||
|
||||
// Polyfill path should request the capability but not have conversions.
|
||||
assert!(!caps_polyfill.contains(&Ca::StorageInputOutput16));
|
||||
assert!(dis_polyfill.contains("OpFConvert"));
|
||||
|
||||
// Should have 2 input conversions, and 2 output conversions
|
||||
let fconvert_count = dis_polyfill.matches("OpFConvert").count();
|
||||
assert_eq!(
|
||||
fconvert_count, 4,
|
||||
"Expected 4 OpFConvert instructions for polyfilled I/O"
|
||||
);
|
||||
}
|
||||
|
||||
761
naga/tests/out/spv/wgsl-f16-native.spvasm
Normal file
761
naga/tests/out/spv/wgsl-f16-native.spvasm
Normal file
@ -0,0 +1,761 @@
|
||||
; SPIR-V
|
||||
; Version: 1.1
|
||||
; Generator: rspirv
|
||||
; Bound: 318
|
||||
OpCapability Shader
|
||||
OpCapability Float16
|
||||
OpCapability StorageBuffer16BitAccess
|
||||
OpCapability UniformAndStorageBuffer16BitAccess
|
||||
OpCapability StorageInputOutput16
|
||||
OpExtension "SPV_KHR_16bit_storage"
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %54 "test_direct" %14 %17 %20 %23 %26 %29 %32 %35 %38 %40 %42 %44 %46 %48 %50 %52
|
||||
OpEntryPoint Fragment %136 "test_struct" %112 %114 %116 %118 %120 %122 %124 %126 %128 %129 %130 %131 %132 %133 %134 %135
|
||||
OpEntryPoint Fragment %199 "test_copy_input" %175 %177 %179 %181 %183 %185 %187 %189 %191 %192 %193 %194 %195 %196 %197 %198
|
||||
OpEntryPoint Fragment %265 "test_return_partial" %248 %250 %252 %254 %256 %258 %260 %262 %264
|
||||
OpEntryPoint Fragment %299 "test_component_access" %275 %277 %279 %281 %283 %285 %287 %289 %291 %292 %293 %294 %295 %296 %297 %298
|
||||
OpExecutionMode %54 OriginUpperLeft
|
||||
OpExecutionMode %136 OriginUpperLeft
|
||||
OpExecutionMode %199 OriginUpperLeft
|
||||
OpExecutionMode %265 OriginUpperLeft
|
||||
OpExecutionMode %299 OriginUpperLeft
|
||||
%3 = OpString "f16-native.wgsl"
|
||||
OpSource Unknown 0 %3 "enable f16;
|
||||
|
||||
@fragment
|
||||
fn test_direct(
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = scalar_f32 + 1.0;
|
||||
output.vec2_f16 = vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct F16IO {
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_struct(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_copy_input(input_original: F16IO) -> F16IO {
|
||||
var input = input_original;
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_return_partial(input_original: F16IO) -> @location(0) f16 {
|
||||
var input = input_original;
|
||||
input.scalar_f16 = 0.0h;
|
||||
return input.scalar_f16;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_component_access(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.vec2_f16.x = input.vec2_f16.y;
|
||||
output.vec2_f16.y = input.vec2_f16.x;
|
||||
return output;
|
||||
}"
|
||||
OpMemberName %12 0 "scalar_f16"
|
||||
OpMemberName %12 1 "scalar_f32"
|
||||
OpMemberName %12 2 "vec2_f16"
|
||||
OpMemberName %12 3 "vec2_f32"
|
||||
OpMemberName %12 4 "vec3_f16"
|
||||
OpMemberName %12 5 "vec3_f32"
|
||||
OpMemberName %12 6 "vec4_f16"
|
||||
OpMemberName %12 7 "vec4_f32"
|
||||
OpName %12 "F16IO"
|
||||
OpName %14 "scalar_f16"
|
||||
OpName %17 "scalar_f32"
|
||||
OpName %20 "vec2_f16"
|
||||
OpName %23 "vec2_f32"
|
||||
OpName %26 "vec3_f16"
|
||||
OpName %29 "vec3_f32"
|
||||
OpName %32 "vec4_f16"
|
||||
OpName %35 "vec4_f32"
|
||||
OpName %38 "scalar_f16"
|
||||
OpName %40 "scalar_f32"
|
||||
OpName %42 "vec2_f16"
|
||||
OpName %44 "vec2_f32"
|
||||
OpName %46 "vec3_f16"
|
||||
OpName %48 "vec3_f32"
|
||||
OpName %50 "vec4_f16"
|
||||
OpName %52 "vec4_f32"
|
||||
OpName %54 "test_direct"
|
||||
OpName %64 "output"
|
||||
OpName %112 "scalar_f16"
|
||||
OpName %114 "scalar_f32"
|
||||
OpName %116 "vec2_f16"
|
||||
OpName %118 "vec2_f32"
|
||||
OpName %120 "vec3_f16"
|
||||
OpName %122 "vec3_f32"
|
||||
OpName %124 "vec4_f16"
|
||||
OpName %126 "vec4_f32"
|
||||
OpName %128 "scalar_f16"
|
||||
OpName %129 "scalar_f32"
|
||||
OpName %130 "vec2_f16"
|
||||
OpName %131 "vec2_f32"
|
||||
OpName %132 "vec3_f16"
|
||||
OpName %133 "vec3_f32"
|
||||
OpName %134 "vec4_f16"
|
||||
OpName %135 "vec4_f32"
|
||||
OpName %136 "test_struct"
|
||||
OpName %137 "output"
|
||||
OpName %175 "scalar_f16"
|
||||
OpName %177 "scalar_f32"
|
||||
OpName %179 "vec2_f16"
|
||||
OpName %181 "vec2_f32"
|
||||
OpName %183 "vec3_f16"
|
||||
OpName %185 "vec3_f32"
|
||||
OpName %187 "vec4_f16"
|
||||
OpName %189 "vec4_f32"
|
||||
OpName %191 "scalar_f16"
|
||||
OpName %192 "scalar_f32"
|
||||
OpName %193 "vec2_f16"
|
||||
OpName %194 "vec2_f32"
|
||||
OpName %195 "vec3_f16"
|
||||
OpName %196 "vec3_f32"
|
||||
OpName %197 "vec4_f16"
|
||||
OpName %198 "vec4_f32"
|
||||
OpName %199 "test_copy_input"
|
||||
OpName %200 "input"
|
||||
OpName %202 "output"
|
||||
OpName %248 "scalar_f16"
|
||||
OpName %250 "scalar_f32"
|
||||
OpName %252 "vec2_f16"
|
||||
OpName %254 "vec2_f32"
|
||||
OpName %256 "vec3_f16"
|
||||
OpName %258 "vec3_f32"
|
||||
OpName %260 "vec4_f16"
|
||||
OpName %262 "vec4_f32"
|
||||
OpName %265 "test_return_partial"
|
||||
OpName %267 "input"
|
||||
OpName %275 "scalar_f16"
|
||||
OpName %277 "scalar_f32"
|
||||
OpName %279 "vec2_f16"
|
||||
OpName %281 "vec2_f32"
|
||||
OpName %283 "vec3_f16"
|
||||
OpName %285 "vec3_f32"
|
||||
OpName %287 "vec4_f16"
|
||||
OpName %289 "vec4_f32"
|
||||
OpName %291 "scalar_f16"
|
||||
OpName %292 "scalar_f32"
|
||||
OpName %293 "vec2_f16"
|
||||
OpName %294 "vec2_f32"
|
||||
OpName %295 "vec3_f16"
|
||||
OpName %296 "vec3_f32"
|
||||
OpName %297 "vec4_f16"
|
||||
OpName %298 "vec4_f32"
|
||||
OpName %299 "test_component_access"
|
||||
OpName %300 "output"
|
||||
OpMemberDecorate %12 0 Offset 0
|
||||
OpMemberDecorate %12 1 Offset 4
|
||||
OpMemberDecorate %12 2 Offset 8
|
||||
OpMemberDecorate %12 3 Offset 16
|
||||
OpMemberDecorate %12 4 Offset 24
|
||||
OpMemberDecorate %12 5 Offset 32
|
||||
OpMemberDecorate %12 6 Offset 48
|
||||
OpMemberDecorate %12 7 Offset 64
|
||||
OpDecorate %14 Location 0
|
||||
OpDecorate %17 Location 1
|
||||
OpDecorate %20 Location 2
|
||||
OpDecorate %23 Location 3
|
||||
OpDecorate %26 Location 4
|
||||
OpDecorate %29 Location 5
|
||||
OpDecorate %32 Location 6
|
||||
OpDecorate %35 Location 7
|
||||
OpDecorate %38 Location 0
|
||||
OpDecorate %40 Location 1
|
||||
OpDecorate %42 Location 2
|
||||
OpDecorate %44 Location 3
|
||||
OpDecorate %46 Location 4
|
||||
OpDecorate %48 Location 5
|
||||
OpDecorate %50 Location 6
|
||||
OpDecorate %52 Location 7
|
||||
OpDecorate %112 Location 0
|
||||
OpDecorate %114 Location 1
|
||||
OpDecorate %116 Location 2
|
||||
OpDecorate %118 Location 3
|
||||
OpDecorate %120 Location 4
|
||||
OpDecorate %122 Location 5
|
||||
OpDecorate %124 Location 6
|
||||
OpDecorate %126 Location 7
|
||||
OpDecorate %128 Location 0
|
||||
OpDecorate %129 Location 1
|
||||
OpDecorate %130 Location 2
|
||||
OpDecorate %131 Location 3
|
||||
OpDecorate %132 Location 4
|
||||
OpDecorate %133 Location 5
|
||||
OpDecorate %134 Location 6
|
||||
OpDecorate %135 Location 7
|
||||
OpDecorate %175 Location 0
|
||||
OpDecorate %177 Location 1
|
||||
OpDecorate %179 Location 2
|
||||
OpDecorate %181 Location 3
|
||||
OpDecorate %183 Location 4
|
||||
OpDecorate %185 Location 5
|
||||
OpDecorate %187 Location 6
|
||||
OpDecorate %189 Location 7
|
||||
OpDecorate %191 Location 0
|
||||
OpDecorate %192 Location 1
|
||||
OpDecorate %193 Location 2
|
||||
OpDecorate %194 Location 3
|
||||
OpDecorate %195 Location 4
|
||||
OpDecorate %196 Location 5
|
||||
OpDecorate %197 Location 6
|
||||
OpDecorate %198 Location 7
|
||||
OpDecorate %248 Location 0
|
||||
OpDecorate %250 Location 1
|
||||
OpDecorate %252 Location 2
|
||||
OpDecorate %254 Location 3
|
||||
OpDecorate %256 Location 4
|
||||
OpDecorate %258 Location 5
|
||||
OpDecorate %260 Location 6
|
||||
OpDecorate %262 Location 7
|
||||
OpDecorate %264 Location 0
|
||||
OpDecorate %275 Location 0
|
||||
OpDecorate %277 Location 1
|
||||
OpDecorate %279 Location 2
|
||||
OpDecorate %281 Location 3
|
||||
OpDecorate %283 Location 4
|
||||
OpDecorate %285 Location 5
|
||||
OpDecorate %287 Location 6
|
||||
OpDecorate %289 Location 7
|
||||
OpDecorate %291 Location 0
|
||||
OpDecorate %292 Location 1
|
||||
OpDecorate %293 Location 2
|
||||
OpDecorate %294 Location 3
|
||||
OpDecorate %295 Location 4
|
||||
OpDecorate %296 Location 5
|
||||
OpDecorate %297 Location 6
|
||||
OpDecorate %298 Location 7
|
||||
%2 = OpTypeVoid
|
||||
%4 = OpTypeFloat 16
|
||||
%5 = OpTypeFloat 32
|
||||
%6 = OpTypeVector %4 2
|
||||
%7 = OpTypeVector %5 2
|
||||
%8 = OpTypeVector %4 3
|
||||
%9 = OpTypeVector %5 3
|
||||
%10 = OpTypeVector %4 4
|
||||
%11 = OpTypeVector %5 4
|
||||
%12 = OpTypeStruct %4 %5 %6 %7 %8 %9 %10 %11
|
||||
%15 = OpTypePointer Input %4
|
||||
%14 = OpVariable %15 Input
|
||||
%18 = OpTypePointer Input %5
|
||||
%17 = OpVariable %18 Input
|
||||
%21 = OpTypePointer Input %6
|
||||
%20 = OpVariable %21 Input
|
||||
%24 = OpTypePointer Input %7
|
||||
%23 = OpVariable %24 Input
|
||||
%27 = OpTypePointer Input %8
|
||||
%26 = OpVariable %27 Input
|
||||
%30 = OpTypePointer Input %9
|
||||
%29 = OpVariable %30 Input
|
||||
%33 = OpTypePointer Input %10
|
||||
%32 = OpVariable %33 Input
|
||||
%36 = OpTypePointer Input %11
|
||||
%35 = OpVariable %36 Input
|
||||
%39 = OpTypePointer Output %4
|
||||
%38 = OpVariable %39 Output
|
||||
%41 = OpTypePointer Output %5
|
||||
%40 = OpVariable %41 Output
|
||||
%43 = OpTypePointer Output %6
|
||||
%42 = OpVariable %43 Output
|
||||
%45 = OpTypePointer Output %7
|
||||
%44 = OpVariable %45 Output
|
||||
%47 = OpTypePointer Output %8
|
||||
%46 = OpVariable %47 Output
|
||||
%49 = OpTypePointer Output %9
|
||||
%48 = OpVariable %49 Output
|
||||
%51 = OpTypePointer Output %10
|
||||
%50 = OpVariable %51 Output
|
||||
%53 = OpTypePointer Output %11
|
||||
%52 = OpVariable %53 Output
|
||||
%55 = OpTypeFunction %2
|
||||
%56 = OpConstant %4 0.000000000000000000000000000000000000000021524
|
||||
%57 = OpConstant %5 1
|
||||
%58 = OpConstantComposite %6 %56 %56
|
||||
%59 = OpConstantComposite %7 %57 %57
|
||||
%60 = OpConstantComposite %8 %56 %56 %56
|
||||
%61 = OpConstantComposite %9 %57 %57 %57
|
||||
%62 = OpConstantComposite %10 %56 %56 %56 %56
|
||||
%63 = OpConstantComposite %11 %57 %57 %57 %57
|
||||
%65 = OpTypePointer Function %12
|
||||
%66 = OpConstantNull %12
|
||||
%68 = OpTypePointer Function %4
|
||||
%71 = OpTypeInt 32 0
|
||||
%70 = OpConstant %71 0
|
||||
%73 = OpTypePointer Function %5
|
||||
%75 = OpConstant %71 1
|
||||
%77 = OpTypePointer Function %6
|
||||
%79 = OpConstant %71 2
|
||||
%81 = OpTypePointer Function %7
|
||||
%83 = OpConstant %71 3
|
||||
%85 = OpTypePointer Function %8
|
||||
%87 = OpConstant %71 4
|
||||
%89 = OpTypePointer Function %9
|
||||
%91 = OpConstant %71 5
|
||||
%93 = OpTypePointer Function %10
|
||||
%95 = OpConstant %71 6
|
||||
%97 = OpTypePointer Function %11
|
||||
%99 = OpConstant %71 7
|
||||
%112 = OpVariable %15 Input
|
||||
%114 = OpVariable %18 Input
|
||||
%116 = OpVariable %21 Input
|
||||
%118 = OpVariable %24 Input
|
||||
%120 = OpVariable %27 Input
|
||||
%122 = OpVariable %30 Input
|
||||
%124 = OpVariable %33 Input
|
||||
%126 = OpVariable %36 Input
|
||||
%128 = OpVariable %39 Output
|
||||
%129 = OpVariable %41 Output
|
||||
%130 = OpVariable %43 Output
|
||||
%131 = OpVariable %45 Output
|
||||
%132 = OpVariable %47 Output
|
||||
%133 = OpVariable %49 Output
|
||||
%134 = OpVariable %51 Output
|
||||
%135 = OpVariable %53 Output
|
||||
%138 = OpConstantNull %12
|
||||
%175 = OpVariable %15 Input
|
||||
%177 = OpVariable %18 Input
|
||||
%179 = OpVariable %21 Input
|
||||
%181 = OpVariable %24 Input
|
||||
%183 = OpVariable %27 Input
|
||||
%185 = OpVariable %30 Input
|
||||
%187 = OpVariable %33 Input
|
||||
%189 = OpVariable %36 Input
|
||||
%191 = OpVariable %39 Output
|
||||
%192 = OpVariable %41 Output
|
||||
%193 = OpVariable %43 Output
|
||||
%194 = OpVariable %45 Output
|
||||
%195 = OpVariable %47 Output
|
||||
%196 = OpVariable %49 Output
|
||||
%197 = OpVariable %51 Output
|
||||
%198 = OpVariable %53 Output
|
||||
%201 = OpConstantNull %12
|
||||
%203 = OpConstantNull %12
|
||||
%248 = OpVariable %15 Input
|
||||
%250 = OpVariable %18 Input
|
||||
%252 = OpVariable %21 Input
|
||||
%254 = OpVariable %24 Input
|
||||
%256 = OpVariable %27 Input
|
||||
%258 = OpVariable %30 Input
|
||||
%260 = OpVariable %33 Input
|
||||
%262 = OpVariable %36 Input
|
||||
%264 = OpVariable %39 Output
|
||||
%266 = OpConstant %4 0
|
||||
%268 = OpConstantNull %12
|
||||
%275 = OpVariable %15 Input
|
||||
%277 = OpVariable %18 Input
|
||||
%279 = OpVariable %21 Input
|
||||
%281 = OpVariable %24 Input
|
||||
%283 = OpVariable %27 Input
|
||||
%285 = OpVariable %30 Input
|
||||
%287 = OpVariable %33 Input
|
||||
%289 = OpVariable %36 Input
|
||||
%291 = OpVariable %39 Output
|
||||
%292 = OpVariable %41 Output
|
||||
%293 = OpVariable %43 Output
|
||||
%294 = OpVariable %45 Output
|
||||
%295 = OpVariable %47 Output
|
||||
%296 = OpVariable %49 Output
|
||||
%297 = OpVariable %51 Output
|
||||
%298 = OpVariable %53 Output
|
||||
%301 = OpConstantNull %12
|
||||
%54 = OpFunction %2 None %55
|
||||
%13 = OpLabel
|
||||
%64 = OpVariable %65 Function %66
|
||||
%16 = OpLoad %4 %14
|
||||
%19 = OpLoad %5 %17
|
||||
%22 = OpLoad %6 %20
|
||||
%25 = OpLoad %7 %23
|
||||
%28 = OpLoad %8 %26
|
||||
%31 = OpLoad %9 %29
|
||||
%34 = OpLoad %10 %32
|
||||
%37 = OpLoad %11 %35
|
||||
OpBranch %67
|
||||
%67 = OpLabel
|
||||
OpLine %3 15 5
|
||||
OpLine %3 15 25
|
||||
%69 = OpFAdd %4 %16 %56
|
||||
OpLine %3 15 5
|
||||
%72 = OpAccessChain %68 %64 %70
|
||||
OpStore %72 %69
|
||||
OpLine %3 16 5
|
||||
OpLine %3 16 25
|
||||
%74 = OpFAdd %5 %19 %57
|
||||
OpLine %3 16 5
|
||||
%76 = OpAccessChain %73 %64 %75
|
||||
OpStore %76 %74
|
||||
OpLine %3 17 5
|
||||
OpLine %3 17 23
|
||||
%78 = OpFAdd %6 %22 %58
|
||||
OpLine %3 17 5
|
||||
%80 = OpAccessChain %77 %64 %79
|
||||
OpStore %80 %78
|
||||
OpLine %3 18 5
|
||||
OpLine %3 18 34
|
||||
OpLine %3 18 23
|
||||
%82 = OpFAdd %7 %25 %59
|
||||
OpLine %3 18 5
|
||||
%84 = OpAccessChain %81 %64 %83
|
||||
OpStore %84 %82
|
||||
OpLine %3 19 5
|
||||
OpLine %3 19 23
|
||||
%86 = OpFAdd %8 %28 %60
|
||||
OpLine %3 19 5
|
||||
%88 = OpAccessChain %85 %64 %87
|
||||
OpStore %88 %86
|
||||
OpLine %3 20 5
|
||||
OpLine %3 20 34
|
||||
OpLine %3 20 23
|
||||
%90 = OpFAdd %9 %31 %61
|
||||
OpLine %3 20 5
|
||||
%92 = OpAccessChain %89 %64 %91
|
||||
OpStore %92 %90
|
||||
OpLine %3 21 5
|
||||
OpLine %3 21 23
|
||||
%94 = OpFAdd %10 %34 %62
|
||||
OpLine %3 21 5
|
||||
%96 = OpAccessChain %93 %64 %95
|
||||
OpStore %96 %94
|
||||
OpLine %3 22 5
|
||||
OpLine %3 22 34
|
||||
OpLine %3 22 23
|
||||
%98 = OpFAdd %11 %37 %63
|
||||
OpLine %3 22 5
|
||||
%100 = OpAccessChain %97 %64 %99
|
||||
OpStore %100 %98
|
||||
OpLine %3 1 1
|
||||
%101 = OpLoad %12 %64
|
||||
%102 = OpCompositeExtract %4 %101 0
|
||||
OpStore %38 %102
|
||||
%103 = OpCompositeExtract %5 %101 1
|
||||
OpStore %40 %103
|
||||
%104 = OpCompositeExtract %6 %101 2
|
||||
OpStore %42 %104
|
||||
%105 = OpCompositeExtract %7 %101 3
|
||||
OpStore %44 %105
|
||||
%106 = OpCompositeExtract %8 %101 4
|
||||
OpStore %46 %106
|
||||
%107 = OpCompositeExtract %9 %101 5
|
||||
OpStore %48 %107
|
||||
%108 = OpCompositeExtract %10 %101 6
|
||||
OpStore %50 %108
|
||||
%109 = OpCompositeExtract %11 %101 7
|
||||
OpStore %52 %109
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%136 = OpFunction %2 None %55
|
||||
%110 = OpLabel
|
||||
%137 = OpVariable %65 Function %138
|
||||
%113 = OpLoad %4 %112
|
||||
%115 = OpLoad %5 %114
|
||||
%117 = OpLoad %6 %116
|
||||
%119 = OpLoad %7 %118
|
||||
%121 = OpLoad %8 %120
|
||||
%123 = OpLoad %9 %122
|
||||
%125 = OpLoad %10 %124
|
||||
%127 = OpLoad %11 %126
|
||||
%111 = OpCompositeConstruct %12 %113 %115 %117 %119 %121 %123 %125 %127
|
||||
OpBranch %139
|
||||
%139 = OpLabel
|
||||
OpLine %3 40 5
|
||||
%140 = OpCompositeExtract %4 %111 0
|
||||
OpLine %3 40 25
|
||||
%141 = OpFAdd %4 %140 %56
|
||||
OpLine %3 40 5
|
||||
%142 = OpAccessChain %68 %137 %70
|
||||
OpStore %142 %141
|
||||
OpLine %3 41 5
|
||||
%143 = OpCompositeExtract %5 %111 1
|
||||
OpLine %3 41 25
|
||||
%144 = OpFAdd %5 %143 %57
|
||||
OpLine %3 41 5
|
||||
%145 = OpAccessChain %73 %137 %75
|
||||
OpStore %145 %144
|
||||
OpLine %3 42 5
|
||||
%146 = OpCompositeExtract %6 %111 2
|
||||
OpLine %3 42 23
|
||||
%147 = OpFAdd %6 %146 %58
|
||||
OpLine %3 42 5
|
||||
%148 = OpAccessChain %77 %137 %79
|
||||
OpStore %148 %147
|
||||
OpLine %3 43 5
|
||||
%149 = OpCompositeExtract %7 %111 3
|
||||
OpLine %3 43 40
|
||||
OpLine %3 43 23
|
||||
%150 = OpFAdd %7 %149 %59
|
||||
OpLine %3 43 5
|
||||
%151 = OpAccessChain %81 %137 %83
|
||||
OpStore %151 %150
|
||||
OpLine %3 44 5
|
||||
%152 = OpCompositeExtract %8 %111 4
|
||||
OpLine %3 44 23
|
||||
%153 = OpFAdd %8 %152 %60
|
||||
OpLine %3 44 5
|
||||
%154 = OpAccessChain %85 %137 %87
|
||||
OpStore %154 %153
|
||||
OpLine %3 45 5
|
||||
%155 = OpCompositeExtract %9 %111 5
|
||||
OpLine %3 45 40
|
||||
OpLine %3 45 23
|
||||
%156 = OpFAdd %9 %155 %61
|
||||
OpLine %3 45 5
|
||||
%157 = OpAccessChain %89 %137 %91
|
||||
OpStore %157 %156
|
||||
OpLine %3 46 5
|
||||
%158 = OpCompositeExtract %10 %111 6
|
||||
OpLine %3 46 23
|
||||
%159 = OpFAdd %10 %158 %62
|
||||
OpLine %3 46 5
|
||||
%160 = OpAccessChain %93 %137 %95
|
||||
OpStore %160 %159
|
||||
OpLine %3 47 5
|
||||
%161 = OpCompositeExtract %11 %111 7
|
||||
OpLine %3 47 40
|
||||
OpLine %3 47 23
|
||||
%162 = OpFAdd %11 %161 %63
|
||||
OpLine %3 47 5
|
||||
%163 = OpAccessChain %97 %137 %99
|
||||
OpStore %163 %162
|
||||
OpLine %3 1 1
|
||||
%164 = OpLoad %12 %137
|
||||
%165 = OpCompositeExtract %4 %164 0
|
||||
OpStore %128 %165
|
||||
%166 = OpCompositeExtract %5 %164 1
|
||||
OpStore %129 %166
|
||||
%167 = OpCompositeExtract %6 %164 2
|
||||
OpStore %130 %167
|
||||
%168 = OpCompositeExtract %7 %164 3
|
||||
OpStore %131 %168
|
||||
%169 = OpCompositeExtract %8 %164 4
|
||||
OpStore %132 %169
|
||||
%170 = OpCompositeExtract %9 %164 5
|
||||
OpStore %133 %170
|
||||
%171 = OpCompositeExtract %10 %164 6
|
||||
OpStore %134 %171
|
||||
%172 = OpCompositeExtract %11 %164 7
|
||||
OpStore %135 %172
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%199 = OpFunction %2 None %55
|
||||
%173 = OpLabel
|
||||
%200 = OpVariable %65 Function %201
|
||||
%202 = OpVariable %65 Function %203
|
||||
%176 = OpLoad %4 %175
|
||||
%178 = OpLoad %5 %177
|
||||
%180 = OpLoad %6 %179
|
||||
%182 = OpLoad %7 %181
|
||||
%184 = OpLoad %8 %183
|
||||
%186 = OpLoad %9 %185
|
||||
%188 = OpLoad %10 %187
|
||||
%190 = OpLoad %11 %189
|
||||
%174 = OpCompositeConstruct %12 %176 %178 %180 %182 %184 %186 %188 %190
|
||||
OpBranch %204
|
||||
%204 = OpLabel
|
||||
OpLine %3 53 5
|
||||
OpStore %200 %174
|
||||
OpLine %3 55 5
|
||||
%205 = OpAccessChain %68 %200 %70
|
||||
%206 = OpLoad %4 %205
|
||||
OpLine %3 55 25
|
||||
%207 = OpFAdd %4 %206 %56
|
||||
OpLine %3 55 5
|
||||
%208 = OpAccessChain %68 %202 %70
|
||||
OpStore %208 %207
|
||||
OpLine %3 56 5
|
||||
%209 = OpAccessChain %73 %200 %75
|
||||
%210 = OpLoad %5 %209
|
||||
OpLine %3 56 25
|
||||
%211 = OpFAdd %5 %210 %57
|
||||
OpLine %3 56 5
|
||||
%212 = OpAccessChain %73 %202 %75
|
||||
OpStore %212 %211
|
||||
OpLine %3 57 5
|
||||
%213 = OpAccessChain %77 %200 %79
|
||||
%214 = OpLoad %6 %213
|
||||
OpLine %3 57 23
|
||||
%215 = OpFAdd %6 %214 %58
|
||||
OpLine %3 57 5
|
||||
%216 = OpAccessChain %77 %202 %79
|
||||
OpStore %216 %215
|
||||
OpLine %3 58 5
|
||||
%217 = OpAccessChain %81 %200 %83
|
||||
%218 = OpLoad %7 %217
|
||||
OpLine %3 58 40
|
||||
OpLine %3 58 23
|
||||
%219 = OpFAdd %7 %218 %59
|
||||
OpLine %3 58 5
|
||||
%220 = OpAccessChain %81 %202 %83
|
||||
OpStore %220 %219
|
||||
OpLine %3 59 5
|
||||
%221 = OpAccessChain %85 %200 %87
|
||||
%222 = OpLoad %8 %221
|
||||
OpLine %3 59 23
|
||||
%223 = OpFAdd %8 %222 %60
|
||||
OpLine %3 59 5
|
||||
%224 = OpAccessChain %85 %202 %87
|
||||
OpStore %224 %223
|
||||
OpLine %3 60 5
|
||||
%225 = OpAccessChain %89 %200 %91
|
||||
%226 = OpLoad %9 %225
|
||||
OpLine %3 60 40
|
||||
OpLine %3 60 23
|
||||
%227 = OpFAdd %9 %226 %61
|
||||
OpLine %3 60 5
|
||||
%228 = OpAccessChain %89 %202 %91
|
||||
OpStore %228 %227
|
||||
OpLine %3 61 5
|
||||
%229 = OpAccessChain %93 %200 %95
|
||||
%230 = OpLoad %10 %229
|
||||
OpLine %3 61 23
|
||||
%231 = OpFAdd %10 %230 %62
|
||||
OpLine %3 61 5
|
||||
%232 = OpAccessChain %93 %202 %95
|
||||
OpStore %232 %231
|
||||
OpLine %3 62 5
|
||||
%233 = OpAccessChain %97 %200 %99
|
||||
%234 = OpLoad %11 %233
|
||||
OpLine %3 62 40
|
||||
OpLine %3 62 23
|
||||
%235 = OpFAdd %11 %234 %63
|
||||
OpLine %3 62 5
|
||||
%236 = OpAccessChain %97 %202 %99
|
||||
OpStore %236 %235
|
||||
OpLine %3 1 1
|
||||
%237 = OpLoad %12 %202
|
||||
%238 = OpCompositeExtract %4 %237 0
|
||||
OpStore %191 %238
|
||||
%239 = OpCompositeExtract %5 %237 1
|
||||
OpStore %192 %239
|
||||
%240 = OpCompositeExtract %6 %237 2
|
||||
OpStore %193 %240
|
||||
%241 = OpCompositeExtract %7 %237 3
|
||||
OpStore %194 %241
|
||||
%242 = OpCompositeExtract %8 %237 4
|
||||
OpStore %195 %242
|
||||
%243 = OpCompositeExtract %9 %237 5
|
||||
OpStore %196 %243
|
||||
%244 = OpCompositeExtract %10 %237 6
|
||||
OpStore %197 %244
|
||||
%245 = OpCompositeExtract %11 %237 7
|
||||
OpStore %198 %245
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%265 = OpFunction %2 None %55
|
||||
%246 = OpLabel
|
||||
%267 = OpVariable %65 Function %268
|
||||
%249 = OpLoad %4 %248
|
||||
%251 = OpLoad %5 %250
|
||||
%253 = OpLoad %6 %252
|
||||
%255 = OpLoad %7 %254
|
||||
%257 = OpLoad %8 %256
|
||||
%259 = OpLoad %9 %258
|
||||
%261 = OpLoad %10 %260
|
||||
%263 = OpLoad %11 %262
|
||||
%247 = OpCompositeConstruct %12 %249 %251 %253 %255 %257 %259 %261 %263
|
||||
OpBranch %269
|
||||
%269 = OpLabel
|
||||
OpLine %3 68 5
|
||||
OpStore %267 %247
|
||||
OpLine %3 69 5
|
||||
OpLine %3 69 5
|
||||
%270 = OpAccessChain %68 %267 %70
|
||||
OpStore %270 %266
|
||||
OpLine %3 70 12
|
||||
%271 = OpAccessChain %68 %267 %70
|
||||
%272 = OpLoad %4 %271
|
||||
OpStore %264 %272
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%299 = OpFunction %2 None %55
|
||||
%273 = OpLabel
|
||||
%300 = OpVariable %65 Function %301
|
||||
%276 = OpLoad %4 %275
|
||||
%278 = OpLoad %5 %277
|
||||
%280 = OpLoad %6 %279
|
||||
%282 = OpLoad %7 %281
|
||||
%284 = OpLoad %8 %283
|
||||
%286 = OpLoad %9 %285
|
||||
%288 = OpLoad %10 %287
|
||||
%290 = OpLoad %11 %289
|
||||
%274 = OpCompositeConstruct %12 %276 %278 %280 %282 %284 %286 %288 %290
|
||||
OpBranch %302
|
||||
%302 = OpLabel
|
||||
OpLine %3 76 5
|
||||
%303 = OpCompositeExtract %6 %274 2
|
||||
%304 = OpCompositeExtract %4 %303 1
|
||||
OpLine %3 76 5
|
||||
%305 = OpAccessChain %68 %300 %79 %70
|
||||
OpStore %305 %304
|
||||
OpLine %3 77 5
|
||||
%306 = OpCompositeExtract %6 %274 2
|
||||
%307 = OpCompositeExtract %4 %306 0
|
||||
OpLine %3 77 5
|
||||
%308 = OpAccessChain %68 %300 %79 %75
|
||||
OpStore %308 %307
|
||||
OpLine %3 1 1
|
||||
%309 = OpLoad %12 %300
|
||||
%310 = OpCompositeExtract %4 %309 0
|
||||
OpStore %291 %310
|
||||
%311 = OpCompositeExtract %5 %309 1
|
||||
OpStore %292 %311
|
||||
%312 = OpCompositeExtract %6 %309 2
|
||||
OpStore %293 %312
|
||||
%313 = OpCompositeExtract %7 %309 3
|
||||
OpStore %294 %313
|
||||
%314 = OpCompositeExtract %8 %309 4
|
||||
OpStore %295 %314
|
||||
%315 = OpCompositeExtract %9 %309 5
|
||||
OpStore %296 %315
|
||||
%316 = OpCompositeExtract %10 %309 6
|
||||
OpStore %297 %316
|
||||
%317 = OpCompositeExtract %11 %309 7
|
||||
OpStore %298 %317
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
789
naga/tests/out/spv/wgsl-f16-polyfill.spvasm
Normal file
789
naga/tests/out/spv/wgsl-f16-polyfill.spvasm
Normal file
@ -0,0 +1,789 @@
|
||||
; SPIR-V
|
||||
; Version: 1.1
|
||||
; Generator: rspirv
|
||||
; Bound: 347
|
||||
OpCapability Shader
|
||||
OpCapability Float16
|
||||
OpCapability StorageBuffer16BitAccess
|
||||
OpCapability UniformAndStorageBuffer16BitAccess
|
||||
OpExtension "SPV_KHR_16bit_storage"
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %50 "test_direct" %14 %18 %20 %24 %26 %30 %32 %36 %38 %40 %41 %43 %44 %46 %47 %49
|
||||
OpEntryPoint Fragment %140 "test_struct" %112 %115 %117 %120 %122 %125 %127 %130 %132 %133 %134 %135 %136 %137 %138 %139
|
||||
OpEntryPoint Fragment %211 "test_copy_input" %183 %186 %188 %191 %193 %196 %198 %201 %203 %204 %205 %206 %207 %208 %209 %210
|
||||
OpEntryPoint Fragment %285 "test_return_partial" %264 %267 %269 %272 %274 %277 %279 %282 %284
|
||||
OpEntryPoint Fragment %324 "test_component_access" %296 %299 %301 %304 %306 %309 %311 %314 %316 %317 %318 %319 %320 %321 %322 %323
|
||||
OpExecutionMode %50 OriginUpperLeft
|
||||
OpExecutionMode %140 OriginUpperLeft
|
||||
OpExecutionMode %211 OriginUpperLeft
|
||||
OpExecutionMode %285 OriginUpperLeft
|
||||
OpExecutionMode %324 OriginUpperLeft
|
||||
%3 = OpString "f16-polyfill.wgsl"
|
||||
OpSource Unknown 0 %3 "enable f16;
|
||||
|
||||
@fragment
|
||||
fn test_direct(
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = scalar_f32 + 1.0;
|
||||
output.vec2_f16 = vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
struct F16IO {
|
||||
@location(0) scalar_f16: f16,
|
||||
@location(1) scalar_f32: f32,
|
||||
@location(2) vec2_f16: vec2<f16>,
|
||||
@location(3) vec2_f32: vec2<f32>,
|
||||
@location(4) vec3_f16: vec3<f16>,
|
||||
@location(5) vec3_f32: vec3<f32>,
|
||||
@location(6) vec4_f16: vec4<f16>,
|
||||
@location(7) vec4_f32: vec4<f32>,
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_struct(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_copy_input(input_original: F16IO) -> F16IO {
|
||||
var input = input_original;
|
||||
var output: F16IO;
|
||||
output.scalar_f16 = input.scalar_f16 + 1.0h;
|
||||
output.scalar_f32 = input.scalar_f32 + 1.0;
|
||||
output.vec2_f16 = input.vec2_f16 + vec2(1.0h);
|
||||
output.vec2_f32 = input.vec2_f32 + vec2(1.0);
|
||||
output.vec3_f16 = input.vec3_f16 + vec3(1.0h);
|
||||
output.vec3_f32 = input.vec3_f32 + vec3(1.0);
|
||||
output.vec4_f16 = input.vec4_f16 + vec4(1.0h);
|
||||
output.vec4_f32 = input.vec4_f32 + vec4(1.0);
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_return_partial(input_original: F16IO) -> @location(0) f16 {
|
||||
var input = input_original;
|
||||
input.scalar_f16 = 0.0h;
|
||||
return input.scalar_f16;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn test_component_access(input: F16IO) -> F16IO {
|
||||
var output: F16IO;
|
||||
output.vec2_f16.x = input.vec2_f16.y;
|
||||
output.vec2_f16.y = input.vec2_f16.x;
|
||||
return output;
|
||||
}"
|
||||
OpMemberName %12 0 "scalar_f16"
|
||||
OpMemberName %12 1 "scalar_f32"
|
||||
OpMemberName %12 2 "vec2_f16"
|
||||
OpMemberName %12 3 "vec2_f32"
|
||||
OpMemberName %12 4 "vec3_f16"
|
||||
OpMemberName %12 5 "vec3_f32"
|
||||
OpMemberName %12 6 "vec4_f16"
|
||||
OpMemberName %12 7 "vec4_f32"
|
||||
OpName %12 "F16IO"
|
||||
OpName %14 "scalar_f16"
|
||||
OpName %18 "scalar_f32"
|
||||
OpName %20 "vec2_f16"
|
||||
OpName %24 "vec2_f32"
|
||||
OpName %26 "vec3_f16"
|
||||
OpName %30 "vec3_f32"
|
||||
OpName %32 "vec4_f16"
|
||||
OpName %36 "vec4_f32"
|
||||
OpName %38 "scalar_f16"
|
||||
OpName %40 "scalar_f32"
|
||||
OpName %41 "vec2_f16"
|
||||
OpName %43 "vec2_f32"
|
||||
OpName %44 "vec3_f16"
|
||||
OpName %46 "vec3_f32"
|
||||
OpName %47 "vec4_f16"
|
||||
OpName %49 "vec4_f32"
|
||||
OpName %50 "test_direct"
|
||||
OpName %60 "output"
|
||||
OpName %112 "scalar_f16"
|
||||
OpName %115 "scalar_f32"
|
||||
OpName %117 "vec2_f16"
|
||||
OpName %120 "vec2_f32"
|
||||
OpName %122 "vec3_f16"
|
||||
OpName %125 "vec3_f32"
|
||||
OpName %127 "vec4_f16"
|
||||
OpName %130 "vec4_f32"
|
||||
OpName %132 "scalar_f16"
|
||||
OpName %133 "scalar_f32"
|
||||
OpName %134 "vec2_f16"
|
||||
OpName %135 "vec2_f32"
|
||||
OpName %136 "vec3_f16"
|
||||
OpName %137 "vec3_f32"
|
||||
OpName %138 "vec4_f16"
|
||||
OpName %139 "vec4_f32"
|
||||
OpName %140 "test_struct"
|
||||
OpName %141 "output"
|
||||
OpName %183 "scalar_f16"
|
||||
OpName %186 "scalar_f32"
|
||||
OpName %188 "vec2_f16"
|
||||
OpName %191 "vec2_f32"
|
||||
OpName %193 "vec3_f16"
|
||||
OpName %196 "vec3_f32"
|
||||
OpName %198 "vec4_f16"
|
||||
OpName %201 "vec4_f32"
|
||||
OpName %203 "scalar_f16"
|
||||
OpName %204 "scalar_f32"
|
||||
OpName %205 "vec2_f16"
|
||||
OpName %206 "vec2_f32"
|
||||
OpName %207 "vec3_f16"
|
||||
OpName %208 "vec3_f32"
|
||||
OpName %209 "vec4_f16"
|
||||
OpName %210 "vec4_f32"
|
||||
OpName %211 "test_copy_input"
|
||||
OpName %212 "input"
|
||||
OpName %214 "output"
|
||||
OpName %264 "scalar_f16"
|
||||
OpName %267 "scalar_f32"
|
||||
OpName %269 "vec2_f16"
|
||||
OpName %272 "vec2_f32"
|
||||
OpName %274 "vec3_f16"
|
||||
OpName %277 "vec3_f32"
|
||||
OpName %279 "vec4_f16"
|
||||
OpName %282 "vec4_f32"
|
||||
OpName %285 "test_return_partial"
|
||||
OpName %287 "input"
|
||||
OpName %296 "scalar_f16"
|
||||
OpName %299 "scalar_f32"
|
||||
OpName %301 "vec2_f16"
|
||||
OpName %304 "vec2_f32"
|
||||
OpName %306 "vec3_f16"
|
||||
OpName %309 "vec3_f32"
|
||||
OpName %311 "vec4_f16"
|
||||
OpName %314 "vec4_f32"
|
||||
OpName %316 "scalar_f16"
|
||||
OpName %317 "scalar_f32"
|
||||
OpName %318 "vec2_f16"
|
||||
OpName %319 "vec2_f32"
|
||||
OpName %320 "vec3_f16"
|
||||
OpName %321 "vec3_f32"
|
||||
OpName %322 "vec4_f16"
|
||||
OpName %323 "vec4_f32"
|
||||
OpName %324 "test_component_access"
|
||||
OpName %325 "output"
|
||||
OpMemberDecorate %12 0 Offset 0
|
||||
OpMemberDecorate %12 1 Offset 4
|
||||
OpMemberDecorate %12 2 Offset 8
|
||||
OpMemberDecorate %12 3 Offset 16
|
||||
OpMemberDecorate %12 4 Offset 24
|
||||
OpMemberDecorate %12 5 Offset 32
|
||||
OpMemberDecorate %12 6 Offset 48
|
||||
OpMemberDecorate %12 7 Offset 64
|
||||
OpDecorate %14 Location 0
|
||||
OpDecorate %18 Location 1
|
||||
OpDecorate %20 Location 2
|
||||
OpDecorate %24 Location 3
|
||||
OpDecorate %26 Location 4
|
||||
OpDecorate %30 Location 5
|
||||
OpDecorate %32 Location 6
|
||||
OpDecorate %36 Location 7
|
||||
OpDecorate %38 Location 0
|
||||
OpDecorate %40 Location 1
|
||||
OpDecorate %41 Location 2
|
||||
OpDecorate %43 Location 3
|
||||
OpDecorate %44 Location 4
|
||||
OpDecorate %46 Location 5
|
||||
OpDecorate %47 Location 6
|
||||
OpDecorate %49 Location 7
|
||||
OpDecorate %112 Location 0
|
||||
OpDecorate %115 Location 1
|
||||
OpDecorate %117 Location 2
|
||||
OpDecorate %120 Location 3
|
||||
OpDecorate %122 Location 4
|
||||
OpDecorate %125 Location 5
|
||||
OpDecorate %127 Location 6
|
||||
OpDecorate %130 Location 7
|
||||
OpDecorate %132 Location 0
|
||||
OpDecorate %133 Location 1
|
||||
OpDecorate %134 Location 2
|
||||
OpDecorate %135 Location 3
|
||||
OpDecorate %136 Location 4
|
||||
OpDecorate %137 Location 5
|
||||
OpDecorate %138 Location 6
|
||||
OpDecorate %139 Location 7
|
||||
OpDecorate %183 Location 0
|
||||
OpDecorate %186 Location 1
|
||||
OpDecorate %188 Location 2
|
||||
OpDecorate %191 Location 3
|
||||
OpDecorate %193 Location 4
|
||||
OpDecorate %196 Location 5
|
||||
OpDecorate %198 Location 6
|
||||
OpDecorate %201 Location 7
|
||||
OpDecorate %203 Location 0
|
||||
OpDecorate %204 Location 1
|
||||
OpDecorate %205 Location 2
|
||||
OpDecorate %206 Location 3
|
||||
OpDecorate %207 Location 4
|
||||
OpDecorate %208 Location 5
|
||||
OpDecorate %209 Location 6
|
||||
OpDecorate %210 Location 7
|
||||
OpDecorate %264 Location 0
|
||||
OpDecorate %267 Location 1
|
||||
OpDecorate %269 Location 2
|
||||
OpDecorate %272 Location 3
|
||||
OpDecorate %274 Location 4
|
||||
OpDecorate %277 Location 5
|
||||
OpDecorate %279 Location 6
|
||||
OpDecorate %282 Location 7
|
||||
OpDecorate %284 Location 0
|
||||
OpDecorate %296 Location 0
|
||||
OpDecorate %299 Location 1
|
||||
OpDecorate %301 Location 2
|
||||
OpDecorate %304 Location 3
|
||||
OpDecorate %306 Location 4
|
||||
OpDecorate %309 Location 5
|
||||
OpDecorate %311 Location 6
|
||||
OpDecorate %314 Location 7
|
||||
OpDecorate %316 Location 0
|
||||
OpDecorate %317 Location 1
|
||||
OpDecorate %318 Location 2
|
||||
OpDecorate %319 Location 3
|
||||
OpDecorate %320 Location 4
|
||||
OpDecorate %321 Location 5
|
||||
OpDecorate %322 Location 6
|
||||
OpDecorate %323 Location 7
|
||||
%2 = OpTypeVoid
|
||||
%4 = OpTypeFloat 16
|
||||
%5 = OpTypeFloat 32
|
||||
%6 = OpTypeVector %4 2
|
||||
%7 = OpTypeVector %5 2
|
||||
%8 = OpTypeVector %4 3
|
||||
%9 = OpTypeVector %5 3
|
||||
%10 = OpTypeVector %4 4
|
||||
%11 = OpTypeVector %5 4
|
||||
%12 = OpTypeStruct %4 %5 %6 %7 %8 %9 %10 %11
|
||||
%15 = OpTypePointer Input %5
|
||||
%14 = OpVariable %15 Input
|
||||
%18 = OpVariable %15 Input
|
||||
%21 = OpTypePointer Input %7
|
||||
%20 = OpVariable %21 Input
|
||||
%24 = OpVariable %21 Input
|
||||
%27 = OpTypePointer Input %9
|
||||
%26 = OpVariable %27 Input
|
||||
%30 = OpVariable %27 Input
|
||||
%33 = OpTypePointer Input %11
|
||||
%32 = OpVariable %33 Input
|
||||
%36 = OpVariable %33 Input
|
||||
%39 = OpTypePointer Output %5
|
||||
%38 = OpVariable %39 Output
|
||||
%40 = OpVariable %39 Output
|
||||
%42 = OpTypePointer Output %7
|
||||
%41 = OpVariable %42 Output
|
||||
%43 = OpVariable %42 Output
|
||||
%45 = OpTypePointer Output %9
|
||||
%44 = OpVariable %45 Output
|
||||
%46 = OpVariable %45 Output
|
||||
%48 = OpTypePointer Output %11
|
||||
%47 = OpVariable %48 Output
|
||||
%49 = OpVariable %48 Output
|
||||
%51 = OpTypeFunction %2
|
||||
%52 = OpConstant %4 0.000000000000000000000000000000000000000021524
|
||||
%53 = OpConstant %5 1
|
||||
%54 = OpConstantComposite %6 %52 %52
|
||||
%55 = OpConstantComposite %7 %53 %53
|
||||
%56 = OpConstantComposite %8 %52 %52 %52
|
||||
%57 = OpConstantComposite %9 %53 %53 %53
|
||||
%58 = OpConstantComposite %10 %52 %52 %52 %52
|
||||
%59 = OpConstantComposite %11 %53 %53 %53 %53
|
||||
%61 = OpTypePointer Function %12
|
||||
%62 = OpConstantNull %12
|
||||
%64 = OpTypePointer Function %4
|
||||
%67 = OpTypeInt 32 0
|
||||
%66 = OpConstant %67 0
|
||||
%69 = OpTypePointer Function %5
|
||||
%71 = OpConstant %67 1
|
||||
%73 = OpTypePointer Function %6
|
||||
%75 = OpConstant %67 2
|
||||
%77 = OpTypePointer Function %7
|
||||
%79 = OpConstant %67 3
|
||||
%81 = OpTypePointer Function %8
|
||||
%83 = OpConstant %67 4
|
||||
%85 = OpTypePointer Function %9
|
||||
%87 = OpConstant %67 5
|
||||
%89 = OpTypePointer Function %10
|
||||
%91 = OpConstant %67 6
|
||||
%93 = OpTypePointer Function %11
|
||||
%95 = OpConstant %67 7
|
||||
%112 = OpVariable %15 Input
|
||||
%115 = OpVariable %15 Input
|
||||
%117 = OpVariable %21 Input
|
||||
%120 = OpVariable %21 Input
|
||||
%122 = OpVariable %27 Input
|
||||
%125 = OpVariable %27 Input
|
||||
%127 = OpVariable %33 Input
|
||||
%130 = OpVariable %33 Input
|
||||
%132 = OpVariable %39 Output
|
||||
%133 = OpVariable %39 Output
|
||||
%134 = OpVariable %42 Output
|
||||
%135 = OpVariable %42 Output
|
||||
%136 = OpVariable %45 Output
|
||||
%137 = OpVariable %45 Output
|
||||
%138 = OpVariable %48 Output
|
||||
%139 = OpVariable %48 Output
|
||||
%142 = OpConstantNull %12
|
||||
%183 = OpVariable %15 Input
|
||||
%186 = OpVariable %15 Input
|
||||
%188 = OpVariable %21 Input
|
||||
%191 = OpVariable %21 Input
|
||||
%193 = OpVariable %27 Input
|
||||
%196 = OpVariable %27 Input
|
||||
%198 = OpVariable %33 Input
|
||||
%201 = OpVariable %33 Input
|
||||
%203 = OpVariable %39 Output
|
||||
%204 = OpVariable %39 Output
|
||||
%205 = OpVariable %42 Output
|
||||
%206 = OpVariable %42 Output
|
||||
%207 = OpVariable %45 Output
|
||||
%208 = OpVariable %45 Output
|
||||
%209 = OpVariable %48 Output
|
||||
%210 = OpVariable %48 Output
|
||||
%213 = OpConstantNull %12
|
||||
%215 = OpConstantNull %12
|
||||
%264 = OpVariable %15 Input
|
||||
%267 = OpVariable %15 Input
|
||||
%269 = OpVariable %21 Input
|
||||
%272 = OpVariable %21 Input
|
||||
%274 = OpVariable %27 Input
|
||||
%277 = OpVariable %27 Input
|
||||
%279 = OpVariable %33 Input
|
||||
%282 = OpVariable %33 Input
|
||||
%284 = OpVariable %39 Output
|
||||
%286 = OpConstant %4 0
|
||||
%288 = OpConstantNull %12
|
||||
%296 = OpVariable %15 Input
|
||||
%299 = OpVariable %15 Input
|
||||
%301 = OpVariable %21 Input
|
||||
%304 = OpVariable %21 Input
|
||||
%306 = OpVariable %27 Input
|
||||
%309 = OpVariable %27 Input
|
||||
%311 = OpVariable %33 Input
|
||||
%314 = OpVariable %33 Input
|
||||
%316 = OpVariable %39 Output
|
||||
%317 = OpVariable %39 Output
|
||||
%318 = OpVariable %42 Output
|
||||
%319 = OpVariable %42 Output
|
||||
%320 = OpVariable %45 Output
|
||||
%321 = OpVariable %45 Output
|
||||
%322 = OpVariable %48 Output
|
||||
%323 = OpVariable %48 Output
|
||||
%326 = OpConstantNull %12
|
||||
%50 = OpFunction %2 None %51
|
||||
%13 = OpLabel
|
||||
%60 = OpVariable %61 Function %62
|
||||
%16 = OpLoad %5 %14
|
||||
%17 = OpFConvert %4 %16
|
||||
%19 = OpLoad %5 %18
|
||||
%22 = OpLoad %7 %20
|
||||
%23 = OpFConvert %6 %22
|
||||
%25 = OpLoad %7 %24
|
||||
%28 = OpLoad %9 %26
|
||||
%29 = OpFConvert %8 %28
|
||||
%31 = OpLoad %9 %30
|
||||
%34 = OpLoad %11 %32
|
||||
%35 = OpFConvert %10 %34
|
||||
%37 = OpLoad %11 %36
|
||||
OpBranch %63
|
||||
%63 = OpLabel
|
||||
OpLine %3 15 5
|
||||
OpLine %3 15 25
|
||||
%65 = OpFAdd %4 %17 %52
|
||||
OpLine %3 15 5
|
||||
%68 = OpAccessChain %64 %60 %66
|
||||
OpStore %68 %65
|
||||
OpLine %3 16 5
|
||||
OpLine %3 16 25
|
||||
%70 = OpFAdd %5 %19 %53
|
||||
OpLine %3 16 5
|
||||
%72 = OpAccessChain %69 %60 %71
|
||||
OpStore %72 %70
|
||||
OpLine %3 17 5
|
||||
OpLine %3 17 23
|
||||
%74 = OpFAdd %6 %23 %54
|
||||
OpLine %3 17 5
|
||||
%76 = OpAccessChain %73 %60 %75
|
||||
OpStore %76 %74
|
||||
OpLine %3 18 5
|
||||
OpLine %3 18 34
|
||||
OpLine %3 18 23
|
||||
%78 = OpFAdd %7 %25 %55
|
||||
OpLine %3 18 5
|
||||
%80 = OpAccessChain %77 %60 %79
|
||||
OpStore %80 %78
|
||||
OpLine %3 19 5
|
||||
OpLine %3 19 23
|
||||
%82 = OpFAdd %8 %29 %56
|
||||
OpLine %3 19 5
|
||||
%84 = OpAccessChain %81 %60 %83
|
||||
OpStore %84 %82
|
||||
OpLine %3 20 5
|
||||
OpLine %3 20 34
|
||||
OpLine %3 20 23
|
||||
%86 = OpFAdd %9 %31 %57
|
||||
OpLine %3 20 5
|
||||
%88 = OpAccessChain %85 %60 %87
|
||||
OpStore %88 %86
|
||||
OpLine %3 21 5
|
||||
OpLine %3 21 23
|
||||
%90 = OpFAdd %10 %35 %58
|
||||
OpLine %3 21 5
|
||||
%92 = OpAccessChain %89 %60 %91
|
||||
OpStore %92 %90
|
||||
OpLine %3 22 5
|
||||
OpLine %3 22 34
|
||||
OpLine %3 22 23
|
||||
%94 = OpFAdd %11 %37 %59
|
||||
OpLine %3 22 5
|
||||
%96 = OpAccessChain %93 %60 %95
|
||||
OpStore %96 %94
|
||||
OpLine %3 1 1
|
||||
%97 = OpLoad %12 %60
|
||||
%98 = OpCompositeExtract %4 %97 0
|
||||
%99 = OpFConvert %5 %98
|
||||
OpStore %38 %99
|
||||
%100 = OpCompositeExtract %5 %97 1
|
||||
OpStore %40 %100
|
||||
%101 = OpCompositeExtract %6 %97 2
|
||||
%102 = OpFConvert %7 %101
|
||||
OpStore %41 %102
|
||||
%103 = OpCompositeExtract %7 %97 3
|
||||
OpStore %43 %103
|
||||
%104 = OpCompositeExtract %8 %97 4
|
||||
%105 = OpFConvert %9 %104
|
||||
OpStore %44 %105
|
||||
%106 = OpCompositeExtract %9 %97 5
|
||||
OpStore %46 %106
|
||||
%107 = OpCompositeExtract %10 %97 6
|
||||
%108 = OpFConvert %11 %107
|
||||
OpStore %47 %108
|
||||
%109 = OpCompositeExtract %11 %97 7
|
||||
OpStore %49 %109
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%140 = OpFunction %2 None %51
|
||||
%110 = OpLabel
|
||||
%141 = OpVariable %61 Function %142
|
||||
%113 = OpLoad %5 %112
|
||||
%114 = OpFConvert %4 %113
|
||||
%116 = OpLoad %5 %115
|
||||
%118 = OpLoad %7 %117
|
||||
%119 = OpFConvert %6 %118
|
||||
%121 = OpLoad %7 %120
|
||||
%123 = OpLoad %9 %122
|
||||
%124 = OpFConvert %8 %123
|
||||
%126 = OpLoad %9 %125
|
||||
%128 = OpLoad %11 %127
|
||||
%129 = OpFConvert %10 %128
|
||||
%131 = OpLoad %11 %130
|
||||
%111 = OpCompositeConstruct %12 %114 %116 %119 %121 %124 %126 %129 %131
|
||||
OpBranch %143
|
||||
%143 = OpLabel
|
||||
OpLine %3 40 5
|
||||
%144 = OpCompositeExtract %4 %111 0
|
||||
OpLine %3 40 25
|
||||
%145 = OpFAdd %4 %144 %52
|
||||
OpLine %3 40 5
|
||||
%146 = OpAccessChain %64 %141 %66
|
||||
OpStore %146 %145
|
||||
OpLine %3 41 5
|
||||
%147 = OpCompositeExtract %5 %111 1
|
||||
OpLine %3 41 25
|
||||
%148 = OpFAdd %5 %147 %53
|
||||
OpLine %3 41 5
|
||||
%149 = OpAccessChain %69 %141 %71
|
||||
OpStore %149 %148
|
||||
OpLine %3 42 5
|
||||
%150 = OpCompositeExtract %6 %111 2
|
||||
OpLine %3 42 23
|
||||
%151 = OpFAdd %6 %150 %54
|
||||
OpLine %3 42 5
|
||||
%152 = OpAccessChain %73 %141 %75
|
||||
OpStore %152 %151
|
||||
OpLine %3 43 5
|
||||
%153 = OpCompositeExtract %7 %111 3
|
||||
OpLine %3 43 40
|
||||
OpLine %3 43 23
|
||||
%154 = OpFAdd %7 %153 %55
|
||||
OpLine %3 43 5
|
||||
%155 = OpAccessChain %77 %141 %79
|
||||
OpStore %155 %154
|
||||
OpLine %3 44 5
|
||||
%156 = OpCompositeExtract %8 %111 4
|
||||
OpLine %3 44 23
|
||||
%157 = OpFAdd %8 %156 %56
|
||||
OpLine %3 44 5
|
||||
%158 = OpAccessChain %81 %141 %83
|
||||
OpStore %158 %157
|
||||
OpLine %3 45 5
|
||||
%159 = OpCompositeExtract %9 %111 5
|
||||
OpLine %3 45 40
|
||||
OpLine %3 45 23
|
||||
%160 = OpFAdd %9 %159 %57
|
||||
OpLine %3 45 5
|
||||
%161 = OpAccessChain %85 %141 %87
|
||||
OpStore %161 %160
|
||||
OpLine %3 46 5
|
||||
%162 = OpCompositeExtract %10 %111 6
|
||||
OpLine %3 46 23
|
||||
%163 = OpFAdd %10 %162 %58
|
||||
OpLine %3 46 5
|
||||
%164 = OpAccessChain %89 %141 %91
|
||||
OpStore %164 %163
|
||||
OpLine %3 47 5
|
||||
%165 = OpCompositeExtract %11 %111 7
|
||||
OpLine %3 47 40
|
||||
OpLine %3 47 23
|
||||
%166 = OpFAdd %11 %165 %59
|
||||
OpLine %3 47 5
|
||||
%167 = OpAccessChain %93 %141 %95
|
||||
OpStore %167 %166
|
||||
OpLine %3 1 1
|
||||
%168 = OpLoad %12 %141
|
||||
%169 = OpCompositeExtract %4 %168 0
|
||||
%170 = OpFConvert %5 %169
|
||||
OpStore %132 %170
|
||||
%171 = OpCompositeExtract %5 %168 1
|
||||
OpStore %133 %171
|
||||
%172 = OpCompositeExtract %6 %168 2
|
||||
%173 = OpFConvert %7 %172
|
||||
OpStore %134 %173
|
||||
%174 = OpCompositeExtract %7 %168 3
|
||||
OpStore %135 %174
|
||||
%175 = OpCompositeExtract %8 %168 4
|
||||
%176 = OpFConvert %9 %175
|
||||
OpStore %136 %176
|
||||
%177 = OpCompositeExtract %9 %168 5
|
||||
OpStore %137 %177
|
||||
%178 = OpCompositeExtract %10 %168 6
|
||||
%179 = OpFConvert %11 %178
|
||||
OpStore %138 %179
|
||||
%180 = OpCompositeExtract %11 %168 7
|
||||
OpStore %139 %180
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%211 = OpFunction %2 None %51
|
||||
%181 = OpLabel
|
||||
%212 = OpVariable %61 Function %213
|
||||
%214 = OpVariable %61 Function %215
|
||||
%184 = OpLoad %5 %183
|
||||
%185 = OpFConvert %4 %184
|
||||
%187 = OpLoad %5 %186
|
||||
%189 = OpLoad %7 %188
|
||||
%190 = OpFConvert %6 %189
|
||||
%192 = OpLoad %7 %191
|
||||
%194 = OpLoad %9 %193
|
||||
%195 = OpFConvert %8 %194
|
||||
%197 = OpLoad %9 %196
|
||||
%199 = OpLoad %11 %198
|
||||
%200 = OpFConvert %10 %199
|
||||
%202 = OpLoad %11 %201
|
||||
%182 = OpCompositeConstruct %12 %185 %187 %190 %192 %195 %197 %200 %202
|
||||
OpBranch %216
|
||||
%216 = OpLabel
|
||||
OpLine %3 53 5
|
||||
OpStore %212 %182
|
||||
OpLine %3 55 5
|
||||
%217 = OpAccessChain %64 %212 %66
|
||||
%218 = OpLoad %4 %217
|
||||
OpLine %3 55 25
|
||||
%219 = OpFAdd %4 %218 %52
|
||||
OpLine %3 55 5
|
||||
%220 = OpAccessChain %64 %214 %66
|
||||
OpStore %220 %219
|
||||
OpLine %3 56 5
|
||||
%221 = OpAccessChain %69 %212 %71
|
||||
%222 = OpLoad %5 %221
|
||||
OpLine %3 56 25
|
||||
%223 = OpFAdd %5 %222 %53
|
||||
OpLine %3 56 5
|
||||
%224 = OpAccessChain %69 %214 %71
|
||||
OpStore %224 %223
|
||||
OpLine %3 57 5
|
||||
%225 = OpAccessChain %73 %212 %75
|
||||
%226 = OpLoad %6 %225
|
||||
OpLine %3 57 23
|
||||
%227 = OpFAdd %6 %226 %54
|
||||
OpLine %3 57 5
|
||||
%228 = OpAccessChain %73 %214 %75
|
||||
OpStore %228 %227
|
||||
OpLine %3 58 5
|
||||
%229 = OpAccessChain %77 %212 %79
|
||||
%230 = OpLoad %7 %229
|
||||
OpLine %3 58 40
|
||||
OpLine %3 58 23
|
||||
%231 = OpFAdd %7 %230 %55
|
||||
OpLine %3 58 5
|
||||
%232 = OpAccessChain %77 %214 %79
|
||||
OpStore %232 %231
|
||||
OpLine %3 59 5
|
||||
%233 = OpAccessChain %81 %212 %83
|
||||
%234 = OpLoad %8 %233
|
||||
OpLine %3 59 23
|
||||
%235 = OpFAdd %8 %234 %56
|
||||
OpLine %3 59 5
|
||||
%236 = OpAccessChain %81 %214 %83
|
||||
OpStore %236 %235
|
||||
OpLine %3 60 5
|
||||
%237 = OpAccessChain %85 %212 %87
|
||||
%238 = OpLoad %9 %237
|
||||
OpLine %3 60 40
|
||||
OpLine %3 60 23
|
||||
%239 = OpFAdd %9 %238 %57
|
||||
OpLine %3 60 5
|
||||
%240 = OpAccessChain %85 %214 %87
|
||||
OpStore %240 %239
|
||||
OpLine %3 61 5
|
||||
%241 = OpAccessChain %89 %212 %91
|
||||
%242 = OpLoad %10 %241
|
||||
OpLine %3 61 23
|
||||
%243 = OpFAdd %10 %242 %58
|
||||
OpLine %3 61 5
|
||||
%244 = OpAccessChain %89 %214 %91
|
||||
OpStore %244 %243
|
||||
OpLine %3 62 5
|
||||
%245 = OpAccessChain %93 %212 %95
|
||||
%246 = OpLoad %11 %245
|
||||
OpLine %3 62 40
|
||||
OpLine %3 62 23
|
||||
%247 = OpFAdd %11 %246 %59
|
||||
OpLine %3 62 5
|
||||
%248 = OpAccessChain %93 %214 %95
|
||||
OpStore %248 %247
|
||||
OpLine %3 1 1
|
||||
%249 = OpLoad %12 %214
|
||||
%250 = OpCompositeExtract %4 %249 0
|
||||
%251 = OpFConvert %5 %250
|
||||
OpStore %203 %251
|
||||
%252 = OpCompositeExtract %5 %249 1
|
||||
OpStore %204 %252
|
||||
%253 = OpCompositeExtract %6 %249 2
|
||||
%254 = OpFConvert %7 %253
|
||||
OpStore %205 %254
|
||||
%255 = OpCompositeExtract %7 %249 3
|
||||
OpStore %206 %255
|
||||
%256 = OpCompositeExtract %8 %249 4
|
||||
%257 = OpFConvert %9 %256
|
||||
OpStore %207 %257
|
||||
%258 = OpCompositeExtract %9 %249 5
|
||||
OpStore %208 %258
|
||||
%259 = OpCompositeExtract %10 %249 6
|
||||
%260 = OpFConvert %11 %259
|
||||
OpStore %209 %260
|
||||
%261 = OpCompositeExtract %11 %249 7
|
||||
OpStore %210 %261
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%285 = OpFunction %2 None %51
|
||||
%262 = OpLabel
|
||||
%287 = OpVariable %61 Function %288
|
||||
%265 = OpLoad %5 %264
|
||||
%266 = OpFConvert %4 %265
|
||||
%268 = OpLoad %5 %267
|
||||
%270 = OpLoad %7 %269
|
||||
%271 = OpFConvert %6 %270
|
||||
%273 = OpLoad %7 %272
|
||||
%275 = OpLoad %9 %274
|
||||
%276 = OpFConvert %8 %275
|
||||
%278 = OpLoad %9 %277
|
||||
%280 = OpLoad %11 %279
|
||||
%281 = OpFConvert %10 %280
|
||||
%283 = OpLoad %11 %282
|
||||
%263 = OpCompositeConstruct %12 %266 %268 %271 %273 %276 %278 %281 %283
|
||||
OpBranch %289
|
||||
%289 = OpLabel
|
||||
OpLine %3 68 5
|
||||
OpStore %287 %263
|
||||
OpLine %3 69 5
|
||||
OpLine %3 69 5
|
||||
%290 = OpAccessChain %64 %287 %66
|
||||
OpStore %290 %286
|
||||
OpLine %3 70 12
|
||||
%291 = OpAccessChain %64 %287 %66
|
||||
%292 = OpLoad %4 %291
|
||||
%293 = OpFConvert %5 %292
|
||||
OpStore %284 %293
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%324 = OpFunction %2 None %51
|
||||
%294 = OpLabel
|
||||
%325 = OpVariable %61 Function %326
|
||||
%297 = OpLoad %5 %296
|
||||
%298 = OpFConvert %4 %297
|
||||
%300 = OpLoad %5 %299
|
||||
%302 = OpLoad %7 %301
|
||||
%303 = OpFConvert %6 %302
|
||||
%305 = OpLoad %7 %304
|
||||
%307 = OpLoad %9 %306
|
||||
%308 = OpFConvert %8 %307
|
||||
%310 = OpLoad %9 %309
|
||||
%312 = OpLoad %11 %311
|
||||
%313 = OpFConvert %10 %312
|
||||
%315 = OpLoad %11 %314
|
||||
%295 = OpCompositeConstruct %12 %298 %300 %303 %305 %308 %310 %313 %315
|
||||
OpBranch %327
|
||||
%327 = OpLabel
|
||||
OpLine %3 76 5
|
||||
%328 = OpCompositeExtract %6 %295 2
|
||||
%329 = OpCompositeExtract %4 %328 1
|
||||
OpLine %3 76 5
|
||||
%330 = OpAccessChain %64 %325 %75 %66
|
||||
OpStore %330 %329
|
||||
OpLine %3 77 5
|
||||
%331 = OpCompositeExtract %6 %295 2
|
||||
%332 = OpCompositeExtract %4 %331 0
|
||||
OpLine %3 77 5
|
||||
%333 = OpAccessChain %64 %325 %75 %71
|
||||
OpStore %333 %332
|
||||
OpLine %3 1 1
|
||||
%334 = OpLoad %12 %325
|
||||
%335 = OpCompositeExtract %4 %334 0
|
||||
%336 = OpFConvert %5 %335
|
||||
OpStore %316 %336
|
||||
%337 = OpCompositeExtract %5 %334 1
|
||||
OpStore %317 %337
|
||||
%338 = OpCompositeExtract %6 %334 2
|
||||
%339 = OpFConvert %7 %338
|
||||
OpStore %318 %339
|
||||
%340 = OpCompositeExtract %7 %334 3
|
||||
OpStore %319 %340
|
||||
%341 = OpCompositeExtract %8 %334 4
|
||||
%342 = OpFConvert %9 %341
|
||||
OpStore %320 %342
|
||||
%343 = OpCompositeExtract %9 %334 5
|
||||
OpStore %321 %343
|
||||
%344 = OpCompositeExtract %10 %334 6
|
||||
%345 = OpFConvert %11 %344
|
||||
OpStore %322 %345
|
||||
%346 = OpCompositeExtract %11 %334 7
|
||||
OpStore %323 %346
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
@ -198,6 +198,13 @@ impl PhysicalDeviceFeatures {
|
||||
info
|
||||
}
|
||||
|
||||
fn supports_storage_input_output_16(&self) -> bool {
|
||||
self._16bit_storage
|
||||
.as_ref()
|
||||
.map(|features| features.storage_input_output16 != 0)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Create a `PhysicalDeviceFeatures` that can be used to create a logical
|
||||
/// device.
|
||||
///
|
||||
@ -226,7 +233,7 @@ impl PhysicalDeviceFeatures {
|
||||
/// [`Adapter::required_device_extensions`]: super::Adapter::required_device_extensions
|
||||
fn from_extensions_and_requested_features(
|
||||
phd_capabilities: &PhysicalDeviceProperties,
|
||||
_phd_features: &PhysicalDeviceFeatures,
|
||||
phd_features: &PhysicalDeviceFeatures,
|
||||
enabled_extensions: &[&'static CStr],
|
||||
requested_features: wgt::Features,
|
||||
downlevel_flags: wgt::DownlevelFlags,
|
||||
@ -399,7 +406,7 @@ impl PhysicalDeviceFeatures {
|
||||
Some(
|
||||
vk::PhysicalDevice16BitStorageFeatures::default()
|
||||
.storage_buffer16_bit_access(true)
|
||||
.storage_input_output16(true)
|
||||
.storage_input_output16(phd_features.supports_storage_input_output_16())
|
||||
.uniform_and_storage_buffer16_bit_access(true),
|
||||
)
|
||||
} else {
|
||||
@ -736,12 +743,13 @@ impl PhysicalDeviceFeatures {
|
||||
|
||||
if let (Some(ref f16_i8), Some(ref bit16)) = (self.shader_float16_int8, self._16bit_storage)
|
||||
{
|
||||
// Note `storage_input_output16` is not required, we polyfill `f16` I/O using `f32`
|
||||
// types when this capability is not available
|
||||
features.set(
|
||||
F::SHADER_F16,
|
||||
f16_i8.shader_float16 != 0
|
||||
&& bit16.storage_buffer16_bit_access != 0
|
||||
&& bit16.uniform_and_storage_buffer16_bit_access != 0
|
||||
&& bit16.storage_input_output16 != 0,
|
||||
&& bit16.uniform_and_storage_buffer16_bit_access != 0,
|
||||
);
|
||||
}
|
||||
|
||||
@ -2148,6 +2156,8 @@ impl super::Adapter {
|
||||
spv::ZeroInitializeWorkgroupMemoryMode::Polyfill
|
||||
},
|
||||
force_loop_bounding: true,
|
||||
use_storage_input_output_16: features.contains(wgt::Features::SHADER_F16)
|
||||
&& self.phd_features.supports_storage_input_output_16(),
|
||||
// We need to build this separately for each invocation, so just default it out here
|
||||
binding_map: BTreeMap::default(),
|
||||
debug_info: None,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user