Bug 1955085 - build(webgpu): update WGPU to c6286791febc64cf8ef054b5356c2669327ef51c r=webgpu-reviewers,supply-chain-reviewers,nical

WRT WebGPU CTS, we have some interesting changes:

- Promotions from tier 3 to tier 2:
	- `webgpu:shader,execution,expression,call,builtin,textureStore:out_of_bounds:*`
	- All of `webgpu:shader,execution,expression,binary,ai_arithmetic:*` on Windows and Linux.
	- Some of `webgpu:shader,execution,expression,binary,bitwise:*` on Windows and Linux:
		- `…:bitwise_and:*`
		- `…:bitwise_exclusive_or:*`
		- `…:bitwise_or:*`
	- `webgpu:shader,execution,expression,call,builtin,textureStore:out_of_bounds:*`
	- Some of `webgpu:shader,execution,expression,unary,*` on Windows and Linux:
		- `…,ai_assignment:abstract:*`
		- `…,ai_assignment:abstract:*`
		- `…,ai_complement:complement:*`
	- `webgpu:shader,execution,limits:switch_case_selectors:*` on Windows and macOS.
	- `webgpu:shader,execution,limits:workgroup_array_byte_size_override:*` on all but Windows debug.
	- `webgpu:shader,execution,zero_init:compute,zero_init:*` on macOS.
	- `webgpu:shader,validation,expression,access,vector:abstract:*`
	- `webgpu:shader,validation,expression,call,builtin,textureGather:offset_argument,non_const:*` on all but Windows debug.
	- `webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument,non_const:*`
	- `webgpu:shader,validation,expression,call,builtin,textureSampleGrad:offset_argument,non_const:*`
	- Most of `webgpu:shader,validation,statement,switch:*`:
		- `…:case_types_match:*`
		- `…:condition_type_match_case_type:*`
		- `…:parse:*`

- Demotions from tier 2 to tier 3:
	- `webgpu:api,validation,capability_checks,limits,maxColorAttachmentBytesPerSample:beginRenderPass,at_over:*`

- Otherwise notable potential regressions:
	- `webgpu:shader,validation,expression,matrix,mul:overflow_scalar_abstract:*`

Differential Revision: https://phabricator.services.mozilla.com/D242218
This commit is contained in:
Erich Gubler
2025-03-21 17:32:17 +00:00
parent 3fe6f32b23
commit d89428603c
151 changed files with 7730 additions and 6348 deletions

View File

@@ -40,9 +40,9 @@ git = "https://github.com/franziskuskiefer/cose-rust"
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"]
[source."git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c"]
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
replace-with = "vendored-sources"
[source."git+https://github.com/glandium/rust-objc?rev=4de89f5aa9851ceca4d40e7ac1e2759410c04324"]

17
Cargo.lock generated
View File

@@ -2811,8 +2811,11 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
dependencies = [
"arbitrary",
"cfg-if",
"crunchy",
"num-traits",
"serde",
]
[[package]]
@@ -4504,17 +4507,19 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"arrayvec",
"bit-set",
"bitflags 2.9.0",
"cfg_aliases",
"codespan-reporting",
"half 2.5.0",
"hashbrown 0.14.5",
"hexf-parse",
"indexmap",
"log",
"num-traits",
"rustc-hash",
"serde",
"spirv",
@@ -7373,7 +7378,7 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"arrayvec",
"bit-vec",
@@ -7401,7 +7406,7 @@ dependencies = [
[[package]]
name = "wgpu-core-deps-apple"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"wgpu-hal",
]
@@ -7409,7 +7414,7 @@ dependencies = [
[[package]]
name = "wgpu-core-deps-windows-linux-android"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"wgpu-hal",
]
@@ -7417,7 +7422,7 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"android_system_properties",
"arrayvec",
@@ -7452,7 +7457,7 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "24.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c#dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
source = "git+https://github.com/gfx-rs/wgpu?rev=c6286791febc64cf8ef054b5356c2669327ef51c#c6286791febc64cf8ef054b5356c2669327ef51c"
dependencies = [
"bitflags 2.9.0",
"js-sys",

View File

@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* THIS FILE IS AUTOGENERATED FROM NotificationEvent.webidl BY Codegen.py - DO NOT EDIT */
#ifndef DOM_NOTIFICATIONEVENT_H_
#define DOM_NOTIFICATIONEVENT_H_
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/NotificationEventBinding.h"
#include "mozilla/dom/ServiceWorkerEvents.h"
struct JSContext;
namespace mozilla::dom {
class NotificationEvent : public ExtendableEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(NotificationEvent, ExtendableEvent)
protected:
virtual ~NotificationEvent();
explicit NotificationEvent(mozilla::dom::EventTarget* aOwner);
RefPtr<Notification> mNotification;
nsString mAction;
public:
NotificationEvent* AsNotificationEvent() override;
JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<NotificationEvent> Constructor(mozilla::dom::EventTarget* aOwner, const nsAString& aType, const NotificationEventInit& aEventInitDict);
static already_AddRefed<NotificationEvent> Constructor(const GlobalObject& aGlobal, const nsAString& aType, const NotificationEventInit& aEventInitDict);
Notification* Notification_() const;
void GetAction(nsString& aRetVal) const;
};
} // namespace mozilla::dom
#endif // DOM_NOTIFICATIONEVENT_H_

View File

@@ -17,7 +17,7 @@ default = []
[dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
# TODO: remove the replay feature on the next update containing https://github.com/gfx-rs/wgpu/pull/5182
features = ["serde", "replay", "trace", "strict_asserts", "wgsl", "api_log_info", "indirect-validation"]
@@ -26,32 +26,32 @@ features = ["serde", "replay", "trace", "strict_asserts", "wgsl", "api_log_info"
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
features = ["metal"]
# We want the wgpu-core Direct3D backends on Windows.
[target.'cfg(windows)'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
features = ["dx12"]
# We want the wgpu-core Vulkan backend on Linux and Windows.
[target.'cfg(any(windows, all(unix, not(any(target_os = "macos", target_os = "ios")))))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
features = ["vulkan"]
[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
[dependencies.wgh]
package = "wgpu-hal"
git = "https://github.com/gfx-rs/wgpu"
rev = "dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
rev = "c6286791febc64cf8ef054b5356c2669327ef51c"
features = ["oom_panic", "device_lost_panic", "internal_error_panic"]
[target.'cfg(windows)'.dependencies]

View File

@@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c (2025-03-07T03:44:36Z).
release: c6286791febc64cf8ef054b5356c2669327ef51c (2025-03-19T16:26:50Z).
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c
revision: c6286791febc64cf8ef054b5356c2669327ef51c
license: ['MIT', 'Apache-2.0']

View File

@@ -502,11 +502,16 @@ pub extern "C" fn wgpu_client_serialize_device_descriptor(
let label = wgpu_string(desc.label);
let required_features =
wgt::Features::from_internal_flags(wgt::FeaturesWGPU::empty(), desc.required_features);
let trace = std::env::var("WGPU_TRACE")
.ok()
.map(|p| wgt::Trace::Directory(p.into()))
.unwrap_or(wgt::Trace::Off);
let desc = wgt::DeviceDescriptor {
label,
required_features,
required_limits: desc.required_limits.clone(),
memory_hints: wgt::MemoryHints::MemoryUsage,
trace,
};
*bb = make_byte_buf(&desc);
}

View File

@@ -157,7 +157,7 @@ mod foreign {
queue::{QueueSubmitError, QueueWriteError},
DeviceError,
},
instance::{RequestAdapterError, RequestDeviceError},
instance::RequestDeviceError,
pipeline::{
CreateComputePipelineError, CreateRenderPipelineError, CreateShaderModuleError,
},
@@ -166,13 +166,16 @@ mod foreign {
CreateTextureError, CreateTextureViewError, DestroyError,
},
};
use wgt::RequestAdapterError;
use super::{ErrorBufferType, HasErrorBufferType};
impl HasErrorBufferType for RequestAdapterError {
fn error_type(&self) -> ErrorBufferType {
match self {
RequestAdapterError::NotFound => ErrorBufferType::Validation,
RequestAdapterError::NotFound { .. } | RequestAdapterError::EnvNotSet => {
ErrorBufferType::Validation
}
// N.B: forced non-exhaustiveness
_ => ErrorBufferType::Validation,

View File

@@ -408,18 +408,23 @@ pub unsafe extern "C" fn wgpu_server_adapter_request_device(
new_queue_id: id::QueueId,
mut error_buf: ErrorBuffer,
) {
let desc: wgc::device::DeviceDescriptor = bincode::deserialize(byte_buf.as_slice()).unwrap();
let trace_string = std::env::var("WGPU_TRACE").ok().map(|s| {
let idx = TRACE_IDX.fetch_add(1, Ordering::Relaxed);
let path = format!("{}/{}/", s, idx);
let mut desc: wgc::device::DeviceDescriptor =
bincode::deserialize(byte_buf.as_slice()).unwrap();
if std::fs::create_dir_all(&path).is_err() {
log::warn!("Failed to create directory {:?} for wgpu recording.", path);
desc.trace = match desc.trace {
wgt::Trace::Directory(s) => {
let idx = TRACE_IDX.fetch_add(1, Ordering::Relaxed);
let path = s.join(idx.to_string());
if std::fs::create_dir_all(&path).is_err() {
log::warn!("Failed to create directory {:?} for wgpu recording.", path);
}
wgt::Trace::Directory(path)
}
other => other,
};
path
});
let trace_path = trace_string.as_deref();
// TODO: in https://github.com/gfx-rs/wgpu/pull/3626/files#diff-033343814319f5a6bd781494692ea626f06f6c3acc0753a12c867b53a646c34eR97
// which introduced the queue id parameter, the queue id is also the device id. I don't know how applicable this is to
// other situations (this one in particular).
@@ -551,7 +556,6 @@ pub unsafe extern "C" fn wgpu_server_adapter_request_device(
self_id,
hal_device.into(),
&desc,
trace_path,
Some(new_device_id),
Some(new_queue_id),
);
@@ -562,13 +566,8 @@ pub unsafe extern "C" fn wgpu_server_adapter_request_device(
}
}
let res = global.adapter_request_device(
self_id,
&desc,
trace_path,
Some(new_device_id),
Some(new_queue_id),
);
let res =
global.adapter_request_device(self_id, &desc, Some(new_device_id), Some(new_queue_id));
if let Err(err) = res {
error_buf.init(err);
}

View File

@@ -3672,7 +3672,7 @@ who = [
"Erich Gubler <erichdongubler@gmail.com>",
]
criteria = "safe-to-deploy"
delta = "24.0.0 -> 24.0.0@git:dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
delta = "24.0.0 -> 24.0.0@git:c6286791febc64cf8ef054b5356c2669327ef51c"
importable = false
[[audits.net2]]
@@ -5906,7 +5906,7 @@ who = [
"Erich Gubler <erichdongubler@gmail.com>",
]
criteria = "safe-to-deploy"
delta = "24.0.0 -> 24.0.0@git:dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
delta = "24.0.0 -> 24.0.0@git:c6286791febc64cf8ef054b5356c2669327ef51c"
importable = false
[[audits.wgpu-hal]]
@@ -5993,7 +5993,7 @@ who = [
"Erich Gubler <erichdongubler@gmail.com>",
]
criteria = "safe-to-deploy"
delta = "24.0.0 -> 24.0.0@git:dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
delta = "24.0.0 -> 24.0.0@git:c6286791febc64cf8ef054b5356c2669327ef51c"
importable = false
[[audits.wgpu-types]]
@@ -6075,7 +6075,7 @@ who = [
"Erich Gubler <erichdongubler@gmail.com>",
]
criteria = "safe-to-deploy"
delta = "24.0.0 -> 24.0.0@git:dc02f91ffe1feab8c35d3fdf41f61a62a5004d2c"
delta = "24.0.0 -> 24.0.0@git:c6286791febc64cf8ef054b5356c2669327ef51c"
importable = false
[[audits.whatsys]]

View File

@@ -1,9 +1,6 @@
[cts.https.html?q=webgpu:api,validation,capability_checks,limits,maxColorAttachmentBytesPerSample:beginRenderPass,at_over:*]
implementation-status: backlog
expected:
if os == "win" and debug: [OK, TIMEOUT]
if os == "linux": [OK, TIMEOUT]
if os == "mac": [OK, TIMEOUT]
expected: [OK, TIMEOUT]
[:limitTest="atDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
@@ -101,385 +98,289 @@
if os == "mac": FAIL
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="overMaximum";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=4;interleaveFormat="r8unorm"]
@@ -490,7 +391,7 @@
[:limitTest="underDefault";testValueName="atLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=4;interleaveFormat="rg8unorm"]
@@ -501,7 +402,7 @@
[:limitTest="underDefault";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
@@ -511,24 +412,17 @@
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=1;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=1;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=1;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba16uint"]
expected:
@@ -537,44 +431,30 @@
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=1;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=4;interleaveFormat="r8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=4;interleaveFormat="rg16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=4;interleaveFormat="rg8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba16uint"]
expected:
if os == "win": FAIL
if os == "win" and debug: FAIL
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";sampleCount=4;interleaveFormat="rgba8unorm"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
expected: [FAIL, TIMEOUT, NOTRUN]
[cts.https.html?q=webgpu:api,validation,capability_checks,limits,maxColorAttachmentBytesPerSample:createRenderBundle,at_over:*]

View File

@@ -2012,7 +2012,8 @@
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=1;order="forward"]
expected:

View File

@@ -1079,8 +1079,7 @@
[:limitTest="atDefault";testValueName="atLimit";visibility=5;type="read-only-storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=5;type="read-only-storage";order="forward"]
@@ -1093,8 +1092,7 @@
[:limitTest="atDefault";testValueName="atLimit";visibility=5;type="read-only-storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="read-only-storage";order="backward"]
@@ -1106,8 +1104,7 @@
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="read-only-storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="read-only-storage";order="shiftByHalf"]
@@ -1119,22 +1116,19 @@
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=6;type="storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac": FAIL
[:limitTest="atDefault";testValueName="atLimit";visibility=7;type="read-only-storage";order="backward"]
@@ -1173,136 +1167,117 @@
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="read-only-storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="read-only-storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="read-only-storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=2;type="storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=3;type="read-only-storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=3;type="read-only-storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=3;type="read-only-storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="read-only-storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="read-only-storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="read-only-storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="storage";order="backward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=4;type="storage";order="shiftByHalf"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=5;type="read-only-storage";order="backward"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=5;type="read-only-storage";order="forward"]
expected:
if os == "win": FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=5;type="read-only-storage";order="shiftByHalf"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=6;type="read-only-storage";order="backward"]
expected:
@@ -1330,16 +1305,14 @@
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=6;type="storage";order="forward"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";visibility=6;type="storage";order="shiftByHalf"]
expected:

View File

@@ -805,8 +805,12 @@
[:limitTest="atDefault";testValueName="atLimit";async=false;bindingCombination="vertexAndFragmentWithPossibleVertexStageOverflow";access="read-only"]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="read-only"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="read-write"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="write-only"]
expected:
@@ -817,12 +821,18 @@
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="fragment";access="read-write"]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="fragment";access="write-only"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="vertex";access="read-only"]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleFragmentStageOverflow";access="read-only"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="atLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleVertexStageOverflow";access="read-only"]
expected:
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="atDefault";testValueName="overLimit";async=false;bindingCombination="compute";access="read-only"]
expected:
@@ -1152,13 +1162,13 @@
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";async=false;bindingCombination="fragment";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";async=false;bindingCombination="fragment";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";async=false;bindingCombination="fragment";access="write-only"]
@@ -1170,7 +1180,7 @@
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";async=false;bindingCombination="vertex";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="betweenDefaultAndMaximum";testValueName="atLimit";async=false;bindingCombination="vertexAndFragmentWithPossibleFragmentStageOverflow";access="read-only"]
@@ -1578,7 +1588,7 @@
[:limitTest="underDefault";testValueName="atLimit";async=false;bindingCombination="compute";access="write-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=false;bindingCombination="fragment";access="read-only"]
@@ -1608,171 +1618,167 @@
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="compute";access="write-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="fragment";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="fragment";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="fragment";access="write-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="vertex";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleFragmentStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="atLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleVertexStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="compute";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="compute";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="compute";access="write-only"]
expected:
if os == "win": [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="fragment";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="fragment";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="fragment";access="write-only"]
expected:
if os == "win": [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="vertex";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="vertexAndFragmentWithPossibleFragmentStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=false;bindingCombination="vertexAndFragmentWithPossibleVertexStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="compute";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="compute";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="compute";access="write-only"]
expected:
if os == "win": [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="fragment";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="fragment";access="read-write"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="fragment";access="write-only"]
expected:
if os == "win": [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="vertex";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleFragmentStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:limitTest="underDefault";testValueName="overLimit";async=true;bindingCombination="vertexAndFragmentWithPossibleVertexStageOverflow";access="read-only"]
expected:
if os == "win": [PASS, TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]

View File

@@ -80,12 +80,14 @@
[:errorFilter="out-of-memory";stackDepth=100000]
expected:
if os == "win": FAIL
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: FAIL
if os == "mac" and not debug: [FAIL, TIMEOUT, NOTRUN]
[:errorFilter="validation";stackDepth=1]
expected:
if os == "win": FAIL
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
[:errorFilter="validation";stackDepth=10]

View File

@@ -8420,8 +8420,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="bgra8unorm";dimension="2d"]
expected:
@@ -8429,8 +8428,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="bgra8unorm";dimension="3d"]
expected:
@@ -8438,8 +8436,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="bgra8unorm-srgb";dimension="1d"]
expected:
@@ -8447,8 +8444,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="bgra8unorm-srgb";dimension="2d"]
expected:
@@ -8456,8 +8452,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="bgra8unorm-srgb";dimension="3d"]
expected:
@@ -8465,8 +8460,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="depth16unorm";dimension="2d"]
expected:
@@ -8590,8 +8584,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="r16uint";dimension="2d"]
expected:
@@ -8599,8 +8592,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="r16uint";dimension="3d"]
expected:
@@ -9194,8 +9186,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8sint";dimension="2d"]
expected:
@@ -9203,8 +9194,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8sint";dimension="3d"]
expected:
@@ -9212,8 +9202,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8snorm";dimension="1d"]
expected:
@@ -9221,8 +9210,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8snorm";dimension="2d"]
expected:
@@ -9230,8 +9218,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8snorm";dimension="3d"]
expected:
@@ -9239,8 +9226,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8uint";dimension="1d"]
expected:
@@ -9248,8 +9234,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8uint";dimension="2d"]
expected:
@@ -9257,8 +9242,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8uint";dimension="3d"]
expected:
@@ -9266,8 +9250,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8unorm";dimension="1d"]
expected:
@@ -9311,8 +9294,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="rgba8unorm-srgb";dimension="3d"]
expected:
@@ -9320,8 +9302,7 @@
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: FAIL
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if os == "mac": [FAIL, TIMEOUT, NOTRUN]
[:method="WriteTexture";format="stencil8";dimension="2d"]
expected:

View File

@@ -1,193 +1,230 @@
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:addition:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:addition_scalar_vector:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_rhs=2]
expected: FAIL
[:inputSource="const";vectorize_rhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:addition_vector_scalar:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_lhs=2]
expected: FAIL
[:inputSource="const";vectorize_lhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:division:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:division_scalar_vector:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_rhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:division_vector_scalar:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_lhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:multiplication:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:multiplication_scalar_vector:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_rhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:multiplication_vector_scalar:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_lhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:remainder:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:remainder_scalar_vector:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_rhs=2]
expected: FAIL
[:inputSource="const";vectorize_rhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:remainder_vector_scalar:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_lhs=2]
expected: FAIL
[:inputSource="const";vectorize_lhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:subtraction:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:subtraction_scalar_vector:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_rhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_rhs=4]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,binary,ai_arithmetic:subtraction_vector_scalar:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize_lhs=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize_lhs=4]
expected: FAIL
expected:
if os == "mac": FAIL

View File

@@ -1,16 +1,21 @@
[cts.https.html?q=webgpu:shader,execution,expression,binary,bitwise:bitwise_and:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:type="abstract-int";inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="storage_r";vectorize="_undef_"]
@@ -178,18 +183,17 @@
[cts.https.html?q=webgpu:shader,execution,expression,binary,bitwise:bitwise_exclusive_or:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:type="abstract-int";inputSource="const";vectorize="_undef_"]
expected: FAIL
[:type="abstract-int";inputSource="const";vectorize=2]
expected: FAIL
[:type="abstract-int";inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=4]
expected: FAIL
[:type="abstract-int";inputSource="storage_r";vectorize="_undef_"]
@@ -357,18 +361,23 @@
[cts.https.html?q=webgpu:shader,execution,expression,binary,bitwise:bitwise_or:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:type="abstract-int";inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL
[:type="abstract-int";inputSource="storage_r";vectorize="_undef_"]

View File

@@ -9005,14 +9005,12 @@
[:case=716;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=716;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=716;type="f32";wgSize=[128,1,1\]]
@@ -9598,6 +9596,7 @@
[:case=739;type="f16";wgSize=[128,1,1\]]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -9605,6 +9604,7 @@
[:case=739;type="f16";wgSize=[64,2,1\]]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -9648,6 +9648,7 @@
[:case=740;type="f32";wgSize=[128,1,1\]]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -9717,28 +9718,56 @@
if os == "mac": [TIMEOUT, NOTRUN]
[:case=743;type="f16";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=743;type="f16";wgSize=[64,2,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=743;type="f32";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=743;type="f32";wgSize=[64,2,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=744;type="f16";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=744;type="f16";wgSize=[64,2,1\]]
expected: [TIMEOUT, NOTRUN]
[:case=744;type="f32";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=744;type="f32";wgSize=[64,2,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=745;type="f16";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]

View File

@@ -3361,13 +3361,11 @@
[:case=422;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=422;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=422;type="f32";wgSize=[128,1,1\]]
expected:
@@ -3375,148 +3373,119 @@
[:case=422;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=423;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=423;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=423;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=423;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=424;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=424;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=424;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=424;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=425;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=425;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=425;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=425;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=426;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=426;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=426;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=426;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=427;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=427;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=427;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=427;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=428;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=428;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=428;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=428;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=429;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=429;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=429;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=429;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=42;type="f16";wgSize=[128,1,1\]]
@@ -3528,123 +3497,99 @@
[:case=430;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=430;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=430;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=430;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=431;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=431;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=431;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=431;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=432;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=432;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=432;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=432;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=433;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=433;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=433;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=433;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=434;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=434;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=434;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=434;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=435;type="f16";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=435;type="f16";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=435;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=435;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=436;type="f16";wgSize=[128,1,1\]]
expected:
@@ -3658,13 +3603,11 @@
[:case=436;type="f32";wgSize=[128,1,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=436;type="f32";wgSize=[64,2,1\]]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:case=437;type="f16";wgSize=[128,1,1\]]
expected:
@@ -8720,14 +8663,12 @@
[:case=704;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=704;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=704;type="f32";wgSize=[128,1,1\]]
@@ -8737,128 +8678,107 @@
[:case=704;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=705;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=705;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=705;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=705;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=706;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=706;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=706;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=706;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=707;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=707;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=707;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=707;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=708;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=708;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=708;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=708;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=709;type="f16";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=709;type="f16";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=709;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=709;type="f32";wgSize=[64,2,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=70;type="f16";wgSize=[128,1,1\]]
@@ -8883,8 +8803,7 @@
[:case=710;type="f32";wgSize=[128,1,1\]]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=710;type="f32";wgSize=[64,2,1\]]
@@ -9415,6 +9334,7 @@
[:case=732;type="f16";wgSize=[128,1,1\]]
expected:
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -9759,10 +9679,18 @@
expected: [TIMEOUT, NOTRUN]
[:case=744;type="f32";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=744;type="f32";wgSize=[64,2,1\]]
expected: [TIMEOUT, NOTRUN]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:case=745;type="f16";wgSize=[128,1,1\]]
expected: [TIMEOUT, NOTRUN]

View File

@@ -34,203 +34,203 @@
if os == "linux" and debug: [OK, TIMEOUT]
[:format="astc-10x10-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x10-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x5-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x5-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x6-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x6-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x8-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-10x8-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-12x10-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-12x10-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-12x12-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-12x12-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-4x4-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-4x4-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-5x4-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-5x4-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-5x5-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-5x5-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-6x5-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-6x5-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-6x6-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-6x6-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x5-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x5-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x6-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x6-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x8-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="astc-8x8-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bc1-rgba-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc1-rgba-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc2-rgba-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc2-rgba-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc3-rgba-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc3-rgba-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc4-r-snorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc4-r-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc5-rg-snorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bc5-rg-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="bc6h-rgb-float";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bc6h-rgb-ufloat";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bc7-rgba-unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bc7-rgba-unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="bgra8unorm";aspect="all";samples=1]
@@ -253,7 +253,7 @@
[:format="depth24plus-stencil8";aspect="depth-only";samples=1]
expected:
if os == "win" and not debug: [PASS, FAIL]
if os == "win": [PASS, FAIL]
[:format="depth24plus-stencil8";aspect="depth-only";samples=4]
expected:
@@ -273,70 +273,68 @@
[:format="depth32float-stencil8";aspect="depth-only";samples=1]
expected:
if os == "win" and debug: [PASS, FAIL]
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="depth32float-stencil8";aspect="depth-only";samples=4]
expected:
if os == "win" and debug: [PASS, FAIL]
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="depth32float-stencil8";aspect="stencil-only";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="depth32float-stencil8";aspect="stencil-only";samples=4]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
[:format="eac-r11snorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="eac-r11unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="eac-rg11snorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="eac-rg11unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgb8a1unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgb8a1unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgb8unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgb8unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgba8unorm";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="etc2-rgba8unorm-srgb";aspect="all";samples=1]
expected:
if os == "win" and not debug: FAIL
if os == "win": [PASS, FAIL]
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="r16float";aspect="all";samples=1]

View File

@@ -5034,20 +5034,19 @@
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="r16float";filt="linear";mode="m"]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="r16float";filt="linear";mode="r"]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="r16float";filt="nearest";mode="c"]
expected:
@@ -5111,7 +5110,8 @@
[:stage="f";format="r32float";filt="linear";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="r32float";filt="linear";mode="r"]
@@ -5316,7 +5316,7 @@
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="rg16sint";filt="nearest";mode="m"]
expected:
@@ -5328,84 +5328,97 @@
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and not debug: [TIMEOUT, NOTRUN]
[:stage="f";format="rg16uint";filt="nearest";mode="c"]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="rg16uint";filt="nearest";mode="m"]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="rg16uint";filt="nearest";mode="r"]
expected:
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="linear";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="linear";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="linear";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="nearest";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="nearest";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32float";filt="nearest";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32sint";filt="nearest";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32sint";filt="nearest";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32sint";filt="nearest";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32uint";filt="nearest";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32uint";filt="nearest";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg32uint";filt="nearest";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rg8sint";filt="nearest";mode="c"]
@@ -5659,32 +5672,38 @@
[:stage="f";format="rgba32sint";filt="nearest";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba32sint";filt="nearest";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba32sint";filt="nearest";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba32uint";filt="nearest";mode="c"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba32uint";filt="nearest";mode="m"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba32uint";filt="nearest";mode="r"]
expected:
if os == "linux": [TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="f";format="rgba8sint";filt="nearest";mode="c"]
@@ -8526,7 +8545,7 @@
[:stage="v";format="rgba8snorm";filt="linear";mode="c"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -8544,19 +8563,19 @@
[:stage="v";format="rgba8snorm";filt="nearest";mode="c"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="v";format="rgba8snorm";filt="nearest";mode="m"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="v";format="rgba8snorm";filt="nearest";mode="r"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
@@ -8616,19 +8635,19 @@
[:stage="v";format="rgba8unorm-srgb";filt="linear";mode="c"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="v";format="rgba8unorm-srgb";filt="linear";mode="m"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]
[:stage="v";format="rgba8unorm-srgb";filt="linear";mode="r"]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux": [TIMEOUT, NOTRUN]
if os == "mac": [TIMEOUT, NOTRUN]

View File

@@ -2100,12 +2100,8 @@
[:format="depth16unorm";filt="nearest";mode="c"]
expected:
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and not debug: FAIL
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
[:format="depth16unorm";filt="nearest";mode="m"]
expected:
@@ -2680,6 +2676,7 @@
[:format="rgb9e5ufloat";filt="linear";mode="c"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="rgb9e5ufloat";filt="linear";mode="m"]
expected:
@@ -2689,6 +2686,7 @@
[:format="rgb9e5ufloat";filt="linear";mode="r"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="rgb9e5ufloat";filt="nearest";mode="c"]
expected:
@@ -2697,10 +2695,12 @@
[:format="rgb9e5ufloat";filt="nearest";mode="m"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="rgb9e5ufloat";filt="nearest";mode="r"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="rgba16float";filt="linear";mode="c"]

View File

@@ -1338,27 +1338,18 @@
[:format="depth16unorm";filt="nearest";mode="c"]
expected:
if os == "win": FAIL
if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and not debug: FAIL
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
[:format="depth16unorm";filt="nearest";mode="m"]
expected:
if os == "win": FAIL
if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and not debug: FAIL
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
[:format="depth16unorm";filt="nearest";mode="r"]
expected:
if os == "win": FAIL
if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and not debug: FAIL
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
[:format="depth24plus";filt="nearest";mode="c"]
expected:
@@ -1392,11 +1383,8 @@
[:format="depth32float";filt="nearest";mode="c"]
expected:
if os == "win": FAIL
if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and not debug: FAIL
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
[:format="depth32float";filt="nearest";mode="m"]
expected:
@@ -1832,6 +1820,8 @@
[:format="r8unorm";filt="nearest";mode="r"]
[:format="rg11b10ufloat";filt="linear";mode="c"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:format="rg11b10ufloat";filt="linear";mode="m"]
expected:
@@ -1913,8 +1903,7 @@
[:format="rgb9e5ufloat";filt="linear";mode="m"]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if debug: [PASS, TIMEOUT, NOTRUN]
[:format="rgb9e5ufloat";filt="linear";mode="r"]
expected:

View File

@@ -1036,8 +1036,11 @@
[:format="depth24plus";filt="nearest";modeU="r";modeV="c";offset=true]
expected:
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
[:format="depth24plus";filt="nearest";modeU="r";modeV="m";offset=false]
expected:
@@ -1059,8 +1062,11 @@
[:format="depth24plus";filt="nearest";modeU="r";modeV="r";offset=false]
expected:
if debug: [FAIL, TIMEOUT, NOTRUN]
if not debug: FAIL
if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "win" and not debug: FAIL
if os == "linux": [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
[:format="depth24plus";filt="nearest";modeU="r";modeV="r";offset=true]
expected:

View File

@@ -3,7 +3,6 @@
[cts.https.html?q=webgpu:shader,execution,expression,call,builtin,textureStore:out_of_bounds:*]
implementation-status: backlog
[:dim="1d";coords="i32";mipCount=1;mip=0]
[:dim="1d";coords="u32";mipCount=1;mip=0]
@@ -33,22 +32,16 @@
[:dim="2d";coords="u32";mipCount=3;mip=2]
[:dim="3d";coords="i32";mipCount=1;mip=0]
expected: FAIL
[:dim="3d";coords="i32";mipCount=2;mip=0]
expected: FAIL
[:dim="3d";coords="i32";mipCount=2;mip=1]
expected: FAIL
[:dim="3d";coords="u32";mipCount=1;mip=0]
expected: FAIL
[:dim="3d";coords="u32";mipCount=2;mip=0]
expected: FAIL
[:dim="3d";coords="u32";mipCount=2;mip=1]
expected: FAIL
[cts.https.html?q=webgpu:shader,execution,expression,call,builtin,textureStore:out_of_bounds_array:*]

View File

@@ -1,13 +1,18 @@
[cts.https.html?q=webgpu:shader,execution,expression,unary,ai_arithmetic:negation:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL

View File

@@ -1,7 +1,9 @@
[cts.https.html?q=webgpu:shader,execution,expression,unary,ai_assignment:abstract:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const"]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:shader,execution,expression,unary,ai_assignment:i32:*]

View File

@@ -1,13 +1,18 @@
[cts.https.html?q=webgpu:shader,execution,expression,unary,ai_complement:complement:*]
implementation-status: backlog
implementation-status:
if os == "mac": backlog
[:inputSource="const";vectorize="_undef_"]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=2]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=3]
expected: FAIL
expected:
if os == "mac": FAIL
[:inputSource="const";vectorize=4]
expected: FAIL
expected:
if os == "mac": FAIL

View File

@@ -63,9 +63,11 @@
[cts.https.html?q=webgpu:shader,execution,limits:switch_case_selectors:*]
implementation-status: backlog
implementation-status:
if os == "linux": backlog
[:]
expected: FAIL
expected:
if os == "linux": FAIL
[cts.https.html?q=webgpu:shader,execution,limits:switch_case_selectors_same_clause:*]
@@ -84,18 +86,12 @@
[cts.https.html?q=webgpu:shader,execution,limits:workgroup_array_byte_size_override:*]
implementation-status: backlog
expected:
if os == "linux": CRASH
if os == "mac": CRASH
implementation-status:
if os == "win" and debug: backlog
[:type="bool"]
expected:
if os == "win" and debug: [PASS, FAIL]
if os == "linux": FAIL
if os == "mac": FAIL
[:type="u32"]
expected: FAIL
[:type="vec4u"]
expected: FAIL

View File

@@ -1,5 +1,4 @@
[cts.https.html?q=webgpu:shader,validation,expression,access,vector:abstract:*]
implementation-status: backlog
[:vector_width=2;abstract_type="float";concrete_type="f16"]
[:vector_width=2;abstract_type="float";concrete_type="f32"]
@@ -11,12 +10,10 @@
[:vector_width=2;abstract_type="int";concrete_type="f16"]
[:vector_width=2;abstract_type="int";concrete_type="f32"]
expected: FAIL
[:vector_width=2;abstract_type="int";concrete_type="i32"]
[:vector_width=2;abstract_type="int";concrete_type="u32"]
expected: FAIL
[:vector_width=3;abstract_type="float";concrete_type="f16"]
@@ -29,12 +26,10 @@
[:vector_width=3;abstract_type="int";concrete_type="f16"]
[:vector_width=3;abstract_type="int";concrete_type="f32"]
expected: FAIL
[:vector_width=3;abstract_type="int";concrete_type="i32"]
[:vector_width=3;abstract_type="int";concrete_type="u32"]
expected: FAIL
[:vector_width=4;abstract_type="float";concrete_type="f16"]
@@ -47,12 +42,10 @@
[:vector_width=4;abstract_type="int";concrete_type="f16"]
[:vector_width=4;abstract_type="int";concrete_type="f32"]
expected: FAIL
[:vector_width=4;abstract_type="int";concrete_type="i32"]
[:vector_width=4;abstract_type="int";concrete_type="u32"]
expected: FAIL
[cts.https.html?q=webgpu:shader,validation,expression,access,vector:concrete:*]

View File

@@ -1893,7 +1893,7 @@
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="i32"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="u32"]
expected:
@@ -1921,7 +1921,7 @@
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec2%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec2%3Cu32%3E"]
expected:
@@ -1949,7 +1949,7 @@
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec3%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec3%3Cu32%3E"]
expected:
@@ -1977,7 +1977,7 @@
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec4%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="quadSwapX";paramType="vec4%3Cu32%3E"]
expected:

View File

@@ -220,7 +220,8 @@
implementation-status:
if os == "mac": backlog
expected:
if os == "mac": TIMEOUT
if os == "mac" and debug: [OK, TIMEOUT]
if os == "mac" and not debug: TIMEOUT
[:retType="bool";op="subgroupAnd";paramType="abstract-float"]
[:retType="bool";op="subgroupAnd";paramType="abstract-int"]
@@ -1877,7 +1878,7 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="i32"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="u32"]
expected:
@@ -1897,15 +1898,15 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec2%3Cf16%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec2%3Cf32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec2%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec2%3Cu32%3E"]
expected:
@@ -1913,7 +1914,7 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec3%3Cabstract-float%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec3%3Cabstract-int%3E"]
expected:
@@ -1925,11 +1926,11 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec3%3Cf16%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec3%3Cf32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec3%3Ci32%3E"]
expected:
@@ -1941,7 +1942,7 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec4%3Cabstract-float%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec4%3Cabstract-int%3E"]
expected:
@@ -1953,11 +1954,11 @@
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec4%3Cf16%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec4%3Cf32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec2%3Cu32%3E";op="subgroupOr";paramType="vec4%3Ci32%3E"]
expected:
@@ -4005,13 +4006,11 @@
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="i32"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="u32"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec2%3Cabstract-float%3E"]
expected:
@@ -4035,13 +4034,11 @@
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec2%3Ci32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec2%3Cu32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec3%3Cabstract-float%3E"]
expected:
@@ -4065,13 +4062,11 @@
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec3%3Ci32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec3%3Cu32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec4%3Cabstract-float%3E"]
expected:
@@ -4087,8 +4082,7 @@
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec4%3Cf16%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec4%3Cf32%3E"]
expected:
@@ -4096,13 +4090,11 @@
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec4%3Ci32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[:retType="vec4%3Cu32%3E";op="subgroupXor";paramType="vec4%3Cu32%3E"]
expected:
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac": [PASS, TIMEOUT, NOTRUN]
[cts.https.html?q=webgpu:shader,validation,expression,call,builtin,subgroupBitwise:stage:*]

View File

@@ -1396,8 +1396,12 @@
[:retType="i32";op="subgroupShuffleUp";paramType="f32"]
[:retType="i32";op="subgroupShuffleUp";paramType="i32"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="u32"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec2%3Cabstract-float%3E"]
@@ -1410,8 +1414,12 @@
[:retType="i32";op="subgroupShuffleUp";paramType="vec2%3Cf32%3E"]
[:retType="i32";op="subgroupShuffleUp";paramType="vec2%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec2%3Cu32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec3%3Cabstract-float%3E"]
@@ -1424,8 +1432,12 @@
[:retType="i32";op="subgroupShuffleUp";paramType="vec3%3Cf32%3E"]
[:retType="i32";op="subgroupShuffleUp";paramType="vec3%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec3%3Cu32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Cabstract-float%3E"]
@@ -1434,10 +1446,14 @@
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Cbool%3E"]
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Cf16%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Cf32%3E"]
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Ci32%3E"]
expected:
if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN]
[:retType="i32";op="subgroupShuffleUp";paramType="vec4%3Cu32%3E"]
expected:

View File

@@ -2985,9 +2985,9 @@
[cts.https.html?q=webgpu:shader,validation,expression,call,builtin,textureGather:offset_argument,non_const:*]
implementation-status: backlog
implementation-status:
if os == "win" and debug: backlog
[:textureType="texture_2d";sampleType="vec4%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d";sampleType="vec4%3Cf32%3E";varType="l"]
expected:
@@ -2998,7 +2998,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_2d";sampleType="vec4%3Ci32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d";sampleType="vec4%3Ci32%3E";varType="l"]
expected:
@@ -3009,7 +3008,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_2d";sampleType="vec4%3Cu32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d";sampleType="vec4%3Cu32%3E";varType="l"]
expected:
@@ -3020,7 +3018,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_2d_array";sampleType="vec4%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d_array";sampleType="vec4%3Cf32%3E";varType="l"]
expected:
@@ -3031,7 +3028,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_2d_array";sampleType="vec4%3Ci32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d_array";sampleType="vec4%3Ci32%3E";varType="l"]
expected:
@@ -3042,7 +3038,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_2d_array";sampleType="vec4%3Cu32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d_array";sampleType="vec4%3Cu32%3E";varType="l"]
expected:
@@ -3053,7 +3048,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_depth_2d";sampleType="vec4%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d";sampleType="vec4%3Cf32%3E";varType="l"]
expected:
@@ -3064,7 +3058,6 @@
if os == "win" and debug: [PASS, FAIL]
[:textureType="texture_depth_2d_array";sampleType="vec4%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d_array";sampleType="vec4%3Cf32%3E";varType="l"]
expected:

View File

@@ -807,37 +807,31 @@
[cts.https.html?q=webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument,non_const:*]
implementation-status: backlog
[:textureType="texture_2d%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d%3Cf32%3E";varType="l"]
[:textureType="texture_2d%3Cf32%3E";varType="u"]
[:textureType="texture_2d_array%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d_array%3Cf32%3E";varType="l"]
[:textureType="texture_2d_array%3Cf32%3E";varType="u"]
[:textureType="texture_3d%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_3d%3Cf32%3E";varType="l"]
[:textureType="texture_3d%3Cf32%3E";varType="u"]
[:textureType="texture_depth_2d";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d";varType="l"]
[:textureType="texture_depth_2d";varType="u"]
[:textureType="texture_depth_2d_array";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d_array";varType="l"]

View File

@@ -986,23 +986,19 @@
[cts.https.html?q=webgpu:shader,validation,expression,call,builtin,textureSampleGrad:offset_argument,non_const:*]
implementation-status: backlog
[:textureType="texture_2d%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d%3Cf32%3E";varType="l"]
[:textureType="texture_2d%3Cf32%3E";varType="u"]
[:textureType="texture_2d_array%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_2d_array%3Cf32%3E";varType="l"]
[:textureType="texture_2d_array%3Cf32%3E";varType="u"]
[:textureType="texture_3d%3Cf32%3E";varType="c"]
expected: FAIL
[:textureType="texture_3d%3Cf32%3E";varType="l"]

View File

@@ -1306,14 +1306,12 @@
[:textureType="texture_3d%3Cf32%3E";varType="u"]
[:textureType="texture_depth_2d";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d";varType="l"]
[:textureType="texture_depth_2d";varType="u"]
[:textureType="texture_depth_2d_array";varType="c"]
expected: FAIL
[:textureType="texture_depth_2d_array";varType="l"]

View File

@@ -467,49 +467,49 @@
[cts.https.html?q=webgpu:shader,validation,expression,matrix,mul:overflow_scalar_abstract:*]
implementation-status: backlog
[:rhs=1.7976931348623157e%2B308;c=2;r=2]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=2;r=3]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=2;r=4]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=3;r=2]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=3;r=3]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=3;r=4]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=4;r=2]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=4;r=3]
expected: FAIL
[:rhs=1.7976931348623157e%2B308;c=4;r=4]
expected: FAIL
[:rhs=1;c=2;r=2]
expected: FAIL
[:rhs=1;c=2;r=3]
expected: FAIL
[:rhs=1;c=2;r=4]
expected: FAIL
[:rhs=1;c=3;r=2]
expected: FAIL
[:rhs=1;c=3;r=3]
expected: FAIL
[:rhs=1;c=3;r=4]
expected: FAIL
[:rhs=1;c=4;r=2]
expected: FAIL
[:rhs=1;c=4;r=3]
expected: FAIL
[:rhs=1;c=4;r=4]
expected: FAIL
[cts.https.html?q=webgpu:shader,validation,expression,matrix,mul:overflow_scalar_f16:*]

View File

@@ -1,11 +1,9 @@
[cts.https.html?q=webgpu:shader,validation,statement,switch:case_types_match:*]
implementation-status: backlog
[:case_a_type="abstract-int";case_b_type="abstract-int"]
[:case_a_type="abstract-int";case_b_type="i32"]
[:case_a_type="abstract-int";case_b_type="u32"]
expected: FAIL
[:case_a_type="i32";case_b_type="abstract-int"]
@@ -14,12 +12,10 @@
[:case_a_type="i32";case_b_type="u32"]
[:case_a_type="u32";case_b_type="abstract-int"]
expected: FAIL
[:case_a_type="u32";case_b_type="i32"]
[:case_a_type="u32";case_b_type="u32"]
expected: FAIL
[cts.https.html?q=webgpu:shader,validation,statement,switch:condition_type:*]
@@ -52,19 +48,16 @@
[:type="texture"]
[:type="u32"]
expected: FAIL
[:type="vec2af"]
[:type="vec2ai"]
expected: FAIL
[:type="vec2f"]
[:type="vec3af"]
[:type="vec3ai"]
expected: FAIL
[:type="vec3b"]
@@ -73,19 +66,16 @@
[:type="vec4af"]
[:type="vec4ai"]
expected: FAIL
[:type="vec4u"]
[cts.https.html?q=webgpu:shader,validation,statement,switch:condition_type_match_case_type:*]
implementation-status: backlog
[:cond_type="abstract-int";case_type="abstract-int"]
[:cond_type="abstract-int";case_type="i32"]
[:cond_type="abstract-int";case_type="u32"]
expected: FAIL
[:cond_type="i32";case_type="abstract-int"]
@@ -94,7 +84,6 @@
[:cond_type="i32";case_type="u32"]
[:cond_type="u32";case_type="abstract-int"]
expected: FAIL
[:cond_type="u32";case_type="i32"]
@@ -102,7 +91,6 @@
[cts.https.html?q=webgpu:shader,validation,statement,switch:parse:*]
implementation-status: backlog
[:test="L_case_1_2_default"]
[:test="L_case_1_case_1_default"]
@@ -132,10 +120,8 @@
[:test="L_case_C1_case_C1_default"]
[:test="L_case_C1_case_C2_default"]
expected: FAIL
[:test="L_case_C1_default"]
expected: FAIL
[:test="L_case_C2_case_expr_default"]

View File

@@ -334,13 +334,10 @@
[:case="after_loop_with_uniform_breaks";init="uniform"]
[:case="after_switch_all_uniform";init="no_init"]
expected: FAIL
[:case="after_switch_all_uniform";init="nonuniform"]
expected: FAIL
[:case="after_switch_all_uniform";init="uniform"]
expected: FAIL
[:case="after_switch_nonuniform";init="no_init"]
expected: FAIL
@@ -352,13 +349,11 @@
expected: FAIL
[:case="after_switch_some_assign";init="no_init"]
expected: FAIL
[:case="after_switch_some_assign";init="nonuniform"]
expected: FAIL
[:case="after_switch_some_assign";init="uniform"]
expected: FAIL
[:case="after_switch_with_break_nonuniform1";init="no_init"]
expected: FAIL
@@ -794,13 +789,11 @@
expected: FAIL
[:case="switch_uniform_case";init="no_init"]
expected: FAIL
[:case="switch_uniform_case";init="nonuniform"]
expected: FAIL
[:case="switch_uniform_case";init="uniform"]
expected: FAIL
[:case="unreachable_nonuniform";init="no_init"]
expected: FAIL

View File

@@ -985,6 +985,8 @@
[:alpha="none";orientation="none";colorSpaceConversion="none";srcFlipYInCopy=true;dstFormat="rgba8unorm";dstPremultiplied=true]
[:alpha="none";orientation="none";colorSpaceConversion="none";srcFlipYInCopy=true;dstFormat="rgba8unorm-srgb";dstPremultiplied=false]
expected:
if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="none";orientation="none";colorSpaceConversion="none";srcFlipYInCopy=true;dstFormat="rgba8unorm-srgb";dstPremultiplied=true]
@@ -1596,11 +1598,8 @@
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=false;dstFormat="r8unorm";dstPremultiplied=true]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=false;dstFormat="rg16float";dstPremultiplied=false]
expected:
@@ -1700,11 +1699,8 @@
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="bgra8unorm-srgb";dstPremultiplied=false]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="bgra8unorm-srgb";dstPremultiplied=true]
expected:
@@ -1806,53 +1802,33 @@
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgb10a2unorm";dstPremultiplied=false]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [TIMEOUT, NOTRUN]
if not debug: [FAIL, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgb10a2unorm";dstPremultiplied=true]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [FAIL, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if os == "mac" and not debug: FAIL
if debug: [TIMEOUT, NOTRUN]
if not debug: [FAIL, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgba16float";dstPremultiplied=false]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgba16float";dstPremultiplied=true]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgba32float";dstPremultiplied=false]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgba32float";dstPremultiplied=true]
expected:
if os == "win" and debug: [TIMEOUT, NOTRUN]
if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "linux" and debug: [TIMEOUT, NOTRUN]
if os == "linux" and not debug: [PASS, TIMEOUT, NOTRUN]
if os == "mac" and debug: [TIMEOUT, NOTRUN]
if debug: [TIMEOUT, NOTRUN]
if not debug: [PASS, TIMEOUT, NOTRUN]
[:alpha="premultiply";orientation="none";colorSpaceConversion="default";srcFlipYInCopy=true;dstFormat="rgba8unorm";dstPremultiplied=false]
expected:

File diff suppressed because one or more lines are too long

View File

@@ -53,6 +53,7 @@ default = []
deserialize = [
"dep:serde",
"bitflags/serde",
"half/serde",
"hashbrown/serde",
"indexmap/serde",
]
@@ -66,6 +67,7 @@ msl-out-if-target-apple = []
serialize = [
"dep:serde",
"bitflags/serde",
"half/serde",
"hashbrown/serde",
"indexmap/serde",
]
@@ -89,6 +91,7 @@ path = "src/lib.rs"
[dependencies]
log = "0.4"
num-traits = "0.2.16"
[dependencies.arbitrary]
version = "1.4"
@@ -109,6 +112,13 @@ version = "2.9"
[dependencies.codespan-reporting]
version = "0.11.0"
[dependencies.half]
version = "2.5"
features = [
"arbitrary",
"num-traits",
]
[dependencies.hashbrown]
version = "0.14.5"
features = [
@@ -138,7 +148,7 @@ version = "1"
default-features = false
[dependencies.serde]
version = "1.0.218"
version = "1.0.219"
features = [
"default",
"derive",

View File

@@ -102,6 +102,18 @@ impl<T> Arena<T> {
.map(|(i, v)| unsafe { (Handle::from_usize_unchecked(i), v) })
}
/// Returns an iterator over the items stored in this arena, returning both
/// the item's handle and a reference to it.
pub fn iter_mut_span(
&mut self,
) -> impl DoubleEndedIterator<Item = (Handle<T>, &mut T, &Span)> + ExactSizeIterator {
self.data
.iter_mut()
.zip(self.span_info.iter())
.enumerate()
.map(|(i, (v, span))| unsafe { (Handle::from_usize_unchecked(i), v, span) })
}
/// Drains the arena, returning an iterator over the items stored.
pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = (Handle<T>, T, Span)> {
let arena = core::mem::take(self);

View File

@@ -185,6 +185,7 @@ impl ContinueCtx {
/// Resets internal state.
///
/// Use this to reuse memory between writing sessions.
#[allow(dead_code, reason = "only used by some backends")]
pub fn clear(&mut self) {
self.stack.clear();
}

View File

@@ -605,7 +605,7 @@ impl<W> Writer<'_, W> {
location: _,
interpolation,
sampling,
second_blend_source,
blend_src,
} => {
if interpolation == Some(Interpolation::Linear) {
self.features.request(Features::NOPERSPECTIVE_QUALIFIER);
@@ -613,7 +613,7 @@ impl<W> Writer<'_, W> {
if sampling == Some(Sampling::Sample) {
self.features.request(Features::SAMPLE_QUALIFIER);
}
if second_blend_source {
if blend_src.is_some() {
self.features.request(Features::DUAL_SOURCE_BLENDING);
}
}

View File

@@ -1,3 +1,7 @@
use std::sync::LazyLock;
use hashbrown::HashSet;
pub const RESERVED_KEYWORDS: &[&str] = &[
//
// GLSL 4.6 keywords, from https://github.com/KhronosGroup/OpenGL-Registry/blob/d00e11dc1a1ffba581d633f21f70202051248d5c/specs/gl/GLSLangSpec.4.60.html#L2004-L2322
@@ -490,3 +494,16 @@ pub const RESERVED_KEYWORDS: &[&str] = &[
super::FREXP_FUNCTION,
super::FIRST_INSTANCE_BINDING,
];
/// The above set of reserved keywords, turned into a cached HashSet. This saves
/// significant time during [`Namer::reset`](crate::proc::Namer::reset).
///
/// See <https://github.com/gfx-rs/wgpu/pull/7338> for benchmarks.
pub static RESERVED_KEYWORD_SET: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
let mut set = HashSet::default();
set.reserve(RESERVED_KEYWORDS.len());
for &word in RESERVED_KEYWORDS {
set.insert(word);
}
set
});

View File

@@ -89,6 +89,7 @@ pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
// Must match code in glsl_built_in
pub const FIRST_INSTANCE_BINDING: &str = "naga_vs_first_instance";
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
struct BindingMapSerialization {
@@ -130,13 +131,6 @@ impl crate::AtomicFunction {
}
impl crate::AddressSpace {
const fn is_buffer(&self) -> bool {
match *self {
crate::AddressSpace::Uniform | crate::AddressSpace::Storage { .. } => true,
_ => false,
}
}
/// Whether a variable with this address space can be initialized
const fn initializable(&self) -> bool {
match *self {
@@ -465,8 +459,7 @@ impl fmt::Display for VaryingName<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self.binding {
crate::Binding::Location {
second_blend_source: true,
..
blend_src: Some(1), ..
} => {
write!(f, "_fs2p_location1",)
}
@@ -479,6 +472,7 @@ impl fmt::Display for VaryingName<'_> {
(ShaderStage::Vertex, true) | (ShaderStage::Fragment, false) => "vs2fs",
// fragment to pipeline
(ShaderStage::Fragment, true) => "fs2p",
(ShaderStage::Task | ShaderStage::Mesh, _) => unreachable!(),
};
write!(f, "_{prefix}_location{location}",)
}
@@ -495,6 +489,7 @@ impl ShaderStage {
ShaderStage::Compute => "cs",
ShaderStage::Fragment => "fs",
ShaderStage::Vertex => "vs",
ShaderStage::Task | ShaderStage::Mesh => unreachable!(),
}
}
}
@@ -539,6 +534,8 @@ pub enum Error {
/// [`crate::Sampling::First`] is unsupported.
#[error("`{:?}` sampling is unsupported", crate::Sampling::First)]
FirstSamplingNotSupported,
#[error(transparent)]
ResolveArraySizeError(#[from] proc::ResolveArraySizeError),
}
/// Binary operation with a different logic on the GLSL side.
@@ -612,10 +609,6 @@ impl<'a, W: Write> Writer<'a, W> {
pipeline_options: &'a PipelineOptions,
policies: proc::BoundsCheckPolicies,
) -> Result<Self, Error> {
if !module.overrides.is_empty() {
return Err(Error::Override);
}
// Check if the requested version is supported
if !options.version.is_supported() {
log::error!("Version {}", options.version);
@@ -636,8 +629,7 @@ impl<'a, W: Write> Writer<'a, W> {
let mut namer = proc::Namer::default();
namer.reset(
module,
keywords::RESERVED_KEYWORDS,
&[],
&keywords::RESERVED_KEYWORD_SET,
&[],
&[
"gl_", // all GL built-in variables
@@ -1013,13 +1005,12 @@ impl<'a, W: Write> Writer<'a, W> {
write!(self.out, "[")?;
// Write the array size
// Writes nothing if `ArraySize::Dynamic`
match size {
crate::ArraySize::Constant(size) => {
// Writes nothing if `IndexableLength::Dynamic`
match size.resolve(self.module.to_ctx())? {
proc::IndexableLength::Known(size) => {
write!(self.out, "{size}")?;
}
crate::ArraySize::Pending(_) => unreachable!(),
crate::ArraySize::Dynamic => (),
proc::IndexableLength::Dynamic => (),
}
write!(self.out, "]")?;
@@ -1262,7 +1253,7 @@ impl<'a, W: Write> Writer<'a, W> {
if global.space.initializable() && is_value_init_supported(self.module, global.ty) {
write!(self.out, " = ")?;
if let Some(init) = global.init {
self.write_const_expr(init)?;
self.write_const_expr(init, &self.module.global_expressions)?;
} else {
self.write_zero_init_value(global.ty)?;
}
@@ -1501,13 +1492,13 @@ impl<'a, W: Write> Writer<'a, W> {
Some(binding) => binding,
};
let (location, interpolation, sampling, second_blend_source) = match *binding {
let (location, interpolation, sampling, blend_src) = match *binding {
crate::Binding::Location {
location,
interpolation,
sampling,
second_blend_source,
} => (location, interpolation, sampling, second_blend_source),
blend_src,
} => (location, interpolation, sampling, blend_src),
crate::Binding::BuiltIn(built_in) => {
if let crate::BuiltIn::Position { invariant: true } = built_in {
match (self.options.version, self.entry_point.stage) {
@@ -1547,6 +1538,7 @@ impl<'a, W: Write> Writer<'a, W> {
ShaderStage::Vertex => output,
ShaderStage::Fragment => !output,
ShaderStage::Compute => false,
ShaderStage::Task | ShaderStage::Mesh => unreachable!(),
};
// Write the I/O locations, if allowed
@@ -1554,8 +1546,11 @@ impl<'a, W: Write> Writer<'a, W> {
|| !emit_interpolation_and_auxiliary
{
if self.options.version.supports_io_locations() {
if second_blend_source {
write!(self.out, "layout(location = {location}, index = 1) ")?;
if let Some(blend_src) = blend_src {
write!(
self.out,
"layout(location = {location}, index = {blend_src}) "
)?;
} else {
write!(self.out, "layout(location = {location}) ")?;
}
@@ -1563,7 +1558,7 @@ impl<'a, W: Write> Writer<'a, W> {
} else {
Some(VaryingLocation {
location,
index: second_blend_source as u32,
index: blend_src.unwrap_or(0),
})
}
} else {
@@ -1604,7 +1599,7 @@ impl<'a, W: Write> Writer<'a, W> {
location,
interpolation: None,
sampling: None,
second_blend_source,
blend_src,
},
stage: self.entry_point.stage,
options: VaryingOptions::from_writer_options(self.options, output),
@@ -1907,7 +1902,7 @@ impl<'a, W: Write> Writer<'a, W> {
self.write_array_size(base, size)?;
}
write!(self.out, " = ")?;
self.write_const_expr(constant.init)?;
self.write_const_expr(constant.init, &self.module.global_expressions)?;
writeln!(self.out, ";")?;
Ok(())
}
@@ -2657,12 +2652,16 @@ impl<'a, W: Write> Writer<'a, W> {
///
/// [`Expression`]: crate::Expression
/// [`Module`]: crate::Module
fn write_const_expr(&mut self, expr: Handle<crate::Expression>) -> BackendResult {
fn write_const_expr(
&mut self,
expr: Handle<crate::Expression>,
arena: &crate::Arena<crate::Expression>,
) -> BackendResult {
self.write_possibly_const_expr(
expr,
&self.module.global_expressions,
arena,
|expr| &self.info[expr],
|writer, expr| writer.write_const_expr(expr),
|writer, expr| writer.write_const_expr(expr, arena),
)
}
@@ -2704,6 +2703,9 @@ impl<'a, W: Write> Writer<'a, W> {
// decimal part even it's zero which is needed for a valid glsl float constant
crate::Literal::F64(value) => write!(self.out, "{value:?}LF")?,
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
crate::Literal::F16(_) => {
return Err(Error::Custom("GLSL has no 16-bit float type".into()));
}
// Unsigned integers need a `u` at the end
//
// While `core` doesn't necessarily need it, it's allowed and since `es` needs it we
@@ -2729,7 +2731,7 @@ impl<'a, W: Write> Writer<'a, W> {
if constant.name.is_some() {
write!(self.out, "{}", self.names[&NameKey::Constant(handle)])?;
} else {
self.write_const_expr(constant.init)?;
self.write_const_expr(constant.init, &self.module.global_expressions)?;
}
}
Expression::ZeroValue(ty) => {
@@ -2759,7 +2761,9 @@ impl<'a, W: Write> Writer<'a, W> {
write_expression(self, value)?;
write!(self.out, ")")?
}
_ => unreachable!(),
_ => {
return Err(Error::Override);
}
}
Ok(())
@@ -3034,7 +3038,7 @@ impl<'a, W: Write> Writer<'a, W> {
if tex_1d_hack {
write!(self.out, "ivec2(")?;
}
self.write_const_expr(constant)?;
self.write_const_expr(constant, ctx.expressions)?;
if tex_1d_hack {
write!(self.out, ", 0)")?;
}
@@ -4574,12 +4578,8 @@ impl<'a, W: Write> Writer<'a, W> {
write!(self.out, ")")?;
}
TypeInner::Array { base, size, .. } => {
let count = match size
.to_indexable_length(self.module)
.expect("Bad array size")
{
let count = match size.resolve(self.module.to_ctx())? {
proc::IndexableLength::Known(count) => count,
proc::IndexableLength::Pending => unreachable!(),
proc::IndexableLength::Dynamic => return Ok(()),
};
self.write_type(base)?;

View File

@@ -54,7 +54,7 @@ impl crate::TypeInner {
}
}
pub(super) fn size_hlsl(&self, gctx: crate::proc::GlobalCtx) -> u32 {
pub(super) fn size_hlsl(&self, gctx: crate::proc::GlobalCtx) -> Result<u32, Error> {
match *self {
Self::Matrix {
columns,
@@ -63,19 +63,18 @@ impl crate::TypeInner {
} => {
let stride = Alignment::from(rows) * scalar.width as u32;
let last_row_size = rows as u32 * scalar.width as u32;
((columns as u32 - 1) * stride) + last_row_size
Ok(((columns as u32 - 1) * stride) + last_row_size)
}
Self::Array { base, size, stride } => {
let count = match size {
crate::ArraySize::Constant(size) => size.get(),
let count = match size.resolve(gctx)? {
crate::proc::IndexableLength::Known(size) => size,
// A dynamically-sized array has to have at least one element
crate::ArraySize::Pending(_) => unreachable!(),
crate::ArraySize::Dynamic => 1,
crate::proc::IndexableLength::Dynamic => 1,
};
let last_el_size = gctx.types[base].inner.size_hlsl(gctx);
((count - 1) * stride) + last_el_size
let last_el_size = gctx.types[base].inner.size_hlsl(gctx)?;
Ok(((count - 1) * stride) + last_el_size)
}
_ => self.size(gctx),
_ => Ok(self.size(gctx)),
}
}

View File

@@ -1777,8 +1777,6 @@ impl<W: Write> super::Writer<'_, W> {
) -> BackendResult {
use crate::back::INDENT;
const RETURN_VARIABLE_NAME: &str = "ret";
// Write function return type and name
if let crate::TypeInner::Array { base, size, .. } = module.types[zero_value.ty].inner {
write!(self.out, "typedef ")?;

View File

@@ -1,3 +1,7 @@
use std::sync::LazyLock;
use hashbrown::HashSet;
// When compiling with FXC without strict mode, these keywords are actually case insensitive.
// If you compile with strict mode and specify a different casing like "Pass" instead in an identifier, FXC will give this error:
// "error X3086: alternate cases for 'pass' are deprecated in strict mode"
@@ -912,6 +916,22 @@ pub const TYPES: &[&str] = &{
res
};
/// The above set of reserved keywords, turned into a cached HashSet. This saves
/// significant time during [`Namer::reset`](crate::proc::Namer::reset).
///
/// See <https://github.com/gfx-rs/wgpu/pull/7338> for benchmarks.
pub static RESERVED_SET: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
let mut set = HashSet::default();
set.reserve(RESERVED.len() + TYPES.len());
for &word in RESERVED {
set.insert(word);
}
for &word in TYPES {
set.insert(word);
}
set
});
pub const RESERVED_PREFIXES: &[&str] = &[
"__dynamic_buffer_offsets",
super::help::IMAGE_STORAGE_LOAD_SCALAR_WRAPPER,

View File

@@ -151,6 +151,7 @@ pub struct OffsetsBindTarget {
pub size: u32,
}
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
struct BindingMapSerialization {
@@ -217,6 +218,7 @@ impl crate::ShaderStage {
Self::Vertex => "vs",
Self::Fragment => "ps",
Self::Compute => "cs",
Self::Task | Self::Mesh => unreachable!(),
}
}
}
@@ -269,6 +271,7 @@ impl Default for SamplerHeapBindTargets {
}
}
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
struct SamplerIndexBufferBindingSerialization {
@@ -300,6 +303,7 @@ where
pub type SamplerIndexBufferBindingMap =
alloc::collections::BTreeMap<SamplerIndexBufferKey, BindTarget>;
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
struct DynamicStorageBufferOffsetTargetSerialization {
@@ -442,6 +446,8 @@ pub enum Error {
Custom(String),
#[error("overrides should not be present at this stage")]
Override,
#[error(transparent)]
ResolveArraySizeError(#[from] proc::ResolveArraySizeError),
}
#[derive(PartialEq, Eq, Hash)]

View File

@@ -140,8 +140,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
self.names.clear();
self.namer.reset(
module,
super::keywords::RESERVED,
super::keywords::TYPES,
&super::keywords::RESERVED_SET,
super::keywords::RESERVED_CASE_INSENSITIVE,
super::keywords::RESERVED_PREFIXES,
&mut self.names,
@@ -268,10 +267,6 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
module_info: &valid::ModuleInfo,
fragment_entry_point: Option<&FragmentEntryPoint<'_>>,
) -> Result<super::ReflectionInfo, Error> {
if !module.overrides.is_empty() {
return Err(Error::Override);
}
self.reset(module);
// Write special constants, if needed
@@ -535,16 +530,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write!(self.out, " : {builtin_str}")?;
}
Some(crate::Binding::Location {
second_blend_source: true,
..
blend_src: Some(1), ..
}) => {
write!(self.out, " : SV_Target1")?;
}
Some(crate::Binding::Location {
location,
second_blend_source: false,
..
}) => {
Some(crate::Binding::Location { location, .. }) => {
if stage == Some((ShaderStage::Fragment, Io::Output)) {
write!(self.out, " : SV_Target{location}")?;
} else {
@@ -1006,7 +996,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if global.space == crate::AddressSpace::Private {
write!(self.out, " = ")?;
if let Some(init) = global.init {
self.write_const_expression(module, init)?;
self.write_const_expression(module, init, &module.global_expressions)?;
} else {
self.write_default_init(module, global.ty)?;
}
@@ -1116,7 +1106,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
self.write_array_size(module, base, size)?;
}
write!(self.out, " = ")?;
self.write_const_expression(module, constant.init)?;
self.write_const_expression(module, constant.init, &module.global_expressions)?;
writeln!(self.out, ";")?;
Ok(())
}
@@ -1129,12 +1119,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
) -> BackendResult {
write!(self.out, "[")?;
match size {
crate::ArraySize::Constant(size) => {
match size.resolve(module.to_ctx())? {
proc::IndexableLength::Known(size) => {
write!(self.out, "{size}")?;
}
crate::ArraySize::Pending(_) => unreachable!(),
crate::ArraySize::Dynamic => unreachable!(),
proc::IndexableLength::Dynamic => unreachable!(),
}
write!(self.out, "]")?;
@@ -1179,7 +1168,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
let ty_inner = &module.types[member.ty].inner;
last_offset = member.offset + ty_inner.size_hlsl(module.to_ctx());
last_offset = member.offset + ty_inner.size_hlsl(module.to_ctx())?;
// The indentation is only for readability
write!(self.out, "{}", back::INDENT)?;
@@ -2614,13 +2603,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
&mut self,
module: &Module,
expr: Handle<crate::Expression>,
arena: &crate::Arena<crate::Expression>,
) -> BackendResult {
self.write_possibly_const_expression(
module,
expr,
&module.global_expressions,
|writer, expr| writer.write_const_expression(module, expr),
)
self.write_possibly_const_expression(module, expr, arena, |writer, expr| {
writer.write_const_expression(module, expr, arena)
})
}
fn write_possibly_const_expression<E>(
@@ -2641,6 +2628,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
// decimal part even it's zero
crate::Literal::F64(value) => write!(self.out, "{value:?}L")?,
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
crate::Literal::F16(value) => write!(self.out, "{value:?}h")?,
crate::Literal::U32(value) => write!(self.out, "{value}u")?,
// HLSL has no suffix for explicit i32 literals, but not using any suffix
// makes the type ambiguous which prevents overload resolution from
@@ -2660,7 +2648,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if constant.name.is_some() {
write!(self.out, "{}", self.names[&NameKey::Constant(handle)])?;
} else {
self.write_const_expression(module, constant.init)?;
self.write_const_expression(module, constant.init, &module.global_expressions)?;
}
}
Expression::ZeroValue(ty) => {
@@ -2701,7 +2689,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
write_expression(self, value)?;
write!(self.out, ").{number_of_components}")?
}
_ => unreachable!(),
_ => {
return Err(Error::Override);
}
}
Ok(())
@@ -2971,7 +2961,6 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
index::IndexableLength::Known(limit) => {
write!(self.out, "{}u", limit - 1)?;
}
index::IndexableLength::Pending => unreachable!(),
index::IndexableLength::Dynamic => unreachable!(),
}
write!(self.out, ")")?;
@@ -3182,7 +3171,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if let Some(offset) = offset {
write!(self.out, ", ")?;
write!(self.out, "int2(")?; // work around https://github.com/microsoft/DirectXShaderCompiler/issues/5082#issuecomment-1540147807
self.write_const_expression(module, offset)?;
self.write_const_expression(module, offset, func_ctx.expressions)?;
write!(self.out, ")")?;
}

View File

@@ -1,7 +1,13 @@
/*!
Backend functions that export shader [`Module`](super::Module)s into binary and text formats.
*/
#![allow(dead_code)] // can be dead if none of the enabled backends need it
#![cfg_attr(
not(any(dot_out, glsl_out, hlsl_out, msl_out, spv_out, wgsl_out)),
allow(
dead_code,
reason = "shared helpers can be dead if none of the enabled backends need it"
)
)]
use alloc::string::String;
@@ -64,7 +70,7 @@ pub type PipelineConstants = hashbrown::HashMap<String, f64>;
pub struct Level(pub usize);
impl Level {
const fn next(&self) -> Self {
pub const fn next(&self) -> Self {
Level(self.0 + 1)
}
}

View File

@@ -1,3 +1,7 @@
use std::sync::LazyLock;
use hashbrown::HashSet;
// MSLS - Metal Shading Language Specification:
// https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
//
@@ -347,3 +351,16 @@ pub const RESERVED: &[&str] = &[
super::writer::NEG_FUNCTION,
super::writer::ARGUMENT_BUFFER_WRAPPER_STRUCT,
];
/// The above set of reserved keywords, turned into a cached HashSet. This saves
/// significant time during [`Namer::reset`](crate::proc::Namer::reset).
///
/// See <https://github.com/gfx-rs/wgpu/pull/7338> for benchmarks.
pub static RESERVED_SET: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
let mut set = HashSet::default();
set.reserve(RESERVED.len());
for &word in RESERVED {
set.insert(word);
}
set
});

View File

@@ -68,6 +68,7 @@ pub struct BindTarget {
pub mutable: bool,
}
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
struct BindingMapSerialization {
@@ -119,7 +120,7 @@ enum ResolvedBinding {
Attribute(u32),
Color {
location: u32,
second_blend_source: bool,
blend_src: Option<u32>,
},
User {
prefix: &'static str,
@@ -182,6 +183,8 @@ pub enum Error {
Override,
#[error("bitcasting to {0:?} is not supported")]
UnsupportedBitCast(crate::TypeInner),
#[error(transparent)]
ResolveArraySizeError(#[from] crate::proc::ResolveArraySizeError),
}
#[derive(Clone, Debug, PartialEq, thiserror::Error)]
@@ -465,18 +468,16 @@ impl Options {
location,
interpolation,
sampling,
second_blend_source,
blend_src,
} => match mode {
LocationMode::VertexInput => Ok(ResolvedBinding::Attribute(location)),
LocationMode::FragmentOutput => {
if second_blend_source && self.lang_version < (1, 2) {
return Err(Error::UnsupportedAttribute(
"second_blend_source".to_string(),
));
if blend_src.is_some() && self.lang_version < (1, 2) {
return Err(Error::UnsupportedAttribute("blend_src".to_string()));
}
Ok(ResolvedBinding::Color {
location,
second_blend_source,
blend_src,
})
}
LocationMode::VertexOutput | LocationMode::FragmentInput => {
@@ -588,13 +589,6 @@ impl ResolvedBinding {
}
}
const fn as_bind_target(&self) -> Option<&BindTarget> {
match *self {
Self::Resource(ref target) => Some(target),
_ => None,
}
}
fn try_fmt<W: Write>(&self, out: &mut W) -> Result<(), Error> {
write!(out, " [[")?;
match *self {
@@ -638,10 +632,10 @@ impl ResolvedBinding {
Self::Attribute(index) => write!(out, "attribute({index})")?,
Self::Color {
location,
second_blend_source,
blend_src,
} => {
if second_blend_source {
write!(out, "color({location}) index(1)")?
if let Some(blend_src) = blend_src {
write!(out, "color({location}) index({blend_src})")?
} else {
write!(out, "color({location})")?
}

View File

@@ -8,6 +8,9 @@ use core::{
fmt::{Display, Error as FmtError, Formatter, Write},
iter,
};
use num_traits::real::Real as _;
use half::f16;
use super::{sampler as sm, Error, LocationMode, Options, PipelineOptions, TranslationInfo};
use crate::{
@@ -149,7 +152,6 @@ struct TypeContext<'a> {
gctx: proc::GlobalCtx<'a>,
names: &'a FastHashMap<NameKey, String>,
access: crate::StorageAccess,
binding: Option<&'a super::ResolvedBinding>,
first_time: bool,
}
@@ -183,9 +185,11 @@ impl Display for TypeContext<'_> {
write!(out, "{}::atomic_{}", NAMESPACE, scalar.to_msl_name())
}
crate::TypeInner::Vector { size, scalar } => put_numeric_type(out, scalar, &[size]),
crate::TypeInner::Matrix { columns, rows, .. } => {
put_numeric_type(out, crate::Scalar::F32, &[rows, columns])
}
crate::TypeInner::Matrix {
columns,
rows,
scalar,
} => put_numeric_type(out, scalar, &[rows, columns]),
crate::TypeInner::Pointer { base, space } => {
let sub = Self {
handle: base,
@@ -323,7 +327,6 @@ struct TypedGlobalVariable<'a> {
names: &'a FastHashMap<NameKey, String>,
handle: Handle<crate::GlobalVariable>,
usage: valid::GlobalUse,
binding: Option<&'a super::ResolvedBinding>,
reference: bool,
}
@@ -356,7 +359,6 @@ impl TypedGlobalVariable<'_> {
gctx: self.module.to_ctx(),
names: self.names,
access: storage_access,
binding: self.binding,
first_time: false,
};
@@ -428,8 +430,12 @@ impl crate::Scalar {
match self {
Self {
kind: Sk::Float,
width: _,
width: 4,
} => "float",
Self {
kind: Sk::Float,
width: 2,
} => "half",
Self {
kind: Sk::Sint,
width: 4,
@@ -486,7 +492,7 @@ fn should_pack_struct_member(
match *ty_inner {
crate::TypeInner::Vector {
size: crate::VectorSize::Tri,
scalar: scalar @ crate::Scalar { width: 4, .. },
scalar: scalar @ crate::Scalar { width: 4 | 2, .. },
} if is_tight => Some(scalar),
_ => None,
}
@@ -1429,15 +1435,16 @@ impl<W: Write> Writer<W> {
expr_handle: Handle<crate::Expression>,
module: &crate::Module,
mod_info: &valid::ModuleInfo,
arena: &crate::Arena<crate::Expression>,
) -> BackendResult {
self.put_possibly_const_expression(
expr_handle,
&module.global_expressions,
arena,
module,
mod_info,
&(module, mod_info),
|&(_, mod_info), expr| &mod_info[expr],
|writer, &(module, _), expr| writer.put_const_expression(expr, module, mod_info),
|writer, &(module, _), expr| writer.put_const_expression(expr, module, mod_info, arena),
)
}
@@ -1461,6 +1468,21 @@ impl<W: Write> Writer<W> {
crate::Literal::F64(_) => {
return Err(Error::CapabilityNotSupported(valid::Capabilities::FLOAT64))
}
crate::Literal::F16(value) => {
if value.is_infinite() {
let sign = if value.is_sign_negative() { "-" } else { "" };
write!(self.out, "{sign}INFINITY")?;
} else if value.is_nan() {
write!(self.out, "NAN")?;
} else {
let suffix = if value.fract() == f16::from_f32(0.0) {
".0h"
} else {
"h"
};
write!(self.out, "{value}{suffix}")?;
}
}
crate::Literal::F32(value) => {
if value.is_infinite() {
let sign = if value.is_sign_negative() { "-" } else { "" };
@@ -1498,7 +1520,12 @@ impl<W: Write> Writer<W> {
if constant.name.is_some() {
write!(self.out, "{}", self.names[&NameKey::Constant(handle)])?;
} else {
self.put_const_expression(constant.init, module, mod_info)?;
self.put_const_expression(
constant.init,
module,
mod_info,
&module.global_expressions,
)?;
}
}
crate::Expression::ZeroValue(ty) => {
@@ -1507,7 +1534,6 @@ impl<W: Write> Writer<W> {
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{ty_name} {{}}")?;
@@ -1518,7 +1544,6 @@ impl<W: Write> Writer<W> {
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{ty_name}")?;
@@ -1563,7 +1588,9 @@ impl<W: Write> Writer<W> {
put_expression(self, ctx, value)?;
write!(self.out, ")")?;
}
_ => unreachable!(),
_ => {
return Err(Error::Override);
}
}
Ok(())
@@ -1721,7 +1748,7 @@ impl<W: Write> Writer<W> {
if let Some(offset) = offset {
write!(self.out, ", ")?;
self.put_const_expression(offset, context.module, context.mod_info)?;
self.put_expression(offset, context, true)?;
}
match gather {
@@ -2612,7 +2639,6 @@ impl<W: Write> Writer<W> {
self.out.write_str(") < ")?;
match length {
index::IndexableLength::Known(value) => write!(self.out, "{value}")?,
index::IndexableLength::Pending => unreachable!(),
index::IndexableLength::Dynamic => {
let global =
context.function.originating_global(base).ok_or_else(|| {
@@ -2749,7 +2775,7 @@ impl<W: Write> Writer<W> {
) -> BackendResult {
let accessing_wrapped_array = match *base_ty {
crate::TypeInner::Array {
size: crate::ArraySize::Constant(_),
size: crate::ArraySize::Constant(_) | crate::ArraySize::Pending(_),
..
} => true,
_ => false,
@@ -2777,7 +2803,6 @@ impl<W: Write> Writer<W> {
index::IndexableLength::Known(limit) => {
write!(self.out, "{}u", limit - 1)?;
}
index::IndexableLength::Pending => unreachable!(),
index::IndexableLength::Dynamic => {
let global = context.function.originating_global(base).ok_or_else(|| {
Error::GenericValidation("Could not find originating global".into())
@@ -3044,7 +3069,6 @@ impl<W: Write> Writer<W> {
gctx: context.module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{ty_name}")?;
@@ -3795,15 +3819,10 @@ impl<W: Write> Writer<W> {
options: &Options,
pipeline_options: &PipelineOptions,
) -> Result<TranslationInfo, Error> {
if !module.overrides.is_empty() {
return Err(Error::Override);
}
self.names.clear();
self.namer.reset(
module,
super::keywords::RESERVED,
&[],
&super::keywords::RESERVED_SET,
&[],
&[CLAMPED_LOD_LOAD_PREFIX],
&mut self.names,
@@ -3991,12 +4010,11 @@ impl<W: Write> Writer<W> {
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
match size {
crate::ArraySize::Constant(size) => {
match size.resolve(module.to_ctx())? {
proc::IndexableLength::Known(size) => {
writeln!(self.out, "struct {name} {{")?;
writeln!(
self.out,
@@ -4008,10 +4026,7 @@ impl<W: Write> Writer<W> {
)?;
writeln!(self.out, "}};")?;
}
crate::ArraySize::Pending(_) => {
unreachable!()
}
crate::ArraySize::Dynamic => {
proc::IndexableLength::Dynamic => {
writeln!(self.out, "typedef {base_name} {name}[1];")?;
}
}
@@ -4050,7 +4065,6 @@ impl<W: Write> Writer<W> {
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
writeln!(
@@ -4080,7 +4094,6 @@ impl<W: Write> Writer<W> {
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: true,
};
writeln!(self.out, "typedef {ty_name} {name};")?;
@@ -4180,12 +4193,11 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
let name = &self.names[&NameKey::Constant(handle)];
write!(self.out, "constant {ty_name} {name} = ")?;
self.put_const_expression(constant.init, module, mod_info)?;
self.put_const_expression(constant.init, module, mod_info, &module.global_expressions)?;
writeln!(self.out, ";")?;
}
@@ -5480,7 +5492,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{ty_name}")?;
@@ -5498,7 +5509,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
let separator = separate(
@@ -5521,7 +5531,7 @@ template <typename A>
names: &self.names,
handle,
usage: fun_info[handle],
binding: None,
reference: true,
};
let separator =
@@ -5566,7 +5576,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
let local_name = &self.names[&NameKey::FunctionLocal(fun_handle, local_handle)];
@@ -5638,6 +5647,7 @@ template <typename A>
LocationMode::Uniform,
false,
),
crate::ShaderStage::Task | crate::ShaderStage::Mesh => unreachable!(),
};
// Should this entry point be modified to do vertex pulling?
@@ -5794,7 +5804,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
let resolved = options.resolve_local_binding(binding, in_mode)?;
@@ -5854,7 +5863,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: true,
};
let binding = binding.ok_or_else(|| {
@@ -5955,7 +5963,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
@@ -6140,7 +6147,6 @@ template <typename A>
names: &self.names,
handle,
usage,
binding: resolved.as_ref(),
reference: true,
};
let separator = if is_first_argument {
@@ -6156,7 +6162,7 @@ template <typename A>
}
if let Some(value) = var.init {
write!(self.out, " = ")?;
self.put_const_expression(value, module, mod_info)?;
self.put_const_expression(value, module, mod_info, &module.global_expressions)?;
}
writeln!(self.out)?;
}
@@ -6353,7 +6359,7 @@ template <typename A>
names: &self.names,
handle,
usage,
binding: None,
reference: false,
};
write!(self.out, "{}", back::INDENT)?;
@@ -6361,7 +6367,12 @@ template <typename A>
match var.init {
Some(value) => {
write!(self.out, " = ")?;
self.put_const_expression(value, module, mod_info)?;
self.put_const_expression(
value,
module,
mod_info,
&module.global_expressions,
)?;
writeln!(self.out, ";")?;
}
None => {
@@ -6476,7 +6487,6 @@ template <typename A>
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{}{} {}", back::INDENT, ty_name, name)?;
@@ -6694,10 +6704,8 @@ mod workgroup_mem_init {
writeln!(self.out, ", 0, {NAMESPACE}::memory_order_relaxed);")?;
}
crate::TypeInner::Array { base, size, .. } => {
let count = match size.to_indexable_length(module).expect("Bad array size")
{
let count = match size.resolve(module.to_ctx())? {
proc::IndexableLength::Known(count) => count,
proc::IndexableLength::Pending => unreachable!(),
proc::IndexableLength::Dynamic => unreachable!(),
};

View File

@@ -85,7 +85,8 @@ pub fn process_overrides<'a>(
// An iterator through the original overrides table, consumed in
// approximate tandem with the global expressions.
let mut override_iter = module.overrides.drain();
let mut overrides = mem::take(&mut module.overrides);
let mut override_iter = overrides.iter_mut_span();
// Do two things in tandem:
//
@@ -164,15 +165,26 @@ pub fn process_overrides<'a>(
// Finish processing any overrides we didn't visit in the loop above.
for entry in override_iter {
process_override(
entry,
pipeline_constants,
&mut module,
&mut override_map,
&adjusted_global_expressions,
&mut adjusted_constant_initializers,
&mut global_expression_kind_tracker,
)?;
match *entry.1 {
Override { name: Some(_), .. } | Override { id: Some(_), .. } => {
process_override(
entry,
pipeline_constants,
&mut module,
&mut override_map,
&adjusted_global_expressions,
&mut adjusted_constant_initializers,
&mut global_expression_kind_tracker,
)?;
}
Override {
init: Some(ref mut init),
..
} => {
*init = adjusted_global_expressions[*init];
}
_ => {}
}
}
// Update the initialization expression handles of all `Constant`s
@@ -204,76 +216,17 @@ pub fn process_overrides<'a>(
process_workgroup_size_override(&mut module, &adjusted_global_expressions, ep)?;
}
module.entry_points = entry_points;
process_pending(&mut module, &override_map, &adjusted_global_expressions)?;
module.overrides = overrides;
// Now that we've rewritten all the expressions, we need to
// recompute their types and other metadata. For the time being,
// do a full re-validation.
let mut validator = Validator::new(ValidationFlags::all(), Capabilities::all());
let module_info = validator.validate_no_overrides(&module)?;
let module_info = validator.validate_resolved_overrides(&module)?;
Ok((Cow::Owned(module), Cow::Owned(module_info)))
}
fn process_pending(
module: &mut Module,
override_map: &HandleVec<Override, Handle<Constant>>,
adjusted_global_expressions: &HandleVec<Expression, Handle<Expression>>,
) -> Result<(), PipelineConstantError> {
for (handle, ty) in module.types.clone().iter() {
if let TypeInner::Array {
base,
size: crate::ArraySize::Pending(size),
stride,
} = ty.inner
{
let expr = match size {
crate::PendingArraySize::Expression(size_expr) => {
adjusted_global_expressions[size_expr]
}
crate::PendingArraySize::Override(size_override) => {
module.constants[override_map[size_override]].init
}
};
let value = module
.to_ctx()
.eval_expr_to_u32(expr)
.map(|n| {
if n == 0 {
Err(PipelineConstantError::ValidationError(
WithSpan::new(ValidationError::ArraySizeError { handle: expr })
.with_span(
module.global_expressions.get_span(expr),
"evaluated to zero",
),
))
} else {
Ok(core::num::NonZeroU32::new(n).unwrap())
}
})
.map_err(|_| {
PipelineConstantError::ValidationError(
WithSpan::new(ValidationError::ArraySizeError { handle: expr })
.with_span(module.global_expressions.get_span(expr), "negative"),
)
})??;
module.types.replace(
handle,
crate::Type {
name: None,
inner: TypeInner::Array {
base,
size: crate::ArraySize::Constant(value),
stride,
},
},
);
}
}
Ok(())
}
fn process_workgroup_size_override(
module: &mut Module,
adjusted_global_expressions: &HandleVec<Expression, Handle<Expression>>,
@@ -313,7 +266,7 @@ fn process_workgroup_size_override(
///
/// Add the new `Constant` to `override_map` and `adjusted_constant_initializers`.
fn process_override(
(old_h, r#override, span): (Handle<Override>, Override, Span),
(old_h, r#override, span): (Handle<Override>, &mut Override, &Span),
pipeline_constants: &PipelineConstants,
module: &mut Module,
override_map: &mut HandleVec<Override, Handle<Constant>>,
@@ -351,13 +304,14 @@ fn process_override(
// Generate a new `Constant` to represent the override's value.
let constant = Constant {
name: r#override.name,
name: r#override.name.clone(),
ty: r#override.ty,
init,
};
let h = module.constants.append(constant, span);
let h = module.constants.append(constant, *span);
override_map.insert(old_h, h);
adjusted_constant_initializers.insert(h);
r#override.init = Some(init);
Ok(h)
}

View File

@@ -4,6 +4,7 @@ Implementations for `BlockContext` methods.
use alloc::vec::Vec;
use arrayvec::ArrayVec;
use spirv::Word;
use super::{
@@ -157,10 +158,7 @@ impl Writer {
position_id: Word,
body: &mut Vec<Instruction>,
) -> Result<(), Error> {
let float_ptr_type_id = self.get_type_id(LookupType::Local(LocalType::LocalPointer {
base: NumericType::Scalar(crate::Scalar::F32),
class: spirv::StorageClass::Output,
}));
let float_ptr_type_id = self.get_f32_pointer_type_id(spirv::StorageClass::Output);
let index_y_id = self.get_index_constant(1);
let access_id = self.id_gen.next();
body.push(Instruction::access_chain(
@@ -170,9 +168,7 @@ impl Writer {
&[index_y_id],
));
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::F32),
)));
let float_type_id = self.get_f32_type_id();
let load_id = self.id_gen.next();
body.push(Instruction::load(float_type_id, load_id, access_id, None));
@@ -194,9 +190,7 @@ impl Writer {
frag_depth_id: Word,
body: &mut Vec<Instruction>,
) -> Result<(), Error> {
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::F32),
)));
let float_type_id = self.get_f32_type_id();
let zero_scalar_id = self.get_constant_scalar(crate::Literal::F32(0.0));
let one_scalar_id = self.get_constant_scalar(crate::Literal::F32(1.0));
@@ -277,13 +271,13 @@ impl BlockContext<'_> {
/// See [`crate::back::msl::Writer::gen_force_bounded_loop_statements`] for details
/// of why this is required.
fn write_force_bounded_loop_instructions(&mut self, mut block: Block, merge_id: Word) -> Block {
let uint_type_id = self.writer.get_uint_type_id();
let uint2_type_id = self.writer.get_uint2_type_id();
let uint_type_id = self.writer.get_u32_type_id();
let uint2_type_id = self.writer.get_vec2u_type_id();
let uint2_ptr_type_id = self
.writer
.get_uint2_pointer_type_id(spirv::StorageClass::Function);
.get_vec2u_pointer_type_id(spirv::StorageClass::Function);
let bool_type_id = self.writer.get_bool_type_id();
let bool2_type_id = self.writer.get_bool2_type_id();
let bool2_type_id = self.writer.get_vec2_bool_type_id();
let zero_uint_const_id = self.writer.get_constant_scalar(crate::Literal::U32(0));
let zero_uint2_const_id = self.writer.get_constant_composite(
LookupType::Local(LocalType::Numeric(NumericType::Vector {
@@ -575,7 +569,7 @@ impl BlockContext<'_> {
}
};
let binding_type_id = self.get_type_id(LookupType::Handle(binding_type));
let binding_type_id = self.get_handle_type_id(binding_type);
let load_id = self.gen_id();
block.body.push(Instruction::load(
@@ -666,7 +660,7 @@ impl BlockContext<'_> {
}
};
let binding_type_id = self.get_type_id(LookupType::Handle(binding_type));
let binding_type_id = self.get_handle_type_id(binding_type);
let load_id = self.gen_id();
block.body.push(Instruction::load(
@@ -1175,9 +1169,8 @@ impl BlockContext<'_> {
&crate::TypeInner::Vector { size, .. },
&crate::TypeInner::Scalar(scalar),
) => {
let selector_type_id = self.get_type_id(LookupType::Local(
LocalType::Numeric(NumericType::Vector { size, scalar }),
));
let selector_type_id =
self.get_numeric_type_id(NumericType::Vector { size, scalar });
self.temp_list.clear();
self.temp_list.resize(size as usize, arg2_id);
@@ -1281,9 +1274,7 @@ impl BlockContext<'_> {
)
}
crate::TypeInner::Scalar(scalar) => (
self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(scalar),
))),
self.get_numeric_type_id(NumericType::Scalar(scalar)),
self.writer
.get_constant_scalar_with(scalar.width * 8 - 1, scalar)?,
scalar.width,
@@ -1348,9 +1339,8 @@ impl BlockContext<'_> {
.writer
.get_constant_scalar(crate::Literal::U32(bit_width as u32));
let u32_type = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::U32),
)));
let u32_type =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::U32));
// o = min(offset, w)
let offset_id = self.gen_id();
@@ -1399,9 +1389,8 @@ impl BlockContext<'_> {
.writer
.get_constant_scalar(crate::Literal::U32(bit_width as u32));
let u32_type = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::U32),
)));
let u32_type =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::U32));
// o = min(offset, w)
let offset_id = self.gen_id();
@@ -1467,16 +1456,14 @@ impl BlockContext<'_> {
Mf::Pack4xU8 => (crate::ScalarKind::Uint, false),
_ => unreachable!(),
};
let uint_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::U32),
)));
let uint_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::U32));
let int_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar {
let int_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar {
kind: int_type,
width: 4,
}),
)));
}));
let mut last_instruction = Instruction::new(spirv::Op::Nop);
@@ -1553,17 +1540,15 @@ impl BlockContext<'_> {
_ => unreachable!(),
};
let sint_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::I32),
)));
let sint_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::I32));
let eight = self.writer.get_constant_scalar(crate::Literal::U32(8));
let int_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar {
let int_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar {
kind: int_type,
width: 4,
}),
)));
}));
block
.body
.reserve(usize::from(VEC_LENGTH) * 2 + usize::from(is_signed));
@@ -1628,159 +1613,7 @@ impl BlockContext<'_> {
expr,
kind,
convert,
} => {
use crate::ScalarKind as Sk;
let expr_id = self.cached[expr];
let (src_scalar, src_size, is_matrix) =
match *self.fun_info[expr].ty.inner_with(&self.ir_module.types) {
crate::TypeInner::Scalar(scalar) => (scalar, None, false),
crate::TypeInner::Vector { scalar, size } => (scalar, Some(size), false),
crate::TypeInner::Matrix { scalar, .. } => (scalar, None, true),
ref other => {
log::error!("As source {:?}", other);
return Err(Error::Validation("Unexpected Expression::As source"));
}
};
enum Cast {
Identity,
Unary(spirv::Op),
Binary(spirv::Op, Word),
Ternary(spirv::Op, Word, Word),
}
let cast = if is_matrix {
// we only support identity casts for matrices
Cast::Unary(spirv::Op::CopyObject)
} else {
match (src_scalar.kind, kind, convert) {
// Filter out identity casts. Some Adreno drivers are
// confused by no-op OpBitCast instructions.
(src_kind, kind, convert)
if src_kind == kind
&& convert.filter(|&width| width != src_scalar.width).is_none() =>
{
Cast::Identity
}
(Sk::Bool, Sk::Bool, _) => Cast::Unary(spirv::Op::CopyObject),
(_, _, None) => Cast::Unary(spirv::Op::Bitcast),
// casting to a bool - generate `OpXxxNotEqual`
(_, Sk::Bool, Some(_)) => {
let op = match src_scalar.kind {
Sk::Sint | Sk::Uint => spirv::Op::INotEqual,
Sk::Float => spirv::Op::FUnordNotEqual,
Sk::Bool | Sk::AbstractInt | Sk::AbstractFloat => unreachable!(),
};
let zero_scalar_id =
self.writer.get_constant_scalar_with(0, src_scalar)?;
let zero_id = match src_size {
Some(size) => {
let ty = LocalType::Numeric(NumericType::Vector {
size,
scalar: src_scalar,
})
.into();
self.temp_list.clear();
self.temp_list.resize(size as _, zero_scalar_id);
self.writer.get_constant_composite(ty, &self.temp_list)
}
None => zero_scalar_id,
};
Cast::Binary(op, zero_id)
}
// casting from a bool - generate `OpSelect`
(Sk::Bool, _, Some(dst_width)) => {
let dst_scalar = crate::Scalar {
kind,
width: dst_width,
};
let zero_scalar_id =
self.writer.get_constant_scalar_with(0, dst_scalar)?;
let one_scalar_id =
self.writer.get_constant_scalar_with(1, dst_scalar)?;
let (accept_id, reject_id) = match src_size {
Some(size) => {
let ty = LocalType::Numeric(NumericType::Vector {
size,
scalar: dst_scalar,
})
.into();
self.temp_list.clear();
self.temp_list.resize(size as _, zero_scalar_id);
let vec0_id =
self.writer.get_constant_composite(ty, &self.temp_list);
self.temp_list.fill(one_scalar_id);
let vec1_id =
self.writer.get_constant_composite(ty, &self.temp_list);
(vec1_id, vec0_id)
}
None => (one_scalar_id, zero_scalar_id),
};
Cast::Ternary(spirv::Op::Select, accept_id, reject_id)
}
(Sk::Float, Sk::Uint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToU),
(Sk::Float, Sk::Sint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToS),
(Sk::Float, Sk::Float, Some(dst_width))
if src_scalar.width != dst_width =>
{
Cast::Unary(spirv::Op::FConvert)
}
(Sk::Sint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertSToF),
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::SConvert)
}
(Sk::Uint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertUToF),
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::UConvert)
}
(Sk::Uint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::SConvert)
}
(Sk::Sint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::UConvert)
}
// We assume it's either an identity cast, or int-uint.
_ => Cast::Unary(spirv::Op::Bitcast),
}
};
let id = self.gen_id();
let instruction = match cast {
Cast::Identity => None,
Cast::Unary(op) => Some(Instruction::unary(op, result_type_id, id, expr_id)),
Cast::Binary(op, operand) => Some(Instruction::binary(
op,
result_type_id,
id,
expr_id,
operand,
)),
Cast::Ternary(op, op1, op2) => Some(Instruction::ternary(
op,
result_type_id,
id,
expr_id,
op1,
op2,
)),
};
if let Some(instruction) = instruction {
block.body.push(instruction);
id
} else {
expr_id
}
}
} => self.write_as_expression(expr, convert, kind, block, result_type_id)?,
crate::Expression::ImageLoad {
image,
coordinate,
@@ -1845,12 +1678,10 @@ impl BlockContext<'_> {
self.temp_list.clear();
self.temp_list.resize(size as usize, condition_id);
let bool_vector_type_id = self.get_type_id(LookupType::Local(
LocalType::Numeric(NumericType::Vector {
size,
scalar: condition_scalar,
}),
));
let bool_vector_type_id = self.get_numeric_type_id(NumericType::Vector {
size,
scalar: condition_scalar,
});
let id = self.gen_id();
block.body.push(Instruction::composite_construct(
@@ -1920,7 +1751,7 @@ impl BlockContext<'_> {
.writer
.write_ray_query_get_intersection_function(committed, self.ir_module);
let ray_intersection = self.ir_module.special_types.ray_intersection.unwrap();
let intersection_type_id = self.get_type_id(LookupType::Handle(ray_intersection));
let intersection_type_id = self.get_handle_type_id(ray_intersection);
let id = self.gen_id();
block.body.push(Instruction::function_call(
intersection_type_id,
@@ -1943,6 +1774,237 @@ impl BlockContext<'_> {
Ok(())
}
/// Helper which focuses on generating the `As` expressions and the various conversions
/// that need to happen because of that.
fn write_as_expression(
&mut self,
expr: Handle<crate::Expression>,
convert: Option<u8>,
kind: crate::ScalarKind,
block: &mut Block,
result_type_id: u32,
) -> Result<u32, Error> {
use crate::ScalarKind as Sk;
let expr_id = self.cached[expr];
let ty = self.fun_info[expr].ty.inner_with(&self.ir_module.types);
// Matrix casts needs special treatment in SPIR-V, as the cast functions
// can take vectors or scalars, but not matrices. In order to cast a matrix
// we need to cast each column of the matrix individually and construct a new
// matrix from the converted columns.
if let crate::TypeInner::Matrix {
columns,
rows,
scalar,
} = *ty
{
let Some(convert) = convert else {
// No conversion needs to be done, passes through.
return Ok(expr_id);
};
if convert == scalar.width {
// No conversion needs to be done, passes through.
return Ok(expr_id);
}
if kind != Sk::Float {
// Only float conversions are supported for matrices.
return Err(Error::Validation("Matrices must be floats"));
}
// Type of each extracted column
let column_src_ty =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: rows,
scalar,
})));
// Type of the column after conversion
let column_dst_ty =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: rows,
scalar: crate::Scalar {
kind,
width: convert,
},
})));
let mut components = ArrayVec::<Word, 4>::new();
for column in 0..columns as usize {
let column_id = self.gen_id();
block.body.push(Instruction::composite_extract(
column_src_ty,
column_id,
expr_id,
&[column as u32],
));
let column_conv_id = self.gen_id();
block.body.push(Instruction::unary(
spirv::Op::FConvert,
column_dst_ty,
column_conv_id,
column_id,
));
components.push(column_conv_id);
}
let construct_id = self.gen_id();
block.body.push(Instruction::composite_construct(
result_type_id,
construct_id,
&components,
));
return Ok(construct_id);
}
let (src_scalar, src_size) = match *ty {
crate::TypeInner::Scalar(scalar) => (scalar, None),
crate::TypeInner::Vector { scalar, size } => (scalar, Some(size)),
ref other => {
log::error!("As source {:?}", other);
return Err(Error::Validation("Unexpected Expression::As source"));
}
};
enum Cast {
Identity,
Unary(spirv::Op),
Binary(spirv::Op, Word),
Ternary(spirv::Op, Word, Word),
}
let cast = match (src_scalar.kind, kind, convert) {
// Filter out identity casts. Some Adreno drivers are
// confused by no-op OpBitCast instructions.
(src_kind, kind, convert)
if src_kind == kind
&& convert.filter(|&width| width != src_scalar.width).is_none() =>
{
Cast::Identity
}
(Sk::Bool, Sk::Bool, _) => Cast::Unary(spirv::Op::CopyObject),
(_, _, None) => Cast::Unary(spirv::Op::Bitcast),
// casting to a bool - generate `OpXxxNotEqual`
(_, Sk::Bool, Some(_)) => {
let op = match src_scalar.kind {
Sk::Sint | Sk::Uint => spirv::Op::INotEqual,
Sk::Float => spirv::Op::FUnordNotEqual,
Sk::Bool | Sk::AbstractInt | Sk::AbstractFloat => unreachable!(),
};
let zero_scalar_id = self.writer.get_constant_scalar_with(0, src_scalar)?;
let zero_id = match src_size {
Some(size) => {
let ty = LocalType::Numeric(NumericType::Vector {
size,
scalar: src_scalar,
})
.into();
self.temp_list.clear();
self.temp_list.resize(size as _, zero_scalar_id);
self.writer.get_constant_composite(ty, &self.temp_list)
}
None => zero_scalar_id,
};
Cast::Binary(op, zero_id)
}
// casting from a bool - generate `OpSelect`
(Sk::Bool, _, Some(dst_width)) => {
let dst_scalar = crate::Scalar {
kind,
width: dst_width,
};
let zero_scalar_id = self.writer.get_constant_scalar_with(0, dst_scalar)?;
let one_scalar_id = self.writer.get_constant_scalar_with(1, dst_scalar)?;
let (accept_id, reject_id) = match src_size {
Some(size) => {
let ty = LocalType::Numeric(NumericType::Vector {
size,
scalar: dst_scalar,
})
.into();
self.temp_list.clear();
self.temp_list.resize(size as _, zero_scalar_id);
let vec0_id = self.writer.get_constant_composite(ty, &self.temp_list);
self.temp_list.fill(one_scalar_id);
let vec1_id = self.writer.get_constant_composite(ty, &self.temp_list);
(vec1_id, vec0_id)
}
None => (one_scalar_id, zero_scalar_id),
};
Cast::Ternary(spirv::Op::Select, accept_id, reject_id)
}
(Sk::Float, Sk::Uint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToU),
(Sk::Float, Sk::Sint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToS),
(Sk::Float, Sk::Float, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::FConvert)
}
(Sk::Sint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertSToF),
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::SConvert)
}
(Sk::Uint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertUToF),
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::UConvert)
}
(Sk::Uint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::SConvert)
}
(Sk::Sint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
Cast::Unary(spirv::Op::UConvert)
}
// We assume it's either an identity cast, or int-uint.
_ => Cast::Unary(spirv::Op::Bitcast),
};
Ok(match cast {
Cast::Identity => expr_id,
Cast::Unary(op) => {
let id = self.gen_id();
block
.body
.push(Instruction::unary(op, result_type_id, id, expr_id));
id
}
Cast::Binary(op, operand) => {
let id = self.gen_id();
block.body.push(Instruction::binary(
op,
result_type_id,
id,
expr_id,
operand,
));
id
}
Cast::Ternary(op, op1, op2) => {
let id = self.gen_id();
block.body.push(Instruction::ternary(
op,
result_type_id,
id,
expr_id,
op1,
op2,
));
id
}
})
}
/// Build an `OpAccessChain` instruction.
///
/// Emit any needed bounds-checking expressions to `block`.
@@ -2354,11 +2416,10 @@ impl BlockContext<'_> {
) {
self.temp_list.clear();
let vector_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: rows,
scalar: crate::Scalar::float(width),
})));
let vector_type_id = self.get_numeric_type_id(NumericType::Vector {
size: rows,
scalar: crate::Scalar::float(width),
});
for index in 0..columns as u32 {
let column_id_left = self.gen_id();
@@ -3116,12 +3177,10 @@ impl BlockContext<'_> {
)
}
crate::AtomicFunction::Exchange { compare: Some(cmp) } => {
let scalar_type_id = self.get_type_id(LookupType::Local(
LocalType::Numeric(NumericType::Scalar(scalar)),
));
let bool_type_id = self.get_type_id(LookupType::Local(
LocalType::Numeric(NumericType::Scalar(crate::Scalar::BOOL)),
));
let scalar_type_id =
self.get_numeric_type_id(NumericType::Scalar(scalar));
let bool_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::BOOL));
let cas_result_id = self.gen_id();
let equality_result_id = self.gen_id();
@@ -3250,7 +3309,7 @@ impl BlockContext<'_> {
// need to end it with some kind of return instruction.
BlockExit::Return => match self.ir_function.result {
Some(ref result) if self.function.entry_point_context.is_none() => {
let type_id = self.get_type_id(LookupType::Handle(result.ty));
let type_id = self.get_handle_type_id(result.ty);
let null_id = self.writer.get_constant_null(type_id);
Instruction::return_value(null_id)
}

View File

@@ -126,12 +126,10 @@ impl Load {
// image produces a scalar `f32`, so in that case we need to find
// the right SPIR-V type for the access instruction here.
let type_id = match image_class {
crate::ImageClass::Depth { .. } => {
ctx.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: crate::VectorSize::Quad,
scalar: crate::Scalar::F32,
})))
}
crate::ImageClass::Depth { .. } => ctx.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Quad,
scalar: crate::Scalar::F32,
}),
_ => result_type_id,
};
@@ -340,9 +338,7 @@ impl BlockContext<'_> {
}
};
let reconciled_array_index_id = if let Some(cast) = cast {
let component_ty_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(component_scalar),
)));
let component_ty_id = self.get_numeric_type_id(NumericType::Scalar(component_scalar));
let reconciled_id = self.gen_id();
block.body.push(Instruction::unary(
cast,
@@ -356,11 +352,10 @@ impl BlockContext<'_> {
};
// Find the SPIR-V type for the combined coordinates/index vector.
let type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size,
scalar: component_scalar,
})));
let type_id = self.get_numeric_type_id(NumericType::Vector {
size,
scalar: component_scalar,
});
// Schmear the coordinates and index together.
let value_id = self.gen_id();
@@ -527,9 +522,7 @@ impl BlockContext<'_> {
&[spirv::Capability::ImageQuery],
)?;
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::I32),
)));
let i32_type_id = self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::I32));
// If `level` is `Some`, clamp it to fall within bounds. This must
// happen first, because we'll use it to query the image size for
@@ -612,9 +605,7 @@ impl BlockContext<'_> {
)?;
let bool_type_id = self.writer.get_bool_type_id();
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::I32),
)));
let i32_type_id = self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::I32));
let null_id = access.out_of_bounds_value(self);
@@ -684,8 +675,7 @@ impl BlockContext<'_> {
},
None => NumericType::Scalar(crate::Scalar::BOOL),
};
let coords_bool_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(coords_numeric_type)));
let coords_bool_type_id = self.get_numeric_type_id(coords_numeric_type);
let coords_conds_id = self.gen_id();
selection.block().body.push(Instruction::binary(
spirv::Op::ULessThan,
@@ -836,16 +826,16 @@ impl BlockContext<'_> {
_ => false,
};
let sample_result_type_id = if needs_sub_access {
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Quad,
scalar: crate::Scalar::F32,
})))
})
} else {
result_type_id
};
// OpTypeSampledImage
let image_type_id = self.get_type_id(LookupType::Handle(image_type));
let image_type_id = self.get_handle_type_id(image_type);
let sampled_image_type_id =
self.get_type_id(LookupType::Local(LocalType::SampledImage { image_type_id }));
@@ -937,9 +927,8 @@ impl BlockContext<'_> {
}
) {
let lod_f32_id = self.gen_id();
let f32_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::F32),
)));
let f32_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::F32));
let convert_op = match *self.fun_info[lod_handle]
.ty
.inner_with(&self.ir_module.types)
@@ -1007,7 +996,7 @@ impl BlockContext<'_> {
};
if let Some(offset_const) = offset {
let offset_id = self.writer.constant_ids[offset_const];
let offset_id = self.cached[offset_const];
main_instruction.add_operand(offset_id);
}
@@ -1079,8 +1068,7 @@ impl BlockContext<'_> {
None => NumericType::Scalar(crate::Scalar::U32),
};
let extended_size_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(vector_numeric_type)));
let extended_size_type_id = self.get_numeric_type_id(vector_numeric_type);
let (query_op, level_id) = match class {
Ic::Sampled { multi: true, .. }
@@ -1146,11 +1134,10 @@ impl BlockContext<'_> {
Id::D2 | Id::Cube => crate::VectorSize::Tri,
Id::D3 => crate::VectorSize::Quad,
};
let extended_size_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: vec_size,
scalar: crate::Scalar::U32,
})));
let extended_size_type_id = self.get_numeric_type_id(NumericType::Vector {
size: vec_size,
scalar: crate::Scalar::U32,
});
let id_extended = self.gen_id();
let mut inst = Instruction::image_query(
spirv::Op::ImageQuerySizeLod,
@@ -1249,10 +1236,8 @@ impl BlockContext<'_> {
return Err(Error::Validation("Invalid image class"));
};
let scalar = format.into();
let pointer_type_id = self.get_type_id(LookupType::Local(LocalType::LocalPointer {
base: NumericType::Scalar(scalar),
class: spirv::StorageClass::Image,
}));
let scalar_type_id = self.get_numeric_type_id(NumericType::Scalar(scalar));
let pointer_type_id = self.get_pointer_type_id(scalar_type_id, spirv::StorageClass::Image);
let signed = scalar.kind == crate::ScalarKind::Sint;
if scalar.width == 8 {
self.writer

View File

@@ -225,8 +225,9 @@ impl BlockContext<'_> {
Some(index_id) => {
let element_type_id = match self.ir_module.types[global.ty].inner {
crate::TypeInner::BindingArray { base, size: _ } => {
let base_id = self.get_handle_type_id(base);
let class = map_storage_class(global.space);
self.get_pointer_id(base, class)
self.get_pointer_type_id(base_id, class)
}
_ => return Err(Error::Validation("array length expression case-5")),
};
@@ -243,7 +244,7 @@ impl BlockContext<'_> {
};
let length_id = self.gen_id();
block.body.push(Instruction::array_length(
self.writer.get_uint_type_id(),
self.writer.get_u32_type_id(),
length_id,
structure_id,
last_member_index,
@@ -267,13 +268,10 @@ impl BlockContext<'_> {
block: &mut Block,
) -> Result<MaybeKnown<u32>, Error> {
let sequence_ty = self.fun_info[sequence].ty.inner_with(&self.ir_module.types);
match sequence_ty.indexable_length(self.ir_module) {
match sequence_ty.indexable_length_resolved(self.ir_module) {
Ok(crate::proc::IndexableLength::Known(known_length)) => {
Ok(MaybeKnown::Known(known_length))
}
Ok(crate::proc::IndexableLength::Pending) => {
unreachable!()
}
Ok(crate::proc::IndexableLength::Dynamic) => {
let length_id = self.write_runtime_array_length(sequence, block)?;
Ok(MaybeKnown::Computed(length_id))
@@ -314,7 +312,7 @@ impl BlockContext<'_> {
let max_index_id = self.gen_id();
block.body.push(Instruction::binary(
spirv::Op::ISub,
self.writer.get_uint_type_id(),
self.writer.get_u32_type_id(),
max_index_id,
length_id,
const_one_id,
@@ -371,7 +369,7 @@ impl BlockContext<'_> {
block.body.push(Instruction::ext_inst(
self.writer.gl450_ext_inst_id,
spirv::GLOp::UMin,
self.writer.get_uint_type_id(),
self.writer.get_u32_type_id(),
restricted_index_id,
&[index_id, max_index_id],
));

View File

@@ -105,10 +105,6 @@ impl super::Instruction {
instruction
}
pub(super) const fn no_line() -> Self {
Self::new(Op::NoLine)
}
//
// Annotation Instructions
//
@@ -409,6 +405,10 @@ impl super::Instruction {
instruction
}
pub(super) fn constant_16bit(result_type_id: Word, id: Word, low: Word) -> Self {
Self::constant(result_type_id, id, &[low])
}
pub(super) fn constant_32bit(result_type_id: Word, id: Word, value: Word) -> Self {
Self::constant(result_type_id, id, &[value])
}

View File

@@ -75,6 +75,8 @@ pub enum Error {
Validation(&'static str),
#[error("overrides should not be present at this stage")]
Override,
#[error(transparent)]
ResolveArraySizeError(#[from] crate::proc::ResolveArraySizeError),
}
#[derive(Default)]
@@ -348,9 +350,9 @@ impl NumericType {
/// never synthesizes new struct types, so `LocalType` has nothing for that.
///
/// Each `LocalType` variant should be handled identically to its analogous
/// `TypeInner` variant. You can use the [`LocalType::from_inner`] function to
/// help with this, by converting everything possible to a `LocalType` before
/// inspecting it.
/// `TypeInner` variant. You can use the [`Writer::localtype_from_inner`]
/// function to help with this, by converting everything possible to a
/// `LocalType` before inspecting it.
///
/// ## `LocalType` equality and SPIR-V `OpType` uniqueness
///
@@ -370,8 +372,10 @@ impl NumericType {
/// variant, is designed to help us deduplicate `OpTypeImage` instructions. See
/// its documentation for details.
///
/// `LocalType` also includes variants like `Pointer` that do not need to be
/// unique - but it is harmless to avoid the duplication.
/// SPIR-V does not require pointer types to be unique - but different
/// SPIR-V ids are considered to be distinct pointer types. Since Naga
/// uses structural type equality, we need to represent each Naga
/// equivalence class with a single SPIR-V `OpTypePointer`.
///
/// As it always must, the `Hash` implementation respects the `Eq` relation.
///
@@ -380,12 +384,8 @@ impl NumericType {
enum LocalType {
/// A numeric type.
Numeric(NumericType),
LocalPointer {
base: NumericType,
class: spirv::StorageClass,
},
Pointer {
base: Handle<crate::Type>,
base: Word,
class: spirv::StorageClass,
},
Image(LocalImageType),
@@ -393,16 +393,6 @@ enum LocalType {
image_type_id: Word,
},
Sampler,
/// Equivalent to a [`LocalType::Pointer`] whose `base` is a Naga IR [`BindingArray`]. SPIR-V
/// permits duplicated `OpTypePointer` ids, so it's fine to have two different [`LocalType`]
/// representations for pointer types.
///
/// [`BindingArray`]: crate::TypeInner::BindingArray
PointerToBindingArray {
base: Handle<crate::Type>,
size: u32,
space: crate::AddressSpace,
},
BindingArray {
base: Handle<crate::Type>,
size: u32,
@@ -451,52 +441,6 @@ struct LookupFunctionType {
return_type_id: Word,
}
impl LocalType {
fn from_inner(inner: &crate::TypeInner) -> Option<Self> {
Some(match *inner {
crate::TypeInner::Scalar(_)
| crate::TypeInner::Atomic(_)
| crate::TypeInner::Vector { .. }
| crate::TypeInner::Matrix { .. } => {
// We expect `NumericType::from_inner` to handle all
// these cases, so unwrap.
LocalType::Numeric(NumericType::from_inner(inner).unwrap())
}
crate::TypeInner::Pointer { base, space } => LocalType::Pointer {
base,
class: helpers::map_storage_class(space),
},
crate::TypeInner::ValuePointer {
size: Some(size),
scalar,
space,
} => LocalType::LocalPointer {
base: NumericType::Vector { size, scalar },
class: helpers::map_storage_class(space),
},
crate::TypeInner::ValuePointer {
size: None,
scalar,
space,
} => LocalType::LocalPointer {
base: NumericType::Scalar(scalar),
class: helpers::map_storage_class(space),
},
crate::TypeInner::Image {
dim,
arrayed,
class,
} => LocalType::Image(LocalImageType::from_inner(dim, arrayed, class)),
crate::TypeInner::Sampler { comparison: _ } => LocalType::Sampler,
crate::TypeInner::AccelerationStructure { .. } => LocalType::AccelerationStructure,
crate::TypeInner::RayQuery { .. } => LocalType::RayQuery,
crate::TypeInner::Array { .. }
| crate::TypeInner::Struct { .. }
| crate::TypeInner::BindingArray { .. } => return None,
})
}
}
#[derive(Debug)]
enum Dimension {
Scalar,
@@ -748,6 +692,10 @@ impl BlockContext<'_> {
self.writer.get_type_id(lookup_type)
}
fn get_handle_type_id(&mut self, handle: Handle<crate::Type>) -> Word {
self.writer.get_handle_type_id(handle)
}
fn get_expression_type_id(&mut self, tr: &TypeResolution) -> Word {
self.writer.get_expression_type_id(tr)
}
@@ -761,8 +709,12 @@ impl BlockContext<'_> {
.get_constant_scalar(crate::Literal::I32(scope as _))
}
fn get_pointer_id(&mut self, handle: Handle<crate::Type>, class: spirv::StorageClass) -> Word {
self.writer.get_pointer_id(handle, class)
fn get_pointer_type_id(&mut self, base: Word, class: spirv::StorageClass) -> Word {
self.writer.get_pointer_type_id(base, class)
}
fn get_numeric_type_id(&mut self, numeric: NumericType) -> Word {
self.writer.get_numeric_type_id(numeric)
}
}

View File

@@ -5,11 +5,10 @@ Generating SPIR-V for ray query operations.
use alloc::vec;
use super::{
Block, BlockContext, Function, FunctionArgument, Instruction, LocalType, LookupFunctionType,
LookupType, NumericType, Writer,
Block, BlockContext, Function, FunctionArgument, Instruction, LookupFunctionType, NumericType,
Writer,
};
use crate::arena::Handle;
use crate::{Type, TypeInner};
impl Writer {
pub(super) fn write_ray_query_get_intersection_function(
@@ -21,100 +20,35 @@ impl Writer {
return func_id;
}
let ray_intersection = ir_module.special_types.ray_intersection.unwrap();
let intersection_type_id = self.get_type_id(LookupType::Handle(ray_intersection));
let intersection_type_id = self.get_handle_type_id(ray_intersection);
let intersection_pointer_type_id =
self.get_type_id(LookupType::Local(LocalType::Pointer {
base: ray_intersection,
class: spirv::StorageClass::Function,
}));
self.get_pointer_type_id(intersection_type_id, spirv::StorageClass::Function);
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::U32),
)));
let flag_type = ir_module
.types
.get(&Type {
name: None,
inner: TypeInner::Scalar(crate::Scalar::U32),
})
.unwrap();
let flag_pointer_type_id = self.get_type_id(LookupType::Local(LocalType::Pointer {
base: flag_type,
class: spirv::StorageClass::Function,
}));
let flag_type_id = self.get_u32_type_id();
let flag_pointer_type_id =
self.get_pointer_type_id(flag_type_id, spirv::StorageClass::Function);
let transform_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Matrix {
columns: crate::VectorSize::Quad,
rows: crate::VectorSize::Tri,
scalar: crate::Scalar::F32,
})));
let transform_type = ir_module
.types
.get(&Type {
name: None,
inner: TypeInner::Matrix {
columns: crate::VectorSize::Quad,
rows: crate::VectorSize::Tri,
scalar: crate::Scalar::F32,
},
})
.unwrap();
let transform_pointer_type_id = self.get_type_id(LookupType::Local(LocalType::Pointer {
base: transform_type,
class: spirv::StorageClass::Function,
}));
let transform_type_id = self.get_numeric_type_id(NumericType::Matrix {
columns: crate::VectorSize::Quad,
rows: crate::VectorSize::Tri,
scalar: crate::Scalar::F32,
});
let transform_pointer_type_id =
self.get_pointer_type_id(transform_type_id, spirv::StorageClass::Function);
let barycentrics_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::F32,
})));
let barycentrics_type = ir_module
.types
.get(&Type {
name: None,
inner: TypeInner::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::F32,
},
})
.unwrap();
let barycentrics_type_id = self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::F32,
});
let barycentrics_pointer_type_id =
self.get_type_id(LookupType::Local(LocalType::Pointer {
base: barycentrics_type,
class: spirv::StorageClass::Function,
}));
self.get_pointer_type_id(barycentrics_type_id, spirv::StorageClass::Function);
let bool_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::BOOL),
)));
let bool_type = ir_module
.types
.get(&Type {
name: None,
inner: TypeInner::Scalar(crate::Scalar::BOOL),
})
.unwrap();
let bool_pointer_type_id = self.get_type_id(LookupType::Local(LocalType::Pointer {
base: bool_type,
class: spirv::StorageClass::Function,
}));
let bool_type_id = self.get_bool_type_id();
let bool_pointer_type_id =
self.get_pointer_type_id(bool_type_id, spirv::StorageClass::Function);
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::F32),
)));
let float_type = ir_module
.types
.get(&Type {
name: None,
inner: TypeInner::Scalar(crate::Scalar::F32),
})
.unwrap();
let float_pointer_type_id = self.get_type_id(LookupType::Local(LocalType::Pointer {
base: float_type,
class: spirv::StorageClass::Function,
}));
let scalar_type_id = self.get_f32_type_id();
let float_pointer_type_id = self.get_f32_pointer_type_id(spirv::StorageClass::Function);
let argument_type_id = self.get_ray_query_pointer_id(ir_module);
@@ -525,9 +459,8 @@ impl BlockContext<'_> {
let desc_id = self.cached[descriptor];
let acc_struct_id = self.get_handle_id(acceleration_structure);
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::U32),
)));
let flag_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::U32));
let ray_flags_id = self.gen_id();
block.body.push(Instruction::composite_extract(
flag_type_id,
@@ -543,9 +476,8 @@ impl BlockContext<'_> {
&[1],
));
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(crate::Scalar::F32),
)));
let scalar_type_id =
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::F32));
let tmin_id = self.gen_id();
block.body.push(Instruction::composite_extract(
scalar_type_id,
@@ -561,11 +493,10 @@ impl BlockContext<'_> {
&[3],
));
let vector_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::F32,
})));
let vector_type_id = self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::F32,
});
let ray_origin_id = self.gen_id();
block.body.push(Instruction::composite_extract(
vector_type_id,
@@ -626,11 +557,12 @@ impl BlockContext<'_> {
) -> spirv::Word {
let query_id = self.cached[query];
let id = self.gen_id();
let result = self
let ray_vertex_return_ty = self
.ir_module
.special_types
.ray_vertex_return
.expect("type should have been populated");
let ray_vertex_return_ty_id = self.writer.get_handle_type_id(ray_vertex_return_ty);
let intersection_id =
self.writer
.get_constant_scalar(crate::Literal::U32(if is_committed {
@@ -641,11 +573,7 @@ impl BlockContext<'_> {
block
.body
.push(Instruction::ray_query_return_vertex_position(
*self
.writer
.lookup_type
.get(&LookupType::Handle(result))
.expect("type should have been populated"),
ray_vertex_return_ty_id,
id,
query_id,
intersection_id,

View File

@@ -1,9 +1,5 @@
use super::{Block, BlockContext, Error, Instruction, NumericType};
use crate::{
arena::Handle,
back::spv::{LocalType, LookupType},
TypeInner,
};
use crate::{arena::Handle, TypeInner};
impl BlockContext<'_> {
pub(super) fn write_subgroup_ballot(
@@ -16,11 +12,10 @@ impl BlockContext<'_> {
"GroupNonUniformBallot",
&[spirv::Capability::GroupNonUniformBallot],
)?;
let vec4_u32_type_id =
self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Vector {
size: crate::VectorSize::Quad,
scalar: crate::Scalar::U32,
})));
let vec4_u32_type_id = self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Quad,
scalar: crate::Scalar::U32,
});
let exec_scope_id = self.get_index_constant(spirv::Scope::Subgroup as u32);
let predicate = if let Some(predicate) = *predicate {
self.cached[predicate]

View File

@@ -11,9 +11,9 @@ use super::{
block::DebugInfoInner,
helpers::{contains_builtin, global_needs_wrapper, map_storage_class},
Block, BlockContext, CachedConstant, CachedExpressions, DebugInfo, EntryPointContext, Error,
Function, FunctionArgument, GlobalVariable, IdGenerator, Instruction, LocalType, LocalVariable,
LogicalLayout, LookupFunctionType, LookupType, NumericType, Options, PhysicalLayout,
PipelineOptions, ResultMember, Writer, WriterFlags, BITS_PER_BYTE,
Function, FunctionArgument, GlobalVariable, IdGenerator, Instruction, LocalImageType,
LocalType, LocalVariable, LogicalLayout, LookupFunctionType, LookupType, NumericType, Options,
PhysicalLayout, PipelineOptions, ResultMember, Writer, WriterFlags, BITS_PER_BYTE,
};
use crate::{
arena::{Handle, HandleVec, UniqueArena},
@@ -222,11 +222,16 @@ impl Writer {
}
}
pub(super) fn get_handle_type_id(&mut self, handle: Handle<crate::Type>) -> Word {
self.get_type_id(LookupType::Handle(handle))
}
pub(super) fn get_expression_lookup_type(&mut self, tr: &TypeResolution) -> LookupType {
match *tr {
TypeResolution::Handle(ty_handle) => LookupType::Handle(ty_handle),
TypeResolution::Value(ref inner) => {
LookupType::Local(LocalType::from_inner(inner).unwrap())
let inner_local_type = self.localtype_from_inner(inner).unwrap();
LookupType::Local(inner_local_type)
}
}
}
@@ -240,15 +245,17 @@ impl Writer {
self.get_type_id(LookupType::Local(local))
}
pub(super) fn get_pointer_id(
pub(super) fn get_pointer_type_id(&mut self, base: Word, class: spirv::StorageClass) -> Word {
self.get_type_id(LookupType::Local(LocalType::Pointer { base, class }))
}
pub(super) fn get_handle_pointer_type_id(
&mut self,
handle: Handle<crate::Type>,
base: Handle<crate::Type>,
class: spirv::StorageClass,
) -> Word {
self.get_type_id(LookupType::Local(LocalType::Pointer {
base: handle,
class,
}))
let base_id = self.get_handle_type_id(base);
self.get_pointer_type_id(base_id, class)
}
pub(super) fn get_ray_query_pointer_id(&mut self, module: &crate::Module) -> Word {
@@ -269,10 +276,7 @@ impl Writer {
})
})
.expect("ray_query type should have been populated by the variable passed into this!");
self.get_type_id(LookupType::Local(LocalType::Pointer {
base: rq_ty,
class: spirv::StorageClass::Function,
}))
self.get_handle_pointer_type_id(rq_ty, spirv::StorageClass::Function)
}
/// Return a SPIR-V type for a pointer to `resolution`.
@@ -284,90 +288,73 @@ impl Writer {
resolution: &TypeResolution,
class: spirv::StorageClass,
) -> Word {
match *resolution {
TypeResolution::Handle(handle) => self.get_pointer_id(handle, class),
TypeResolution::Value(ref inner) => {
let base = NumericType::from_inner(inner).unwrap();
self.get_type_id(LookupType::Local(LocalType::LocalPointer { base, class }))
}
}
let resolution_type_id = self.get_expression_type_id(resolution);
self.get_pointer_type_id(resolution_type_id, class)
}
pub(super) fn get_uint_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Scalar(crate::Scalar::U32));
self.get_type_id(local_type.into())
pub(super) fn get_numeric_type_id(&mut self, numeric: NumericType) -> Word {
self.get_type_id(LocalType::Numeric(numeric).into())
}
pub(super) fn get_float_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Scalar(crate::Scalar::F32));
self.get_type_id(local_type.into())
pub(super) fn get_u32_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::U32))
}
pub(super) fn get_uint2_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Vector {
pub(super) fn get_f32_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::F32))
}
pub(super) fn get_vec2u_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::U32,
})
}
pub(super) fn get_vec3u_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::U32,
})
}
pub(super) fn get_f32_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let f32_id = self.get_f32_type_id();
self.get_pointer_type_id(f32_id, class)
}
pub(super) fn get_vec2u_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let vec2u_id = self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::U32,
});
self.get_type_id(local_type.into())
self.get_pointer_type_id(vec2u_id, class)
}
pub(super) fn get_uint3_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Vector {
pub(super) fn get_vec3u_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let vec3u_id = self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::U32,
});
self.get_type_id(local_type.into())
}
pub(super) fn get_float_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let local_type = LocalType::LocalPointer {
base: NumericType::Scalar(crate::Scalar::F32),
class,
};
self.get_type_id(local_type.into())
}
pub(super) fn get_uint2_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let local_type = LocalType::LocalPointer {
base: NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::U32,
},
class,
};
self.get_type_id(local_type.into())
}
pub(super) fn get_uint3_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
let local_type = LocalType::LocalPointer {
base: NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::U32,
},
class,
};
self.get_type_id(local_type.into())
self.get_pointer_type_id(vec3u_id, class)
}
pub(super) fn get_bool_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Scalar(crate::Scalar::BOOL));
self.get_type_id(local_type.into())
self.get_numeric_type_id(NumericType::Scalar(crate::Scalar::BOOL))
}
pub(super) fn get_bool2_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Vector {
pub(super) fn get_vec2_bool_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Bi,
scalar: crate::Scalar::BOOL,
});
self.get_type_id(local_type.into())
})
}
pub(super) fn get_bool3_type_id(&mut self) -> Word {
let local_type = LocalType::Numeric(NumericType::Vector {
pub(super) fn get_vec3_bool_type_id(&mut self) -> Word {
self.get_numeric_type_id(NumericType::Vector {
size: crate::VectorSize::Tri,
scalar: crate::Scalar::BOOL,
});
self.get_type_id(local_type.into())
})
}
pub(super) fn decorate(&mut self, id: Word, decoration: spirv::Decoration, operands: &[Word]) {
@@ -375,6 +362,58 @@ impl Writer {
.push(Instruction::decorate(id, decoration, operands));
}
/// Return `inner` as a `LocalType`, if that's possible.
///
/// If `inner` can be represented as a `LocalType`, return
/// `Some(local_type)`.
///
/// Otherwise, return `None`. In this case, the type must always be looked
/// up using a `LookupType::Handle`.
fn localtype_from_inner(&mut self, inner: &crate::TypeInner) -> Option<LocalType> {
Some(match *inner {
crate::TypeInner::Scalar(_)
| crate::TypeInner::Atomic(_)
| crate::TypeInner::Vector { .. }
| crate::TypeInner::Matrix { .. } => {
// We expect `NumericType::from_inner` to handle all
// these cases, so unwrap.
LocalType::Numeric(NumericType::from_inner(inner).unwrap())
}
crate::TypeInner::Pointer { base, space } => {
let base_type_id = self.get_handle_type_id(base);
LocalType::Pointer {
base: base_type_id,
class: map_storage_class(space),
}
}
crate::TypeInner::ValuePointer {
size,
scalar,
space,
} => {
let base_numeric_type = match size {
Some(size) => NumericType::Vector { size, scalar },
None => NumericType::Scalar(scalar),
};
LocalType::Pointer {
base: self.get_numeric_type_id(base_numeric_type),
class: map_storage_class(space),
}
}
crate::TypeInner::Image {
dim,
arrayed,
class,
} => LocalType::Image(LocalImageType::from_inner(dim, arrayed, class)),
crate::TypeInner::Sampler { comparison: _ } => LocalType::Sampler,
crate::TypeInner::AccelerationStructure { .. } => LocalType::AccelerationStructure,
crate::TypeInner::RayQuery { .. } => LocalType::RayQuery,
crate::TypeInner::Array { .. }
| crate::TypeInner::Struct { .. }
| crate::TypeInner::BindingArray { .. } => return None,
})
}
/// Emits code for any wrapper functions required by the expressions in ir_function.
/// The IDs of any emitted functions will be stored in [`Self::wrapped_functions`].
fn write_wrapped_functions(
@@ -502,7 +541,7 @@ impl Writer {
let mut block = Block::new(label_id);
let bool_type = return_type.with_scalar(crate::Scalar::BOOL);
let bool_type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(bool_type)));
let bool_type_id = self.get_numeric_type_id(bool_type);
let maybe_splat_const = |writer: &mut Self, const_id| match return_type {
NumericType::Scalar(_) => const_id,
@@ -637,9 +676,10 @@ impl Writer {
for argument in ir_function.arguments.iter() {
let class = spirv::StorageClass::Input;
let handle_ty = ir_module.types[argument.ty].inner.is_handle();
let argument_type_id = match handle_ty {
true => self.get_pointer_id(argument.ty, spirv::StorageClass::UniformConstant),
false => self.get_type_id(LookupType::Handle(argument.ty)),
let argument_type_id = if handle_ty {
self.get_handle_pointer_type_id(argument.ty, spirv::StorageClass::UniformConstant)
} else {
self.get_handle_type_id(argument.ty)
};
if let Some(ref mut iface) = interface {
@@ -671,7 +711,7 @@ impl Writer {
let struct_id = self.id_gen.next();
let mut constituent_ids = Vec::with_capacity(members.len());
for member in members {
let type_id = self.get_type_id(LookupType::Handle(member.ty));
let type_id = self.get_handle_type_id(member.ty);
let name = member.name.as_deref();
let binding = member.binding.as_ref().unwrap();
let varying_id = self.write_varying(
@@ -716,7 +756,7 @@ impl Writer {
handle_id: if handle_ty {
let id = self.id_gen.next();
prelude.body.push(Instruction::load(
self.get_type_id(LookupType::Handle(argument.ty)),
self.get_handle_type_id(argument.ty),
id,
argument_id,
None,
@@ -738,7 +778,7 @@ impl Writer {
if let Some(ref binding) = result.binding {
has_point_size |=
*binding == crate::Binding::BuiltIn(crate::BuiltIn::PointSize);
let type_id = self.get_type_id(LookupType::Handle(result.ty));
let type_id = self.get_handle_type_id(result.ty);
let varying_id = self.write_varying(
ir_module,
iface.stage,
@@ -757,7 +797,7 @@ impl Writer {
ir_module.types[result.ty].inner
{
for member in members {
let type_id = self.get_type_id(LookupType::Handle(member.ty));
let type_id = self.get_handle_type_id(member.ty);
let name = member.name.as_deref();
let binding = member.binding.as_ref().unwrap();
has_point_size |=
@@ -787,7 +827,7 @@ impl Writer {
{
// add point size artificially
let varying_id = self.id_gen.next();
let pointer_type_id = self.get_float_pointer_type_id(class);
let pointer_type_id = self.get_f32_pointer_type_id(class);
Instruction::variable(pointer_type_id, varying_id, class, None)
.to_words(&mut self.logical_layout.declarations);
self.decorate(
@@ -804,7 +844,7 @@ impl Writer {
}
self.void_type
} else {
self.get_type_id(LookupType::Handle(result.ty))
self.get_handle_type_id(result.ty)
}
}
None => self.void_type,
@@ -860,7 +900,7 @@ impl Writer {
}
_ => {
if var.space == crate::AddressSpace::Handle {
let var_type_id = self.get_type_id(LookupType::Handle(var.ty));
let var_type_id = self.get_handle_type_id(var.ty);
let id = self.id_gen.next();
prelude
.body
@@ -869,7 +909,7 @@ impl Writer {
gv.handle_id = id;
} else if global_needs_wrapper(ir_module, var) {
let class = map_storage_class(var.space);
let pointer_type_id = self.get_pointer_id(var.ty, class);
let pointer_type_id = self.get_handle_pointer_type_id(var.ty, class);
let index_id = self.get_index_constant(0);
let id = self.id_gen.next();
prelude.body.push(Instruction::access_chain(
@@ -931,7 +971,7 @@ impl Writer {
let init_word = variable.init.map(|constant| context.cached[constant]);
let pointer_type_id = context
.writer
.get_pointer_id(variable.ty, spirv::StorageClass::Function);
.get_handle_pointer_type_id(variable.ty, spirv::StorageClass::Function);
let instruction = Instruction::variable(
pointer_type_id,
id,
@@ -939,7 +979,7 @@ impl Writer {
init_word.or_else(|| match ir_module.types[variable.ty].inner {
crate::TypeInner::RayQuery { .. } => None,
_ => {
let type_id = context.get_type_id(LookupType::Handle(variable.ty));
let type_id = context.get_handle_type_id(variable.ty);
Some(context.writer.write_constant_null(type_id))
}
}),
@@ -1076,6 +1116,7 @@ impl Writer {
.to_words(&mut self.logical_layout.execution_modes);
spirv::ExecutionModel::GLCompute
}
crate::ShaderStage::Task | crate::ShaderStage::Mesh => unreachable!(),
};
//self.check(exec_model.required_capabilities())?;
@@ -1113,6 +1154,15 @@ impl Writer {
if bits == 64 {
self.capabilities_used.insert(spirv::Capability::Float64);
}
if bits == 16 {
self.capabilities_used.insert(spirv::Capability::Float16);
self.capabilities_used
.insert(spirv::Capability::StorageBuffer16BitAccess);
self.capabilities_used
.insert(spirv::Capability::UniformAndStorageBuffer16BitAccess);
self.capabilities_used
.insert(spirv::Capability::StorageInputOutput16);
}
Instruction::type_float(id, bits)
}
Sk::Bool => Instruction::type_bool(id),
@@ -1181,32 +1231,41 @@ impl Writer {
)?;
self.use_extension("SPV_EXT_shader_atomic_float_add");
}
// 16 bit floating-point support requires Float16 capability
crate::TypeInner::Matrix {
scalar: crate::Scalar::F16,
..
}
| crate::TypeInner::Vector {
scalar: crate::Scalar::F16,
..
}
| crate::TypeInner::Scalar(crate::Scalar::F16) => {
self.require_any("16 bit floating-point", &[spirv::Capability::Float16])?;
self.use_extension("SPV_KHR_16bit_storage");
}
_ => {}
}
Ok(())
}
fn write_numeric_type_declaration_local(&mut self, id: Word, numeric: NumericType) {
let instruction =
match numeric {
NumericType::Scalar(scalar) => self.make_scalar(id, scalar),
NumericType::Vector { size, scalar } => {
let scalar_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Scalar(scalar),
)));
Instruction::type_vector(id, scalar_id, size)
}
NumericType::Matrix {
columns,
rows,
scalar,
} => {
let column_id = self.get_type_id(LookupType::Local(LocalType::Numeric(
NumericType::Vector { size: rows, scalar },
)));
Instruction::type_matrix(id, column_id, columns)
}
};
let instruction = match numeric {
NumericType::Scalar(scalar) => self.make_scalar(id, scalar),
NumericType::Vector { size, scalar } => {
let scalar_id = self.get_numeric_type_id(NumericType::Scalar(scalar));
Instruction::type_vector(id, scalar_id, size)
}
NumericType::Matrix {
columns,
rows,
scalar,
} => {
let column_id =
self.get_numeric_type_id(NumericType::Vector { size: rows, scalar });
Instruction::type_matrix(id, column_id, columns)
}
};
instruction.to_words(&mut self.logical_layout.declarations);
}
@@ -1217,14 +1276,7 @@ impl Writer {
self.write_numeric_type_declaration_local(id, numeric);
return;
}
LocalType::LocalPointer { base, class } => {
let base_id = self.get_type_id(LookupType::Local(LocalType::Numeric(base)));
Instruction::type_pointer(id, class, base_id)
}
LocalType::Pointer { base, class } => {
let type_id = self.get_type_id(LookupType::Handle(base));
Instruction::type_pointer(id, class, type_id)
}
LocalType::Pointer { base, class } => Instruction::type_pointer(id, class, base),
LocalType::Image(image) => {
let local_type = LocalType::Numeric(NumericType::Scalar(image.sampled_type));
let type_id = self.get_localtype_id(local_type);
@@ -1235,16 +1287,10 @@ impl Writer {
Instruction::type_sampled_image(id, image_type_id)
}
LocalType::BindingArray { base, size } => {
let inner_ty = self.get_type_id(LookupType::Handle(base));
let inner_ty = self.get_handle_type_id(base);
let scalar_id = self.get_constant_scalar(crate::Literal::U32(size));
Instruction::type_array(id, inner_ty, scalar_id)
}
LocalType::PointerToBindingArray { base, size, space } => {
let inner_ty =
self.get_type_id(LookupType::Local(LocalType::BindingArray { base, size }));
let class = map_storage_class(space);
Instruction::type_pointer(id, class, inner_ty)
}
LocalType::AccelerationStructure => Instruction::type_acceleration_structure(id),
LocalType::RayQuery => Instruction::type_ray_query(id),
};
@@ -1254,16 +1300,16 @@ impl Writer {
fn write_type_declaration_arena(
&mut self,
arena: &UniqueArena<crate::Type>,
module: &crate::Module,
handle: Handle<crate::Type>,
) -> Result<Word, Error> {
let ty = &arena[handle];
let ty = &module.types[handle];
// If it's a type that needs SPIR-V capabilities, request them now.
// This needs to happen regardless of the LocalType lookup succeeding,
// because some types which map to the same LocalType have different
// capability requirements. See https://github.com/gfx-rs/wgpu/issues/5569
self.request_type_capabilities(&ty.inner)?;
let id = if let Some(local) = LocalType::from_inner(&ty.inner) {
let id = if let Some(local) = self.localtype_from_inner(&ty.inner) {
// This type can be represented as a `LocalType`, so check if we've
// already written an instruction for it. If not, do so now, with
// `write_type_declaration_local`.
@@ -1289,25 +1335,27 @@ impl Writer {
crate::TypeInner::Array { base, size, stride } => {
self.decorate(id, Decoration::ArrayStride, &[stride]);
let type_id = self.get_type_id(LookupType::Handle(base));
match size {
crate::ArraySize::Constant(length) => {
let length_id = self.get_index_constant(length.get());
let type_id = self.get_handle_type_id(base);
match size.resolve(module.to_ctx())? {
crate::proc::IndexableLength::Known(length) => {
let length_id = self.get_index_constant(length);
Instruction::type_array(id, type_id, length_id)
}
crate::ArraySize::Pending(_) => unreachable!(),
crate::ArraySize::Dynamic => Instruction::type_runtime_array(id, type_id),
crate::proc::IndexableLength::Dynamic => {
Instruction::type_runtime_array(id, type_id)
}
}
}
crate::TypeInner::BindingArray { base, size } => {
let type_id = self.get_type_id(LookupType::Handle(base));
match size {
crate::ArraySize::Constant(length) => {
let length_id = self.get_index_constant(length.get());
let type_id = self.get_handle_type_id(base);
match size.resolve(module.to_ctx())? {
crate::proc::IndexableLength::Known(length) => {
let length_id = self.get_index_constant(length);
Instruction::type_array(id, type_id, length_id)
}
crate::ArraySize::Pending(_) => unreachable!(),
crate::ArraySize::Dynamic => Instruction::type_runtime_array(id, type_id),
crate::proc::IndexableLength::Dynamic => {
Instruction::type_runtime_array(id, type_id)
}
}
}
crate::TypeInner::Struct {
@@ -1317,7 +1365,7 @@ impl Writer {
let mut has_runtime_array = false;
let mut member_ids = Vec::with_capacity(members.len());
for (index, member) in members.iter().enumerate() {
let member_ty = &arena[member.ty];
let member_ty = &module.types[member.ty];
match member_ty.inner {
crate::TypeInner::Array {
base: _,
@@ -1328,8 +1376,8 @@ impl Writer {
}
_ => (),
}
self.decorate_struct_member(id, index, member, arena)?;
let member_id = self.get_type_id(LookupType::Handle(member.ty));
self.decorate_struct_member(id, index, member, &module.types)?;
let member_id = self.get_handle_type_id(member.ty);
member_ids.push(member_id);
}
if has_runtime_array {
@@ -1465,15 +1513,17 @@ impl Writer {
self.debugs.push(Instruction::name(id, name));
}
}
let type_id = self.get_type_id(LookupType::Local(LocalType::Numeric(NumericType::Scalar(
value.scalar(),
))));
let type_id = self.get_numeric_type_id(NumericType::Scalar(value.scalar()));
let instruction = match *value {
crate::Literal::F64(value) => {
let bits = value.to_bits();
Instruction::constant_64bit(type_id, id, bits as u32, (bits >> 32) as u32)
}
crate::Literal::F32(value) => Instruction::constant_32bit(type_id, id, value.to_bits()),
crate::Literal::F16(value) => {
let low = value.to_bits();
Instruction::constant_16bit(type_id, id, low as u32)
}
crate::Literal::U32(value) => Instruction::constant_32bit(type_id, id, value),
crate::Literal::I32(value) => Instruction::constant_32bit(type_id, id, value as u32),
crate::Literal::U64(value) => {
@@ -1557,7 +1607,7 @@ impl Writer {
self.constant_ids[constant.init]
}
crate::Expression::ZeroValue(ty) => {
let type_id = self.get_type_id(LookupType::Handle(ty));
let type_id = self.get_handle_type_id(ty);
self.get_constant_null(type_id)
}
crate::Expression::Compose { ty, ref components } => {
@@ -1579,7 +1629,9 @@ impl Writer {
self.get_constant_composite(ty, component_ids)
}
_ => unreachable!(),
_ => {
return Err(Error::Override);
}
};
self.constant_ids[handle] = id;
@@ -1640,7 +1692,7 @@ impl Writer {
// variables in the `Uniform` and `StorageBuffer` address spaces
// get wrapped, and we're initializing `WorkGroup` variables.
let var_id = self.global_variables[handle].var_id;
let var_type_id = self.get_type_id(LookupType::Handle(var.ty));
let var_type_id = self.get_handle_type_id(var.ty);
let init_word = self.get_constant_null(var_type_id);
Instruction::store(var_id, init_word, None)
})
@@ -1650,7 +1702,7 @@ impl Writer {
return None;
}
let uint3_type_id = self.get_uint3_type_id();
let uint3_type_id = self.get_vec3u_type_id();
let mut pre_if_block = Block::new(entry_id);
@@ -1659,7 +1711,7 @@ impl Writer {
} else {
let varying_id = self.id_gen.next();
let class = spirv::StorageClass::Input;
let pointer_type_id = self.get_uint3_pointer_type_id(class);
let pointer_type_id = self.get_vec3u_pointer_type_id(class);
Instruction::variable(pointer_type_id, varying_id, class, None)
.to_words(&mut self.logical_layout.declarations);
@@ -1680,7 +1732,7 @@ impl Writer {
};
let zero_id = self.get_constant_null(uint3_type_id);
let bool3_type_id = self.get_bool3_type_id();
let bool3_type_id = self.get_vec3_bool_type_id();
let eq_id = self.id_gen.next();
pre_if_block.body.push(Instruction::binary(
@@ -1756,7 +1808,7 @@ impl Writer {
binding: &crate::Binding,
) -> Result<Word, Error> {
let id = self.id_gen.next();
let pointer_type_id = self.get_pointer_id(ty, class);
let pointer_type_id = self.get_handle_pointer_type_id(ty, class);
Instruction::variable(pointer_type_id, id, class, None)
.to_words(&mut self.logical_layout.declarations);
@@ -1776,7 +1828,7 @@ impl Writer {
location,
interpolation,
sampling,
second_blend_source,
blend_src,
} => {
self.decorate(id, Decoration::Location, &[location]);
@@ -1821,8 +1873,8 @@ impl Writer {
}
}
}
if second_blend_source {
self.decorate(id, Decoration::Index, &[1]);
if let Some(blend_src) = blend_src {
self.decorate(id, Decoration::Index, &[blend_src]);
}
}
crate::Binding::BuiltIn(built_in) => {
@@ -2014,12 +2066,15 @@ impl Writer {
if let crate::TypeInner::BindingArray { base, .. } =
ir_module.types[global_variable.ty].inner
{
substitute_inner_type_lookup =
Some(LookupType::Local(LocalType::PointerToBindingArray {
let binding_array_type_id =
self.get_type_id(LookupType::Local(LocalType::BindingArray {
base,
size: remapped_binding_array_size,
space: global_variable.space,
}))
}));
substitute_inner_type_lookup = Some(LookupType::Local(LocalType::Pointer {
base: binding_array_type_id,
class,
}));
}
}
};
@@ -2079,7 +2134,7 @@ impl Writer {
}
}
if should_decorate {
let decorated_id = self.get_type_id(LookupType::Handle(base));
let decorated_id = self.get_handle_type_id(base);
self.decorate(decorated_id, Decoration::Block, &[]);
}
}
@@ -2089,7 +2144,7 @@ impl Writer {
if substitute_inner_type_lookup.is_some() {
inner_type_id
} else {
self.get_pointer_id(global_variable.ty, class)
self.get_handle_pointer_type_id(global_variable.ty, class)
}
};
@@ -2278,7 +2333,7 @@ impl Writer {
// write all types
for (handle, _) in ir_module.types.iter() {
self.write_type_declaration_arena(&ir_module.types, handle)?;
self.write_type_declaration_arena(ir_module, handle)?;
}
// write all const-expressions as constants
@@ -2398,10 +2453,6 @@ impl Writer {
debug_info: &Option<DebugInfo>,
words: &mut Vec<Word>,
) -> Result<(), Error> {
if !ir_module.overrides.is_empty() {
return Err(Error::Override);
}
self.reset();
// Try to find the entry point and corresponding index

View File

@@ -5,10 +5,11 @@ use alloc::{
vec::Vec,
};
use core::fmt::Write;
use hashbrown::HashSet;
use super::Error;
use super::ToWgslIfImplemented as _;
use crate::back::wgsl::polyfill::InversePolyfill;
use crate::{back::wgsl::polyfill::InversePolyfill, common::wgsl::TypeContext};
use crate::{
back::{self, Baked},
common::{
@@ -30,7 +31,7 @@ enum Attribute {
Invariant,
Interpolate(Option<crate::Interpolation>, Option<crate::Sampling>),
Location(u32),
SecondBlendSource,
BlendSrc(u32),
Stage(ShaderStage),
WorkGroupSize([u32; 3]),
}
@@ -99,10 +100,9 @@ impl<W: Write> Writer<W> {
self.names.clear();
self.namer.reset(
module,
crate::keywords::wgsl::RESERVED,
&crate::keywords::wgsl::RESERVED_SET,
// an identifier must not start with two underscore
&[],
&[],
&["__", "_naga"],
&mut self.names,
);
@@ -127,6 +127,12 @@ impl<W: Write> Writer<W> {
self.reset(module);
// Write all needed directives.
self.write_enable_dual_source_blending_if_needed(module)?;
// Write all `enable` declarations
self.write_enable_declarations(module)?;
// Write all structs
for (handle, ty) in module.types.iter() {
if let TypeInner::Struct { ref members, .. } = ty.inner {
@@ -189,6 +195,7 @@ impl<W: Write> Writer<W> {
Attribute::Stage(ShaderStage::Compute),
Attribute::WorkGroupSize(ep.workgroup_size),
],
ShaderStage::Task | ShaderStage::Mesh => unreachable!(),
};
self.write_attributes(&attributes)?;
@@ -219,6 +226,41 @@ impl<W: Write> Writer<W> {
Ok(())
}
/// Helper method which writes all the `enable` declarations
/// needed for a module.
fn write_enable_declarations(&mut self, module: &Module) -> BackendResult {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum WrittenDeclarations {
F16,
}
let mut written_declarations = HashSet::new();
// Write all the `enable` declarations
for (_, ty) in module.types.iter() {
match ty.inner {
TypeInner::Scalar(scalar)
| TypeInner::Vector { scalar, .. }
| TypeInner::Matrix { scalar, .. } => {
if scalar == crate::Scalar::F16
&& !written_declarations.contains(&WrittenDeclarations::F16)
{
writeln!(self.out, "enable f16;")?;
written_declarations.insert(WrittenDeclarations::F16);
}
}
_ => {}
}
}
if !written_declarations.is_empty() {
// Empty line for readability
writeln!(self.out)?;
}
Ok(())
}
/// Helper method used to write
/// [functions](https://gpuweb.github.io/gpuweb/wgsl/#functions)
///
@@ -319,7 +361,7 @@ impl<W: Write> Writer<W> {
for attribute in attributes {
match *attribute {
Attribute::Location(id) => write!(self.out, "@location({id}) ")?,
Attribute::SecondBlendSource => write!(self.out, "@second_blend_source ")?,
Attribute::BlendSrc(blend_src) => write!(self.out, "@blend_src({blend_src}) ")?,
Attribute::BuiltIn(builtin_attrib) => {
let builtin = builtin_attrib.to_wgsl_if_implemented()?;
write!(self.out, "@builtin({builtin}) ")?;
@@ -329,6 +371,7 @@ impl<W: Write> Writer<W> {
ShaderStage::Vertex => "vertex",
ShaderStage::Fragment => "fragment",
ShaderStage::Compute => "compute",
ShaderStage::Task | ShaderStage::Mesh => unreachable!(),
};
write!(self.out, "@{stage_str} ")?;
}
@@ -363,10 +406,42 @@ impl<W: Write> Writer<W> {
Ok(())
}
/// Writes all the necessary directives out
fn write_enable_dual_source_blending_if_needed(&mut self, module: &Module) -> BackendResult {
// Check for dual source blending.
if module.types.iter().any(|(_handle, ty)| {
if let TypeInner::Struct { ref members, .. } = ty.inner {
members.iter().any(|member| {
member.binding.as_ref().is_some_and(|binding| {
matches!(
binding,
&crate::Binding::Location {
blend_src: Some(_),
..
}
)
})
})
} else {
false
}
}) {
writeln!(self.out, "enable dual_source_blending;")?;
}
Ok(())
}
/// Helper method used to write structs
/// Write the full declaration of a struct type.
///
/// # Notes
/// Ends in a newline
/// Write out a definition of the struct type referred to by
/// `handle` in `module`. The output will be an instance of the
/// `struct_decl` production in the WGSL grammar.
///
/// Use `members` as the list of `handle`'s members. (This
/// function is usually called after matching a `TypeInner`, so
/// the callers already have the members at hand.)
fn write_struct(
&mut self,
module: &Module,
@@ -390,227 +465,37 @@ impl<W: Write> Writer<W> {
writeln!(self.out)?;
}
write!(self.out, "}}")?;
writeln!(self.out)?;
writeln!(self.out, "}}")?;
Ok(())
}
/// Helper method used to write non image/sampler types
///
/// # Notes
/// Adds no trailing or leading whitespace
fn write_type(&mut self, module: &Module, ty: Handle<crate::Type>) -> BackendResult {
let inner = &module.types[ty].inner;
match *inner {
TypeInner::Struct { .. } => {
write!(self.out, "{}", self.names[&NameKey::Type(ty)])?;
}
ref other => self.write_value_type(module, other)?,
}
// This actually can't be factored out into a nice constructor method,
// because the borrow checker needs to be able to see that the borrows
// of `self.names` and `self.out` are disjoint.
let type_context = WriterTypeContext {
module,
names: &self.names,
};
type_context.write_type(ty, &mut self.out)?;
Ok(())
}
/// Helper method used to write value types
///
/// # Notes
/// Adds no trailing or leading whitespace
fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
match *inner {
TypeInner::Vector { size, scalar } => write!(
self.out,
"vec{}<{}>",
common::vector_size_str(size),
scalar.to_wgsl_if_implemented()?,
)?,
TypeInner::Sampler { comparison: false } => {
write!(self.out, "sampler")?;
}
TypeInner::Sampler { comparison: true } => {
write!(self.out, "sampler_comparison")?;
}
TypeInner::Image {
dim,
arrayed,
class,
} => {
// More about texture types: https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type
use crate::ImageClass as Ic;
let dim_str = dim.to_wgsl();
let arrayed_str = if arrayed { "_array" } else { "" };
let (class_str, multisampled_str, format_str, storage_str) = match class {
Ic::Sampled { kind, multi } => (
"",
if multi { "multisampled_" } else { "" },
crate::Scalar { kind, width: 4 }.to_wgsl_if_implemented()?,
"",
),
Ic::Depth { multi } => {
("depth_", if multi { "multisampled_" } else { "" }, "", "")
}
Ic::Storage { format, access } => (
"storage_",
"",
format.to_wgsl(),
if access.contains(crate::StorageAccess::ATOMIC) {
",atomic"
} else if access
.contains(crate::StorageAccess::LOAD | crate::StorageAccess::STORE)
{
",read_write"
} else if access.contains(crate::StorageAccess::LOAD) {
",read"
} else {
",write"
},
),
};
write!(
self.out,
"texture_{class_str}{multisampled_str}{dim_str}{arrayed_str}"
)?;
if !format_str.is_empty() {
write!(self.out, "<{format_str}{storage_str}>")?;
}
}
TypeInner::Scalar(scalar) => {
write!(self.out, "{}", scalar.to_wgsl_if_implemented()?)?;
}
TypeInner::Atomic(scalar) => {
write!(self.out, "atomic<{}>", scalar.to_wgsl_if_implemented()?)?;
}
TypeInner::Array {
base,
size,
stride: _,
} => {
// More info https://gpuweb.github.io/gpuweb/wgsl/#array-types
// array<A, 3> -- Constant array
// array<A> -- Dynamic array
write!(self.out, "array<")?;
match size {
crate::ArraySize::Constant(len) => {
self.write_type(module, base)?;
write!(self.out, ", {len}")?;
}
crate::ArraySize::Pending(_) => {
unreachable!();
}
crate::ArraySize::Dynamic => {
self.write_type(module, base)?;
}
}
write!(self.out, ">")?;
}
TypeInner::BindingArray { base, size } => {
// More info https://github.com/gpuweb/gpuweb/issues/2105
write!(self.out, "binding_array<")?;
match size {
crate::ArraySize::Constant(len) => {
self.write_type(module, base)?;
write!(self.out, ", {len}")?;
}
crate::ArraySize::Pending(_) => {
unreachable!();
}
crate::ArraySize::Dynamic => {
self.write_type(module, base)?;
}
}
write!(self.out, ">")?;
}
TypeInner::Matrix {
columns,
rows,
scalar,
} => {
write!(
self.out,
"mat{}x{}<{}>",
common::vector_size_str(columns),
common::vector_size_str(rows),
scalar.to_wgsl_if_implemented()?
)?;
}
TypeInner::Pointer { base, space } => {
let (address, maybe_access) = address_space_str(space);
// Everything but `AddressSpace::Handle` gives us a `address` name, but
// Naga IR never produces pointers to handles, so it doesn't matter much
// how we write such a type. Just write it as the base type alone.
if let Some(space) = address {
write!(self.out, "ptr<{space}, ")?;
}
self.write_type(module, base)?;
if address.is_some() {
if let Some(access) = maybe_access {
write!(self.out, ", {access}")?;
}
write!(self.out, ">")?;
}
}
TypeInner::ValuePointer {
size: None,
scalar,
space,
} => {
let (address, maybe_access) = address_space_str(space);
if let Some(space) = address {
write!(
self.out,
"ptr<{}, {}",
space,
scalar.to_wgsl_if_implemented()?
)?;
if let Some(access) = maybe_access {
write!(self.out, ", {access}")?;
}
write!(self.out, ">")?;
} else {
return Err(Error::Unimplemented(format!(
"ValuePointer to AddressSpace::Handle {inner:?}"
)));
}
}
TypeInner::ValuePointer {
size: Some(size),
scalar,
space,
} => {
let (address, maybe_access) = address_space_str(space);
if let Some(space) = address {
write!(
self.out,
"ptr<{}, vec{}<{}>",
space,
common::vector_size_str(size),
scalar.to_wgsl_if_implemented()?
)?;
if let Some(access) = maybe_access {
write!(self.out, ", {access}")?;
}
write!(self.out, ">")?;
} else {
return Err(Error::Unimplemented(format!(
"ValuePointer to AddressSpace::Handle {inner:?}"
)));
}
write!(self.out, ">")?;
}
TypeInner::AccelerationStructure { vertex_return } => {
let caps = if vertex_return { "<vertex_return>" } else { "" };
write!(self.out, "acceleration_structure{}", caps)?
}
_ => {
return Err(Error::Unimplemented(format!("write_value_type {inner:?}")));
}
}
fn write_type_inner(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
// This actually can't be factored out into a nice constructor method,
// because the borrow checker needs to be able to see that the borrows
// of `self.names` and `self.out` are disjoint.
let type_context = WriterTypeContext {
module,
names: &self.names,
};
type_context.write_type_inner(inner, &mut self.out)?;
Ok(())
}
/// Helper method used to write statements
///
/// # Notes
@@ -1161,7 +1046,7 @@ impl<W: Write> Writer<W> {
self.write_type(module, handle)?;
}
proc::TypeResolution::Value(ref inner) => {
self.write_value_type(module, inner)?;
self.write_type_inner(module, inner)?;
}
}
}
@@ -1225,13 +1110,11 @@ impl<W: Write> Writer<W> {
&mut self,
module: &Module,
expr: Handle<crate::Expression>,
arena: &crate::Arena<crate::Expression>,
) -> BackendResult {
self.write_possibly_const_expression(
module,
expr,
&module.global_expressions,
|writer, expr| writer.write_const_expression(module, expr),
)
self.write_possibly_const_expression(module, expr, arena, |writer, expr| {
writer.write_const_expression(module, expr, arena)
})
}
fn write_possibly_const_expression<E>(
@@ -1248,6 +1131,7 @@ impl<W: Write> Writer<W> {
match expressions[expr] {
Expression::Literal(literal) => match literal {
crate::Literal::F16(value) => write!(self.out, "{value}h")?,
crate::Literal::F32(value) => write!(self.out, "{value}f")?,
crate::Literal::U32(value) => write!(self.out, "{value}u")?,
crate::Literal::I32(value) => {
@@ -1284,7 +1168,7 @@ impl<W: Write> Writer<W> {
if constant.name.is_some() {
write!(self.out, "{}", self.names[&NameKey::Constant(handle)])?;
} else {
self.write_const_expression(module, constant.init)?;
self.write_const_expression(module, constant.init, &module.global_expressions)?;
}
}
Expression::ZeroValue(ty) => {
@@ -1480,7 +1364,7 @@ impl<W: Write> Writer<W> {
if let Some(offset) = offset {
write!(self.out, ", ")?;
self.write_const_expression(module, offset)?;
self.write_const_expression(module, offset, func_ctx.expressions)?;
}
write!(self.out, ")")?;
@@ -1529,7 +1413,7 @@ impl<W: Write> Writer<W> {
if let Some(offset) = offset {
write!(self.out, ", ")?;
self.write_const_expression(module, offset)?;
self.write_const_expression(module, offset, func_ctx.expressions)?;
}
write!(self.out, ")")?;
@@ -1840,7 +1724,7 @@ impl<W: Write> Writer<W> {
// Write initializer
if let Some(init) = global.init {
write!(self.out, " = ")?;
self.write_const_expression(module, init)?;
self.write_const_expression(module, init, &module.global_expressions)?;
}
// End with semicolon
@@ -1864,7 +1748,7 @@ impl<W: Write> Writer<W> {
self.write_type(module, module.constants[handle].ty)?;
write!(self.out, " = ")?;
let init = module.constants[handle].init;
self.write_const_expression(module, init)?;
self.write_const_expression(module, init, &module.global_expressions)?;
writeln!(self.out, ";")?;
Ok(())
@@ -1877,6 +1761,33 @@ impl<W: Write> Writer<W> {
}
}
struct WriterTypeContext<'m> {
module: &'m Module,
names: &'m crate::FastHashMap<NameKey, String>,
}
impl TypeContext for WriterTypeContext<'_> {
fn lookup_type(&self, handle: Handle<crate::Type>) -> &crate::Type {
&self.module.types[handle]
}
fn type_name(&self, handle: Handle<crate::Type>) -> &str {
self.names[&NameKey::Type(handle)].as_str()
}
fn write_override<W: Write>(&self, _: Handle<crate::Override>, _: &mut W) -> core::fmt::Result {
unreachable!("overrides should be validated out");
}
fn write_non_wgsl_inner<W: Write>(&self, _: &TypeInner, _: &mut W) -> core::fmt::Result {
unreachable!("backends should only be passed validated modules");
}
fn write_non_wgsl_scalar<W: Write>(&self, _: crate::Scalar, _: &mut W) -> core::fmt::Result {
unreachable!("backends should only be passed validated modules");
}
}
fn map_binding_to_attribute(binding: &crate::Binding) -> Vec<Attribute> {
match *binding {
crate::Binding::BuiltIn(built_in) => {
@@ -1890,7 +1801,7 @@ fn map_binding_to_attribute(binding: &crate::Binding) -> Vec<Attribute> {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src: None,
} => vec![
Attribute::Location(location),
Attribute::Interpolate(interpolation, sampling),
@@ -1899,10 +1810,10 @@ fn map_binding_to_attribute(binding: &crate::Binding) -> Vec<Attribute> {
location,
interpolation,
sampling,
second_blend_source: true,
blend_src: Some(blend_src),
} => vec![
Attribute::Location(location),
Attribute::SecondBlendSource,
Attribute::BlendSrc(blend_src),
Attribute::Interpolate(interpolation, sampling),
],
}

View File

@@ -0,0 +1,69 @@
//! WGSL diagnostic filters and severities.
use core::fmt::{self, Display, Formatter};
use crate::diagnostic_filter::{
FilterableTriggeringRule, Severity, StandardFilterableTriggeringRule,
};
impl Severity {
const ERROR: &'static str = "error";
const WARNING: &'static str = "warning";
const INFO: &'static str = "info";
const OFF: &'static str = "off";
/// Convert from a sentinel word in WGSL into its associated [`Severity`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::ERROR => Self::Error,
Self::WARNING => Self::Warning,
Self::INFO => Self::Info,
Self::OFF => Self::Off,
_ => return None,
})
}
}
pub struct DisplayFilterableTriggeringRule<'a>(&'a FilterableTriggeringRule);
impl Display for DisplayFilterableTriggeringRule<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let &Self(inner) = self;
match *inner {
FilterableTriggeringRule::Standard(rule) => write!(f, "{}", rule.to_wgsl_ident()),
FilterableTriggeringRule::Unknown(ref rule) => write!(f, "{rule}"),
FilterableTriggeringRule::User(ref rules) => {
let &[ref seg1, ref seg2] = rules.as_ref();
write!(f, "{seg1}.{seg2}")
}
}
}
}
impl FilterableTriggeringRule {
/// [`Display`] this rule's identifiers in WGSL.
pub const fn display_wgsl_ident(&self) -> impl Display + '_ {
DisplayFilterableTriggeringRule(self)
}
}
impl StandardFilterableTriggeringRule {
const DERIVATIVE_UNIFORMITY: &'static str = "derivative_uniformity";
/// Convert from a sentinel word in WGSL into its associated
/// [`StandardFilterableTriggeringRule`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::DERIVATIVE_UNIFORMITY => Self::DerivativeUniformity,
_ => return None,
})
}
/// Maps this [`StandardFilterableTriggeringRule`] into the sentinel word associated with it in
/// WGSL.
pub const fn to_wgsl_ident(self) -> &'static str {
match self {
Self::DerivativeUniformity => Self::DERIVATIVE_UNIFORMITY,
}
}
}

View File

@@ -0,0 +1,9 @@
//! Code shared between the WGSL front and back ends.
mod diagnostics;
mod to_wgsl;
mod types;
pub use diagnostics::DisplayFilterableTriggeringRule;
pub use to_wgsl::{address_space_str, ToWgsl, TryToWgsl};
pub use types::TypeContext;

View File

@@ -1,72 +1,7 @@
//! Code shared between the WGSL front and back ends.
//! Generating WGSL source code for Naga IR types.
use core::fmt::{self, Display, Formatter};
use crate::diagnostic_filter::{
FilterableTriggeringRule, Severity, StandardFilterableTriggeringRule,
};
impl Severity {
const ERROR: &'static str = "error";
const WARNING: &'static str = "warning";
const INFO: &'static str = "info";
const OFF: &'static str = "off";
/// Convert from a sentinel word in WGSL into its associated [`Severity`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::ERROR => Self::Error,
Self::WARNING => Self::Warning,
Self::INFO => Self::Info,
Self::OFF => Self::Off,
_ => return None,
})
}
}
struct DisplayFilterableTriggeringRule<'a>(&'a FilterableTriggeringRule);
impl Display for DisplayFilterableTriggeringRule<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let &Self(inner) = self;
match *inner {
FilterableTriggeringRule::Standard(rule) => write!(f, "{}", rule.to_wgsl_ident()),
FilterableTriggeringRule::Unknown(ref rule) => write!(f, "{rule}"),
FilterableTriggeringRule::User(ref rules) => {
let &[ref seg1, ref seg2] = rules.as_ref();
write!(f, "{seg1}.{seg2}")
}
}
}
}
impl FilterableTriggeringRule {
/// [`Display`] this rule's identifiers in WGSL.
pub const fn display_wgsl_ident(&self) -> impl Display + '_ {
DisplayFilterableTriggeringRule(self)
}
}
impl StandardFilterableTriggeringRule {
const DERIVATIVE_UNIFORMITY: &'static str = "derivative_uniformity";
/// Convert from a sentinel word in WGSL into its associated
/// [`StandardFilterableTriggeringRule`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::DERIVATIVE_UNIFORMITY => Self::DerivativeUniformity,
_ => return None,
})
}
/// Maps this [`StandardFilterableTriggeringRule`] into the sentinel word associated with it in
/// WGSL.
pub const fn to_wgsl_ident(self) -> &'static str {
match self {
Self::DerivativeUniformity => Self::DERIVATIVE_UNIFORMITY,
}
}
}
use alloc::format;
use alloc::string::{String, ToString};
/// Types that can return the WGSL source representation of their
/// values as a `'static` string.
@@ -107,6 +42,26 @@ pub trait TryToWgsl: Sized {
/// What kind of WGSL thing `Self` represents.
const DESCRIPTION: &'static str;
/// Return the WGSL form of `self` as appropriate for diagnostics.
///
/// If `self` can be expressed in WGSL, return that form as a
/// [`String`]. Otherwise, return some representation of `self`
/// that is appropriate for use in diagnostic messages.
///
/// The default implementation of this function falls back to
/// `self`'s [`Debug`] form.
///
/// [`Debug`]: core::fmt::Debug
fn to_wgsl_for_diagnostics(self) -> String
where
Self: core::fmt::Debug + Copy,
{
match self.try_to_wgsl() {
Some(static_string) => static_string.to_string(),
None => format!("{{non-WGSL {} {self:?}}}", Self::DESCRIPTION),
}
}
}
impl TryToWgsl for crate::MathFunction {
@@ -315,6 +270,7 @@ impl TryToWgsl for crate::Scalar {
Some(match self {
Scalar::F64 => "f64",
Scalar::F32 => "f32",
Scalar::F16 => "f16",
Scalar::I32 => "i32",
Scalar::U32 => "u32",
Scalar::I64 => "i64",
@@ -323,6 +279,20 @@ impl TryToWgsl for crate::Scalar {
_ => return None,
})
}
fn to_wgsl_for_diagnostics(self) -> String {
match self.try_to_wgsl() {
Some(static_string) => static_string.to_string(),
None => match self.kind {
crate::ScalarKind::Sint
| crate::ScalarKind::Uint
| crate::ScalarKind::Float
| crate::ScalarKind::Bool => format!("{{non-WGSL scalar {self:?}}}"),
crate::ScalarKind::AbstractInt => "{AbstractInt}".to_string(),
crate::ScalarKind::AbstractFloat => "{AbstractFloat}".to_string(),
},
}
}
}
impl ToWgsl for crate::ImageDimension {

View File

@@ -0,0 +1,358 @@
//! Code for formatting Naga IR types as WGSL source code.
use super::{address_space_str, ToWgsl, TryToWgsl};
use crate::common;
use crate::proc::TypeResolution;
use crate::{Handle, Scalar, TypeInner};
use alloc::string::String;
use core::fmt::Write;
/// A context for printing Naga IR types as WGSL.
///
/// This trait's default methods [`write_type`] and
/// [`write_type_inner`] do the work of formatting types as WGSL.
/// Implementors must provide the remaining methods, to customize
/// behavior for the context at hand.
///
/// For example, the WGSL backend would provide an implementation of
/// [`type_name`] that handles hygienic renaming, whereas the WGSL
/// front end would simply show the name that was given in the source.
///
/// [`write_type`]: TypeContext::write_type
/// [`write_type_inner`]: TypeContext::write_type_inner
/// [`type_name`]: TypeContext::type_name
pub trait TypeContext {
/// Return the [`Type`] referred to by `handle`.
///
/// [`Type`]: crate::Type
fn lookup_type(&self, handle: Handle<crate::Type>) -> &crate::Type;
/// Return the name to be used for the type referred to by
/// `handle`.
fn type_name(&self, handle: Handle<crate::Type>) -> &str;
/// Write the WGSL form of `override` to `out`.
fn write_override<W: Write>(
&self,
r#override: Handle<crate::Override>,
out: &mut W,
) -> core::fmt::Result;
/// Write a [`TypeInner`] that has no representation as WGSL source,
/// even including Naga extensions.
///
/// A backend might implement this with a call to the [`unreachable!`]
/// macro, since backends are allowed to assume that the module has passed
/// validation.
///
/// The default implementation is appropriate for generating type names to
/// appear in error messages. It punts to `TypeInner`'s [`core::fmt::Debug`]
/// implementation, since it's probably best to show the user something they
/// can act on.
fn write_non_wgsl_inner<W: Write>(&self, inner: &TypeInner, out: &mut W) -> core::fmt::Result {
write!(out, "{{non-WGSL Naga type {inner:?}}}")
}
/// Write a [`Scalar`] that has no representation as WGSL source,
/// even including Naga extensions.
///
/// A backend might implement this with a call to the [`unreachable!`]
/// macro, since backends are allowed to assume that the module has passed
/// validation.
///
/// The default implementation is appropriate for generating type names to
/// appear in error messages. It punts to `Scalar`'s [`core::fmt::Debug`]
/// implementation, since it's probably best to show the user something they
/// can act on.
fn write_non_wgsl_scalar<W: Write>(&self, scalar: Scalar, out: &mut W) -> core::fmt::Result {
match scalar.kind {
crate::ScalarKind::Sint
| crate::ScalarKind::Uint
| crate::ScalarKind::Float
| crate::ScalarKind::Bool => write!(out, "{{non-WGSL Naga scalar {scalar:?}}}"),
// The abstract types are kind of an odd quasi-WGSL category:
// they are definitely part of the spec, but they are not expressible
// in WGSL itself. So we want to call them out by name in error messages,
// but the WGSL backend should never generate these.
crate::ScalarKind::AbstractInt => out.write_str("{AbstractInt}"),
crate::ScalarKind::AbstractFloat => out.write_str("{AbstractFloat}"),
}
}
/// Write the type `ty` as it would appear in a value's declaration.
///
/// Write the type referred to by `ty` in `module` as it would appear in
/// a `var`, `let`, etc. declaration, or in a function's argument list.
fn write_type<W: Write>(&self, handle: Handle<crate::Type>, out: &mut W) -> core::fmt::Result {
let ty = self.lookup_type(handle);
match ty.inner {
TypeInner::Struct { .. } => out.write_str(self.type_name(handle))?,
ref other => self.write_type_inner(other, out)?,
}
Ok(())
}
/// Write the [`TypeInner`] `inner` as it would appear in a value's declaration.
///
/// Write `inner` as it would appear in a `var`, `let`, etc.
/// declaration, or in a function's argument list.
///
/// Note that this cannot handle writing [`Struct`] types: those
/// must be referred to by name, but the name isn't available in
/// [`TypeInner`].
///
/// [`Struct`]: TypeInner::Struct
fn write_type_inner<W: Write>(&self, inner: &TypeInner, out: &mut W) -> core::fmt::Result {
match try_write_type_inner(self, inner, out) {
Ok(()) => Ok(()),
Err(WriteTypeError::Format(err)) => Err(err),
Err(WriteTypeError::NonWgsl) => self.write_non_wgsl_inner(inner, out),
}
}
/// Write the [`Scalar`] `scalar` as a WGSL type.
fn write_scalar<W: Write>(&self, scalar: Scalar, out: &mut W) -> core::fmt::Result {
match scalar.try_to_wgsl() {
Some(string) => out.write_str(string),
None => self.write_non_wgsl_scalar(scalar, out),
}
}
/// Write the [`TypeResolution`] `resolution` as a WGSL type.
fn write_type_resolution<W: Write>(
&self,
resolution: &TypeResolution,
out: &mut W,
) -> core::fmt::Result {
match *resolution {
TypeResolution::Handle(handle) => self.write_type(handle, out),
TypeResolution::Value(ref inner) => self.write_type_inner(inner, out),
}
}
fn type_to_string(&self, handle: Handle<crate::Type>) -> String {
let mut buf = String::new();
self.write_type(handle, &mut buf).unwrap();
buf
}
fn type_inner_to_string(&self, inner: &TypeInner) -> String {
let mut buf = String::new();
self.write_type_inner(inner, &mut buf).unwrap();
buf
}
fn type_resolution_to_string(&self, resolution: &TypeResolution) -> String {
let mut buf = String::new();
self.write_type_resolution(resolution, &mut buf).unwrap();
buf
}
}
fn try_write_type_inner<C, W>(ctx: &C, inner: &TypeInner, out: &mut W) -> Result<(), WriteTypeError>
where
C: TypeContext + ?Sized,
W: Write,
{
match *inner {
TypeInner::Vector { size, scalar } => {
write!(out, "vec{}<", common::vector_size_str(size))?;
ctx.write_scalar(scalar, out)?;
out.write_str(">")?;
}
TypeInner::Sampler { comparison: false } => {
write!(out, "sampler")?;
}
TypeInner::Sampler { comparison: true } => {
write!(out, "sampler_comparison")?;
}
TypeInner::Image {
dim,
arrayed,
class,
} => {
// More about texture types: https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type
use crate::ImageClass as Ic;
let dim_str = dim.to_wgsl();
let arrayed_str = if arrayed { "_array" } else { "" };
match class {
Ic::Sampled { kind, multi } => {
let multisampled_str = if multi { "multisampled_" } else { "" };
write!(out, "texture_{multisampled_str}{dim_str}{arrayed_str}<")?;
ctx.write_scalar(Scalar { kind, width: 4 }, out)?;
out.write_str(">")?;
}
Ic::Depth { multi } => {
let multisampled_str = if multi { "multisampled_" } else { "" };
write!(
out,
"texture_depth_{multisampled_str}{dim_str}{arrayed_str}"
)?;
}
Ic::Storage { format, access } => {
let format_str = format.to_wgsl();
let access_str = if access.contains(crate::StorageAccess::ATOMIC) {
",atomic"
} else if access
.contains(crate::StorageAccess::LOAD | crate::StorageAccess::STORE)
{
",read_write"
} else if access.contains(crate::StorageAccess::LOAD) {
",read"
} else {
",write"
};
write!(
out,
"texture_storage_{dim_str}{arrayed_str}<{format_str}{access_str}>"
)?;
}
}
}
TypeInner::Scalar(scalar) => {
ctx.write_scalar(scalar, out)?;
}
TypeInner::Atomic(scalar) => {
out.write_str("atomic<")?;
ctx.write_scalar(scalar, out)?;
out.write_str(">")?;
}
TypeInner::Array {
base,
size,
stride: _,
} => {
// More info https://gpuweb.github.io/gpuweb/wgsl/#array-types
// array<A, 3> -- Constant array
// array<A> -- Dynamic array
write!(out, "array<")?;
match size {
crate::ArraySize::Constant(len) => {
ctx.write_type(base, out)?;
write!(out, ", {len}")?;
}
crate::ArraySize::Pending(r#override) => {
ctx.write_override(r#override, out)?;
}
crate::ArraySize::Dynamic => {
ctx.write_type(base, out)?;
}
}
write!(out, ">")?;
}
TypeInner::BindingArray { base, size } => {
// More info https://github.com/gpuweb/gpuweb/issues/2105
write!(out, "binding_array<")?;
match size {
crate::ArraySize::Constant(len) => {
ctx.write_type(base, out)?;
write!(out, ", {len}")?;
}
crate::ArraySize::Pending(r#override) => {
ctx.write_override(r#override, out)?;
}
crate::ArraySize::Dynamic => {
ctx.write_type(base, out)?;
}
}
write!(out, ">")?;
}
TypeInner::Matrix {
columns,
rows,
scalar,
} => {
write!(
out,
"mat{}x{}<",
common::vector_size_str(columns),
common::vector_size_str(rows),
)?;
ctx.write_scalar(scalar, out)?;
out.write_str(">")?;
}
TypeInner::Pointer { base, space } => {
let (address, maybe_access) = address_space_str(space);
// Everything but `AddressSpace::Handle` gives us a `address` name, but
// Naga IR never produces pointers to handles, so it doesn't matter much
// how we write such a type. Just write it as the base type alone.
if let Some(space) = address {
write!(out, "ptr<{space}, ")?;
}
ctx.write_type(base, out)?;
if address.is_some() {
if let Some(access) = maybe_access {
write!(out, ", {access}")?;
}
write!(out, ">")?;
}
}
TypeInner::ValuePointer {
size: None,
scalar,
space,
} => {
let (address, maybe_access) = address_space_str(space);
if let Some(space) = address {
write!(out, "ptr<{}, ", space)?;
ctx.write_scalar(scalar, out)?;
if let Some(access) = maybe_access {
write!(out, ", {access}")?;
}
write!(out, ">")?;
} else {
return Err(WriteTypeError::NonWgsl);
}
}
TypeInner::ValuePointer {
size: Some(size),
scalar,
space,
} => {
let (address, maybe_access) = address_space_str(space);
if let Some(space) = address {
write!(out, "ptr<{}, vec{}<", space, common::vector_size_str(size),)?;
ctx.write_scalar(scalar, out)?;
out.write_str(">")?;
if let Some(access) = maybe_access {
write!(out, ", {access}")?;
}
write!(out, ">")?;
} else {
return Err(WriteTypeError::NonWgsl);
}
write!(out, ">")?;
}
TypeInner::AccelerationStructure { vertex_return } => {
let caps = if vertex_return { "<vertex_return>" } else { "" };
write!(out, "acceleration_structure{}", caps)?
}
TypeInner::Struct { .. } => {
unreachable!("structs can only be referenced by name in WGSL");
}
TypeInner::RayQuery { vertex_return } => {
let caps = if vertex_return { "<vertex_return>" } else { "" };
write!(out, "ray_query{}", caps)?
}
}
Ok(())
}
/// Error type returned by `try_write_type_inner`.
///
/// This type is private to the module.
enum WriteTypeError {
Format(core::fmt::Error),
NonWgsl,
}
impl From<core::fmt::Error> for WriteTypeError {
fn from(err: core::fmt::Error) -> Self {
Self::Format(err)
}
}

View File

@@ -150,10 +150,7 @@ impl ExpressionTracer<'_> {
self.expressions_used
.insert_iter([image, sampler, coordinate]);
self.expressions_used.insert_iter(array_index);
match self.global_expressions_used {
Some(ref mut used) => used.insert_iter(offset),
None => self.expressions_used.insert_iter(offset),
}
self.expressions_used.insert_iter(offset);
use crate::SampleLevel as Sl;
match *level {
Sl::Auto | Sl::Zero => {}
@@ -324,9 +321,7 @@ impl ModuleMap {
adjust(sampler);
adjust(coordinate);
operand_map.adjust_option(array_index);
if let Some(ref mut offset) = *offset {
self.global_expressions.adjust(offset);
}
operand_map.adjust_option(offset);
self.adjust_sample_level(level, operand_map);
operand_map.adjust_option(depth_ref);
}

View File

@@ -359,12 +359,7 @@ impl<'module> ModuleTracer<'module> {
crate::TypeInner::Array { size, .. }
| crate::TypeInner::BindingArray { size, .. } => match size {
crate::ArraySize::Constant(_) | crate::ArraySize::Dynamic => None,
crate::ArraySize::Pending(pending) => match pending {
crate::PendingArraySize::Expression(handle) => Some(handle),
crate::PendingArraySize::Override(handle) => {
self.module.overrides[handle].init
}
},
crate::ArraySize::Pending(handle) => self.module.overrides[handle].init,
},
_ => None,
},
@@ -517,12 +512,21 @@ fn type_expression_interdependence() {
crate::Span::default(),
);
let type_needs_expression = |module: &mut crate::Module, handle| {
let override_handle = module.overrides.append(
crate::Override {
name: None,
id: None,
ty: u32,
init: Some(handle),
},
crate::Span::default(),
);
module.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Array {
base: u32,
size: crate::ArraySize::Pending(crate::PendingArraySize::Expression(handle)),
size: crate::ArraySize::Pending(override_handle),
stride: 4,
},
},
@@ -654,7 +658,7 @@ fn array_length_override() {
name: Some("array<bool, o>".to_string()),
inner: crate::TypeInner::Array {
base: ty_bool,
size: crate::ArraySize::Pending(crate::PendingArraySize::Override(o)),
size: crate::ArraySize::Pending(o),
stride: 4,
},
},
@@ -760,7 +764,7 @@ fn array_length_override_mutual() {
name: Some("delicious_array".to_string()),
inner: Ti::Array {
base: ty_u32,
size: crate::ArraySize::Pending(crate::PendingArraySize::Override(second_override)),
size: crate::ArraySize::Pending(second_override),
stride: 4,
},
},
@@ -795,12 +799,21 @@ fn array_length_expression() {
crate::Expression::Literal(crate::Literal::U32(1)),
crate::Span::default(),
);
let override_one = module.overrides.append(
crate::Override {
name: None,
id: None,
ty: ty_u32,
init: Some(one),
},
crate::Span::default(),
);
let _ty_array = module.types.insert(
crate::Type {
name: Some("array<u32, 1>".to_string()),
inner: crate::TypeInner::Array {
base: ty_u32,
size: crate::ArraySize::Pending(crate::PendingArraySize::Expression(one)),
size: crate::ArraySize::Pending(override_one),
stride: 4,
},
},

View File

@@ -32,19 +32,14 @@ impl TypeTracer<'_> {
| Ti::BindingArray { base, size } => {
self.types_used.insert(base);
match size {
crate::ArraySize::Pending(pending) => match pending {
crate::PendingArraySize::Expression(expr) => {
crate::ArraySize::Pending(handle) => {
self.overrides_used.insert(handle);
let r#override = &self.overrides[handle];
self.types_used.insert(r#override.ty);
if let Some(expr) = r#override.init {
self.expressions_used.insert(expr);
}
crate::PendingArraySize::Override(handle) => {
self.overrides_used.insert(handle);
let r#override = &self.overrides[handle];
self.types_used.insert(r#override.ty);
if let Some(expr) = r#override.init {
self.expressions_used.insert(expr);
}
}
},
}
crate::ArraySize::Constant(_) | crate::ArraySize::Dynamic => {}
}
}
@@ -94,14 +89,7 @@ impl ModuleMap {
} => {
adjust(base);
match *size {
crate::ArraySize::Pending(crate::PendingArraySize::Expression(
ref mut size_expr,
)) => {
self.global_expressions.adjust(size_expr);
}
crate::ArraySize::Pending(crate::PendingArraySize::Override(
ref mut r#override,
)) => {
crate::ArraySize::Pending(ref mut r#override) => {
self.overrides.adjust(r#override);
}
crate::ArraySize::Constant(_) | crate::ArraySize::Dynamic => {}

View File

@@ -179,6 +179,8 @@ pub enum QualifierKey<'a> {
Layout,
/// Used for image formats
Format,
/// Used for `index` layout qualifiers
Index,
}
#[derive(Debug)]

View File

@@ -1700,13 +1700,7 @@ impl MacroCall {
true => {
let offset_arg = args[num_args];
num_args += 1;
match ctx.lift_up_const_expression(offset_arg) {
Ok(v) => Some(v),
Err(e) => {
frontend.errors.push(e);
None
}
}
Some(offset_arg)
}
false => None,
};

View File

@@ -109,9 +109,15 @@ pub enum ErrorKind {
/// Unsupported matrix of the form matCx2
///
/// Our IR expects matrices of the form matCx2 to have a stride of 8 however
/// matrices in the std140 layout have a stride of at least 16
#[error("unsupported matrix of the form matCx2 in std140 block layout")]
UnsupportedMatrixTypeInStd140,
/// matrices in the std140 layout have a stride of at least 16.
#[error("unsupported matrix of the form matCx2 (in this case mat{columns}x2) in std140 block layout. See https://github.com/gfx-rs/wgpu/issues/4375")]
UnsupportedMatrixWithTwoRowsInStd140 { columns: u8 },
/// Unsupported matrix of the form f16matCxR
///
/// Our IR expects matrices of the form f16matCxR to have a stride of 4/8/8 depending on row-count,
/// however matrices in the std140 layout have a stride of at least 16.
#[error("unsupported matrix of the form f16matCxR (in this case f16mat{columns}x{rows}) in std140 block layout. See https://github.com/gfx-rs/wgpu/issues/4375")]
UnsupportedF16MatrixInStd140 { columns: u8, rows: u8 },
/// A variable with the same name already exists in the current scope.
#[error("Variable already declared: {0}")]
VariableAlreadyDeclared(String),

View File

@@ -1449,7 +1449,7 @@ impl Context<'_> {
location,
interpolation,
sampling: None,
second_blend_source: false,
blend_src: None,
};
location += 1;
@@ -1485,7 +1485,7 @@ impl Context<'_> {
location,
interpolation,
sampling: None,
second_blend_source: false,
blend_src: None,
};
location += 1;
binding

View File

@@ -122,11 +122,25 @@ pub fn calculate_offset(
}
// See comment on the error kind
if StructLayout::Std140 == layout && rows == crate::VectorSize::Bi {
errors.push(Error {
kind: ErrorKind::UnsupportedMatrixTypeInStd140,
meta,
});
if StructLayout::Std140 == layout {
// Do the f16 test first, as it's more specific
if scalar == Scalar::F16 {
errors.push(Error {
kind: ErrorKind::UnsupportedF16MatrixInStd140 {
columns: columns as u8,
rows: rows as u8,
},
meta,
});
}
if rows == crate::VectorSize::Bi {
errors.push(Error {
kind: ErrorKind::UnsupportedMatrixWithTwoRowsInStd140 {
columns: columns as u8,
},
meta,
});
}
}
(align, align * columns as u32)

View File

@@ -344,6 +344,13 @@ impl ParsingContext<'_> {
QualifierKey::Layout,
QualifierValue::Layout(StructLayout::Std430),
),
"index" => {
self.expect(frontend, TokenValue::Assign)?;
let (value, end_meta) = self.parse_uint_constant(frontend, ctx)?;
token.meta.subsume(end_meta);
(QualifierKey::Index, QualifierValue::Uint(value))
}
word => {
if let Some(format) = map_image_format(word) {
(QualifierKey::Format, QualifierValue::Format(format))

View File

@@ -12,6 +12,10 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
name: None,
inner: TypeInner::Scalar(Scalar::BOOL),
}),
"float16_t" => Some(Type {
name: None,
inner: TypeInner::Scalar(Scalar::F16),
}),
"float" => Some(Type {
name: None,
inner: TypeInner::Scalar(Scalar::F32),
@@ -42,6 +46,7 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
"i" => Scalar::I32,
"u" => Scalar::U32,
"d" => Scalar::F64,
"f16" => Scalar::F16,
_ => return None,
})
}

View File

@@ -449,6 +449,14 @@ impl Frontend {
meta,
);
let blend_src = qualifiers
.layout_qualifiers
.remove(&QualifierKey::Index)
.and_then(|(value, _span)| match value {
QualifierValue::Uint(index) => Some(index),
_ => None,
});
let idx = self.entry_args.len();
self.entry_args.push(EntryArg {
name: name.clone(),
@@ -456,7 +464,7 @@ impl Frontend {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src,
},
handle,
storage,

View File

@@ -43,7 +43,7 @@ impl crate::Binding {
location: _,
interpolation: ref mut interpolation @ None,
ref mut sampling,
second_blend_source: _,
blend_src: _,
} = *self
{
match ty.scalar_kind() {

View File

@@ -602,16 +602,16 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> {
words_left -= 2;
}
spirv::ImageOperands::CONST_OFFSET => {
let offset_constant = self.next()?;
let offset_expr = self
.lookup_constant
.lookup(offset_constant)?
.inner
.to_expr();
let offset_handle = ctx
.module
.global_expressions
.append(offset_expr, Default::default());
let offset_expr = self.next()?;
let offset_lexp = self.lookup_expression.lookup(offset_expr)?;
let offset_handle = self.get_expr_handle(
offset_expr,
offset_lexp,
ctx,
emitter,
block,
body_idx,
);
offset = Some(offset_handle);
words_left -= 1;
}

View File

@@ -39,6 +39,7 @@ use alloc::{borrow::ToOwned, format, string::String, vec, vec::Vec};
use core::{convert::TryInto, mem, num::NonZeroU32};
use std::path::PathBuf;
use half::f16;
use petgraph::graphmap::GraphMap;
use super::atomic_upgrade::Upgrades;
@@ -82,6 +83,7 @@ pub const SUPPORTED_EXTENSIONS: &[&str] = &[
"SPV_KHR_vulkan_memory_model",
"SPV_KHR_multiview",
"SPV_EXT_shader_atomic_float_add",
"SPV_KHR_16bit_storage",
];
pub const SUPPORTED_EXT_SETS: &[&str] = &["GLSL.std.450"];
@@ -252,7 +254,7 @@ impl Decoration {
location,
interpolation,
sampling,
second_blend_source: false,
blend_src: None,
}),
_ => Err(Error::MissingDecoration(spirv::Decoration::Location)),
}
@@ -5604,6 +5606,9 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
}) => {
let low = self.next()?;
match width {
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Literal
// If a numeric types bit width is less than 32-bits, the value appears in the low-order bits of the word.
2 => crate::Literal::F16(f16::from_bits(low as u16)),
4 => crate::Literal::F32(f32::from_bits(low)),
8 => {
inst.expect(5)?;

View File

@@ -1,3 +1,22 @@
//! Formatting WGSL front end error messages.
use crate::common::wgsl::TryToWgsl;
use crate::diagnostic_filter::ConflictingDiagnosticRuleError;
use crate::proc::{Alignment, ConstantEvaluatorError, ResolveError};
use crate::{Scalar, SourceLocation, Span};
use super::parse::directive::enable_extension::{EnableExtension, UnimplementedEnableExtension};
use super::parse::directive::language_extension::{
LanguageExtension, UnimplementedLanguageExtension,
};
use super::parse::lexer::Token;
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use termcolor::{ColorChoice, NoColor, StandardStream};
use thiserror::Error;
use alloc::{
borrow::Cow,
boxed::Box,
@@ -8,24 +27,6 @@ use alloc::{
};
use core::ops::Range;
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use termcolor::{ColorChoice, NoColor, StandardStream};
use thiserror::Error;
use crate::diagnostic_filter::ConflictingDiagnosticRuleError;
use crate::front::wgsl::parse::directive::enable_extension::{
EnableExtension, UnimplementedEnableExtension,
};
use crate::front::wgsl::parse::directive::language_extension::{
LanguageExtension, UnimplementedLanguageExtension,
};
use crate::front::wgsl::parse::lexer::Token;
use crate::front::wgsl::Scalar;
use crate::proc::{Alignment, ConstantEvaluatorError, ResolveError};
use crate::{SourceLocation, Span};
#[derive(Clone, Debug)]
pub struct ParseError {
message: String,
@@ -152,8 +153,6 @@ pub enum NumberError {
Invalid,
#[error("numeric literal not representable by target type")]
NotRepresentable,
#[error("unimplemented f16 type")]
UnimplementedF16,
}
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -174,8 +173,8 @@ pub(crate) enum Error<'a> {
BadTexture(Span),
BadTypeCast {
span: Span,
from_type: Box<str>,
to_type: Box<str>,
from_type: String,
to_type: String,
},
BadTextureSampleType {
span: Span,
@@ -211,8 +210,8 @@ pub(crate) enum Error<'a> {
TypeNotInferable(Span),
InitializationTypeMismatch {
name: Span,
expected: Box<str>,
got: Box<str>,
expected: String,
got: String,
},
DeclMissingTypeAndInit(Span),
MissingAttribute(&'static str, Span),
@@ -256,8 +255,13 @@ pub(crate) enum Error<'a> {
/// the same identifier as `ident`, above.
path: Box<[(Span, Span)]>,
},
InvalidSwitchValue {
uint: bool,
InvalidSwitchSelector {
span: Span,
},
InvalidSwitchCase {
span: Span,
},
SwitchCaseTypeMismatch {
span: Span,
},
CalledEntryPoint(Span),
@@ -337,24 +341,24 @@ impl From<&'static str> for DiagnosticAttributeNotSupportedPosition {
#[derive(Clone, Debug)]
pub(crate) struct AutoConversionError {
pub dest_span: Span,
pub dest_type: Box<str>,
pub dest_type: String,
pub source_span: Span,
pub source_type: Box<str>,
pub source_type: String,
}
#[derive(Clone, Debug)]
pub(crate) struct AutoConversionLeafScalarError {
pub dest_span: Span,
pub dest_scalar: Box<str>,
pub dest_scalar: String,
pub source_span: Span,
pub source_type: Box<str>,
pub source_type: String,
}
#[derive(Clone, Debug)]
pub(crate) struct ConcretizationFailedError {
pub expr_span: Span,
pub expr_type: Box<str>,
pub scalar: Box<str>,
pub expr_type: String,
pub scalar: String,
pub inner: ConstantEvaluatorError,
}
@@ -441,7 +445,7 @@ impl<'a> Error<'a> {
Error::BadMatrixScalarKind(span, scalar) => ParseError {
message: format!(
"matrix scalar type must be floating-point, but found `{}`",
scalar.to_wgsl()
scalar.to_wgsl_for_diagnostics()
),
labels: vec![(span, "must be floating-point (e.g. `f32`)".into())],
notes: vec![],
@@ -464,7 +468,7 @@ impl<'a> Error<'a> {
Error::BadTextureSampleType { span, scalar } => ParseError {
message: format!(
"texture sample type must be one of f32, i32 or u32, but found {}",
scalar.to_wgsl()
scalar.to_wgsl_for_diagnostics()
),
labels: vec![(span, "must be one of f32, i32 or u32".into())],
notes: vec![],
@@ -772,26 +776,32 @@ impl<'a> Error<'a> {
.collect(),
notes: vec![],
},
Error::InvalidSwitchValue { uint, span } => ParseError {
message: "invalid switch value".to_string(),
Error::InvalidSwitchSelector { span } => ParseError {
message: "invalid `switch` selector".to_string(),
labels: vec![(
span,
if uint {
"expected unsigned integer"
} else {
"expected signed integer"
}
"`switch` selector must be a scalar integer"
.into(),
)],
notes: vec![if uint {
format!("suffix the integer with a `u`: `{}u`", &source[span])
} else {
let span = span.to_range().unwrap();
format!(
"remove the `u` suffix: `{}`",
&source[span.start..span.end - 1]
)
}],
notes: vec![],
},
Error::InvalidSwitchCase { span } => ParseError {
message: "invalid `switch` case selector value".to_string(),
labels: vec![(
span,
"`switch` case selector must be a scalar integer const expression"
.into(),
)],
notes: vec![],
},
Error::SwitchCaseTypeMismatch { span } => ParseError {
message: "invalid `switch` case selector value".to_string(),
labels: vec![(
span,
"`switch` case selector must have the same type as the `switch` selector expression"
.into(),
)],
notes: vec![],
},
Error::CalledEntryPoint(span) => ParseError {
message: "entry point cannot be called".to_string(),
@@ -1014,23 +1024,22 @@ impl<'a> Error<'a> {
)],
},
Error::EnableExtensionNotEnabled { kind, span } => ParseError {
message: format!("`{}` enable-extension is not enabled", kind.to_ident()),
message: format!("the `{}` enable extension is not enabled", kind.to_ident()),
labels: vec![(
span,
format!(
concat!(
"the `{}` enable-extension is needed for this functionality, ",
"but it is not currently enabled"
"the `{}` \"Enable Extension\" is needed for this functionality, ",
"but it is not currently enabled."
),
kind.to_ident()
)
.into(),
)],
#[allow(irrefutable_let_patterns)]
notes: if let EnableExtension::Unimplemented(kind) = kind {
vec![format!(
concat!(
"This enable-extension is not yet implemented. ",
"This \"Enable Extension\" is not yet implemented. ",
"Let Naga maintainers know that you ran into this at ",
"<https://github.com/gfx-rs/wgpu/issues/{}>, ",
"so they can prioritize it!"
@@ -1038,7 +1047,12 @@ impl<'a> Error<'a> {
kind.tracking_issue_num()
)]
} else {
vec![]
vec![
format!(
"You can enable this extension by adding `enable {};` at the top of the shader, before any other items.",
kind.to_ident()
),
]
},
},
Error::LanguageExtensionNotYetImplemented { kind, span } => ParseError {
@@ -1168,8 +1182,3 @@ impl<'a> Error<'a> {
}
}
}
#[test]
fn test_error_size() {
assert!(size_of::<Error<'_>>() <= 48);
}

View File

@@ -1,6 +1,6 @@
use alloc::{vec, vec::Vec};
use alloc::{boxed::Box, vec, vec::Vec};
use super::Error;
use super::{Error, Result};
use crate::front::wgsl::parse::ast;
use crate::{FastHashMap, Handle, Span};
@@ -17,7 +17,7 @@ impl<'a> Index<'a> {
///
/// Return an error if the graph of references between declarations contains
/// any cycles.
pub fn generate(tu: &ast::TranslationUnit<'a>) -> Result<Self, Error<'a>> {
pub fn generate(tu: &ast::TranslationUnit<'a>) -> Result<'a, Self> {
// Produce a map from global definitions' names to their `Handle<GlobalDecl>`s.
// While doing so, reject conflicting definitions.
let mut globals = FastHashMap::with_capacity_and_hasher(tu.decls.len(), Default::default());
@@ -25,12 +25,12 @@ impl<'a> Index<'a> {
if let Some(ident) = decl_ident(decl) {
let name = ident.name;
if let Some(old) = globals.insert(name, handle) {
return Err(Error::Redefinition {
return Err(Box::new(Error::Redefinition {
previous: decl_ident(&tu.decls[old])
.expect("decl should have ident for redefinition")
.span,
current: ident.span,
});
}));
}
}
}
@@ -103,7 +103,7 @@ struct DependencySolver<'source, 'temp> {
impl<'a> DependencySolver<'a, '_> {
/// Produce the sorted list of declaration handles, and check for cycles.
fn solve(mut self) -> Result<Vec<Handle<ast::GlobalDecl<'a>>>, Error<'a>> {
fn solve(mut self) -> Result<'a, Vec<Handle<ast::GlobalDecl<'a>>>> {
for (id, _) in self.module.decls.iter() {
if self.visited[id.index()] {
continue;
@@ -117,7 +117,7 @@ impl<'a> DependencySolver<'a, '_> {
/// Ensure that all declarations used by `id` have been added to the
/// ordering, and then append `id` itself.
fn dfs(&mut self, id: Handle<ast::GlobalDecl<'a>>) -> Result<(), Error<'a>> {
fn dfs(&mut self, id: Handle<ast::GlobalDecl<'a>>) -> Result<'a, ()> {
let decl = &self.module.decls[id];
let id_usize = id.index();
@@ -134,10 +134,10 @@ impl<'a> DependencySolver<'a, '_> {
// Found a cycle.
return if dep_id == id {
// A declaration refers to itself directly.
Err(Error::RecursiveDeclaration {
Err(Box::new(Error::RecursiveDeclaration {
ident: decl_ident(decl).expect("decl should have ident").span,
usage: dep.usage,
})
}))
} else {
// A declaration refers to itself indirectly, through
// one or more other definitions. Report the entire path
@@ -150,7 +150,7 @@ impl<'a> DependencySolver<'a, '_> {
.find_map(|(i, dep)| (dep.decl == dep_id).then_some(i))
.unwrap_or(0);
Err(Error::CyclicDeclaration {
Err(Box::new(Error::CyclicDeclaration {
ident: decl_ident(&self.module.decls[dep_id])
.expect("decl should have ident")
.span,
@@ -166,7 +166,7 @@ impl<'a> DependencySolver<'a, '_> {
)
})
.collect(),
})
}))
};
} else if !self.visited[dep_id_usize] {
self.dfs(dep_id)?;

View File

@@ -1,4 +1,5 @@
use alloc::{
boxed::Box,
format,
string::{String, ToString},
vec,
@@ -6,9 +7,10 @@ use alloc::{
};
use core::num::NonZeroU32;
use crate::front::wgsl::error::Error;
use crate::common::wgsl::TypeContext;
use crate::front::wgsl::lower::{ExpressionContext, Lowerer};
use crate::front::wgsl::parse::ast;
use crate::front::wgsl::{Error, Result};
use crate::{Handle, Span};
/// A cooked form of `ast::ConstructorType` that uses Naga types whenever
@@ -70,7 +72,7 @@ impl Constructor<(Handle<crate::Type>, &crate::TypeInner)> {
format!("mat{}x{}<?>", columns as u32, rows as u32,)
}
Self::PartialArray => "array<?, ?>".to_string(),
Self::Type((handle, _inner)) => handle.to_wgsl(&ctx.module.to_ctx()),
Self::Type((handle, _inner)) => ctx.type_to_string(handle),
}
}
}
@@ -119,7 +121,7 @@ impl<'source> Lowerer<'source, '_> {
ty_span: Span,
components: &[Handle<ast::Expression<'source>>],
ctx: &mut ExpressionContext<'source, '_, '_>,
) -> Result<Handle<crate::Expression>, Error<'source>> {
) -> Result<'source, Handle<crate::Expression>> {
use crate::proc::TypeResolution as Tr;
let constructor_h = self.constructor(constructor, ctx)?;
@@ -141,7 +143,7 @@ impl<'source> Lowerer<'source, '_> {
let components = ast_components
.iter()
.map(|&expr| self.expression_for_abstract(expr, ctx))
.collect::<Result<_, _>>()?;
.collect::<Result<_>>()?;
let spans = ast_components
.iter()
.map(|&expr| ctx.ast_expressions.get_span(expr))
@@ -172,7 +174,7 @@ impl<'source> Lowerer<'source, '_> {
| Constructor::PartialArray => {
// We have no arguments from which to infer the result type, so
// partial constructors aren't acceptable here.
return Err(Error::TypeNotInferable(ty_span));
return Err(Box::new(Error::TypeNotInferable(ty_span)));
}
},
@@ -373,7 +375,7 @@ impl<'source> Lowerer<'source, '_> {
Default::default(),
)
})
.collect::<Result<Vec<_>, _>>()?;
.collect::<Result<Vec<_>>>()?;
let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix {
columns,
@@ -410,7 +412,7 @@ impl<'source> Lowerer<'source, '_> {
Default::default(),
)
})
.collect::<Result<Vec<_>, _>>()?;
.collect::<Result<Vec<_>>>()?;
let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix {
columns,
@@ -535,12 +537,12 @@ impl<'source> Lowerer<'source, '_> {
// Bad conversion (type cast)
(Components::One { span, ty_inner, .. }, constructor) => {
let from_type = ty_inner.to_wgsl(&ctx.module.to_ctx()).into();
return Err(Error::BadTypeCast {
let from_type = ctx.type_inner_to_string(ty_inner);
return Err(Box::new(Error::BadTypeCast {
span,
from_type,
to_type: constructor.to_error_string(ctx).into(),
});
to_type: constructor.to_error_string(ctx),
}));
}
// Too many parameters for scalar constructor
@@ -549,11 +551,11 @@ impl<'source> Lowerer<'source, '_> {
Constructor::Type((_, &crate::TypeInner::Scalar { .. })),
) => {
let span = spans[1].until(spans.last().unwrap());
return Err(Error::UnexpectedComponents(span));
return Err(Box::new(Error::UnexpectedComponents(span)));
}
// Other types can't be constructed
_ => return Err(Error::TypeNotConstructible(ty_span)),
_ => return Err(Box::new(Error::TypeNotConstructible(ty_span))),
}
let expr = ctx.append_expression(expr, span)?;
@@ -576,7 +578,7 @@ impl<'source> Lowerer<'source, '_> {
&mut self,
constructor: &ast::ConstructorType<'source>,
ctx: &mut ExpressionContext<'source, '_, 'out>,
) -> Result<Constructor<Handle<crate::Type>>, Error<'source>> {
) -> Result<'source, Constructor<Handle<crate::Type>>> {
let handle = match *constructor {
ast::ConstructorType::Scalar(scalar) => {
let ty = ctx.ensure_type_exists(scalar.to_inner_scalar());
@@ -587,7 +589,7 @@ impl<'source> Lowerer<'source, '_> {
let ty = self.resolve_ast_type(ty, &mut ctx.as_const())?;
let scalar = match ctx.module.types[ty].inner {
crate::TypeInner::Scalar(sc) => sc,
_ => return Err(Error::UnknownScalarType(ty_span)),
_ => return Err(Box::new(Error::UnknownScalarType(ty_span))),
};
let ty = ctx.ensure_type_exists(crate::TypeInner::Vector { size, scalar });
Constructor::Type(ty)
@@ -604,7 +606,7 @@ impl<'source> Lowerer<'source, '_> {
let ty = self.resolve_ast_type(ty, &mut ctx.as_const())?;
let scalar = match ctx.module.types[ty].inner {
crate::TypeInner::Scalar(sc) => sc,
_ => return Err(Error::UnknownScalarType(ty_span)),
_ => return Err(Box::new(Error::UnknownScalarType(ty_span))),
};
let ty = match scalar.kind {
crate::ScalarKind::Float => ctx.ensure_type_exists(crate::TypeInner::Matrix {
@@ -612,7 +614,7 @@ impl<'source> Lowerer<'source, '_> {
rows,
scalar,
}),
_ => return Err(Error::BadMatrixScalarKind(ty_span, scalar)),
_ => return Err(Box::new(Error::BadMatrixScalarKind(ty_span, scalar))),
};
Constructor::Type(ty)
}

View File

@@ -2,9 +2,11 @@
use alloc::{boxed::Box, string::String, vec::Vec};
use crate::common::wgsl::{TryToWgsl, TypeContext};
use crate::front::wgsl::error::{
AutoConversionError, AutoConversionLeafScalarError, ConcretizationFailedError,
};
use crate::front::wgsl::Result;
use crate::{Handle, Span};
impl<'source> super::ExpressionContext<'source, '_, '_> {
@@ -25,7 +27,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
expr: Handle<crate::Expression>,
goal_ty: &crate::proc::TypeResolution,
goal_span: Span,
) -> Result<Handle<crate::Expression>, super::Error<'source>> {
) -> Result<'source, Handle<crate::Expression>> {
let expr_span = self.get_expression_span(expr);
// Keep the TypeResolution so we can get type names for
// structs in error messages.
@@ -52,18 +54,17 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
match expr_inner.automatically_converts_to(goal_inner, types) {
Some(scalars) => scalars,
None => {
let gctx = &self.module.to_ctx();
let source_type = expr_resolution.to_wgsl(gctx).into();
let dest_type = goal_ty.to_wgsl(gctx).into();
let source_type = self.type_resolution_to_string(expr_resolution);
let dest_type = self.type_resolution_to_string(goal_ty);
return Err(super::Error::AutoConversion(Box::new(
return Err(Box::new(super::Error::AutoConversion(Box::new(
AutoConversionError {
dest_span: goal_span,
dest_type,
source_span: expr_span,
source_type,
},
)));
))));
}
};
@@ -87,18 +88,17 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
expr: Handle<crate::Expression>,
goal_scalar: crate::Scalar,
goal_span: Span,
) -> Result<Handle<crate::Expression>, super::Error<'source>> {
) -> Result<'source, Handle<crate::Expression>> {
let expr_span = self.get_expression_span(expr);
let expr_resolution = super::resolve!(self, expr);
let types = &self.module.types;
let expr_inner = expr_resolution.inner_with(types);
let make_error = || {
let gctx = &self.module.to_ctx();
let source_type = expr_resolution.to_wgsl(gctx).into();
let source_type = self.type_resolution_to_string(expr_resolution);
super::Error::AutoConversionLeafScalar(Box::new(AutoConversionLeafScalarError {
dest_span: goal_span,
dest_scalar: goal_scalar.to_wgsl().into(),
dest_scalar: goal_scalar.to_wgsl_for_diagnostics(),
source_span: expr_span,
source_type,
}))
@@ -106,7 +106,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
let expr_scalar = match expr_inner.automatically_convertible_scalar(&self.module.types) {
Some(scalar) => scalar,
None => return Err(make_error()),
None => return Err(Box::new(make_error())),
};
if expr_scalar == goal_scalar {
@@ -114,7 +114,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
}
if !expr_scalar.automatically_converts_to(goal_scalar) {
return Err(make_error());
return Err(Box::new(make_error()));
}
assert!(expr_scalar.is_abstract());
@@ -127,12 +127,14 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
expr: Handle<crate::Expression>,
expr_span: Span,
goal_scalar: crate::Scalar,
) -> Result<Handle<crate::Expression>, super::Error<'source>> {
) -> Result<'source, Handle<crate::Expression>> {
let expr_inner = super::resolve_inner!(self, expr);
if let crate::TypeInner::Array { .. } = *expr_inner {
self.as_const_evaluator()
.cast_array(expr, goal_scalar, expr_span)
.map_err(|err| super::Error::ConstantEvaluatorError(err.into(), expr_span))
.map_err(|err| {
Box::new(super::Error::ConstantEvaluatorError(err.into(), expr_span))
})
} else {
let cast = crate::Expression::As {
expr,
@@ -149,7 +151,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
exprs: &mut [Handle<crate::Expression>],
goal_ty: &crate::proc::TypeResolution,
goal_span: Span,
) -> Result<(), super::Error<'source>> {
) -> Result<'source, ()> {
for expr in exprs.iter_mut() {
*expr = self.try_automatic_conversions(*expr, goal_ty, goal_span)?;
}
@@ -170,7 +172,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
exprs: &mut [Handle<crate::Expression>],
goal_scalar: crate::Scalar,
goal_span: Span,
) -> Result<(), super::Error<'source>> {
) -> Result<'source, ()> {
use crate::proc::TypeResolution as Tr;
use crate::TypeInner as Ti;
let goal_scalar_res = Tr::Value(Ti::Scalar(goal_scalar));
@@ -195,9 +197,9 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
}
_ => {
let span = self.get_expression_span(*expr);
return Err(super::Error::InvalidConstructorComponentType(
return Err(Box::new(super::Error::InvalidConstructorComponentType(
span, i as i32,
));
)));
}
}
}
@@ -210,7 +212,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
&mut self,
expr: &mut Handle<crate::Expression>,
goal: crate::Scalar,
) -> Result<(), super::Error<'source>> {
) -> Result<'source, ()> {
let inner = super::resolve_inner!(self, *expr);
// Do nothing if `inner` doesn't even have leaf scalars;
// it's a type error that validation will catch.
@@ -241,7 +243,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
&mut self,
exprs: &mut [Handle<crate::Expression>],
goal: crate::Scalar,
) -> Result<(), super::Error<'source>> {
) -> Result<'source, ()> {
for expr in exprs.iter_mut() {
self.convert_to_leaf_scalar(expr, goal)?;
}
@@ -255,7 +257,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
pub fn concretize(
&mut self,
mut expr: Handle<crate::Expression>,
) -> Result<Handle<crate::Expression>, super::Error<'source>> {
) -> Result<'source, Handle<crate::Expression>> {
let inner = super::resolve_inner!(self, expr);
if let Some(scalar) = inner.automatically_convertible_scalar(&self.module.types) {
let concretized = scalar.concretize();
@@ -272,8 +274,8 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
let expr_type = &self.typifier()[expr];
super::Error::ConcretizationFailed(Box::new(ConcretizationFailedError {
expr_span,
expr_type: expr_type.to_wgsl(&self.module.to_ctx()).into(),
scalar: concretized.to_wgsl().into(),
expr_type: self.type_resolution_to_string(expr_type),
scalar: concretized.to_wgsl_for_diagnostics(),
inner: err,
}))
})?;
@@ -303,7 +305,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
pub fn automatic_conversion_consensus<'handle, I>(
&self,
components: I,
) -> Result<crate::Scalar, usize>
) -> core::result::Result<crate::Scalar, usize>
where
I: IntoIterator<Item = &'handle Handle<crate::Expression>>,
I::IntoIter: Clone, // for debugging
@@ -313,11 +315,12 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
.into_iter()
.map(|&c| self.typifier()[c].inner_with(types));
log::debug!(
"wgsl automatic_conversion_consensus: {:?}",
"wgsl automatic_conversion_consensus: {}",
inners
.clone()
.map(|inner| inner.to_wgsl(&self.module.to_ctx()))
.map(|inner| self.type_inner_to_string(inner))
.collect::<Vec<String>>()
.join(", ")
);
let mut best = inners.next().unwrap().scalar().ok_or(0_usize)?;
for (inner, i) in inners.zip(1..) {
@@ -330,7 +333,7 @@ impl<'source> super::ExpressionContext<'source, '_, '_> {
}
}
log::debug!(" consensus: {:?}", best.to_wgsl());
log::debug!(" consensus: {}", best.to_wgsl_for_diagnostics());
Ok(best)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,13 +10,13 @@ mod lower;
mod parse;
#[cfg(test)]
mod tests;
mod to_wgsl;
pub use crate::front::wgsl::error::ParseError;
pub use crate::front::wgsl::parse::directive::language_extension::{
ImplementedLanguageExtension, LanguageExtension, UnimplementedLanguageExtension,
};
use alloc::boxed::Box;
use thiserror::Error;
use crate::front::wgsl::error::Error;
@@ -27,6 +27,8 @@ use crate::Scalar;
#[cfg(test)]
use std::println;
pub(crate) type Result<'a, T> = core::result::Result<T, Box<Error<'a>>>;
pub struct Frontend {
parser: Parser,
}
@@ -38,11 +40,11 @@ impl Frontend {
}
}
pub fn parse(&mut self, source: &str) -> Result<crate::Module, ParseError> {
pub fn parse(&mut self, source: &str) -> core::result::Result<crate::Module, ParseError> {
self.inner(source).map_err(|x| x.as_parse_error(source))
}
fn inner<'a>(&mut self, source: &'a str) -> Result<crate::Module, Error<'a>> {
fn inner<'a>(&mut self, source: &'a str) -> Result<'a, crate::Module> {
let tu = self.parser.parse(source)?;
let index = index::Index::generate(&tu)?;
let module = Lowerer::new(&index).lower(tu)?;
@@ -62,7 +64,7 @@ impl Frontend {
/// for this, particularly if calls to this method are exposed to user input.
///
/// </div>
pub fn parse_str(source: &str) -> Result<crate::Module, ParseError> {
pub fn parse_str(source: &str) -> core::result::Result<crate::Module, ParseError> {
Frontend::new().parse(source)
}

View File

@@ -144,9 +144,9 @@ pub enum Binding<'a> {
BuiltIn(crate::BuiltIn),
Location {
location: Handle<Expression<'a>>,
second_blend_source: bool,
interpolation: Option<crate::Interpolation>,
sampling: Option<crate::Sampling>,
blend_src: Option<Handle<Expression<'a>>>,
},
}

View File

@@ -1,8 +1,12 @@
use super::Error;
use crate::front::wgsl::Scalar;
use crate::front::wgsl::parse::directive::enable_extension::{
EnableExtensions, ImplementedEnableExtension,
};
use crate::front::wgsl::{Error, Result, Scalar};
use crate::Span;
pub fn map_address_space(word: &str, span: Span) -> Result<crate::AddressSpace, Error<'_>> {
use alloc::boxed::Box;
pub fn map_address_space(word: &str, span: Span) -> Result<'_, crate::AddressSpace> {
match word {
"private" => Ok(crate::AddressSpace::Private),
"workgroup" => Ok(crate::AddressSpace::WorkGroup),
@@ -12,11 +16,11 @@ pub fn map_address_space(word: &str, span: Span) -> Result<crate::AddressSpace,
}),
"push_constant" => Ok(crate::AddressSpace::PushConstant),
"function" => Ok(crate::AddressSpace::Function),
_ => Err(Error::UnknownAddressSpace(span)),
_ => Err(Box::new(Error::UnknownAddressSpace(span))),
}
}
pub fn map_built_in(word: &str, span: Span) -> Result<crate::BuiltIn, Error<'_>> {
pub fn map_built_in(word: &str, span: Span) -> Result<'_, crate::BuiltIn> {
Ok(match word {
"position" => crate::BuiltIn::Position { invariant: false },
// vertex
@@ -40,31 +44,31 @@ pub fn map_built_in(word: &str, span: Span) -> Result<crate::BuiltIn, Error<'_>>
"subgroup_id" => crate::BuiltIn::SubgroupId,
"subgroup_size" => crate::BuiltIn::SubgroupSize,
"subgroup_invocation_id" => crate::BuiltIn::SubgroupInvocationId,
_ => return Err(Error::UnknownBuiltin(span)),
_ => return Err(Box::new(Error::UnknownBuiltin(span))),
})
}
pub fn map_interpolation(word: &str, span: Span) -> Result<crate::Interpolation, Error<'_>> {
pub fn map_interpolation(word: &str, span: Span) -> Result<'_, crate::Interpolation> {
match word {
"linear" => Ok(crate::Interpolation::Linear),
"flat" => Ok(crate::Interpolation::Flat),
"perspective" => Ok(crate::Interpolation::Perspective),
_ => Err(Error::UnknownAttribute(span)),
_ => Err(Box::new(Error::UnknownAttribute(span))),
}
}
pub fn map_sampling(word: &str, span: Span) -> Result<crate::Sampling, Error<'_>> {
pub fn map_sampling(word: &str, span: Span) -> Result<'_, crate::Sampling> {
match word {
"center" => Ok(crate::Sampling::Center),
"centroid" => Ok(crate::Sampling::Centroid),
"sample" => Ok(crate::Sampling::Sample),
"first" => Ok(crate::Sampling::First),
"either" => Ok(crate::Sampling::Either),
_ => Err(Error::UnknownAttribute(span)),
_ => Err(Box::new(Error::UnknownAttribute(span))),
}
}
pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat, Error<'_>> {
pub fn map_storage_format(word: &str, span: Span) -> Result<'_, crate::StorageFormat> {
use crate::StorageFormat as Sf;
Ok(match word {
"r8unorm" => Sf::R8Unorm,
@@ -108,14 +112,21 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
"rgba32sint" => Sf::Rgba32Sint,
"rgba32float" => Sf::Rgba32Float,
"bgra8unorm" => Sf::Bgra8Unorm,
_ => return Err(Error::UnknownStorageFormat(span)),
_ => return Err(Box::new(Error::UnknownStorageFormat(span))),
})
}
pub fn get_scalar_type(word: &str) -> Option<Scalar> {
pub fn get_scalar_type(
enable_extensions: &EnableExtensions,
span: Span,
word: &str,
) -> Result<'static, Option<Scalar>> {
use crate::ScalarKind as Sk;
match word {
// "f16" => Some(Scalar { kind: Sk::Float, width: 2 }),
let scalar = match word {
"f16" => Some(Scalar {
kind: Sk::Float,
width: 2,
}),
"f32" => Some(Scalar {
kind: Sk::Float,
width: 4,
@@ -145,7 +156,18 @@ pub fn get_scalar_type(word: &str) -> Option<Scalar> {
width: crate::BOOL_WIDTH,
}),
_ => None,
};
if matches!(scalar, Some(Scalar::F16))
&& !enable_extensions.contains(ImplementedEnableExtension::F16)
{
return Err(Box::new(Error::EnableExtensionNotEnabled {
span,
kind: ImplementedEnableExtension::F16.into(),
}));
}
Ok(scalar)
}
pub fn map_derivative(word: &str) -> Option<(crate::DerivativeAxis, crate::DerivativeControl)> {
@@ -261,16 +283,13 @@ pub fn map_standard_fun(word: &str) -> Option<crate::MathFunction> {
})
}
pub fn map_conservative_depth(
word: &str,
span: Span,
) -> Result<crate::ConservativeDepth, Error<'_>> {
pub fn map_conservative_depth(word: &str, span: Span) -> Result<'_, crate::ConservativeDepth> {
use crate::ConservativeDepth as Cd;
match word {
"greater_equal" => Ok(Cd::GreaterEqual),
"less_equal" => Ok(Cd::LessEqual),
"unchanged" => Ok(Cd::Unchanged),
_ => Err(Error::UnknownConservativeDepth(span)),
_ => Err(Box::new(Error::UnknownConservativeDepth(span))),
}
}

View File

@@ -5,6 +5,8 @@
pub mod enable_extension;
pub(crate) mod language_extension;
use alloc::boxed::Box;
/// A parsed sentinel word indicating the type of directive to be parsed next.
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(test, derive(strum::EnumIter))]
@@ -37,9 +39,9 @@ impl crate::diagnostic_filter::Severity {
#[cfg(feature = "wgsl-in")]
pub(crate) fn report_wgsl_parse_diag<'a>(
self,
err: crate::front::wgsl::error::Error<'a>,
err: Box<crate::front::wgsl::error::Error<'a>>,
source: &str,
) -> Result<(), crate::front::wgsl::error::Error<'a>> {
) -> crate::front::wgsl::Result<'a, ()> {
self.report_diag(err, |e, level| {
let e = e.as_parse_error(source);
log::log!(level, "{}", e.emit_to_string(source));

View File

@@ -2,28 +2,42 @@
//!
//! The focal point of this module is the [`EnableExtension`] API.
use crate::{front::wgsl::error::Error, Span};
use crate::front::wgsl::{Error, Result};
use crate::Span;
use alloc::boxed::Box;
/// Tracks the status of every enable-extension known to Naga.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EnableExtensions {}
pub struct EnableExtensions {
dual_source_blending: bool,
/// Whether `enable f16;` was written earlier in the shader module.
f16: bool,
}
impl EnableExtensions {
pub(crate) const fn empty() -> Self {
Self {}
Self {
f16: false,
dual_source_blending: false,
}
}
/// Add an enable-extension to the set requested by a module.
#[allow(unreachable_code)]
pub(crate) fn add(&mut self, ext: ImplementedEnableExtension) {
let _field: &mut bool = match ext {};
*_field = true;
let field = match ext {
ImplementedEnableExtension::DualSourceBlending => &mut self.dual_source_blending,
ImplementedEnableExtension::F16 => &mut self.f16,
};
*field = true;
}
/// Query whether an enable-extension tracked here has been requested.
#[allow(unused)]
pub(crate) const fn contains(&self, ext: ImplementedEnableExtension) -> bool {
match ext {}
match ext {
ImplementedEnableExtension::DualSourceBlending => self.dual_source_blending,
ImplementedEnableExtension::F16 => self.f16,
}
}
}
@@ -38,7 +52,6 @@ impl Default for EnableExtensions {
/// WGSL spec.: <https://www.w3.org/TR/WGSL/#enable-extensions-sec>
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum EnableExtension {
#[allow(unused)]
Implemented(ImplementedEnableExtension),
Unimplemented(UnimplementedEnableExtension),
}
@@ -55,27 +68,28 @@ impl EnableExtension {
const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending";
/// Convert from a sentinel word in WGSL into its associated [`EnableExtension`], if possible.
pub(crate) fn from_ident(word: &str, span: Span) -> Result<Self, Error<'_>> {
pub(crate) fn from_ident(word: &str, span: Span) -> Result<Self> {
Ok(match word {
Self::F16 => Self::Unimplemented(UnimplementedEnableExtension::F16),
Self::F16 => Self::Implemented(ImplementedEnableExtension::F16),
Self::CLIP_DISTANCES => {
Self::Unimplemented(UnimplementedEnableExtension::ClipDistances)
}
Self::DUAL_SOURCE_BLENDING => {
Self::Unimplemented(UnimplementedEnableExtension::DualSourceBlending)
Self::Implemented(ImplementedEnableExtension::DualSourceBlending)
}
_ => return Err(Error::UnknownEnableExtension(span, word)),
_ => return Err(Box::new(Error::UnknownEnableExtension(span, word))),
})
}
/// Maps this [`EnableExtension`] into the sentinel word associated with it in WGSL.
pub const fn to_ident(self) -> &'static str {
match self {
Self::Implemented(kind) => match kind {},
Self::Implemented(kind) => match kind {
ImplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
ImplementedEnableExtension::F16 => Self::F16,
},
Self::Unimplemented(kind) => match kind {
UnimplementedEnableExtension::F16 => Self::F16,
UnimplementedEnableExtension::ClipDistances => Self::CLIP_DISTANCES,
UnimplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
},
}
}
@@ -83,37 +97,36 @@ impl EnableExtension {
/// A variant of [`EnableExtension::Implemented`].
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum ImplementedEnableExtension {}
/// A variant of [`EnableExtension::Unimplemented`].
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum UnimplementedEnableExtension {
/// Enables `f16`/`half` primitive support in all shader languages.
///
/// In the WGSL standard, this corresponds to [`enable f16;`].
///
/// [`enable f16;`]: https://www.w3.org/TR/WGSL/#extension-f16
F16,
/// Enables the `clip_distances` variable in WGSL.
///
/// In the WGSL standard, this corresponds to [`enable clip_distances;`].
///
/// [`enable clip_distances;`]: https://www.w3.org/TR/WGSL/#extension-clip_distances
ClipDistances,
pub enum ImplementedEnableExtension {
/// Enables the `blend_src` attribute in WGSL.
///
/// In the WGSL standard, this corresponds to [`enable dual_source_blending;`].
///
/// [`enable dual_source_blending;`]: https://www.w3.org/TR/WGSL/#extension-dual_source_blending
DualSourceBlending,
/// Enables `f16`/`half` primitive support in all shader languages.
///
/// In the WGSL standard, this corresponds to [`enable f16;`].
///
/// [`enable f16;`]: https://www.w3.org/TR/WGSL/#extension-f16
F16,
}
/// A variant of [`EnableExtension::Unimplemented`].
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum UnimplementedEnableExtension {
/// Enables the `clip_distances` variable in WGSL.
///
/// In the WGSL standard, this corresponds to [`enable clip_distances;`].
///
/// [`enable clip_distances;`]: https://www.w3.org/TR/WGSL/#extension-clip_distances
ClipDistances,
}
impl UnimplementedEnableExtension {
pub(crate) const fn tracking_issue_num(self) -> u16 {
match self {
Self::F16 => 4384,
Self::ClipDistances => 6236,
Self::DualSourceBlending => 6402,
}
}
}

View File

@@ -1,10 +1,12 @@
use super::{number::consume_number, Error, ExpectedToken};
use super::{number::consume_number, Error, ExpectedToken, Result};
use crate::front::wgsl::error::NumberError;
use crate::front::wgsl::parse::directive::enable_extension::EnableExtensions;
use crate::front::wgsl::parse::{conv, Number};
use crate::front::wgsl::Scalar;
use crate::Span;
use alloc::boxed::Box;
type TokenSpan<'a> = (Token<'a>, Span);
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -12,7 +14,7 @@ pub enum Token<'a> {
Separator(char),
Paren(char),
Attribute,
Number(Result<Number, NumberError>),
Number(core::result::Result<Number, NumberError>),
Word(&'a str),
Operation(char),
LogicalOperation(char),
@@ -218,7 +220,6 @@ pub(in crate::front::wgsl) struct Lexer<'a> {
/// statements.
last_end_offset: usize,
#[allow(dead_code)]
pub(in crate::front::wgsl) enable_extensions: EnableExtensions,
}
@@ -243,8 +244,8 @@ impl<'a> Lexer<'a> {
#[inline]
pub fn capture_span<T, E>(
&mut self,
inner: impl FnOnce(&mut Self) -> Result<T, E>,
) -> Result<(T, Span), E> {
inner: impl FnOnce(&mut Self) -> core::result::Result<T, E>,
) -> core::result::Result<(T, Span), E> {
let start = self.current_byte_offset();
let res = inner(self)?;
let end = self.current_byte_offset();
@@ -320,19 +321,19 @@ impl<'a> Lexer<'a> {
token
}
pub(in crate::front::wgsl) fn expect_span(
&mut self,
expected: Token<'a>,
) -> Result<Span, Error<'a>> {
pub(in crate::front::wgsl) fn expect_span(&mut self, expected: Token<'a>) -> Result<'a, Span> {
let next = self.next();
if next.0 == expected {
Ok(next.1)
} else {
Err(Error::Unexpected(next.1, ExpectedToken::Token(expected)))
Err(Box::new(Error::Unexpected(
next.1,
ExpectedToken::Token(expected),
)))
}
}
pub(in crate::front::wgsl) fn expect(&mut self, expected: Token<'a>) -> Result<(), Error<'a>> {
pub(in crate::front::wgsl) fn expect(&mut self, expected: Token<'a>) -> Result<'a, ()> {
self.expect_span(expected)?;
Ok(())
}
@@ -340,15 +341,15 @@ impl<'a> Lexer<'a> {
pub(in crate::front::wgsl) fn expect_generic_paren(
&mut self,
expected: char,
) -> Result<(), Error<'a>> {
) -> Result<'a, ()> {
let next = self.next_generic();
if next.0 == Token::Paren(expected) {
Ok(())
} else {
Err(Error::Unexpected(
Err(Box::new(Error::Unexpected(
next.1,
ExpectedToken::Token(Token::Paren(expected)),
))
)))
}
}
@@ -367,59 +368,62 @@ impl<'a> Lexer<'a> {
}
}
pub(in crate::front::wgsl) fn next_ident_with_span(
&mut self,
) -> Result<(&'a str, Span), Error<'a>> {
pub(in crate::front::wgsl) fn next_ident_with_span(&mut self) -> Result<'a, (&'a str, Span)> {
match self.next() {
(Token::Word(word), span) => Self::word_as_ident_with_span(word, span),
other => Err(Error::Unexpected(other.1, ExpectedToken::Identifier)),
other => Err(Box::new(Error::Unexpected(
other.1,
ExpectedToken::Identifier,
))),
}
}
pub(in crate::front::wgsl) fn peek_ident_with_span(
&mut self,
) -> Result<(&'a str, Span), Error<'a>> {
pub(in crate::front::wgsl) fn peek_ident_with_span(&mut self) -> Result<'a, (&'a str, Span)> {
match self.peek() {
(Token::Word(word), span) => Self::word_as_ident_with_span(word, span),
other => Err(Error::Unexpected(other.1, ExpectedToken::Identifier)),
other => Err(Box::new(Error::Unexpected(
other.1,
ExpectedToken::Identifier,
))),
}
}
fn word_as_ident_with_span(word: &'a str, span: Span) -> Result<(&'a str, Span), Error<'a>> {
fn word_as_ident_with_span(word: &'a str, span: Span) -> Result<'a, (&'a str, Span)> {
match word {
"_" => Err(Error::InvalidIdentifierUnderscore(span)),
word if word.starts_with("__") => Err(Error::ReservedIdentifierPrefix(span)),
"_" => Err(Box::new(Error::InvalidIdentifierUnderscore(span))),
word if word.starts_with("__") => Err(Box::new(Error::ReservedIdentifierPrefix(span))),
word => Ok((word, span)),
}
}
pub(in crate::front::wgsl) fn next_ident(
&mut self,
) -> Result<super::ast::Ident<'a>, Error<'a>> {
pub(in crate::front::wgsl) fn next_ident(&mut self) -> Result<'a, super::ast::Ident<'a>> {
self.next_ident_with_span()
.and_then(|(word, span)| Self::word_as_ident(word, span))
.map(|(name, span)| super::ast::Ident { name, span })
}
fn word_as_ident(word: &'a str, span: Span) -> Result<(&'a str, Span), Error<'a>> {
fn word_as_ident(word: &'a str, span: Span) -> Result<'a, (&'a str, Span)> {
if crate::keywords::wgsl::RESERVED.contains(&word) {
Err(Error::ReservedKeyword(span))
Err(Box::new(Error::ReservedKeyword(span)))
} else {
Ok((word, span))
}
}
/// Parses a generic scalar type, for example `<f32>`.
pub(in crate::front::wgsl) fn next_scalar_generic(&mut self) -> Result<Scalar, Error<'a>> {
pub(in crate::front::wgsl) fn next_scalar_generic(&mut self) -> Result<'a, Scalar> {
self.expect_generic_paren('<')?;
let pair = match self.next() {
let (scalar, _span) = match self.next() {
(Token::Word(word), span) => {
conv::get_scalar_type(word).ok_or(Error::UnknownScalarType(span))
conv::get_scalar_type(&self.enable_extensions, span, word)?
.map(|scalar| (scalar, span))
.ok_or(Error::UnknownScalarType(span))?
}
(_, span) => Err(Error::UnknownScalarType(span)),
}?;
(_, span) => return Err(Box::new(Error::UnknownScalarType(span))),
};
self.expect_generic_paren('>')?;
Ok(pair)
Ok(scalar)
}
/// Parses a generic scalar type, for example `<f32>`.
@@ -427,21 +431,25 @@ impl<'a> Lexer<'a> {
/// Returns the span covering the inner type, excluding the brackets.
pub(in crate::front::wgsl) fn next_scalar_generic_with_span(
&mut self,
) -> Result<(Scalar, Span), Error<'a>> {
) -> Result<'a, (Scalar, Span)> {
self.expect_generic_paren('<')?;
let pair = match self.next() {
(Token::Word(word), span) => conv::get_scalar_type(word)
.map(|scalar| (scalar, span))
.ok_or(Error::UnknownScalarType(span)),
(_, span) => Err(Error::UnknownScalarType(span)),
}?;
let (scalar, span) = match self.next() {
(Token::Word(word), span) => {
conv::get_scalar_type(&self.enable_extensions, span, word)?
.map(|scalar| (scalar, span))
.ok_or(Error::UnknownScalarType(span))?
}
(_, span) => return Err(Box::new(Error::UnknownScalarType(span))),
};
self.expect_generic_paren('>')?;
Ok(pair)
Ok((scalar, span))
}
pub(in crate::front::wgsl) fn next_storage_access(
&mut self,
) -> Result<crate::StorageAccess, Error<'a>> {
) -> Result<'a, crate::StorageAccess> {
let (ident, span) = self.next_ident_with_span()?;
match ident {
"read" => Ok(crate::StorageAccess::LOAD),
@@ -450,13 +458,13 @@ impl<'a> Lexer<'a> {
"atomic" => Ok(crate::StorageAccess::ATOMIC
| crate::StorageAccess::LOAD
| crate::StorageAccess::STORE),
_ => Err(Error::UnknownAccess(span)),
_ => Err(Box::new(Error::UnknownAccess(span))),
}
}
pub(in crate::front::wgsl) fn next_format_generic(
&mut self,
) -> Result<(crate::StorageFormat, crate::StorageAccess), Error<'a>> {
) -> Result<'a, (crate::StorageFormat, crate::StorageAccess)> {
self.expect(Token::Paren('<'))?;
let (ident, ident_span) = self.next_ident_with_span()?;
let format = conv::map_storage_format(ident, ident_span)?;
@@ -466,16 +474,14 @@ impl<'a> Lexer<'a> {
Ok((format, access))
}
pub(in crate::front::wgsl) fn next_acceleration_structure_flags(
&mut self,
) -> Result<bool, Error<'a>> {
pub(in crate::front::wgsl) fn next_acceleration_structure_flags(&mut self) -> Result<'a, bool> {
Ok(if self.skip(Token::Paren('<')) {
if !self.skip(Token::Paren('>')) {
let (name, span) = self.next_ident_with_span()?;
let ret = if name == "vertex_return" {
true
} else {
return Err(Error::UnknownAttribute(span));
return Err(Box::new(Error::UnknownAttribute(span)));
};
self.skip(Token::Separator(','));
self.expect(Token::Paren('>'))?;
@@ -488,16 +494,16 @@ impl<'a> Lexer<'a> {
})
}
pub(in crate::front::wgsl) fn open_arguments(&mut self) -> Result<(), Error<'a>> {
pub(in crate::front::wgsl) fn open_arguments(&mut self) -> Result<'a, ()> {
self.expect(Token::Paren('('))
}
pub(in crate::front::wgsl) fn close_arguments(&mut self) -> Result<(), Error<'a>> {
pub(in crate::front::wgsl) fn close_arguments(&mut self) -> Result<'a, ()> {
let _ = self.skip(Token::Separator(','));
self.expect(Token::Paren(')'))
}
pub(in crate::front::wgsl) fn next_argument(&mut self) -> Result<bool, Error<'a>> {
pub(in crate::front::wgsl) fn next_argument(&mut self) -> Result<'a, bool> {
let paren = Token::Paren(')');
if self.skip(Token::Separator(',')) {
Ok(!self.skip(paren))
@@ -519,6 +525,7 @@ fn sub_test(source: &str, expected_tokens: &[Token]) {
#[test]
fn test_numbers() {
use half::f16;
// WGSL spec examples //
// decimal integer
@@ -543,14 +550,16 @@ fn test_numbers() {
Token::Number(Ok(Number::AbstractFloat(0.01))),
Token::Number(Ok(Number::AbstractFloat(12.34))),
Token::Number(Ok(Number::F32(0.))),
Token::Number(Err(NumberError::UnimplementedF16)),
Token::Number(Ok(Number::F16(f16::from_f32(0.)))),
Token::Number(Ok(Number::AbstractFloat(0.001))),
Token::Number(Ok(Number::AbstractFloat(43.75))),
Token::Number(Ok(Number::F32(16.))),
Token::Number(Ok(Number::AbstractFloat(0.1875))),
Token::Number(Err(NumberError::UnimplementedF16)),
// https://github.com/gfx-rs/wgpu/issues/7046
Token::Number(Err(NumberError::NotRepresentable)), // Should be 0.75
Token::Number(Ok(Number::AbstractFloat(0.12109375))),
Token::Number(Err(NumberError::UnimplementedF16)),
// https://github.com/gfx-rs/wgpu/issues/7046
Token::Number(Err(NumberError::NotRepresentable)), // Should be 12.5
],
);

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,9 @@
use alloc::format;
use crate::front::wgsl::error::NumberError;
use crate::front::wgsl::parse::directive::enable_extension::ImplementedEnableExtension;
use crate::front::wgsl::parse::lexer::Token;
use half::f16;
/// When using this type assume no Abstract Int/Float for now
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -18,12 +20,23 @@ pub enum Number {
I64(i64),
/// Concrete u64
U64(u64),
/// Concrete f16
F16(f16),
/// Concrete f32
F32(f32),
/// Concrete f64
F64(f64),
}
impl Number {
pub(super) const fn requires_enable_extension(&self) -> Option<ImplementedEnableExtension> {
match *self {
Number::F16(_) => Some(ImplementedEnableExtension::F16),
_ => None,
}
}
}
pub(in crate::front::wgsl) fn consume_number(input: &str) -> (Token<'_>, &str) {
let (result, rest) = parse(input);
(Token::Number(result), rest)
@@ -369,7 +382,8 @@ fn parse_hex_float(input: &str, kind: Option<FloatKind>) -> Result<Number, Numbe
// can only be ParseHexfErrorKind::Inexact but we can't check since it's private
_ => Err(NumberError::NotRepresentable),
},
Some(FloatKind::F16) => Err(NumberError::UnimplementedF16),
// TODO: f16 is not supported by hexf_parse
Some(FloatKind::F16) => Err(NumberError::NotRepresentable),
Some(FloatKind::F32) => match hexf_parse::parse_hexf32(input, false) {
Ok(num) => Ok(Number::F32(num)),
// can only be ParseHexfErrorKind::Inexact but we can't check since it's private
@@ -405,7 +419,12 @@ fn parse_dec_float(input: &str, kind: Option<FloatKind>) -> Result<Number, Numbe
.then_some(Number::F64(num))
.ok_or(NumberError::NotRepresentable)
}
Some(FloatKind::F16) => Err(NumberError::UnimplementedF16),
Some(FloatKind::F16) => {
let num = input.parse::<f16>().unwrap(); // will never fail
num.is_finite()
.then_some(Number::F16(num))
.ok_or(NumberError::NotRepresentable)
}
}
}

Some files were not shown because too many files have changed in this diff Show More