Bug 1810495 - Update wgpu to fac4731288117d951d0944d96cf0b00fa006dd6c. r=webgpu-reviewers,teoxoy

Differential Revision: https://phabricator.services.mozilla.com/D166916
This commit is contained in:
Nicolas Silva 2023-01-20 15:39:41 +00:00
Родитель 5a7dea7d91
Коммит db956b65c9
68 изменённых файлов: 3114 добавлений и 1217 удалений

Просмотреть файл

@ -27,12 +27,12 @@ rev = "722b30d2f1634714befab967ecae627813fa4cf0"
[source."https://github.com/gfx-rs/naga"]
git = "https://github.com/gfx-rs/naga"
rev = "e7fc8e6"
rev = "e98bd92"
replace-with = "vendored-sources"
[source."https://github.com/gfx-rs/wgpu"]
git = "https://github.com/gfx-rs/wgpu"
rev = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
replace-with = "vendored-sources"
[source."https://github.com/glandium/warp"]

16
Cargo.lock сгенерированный
Просмотреть файл

@ -140,9 +140,9 @@ dependencies = [
[[package]]
name = "ash"
version = "0.37.1+1.3.235"
version = "0.37.2+1.3.238"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "911015c962d56e2e4052f40182ca5462ba60a3d2ff04e827c365a0ab3d65726d"
checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03"
dependencies = [
"libloading",
]
@ -3638,7 +3638,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "0.10.0"
source = "git+https://github.com/gfx-rs/naga?rev=e7fc8e6#e7fc8e64f2f23397b149217ecce6e123c5aa5092"
source = "git+https://github.com/gfx-rs/naga?rev=e98bd92#e98bd9264c3a6b04dff15a6b1213c0c80201740a"
dependencies = [
"bit-set",
"bitflags",
@ -6347,7 +6347,7 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "0.14.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=186a29c34d54d8628bbebb998a537210ac565b71#186a29c34d54d8628bbebb998a537210ac565b71"
source = "git+https://github.com/gfx-rs/wgpu?rev=fac4731288117d951d0944d96cf0b00fa006dd6c#fac4731288117d951d0944d96cf0b00fa006dd6c"
dependencies = [
"arrayvec",
"bit-vec",
@ -6356,7 +6356,7 @@ dependencies = [
"fxhash",
"log",
"naga",
"parking_lot 0.12.999",
"parking_lot 0.11.2",
"profiling",
"ron",
"serde",
@ -6370,7 +6370,7 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "0.14.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=186a29c34d54d8628bbebb998a537210ac565b71#186a29c34d54d8628bbebb998a537210ac565b71"
source = "git+https://github.com/gfx-rs/wgpu?rev=fac4731288117d951d0944d96cf0b00fa006dd6c#fac4731288117d951d0944d96cf0b00fa006dd6c"
dependencies = [
"android_system_properties",
"arrayvec",
@ -6392,7 +6392,7 @@ dependencies = [
"metal",
"naga",
"objc",
"parking_lot 0.12.999",
"parking_lot 0.11.2",
"profiling",
"range-alloc",
"raw-window-handle",
@ -6408,7 +6408,7 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "0.14.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=186a29c34d54d8628bbebb998a537210ac565b71#186a29c34d54d8628bbebb998a537210ac565b71"
source = "git+https://github.com/gfx-rs/wgpu?rev=fac4731288117d951d0944d96cf0b00fa006dd6c#fac4731288117d951d0944d96cf0b00fa006dd6c"
dependencies = [
"bitflags",
"serde",

Просмотреть файл

@ -17,7 +17,7 @@ default = []
[dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
#Note: "replay" shouldn't ideally be needed,
# but it allows us to serialize everything across IPC.
features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl", "renderdoc"]
@ -27,32 +27,32 @@ features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl", "renderd
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
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 = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
features = ["dx11", "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 = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
features = ["vulkan"]
[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
[dependencies.wgh]
package = "wgpu-hal"
git = "https://github.com/gfx-rs/wgpu"
rev = "186a29c34d54d8628bbebb998a537210ac565b71"
rev = "fac4731288117d951d0944d96cf0b00fa006dd6c"
[dependencies]
bincode = "1"

Просмотреть файл

@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: commit f14bee67
release: commit fac4731288117d951d0944d96cf0b00fa006dd6c
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: 186a29c34d54d8628bbebb998a537210ac565b71
revision: fac4731288117d951d0944d96cf0b00fa006dd6c
license: ['MIT', 'Apache-2.0']

2
third_party/rust/ash/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

2
third_party/rust/ash/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.59.0"
name = "ash"
version = "0.37.1+1.3.235"
version = "0.37.2+1.3.238"
authors = [
"Maik Klein <maikklein@googlemail.com>",
"Benjamin Saunders <ben.e.saunders@gmail.com>",

Просмотреть файл

@ -51,7 +51,7 @@ impl DrawIndirectCount {
max_draw_count: u32,
stride: u32,
) {
(self.fp.cmd_draw_indexed_indirect_count_khr)(
(self.fp.cmd_draw_indirect_count_khr)(
command_buffer,
buffer,
offset,

28
third_party/rust/ash/src/vk/bitflags.rs поставляемый
Просмотреть файл

@ -1143,6 +1143,26 @@ impl DeviceAddressBindingFlagsEXT {
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPresentScalingFlagBitsEXT.html>"]
pub struct PresentScalingFlagsEXT(pub(crate) Flags);
vk_bitflags_wrapped!(PresentScalingFlagsEXT, Flags);
impl PresentScalingFlagsEXT {
pub const ONE_TO_ONE: Self = Self(0b1);
pub const ASPECT_RATIO_STRETCH: Self = Self(0b10);
pub const STRETCH: Self = Self(0b100);
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkPresentGravityFlagBitsEXT.html>"]
pub struct PresentGravityFlagsEXT(pub(crate) Flags);
vk_bitflags_wrapped!(PresentGravityFlagsEXT, Flags);
impl PresentGravityFlagsEXT {
pub const MIN: Self = Self(0b1);
pub const MAX: Self = Self(0b10);
pub const CENTERED: Self = Self(0b100);
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkVideoCodecOperationFlagBitsKHR.html>"]
pub struct VideoCodecOperationFlagsKHR(pub(crate) Flags);
vk_bitflags_wrapped!(VideoCodecOperationFlagsKHR, Flags);
@ -1191,10 +1211,10 @@ impl VideoSessionCreateFlagsKHR {
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkVideoDecodeH264PictureLayoutFlagBitsEXT.html>"]
pub struct VideoDecodeH264PictureLayoutFlagsEXT(pub(crate) Flags);
vk_bitflags_wrapped!(VideoDecodeH264PictureLayoutFlagsEXT, Flags);
impl VideoDecodeH264PictureLayoutFlagsEXT {
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkVideoDecodeH264PictureLayoutFlagBitsKHR.html>"]
pub struct VideoDecodeH264PictureLayoutFlagsKHR(pub(crate) Flags);
vk_bitflags_wrapped!(VideoDecodeH264PictureLayoutFlagsKHR, Flags);
impl VideoDecodeH264PictureLayoutFlagsKHR {
pub const PROGRESSIVE: Self = Self(0);
pub const INTERLACED_INTERLEAVED_LINES: Self = Self(0b1);
pub const INTERLACED_SEPARATE_PLANES: Self = Self(0b10);

126
third_party/rust/ash/src/vk/const_debugs.rs поставляемый
Просмотреть файл

@ -1404,6 +1404,26 @@ impl fmt::Debug for DeviceQueueCreateFlags {
debug_flags(f, KNOWN, self.0)
}
}
impl fmt::Debug for DirectDriverLoadingFlagsLUNARG {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const KNOWN: &[(Flags, &str)] = &[];
debug_flags(f, KNOWN, self.0)
}
}
impl fmt::Debug for DirectDriverLoadingModeLUNARG {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let name = match *self {
Self::EXCLUSIVE => Some("EXCLUSIVE"),
Self::INCLUSIVE => Some("INCLUSIVE"),
_ => None,
};
if let Some(x) = name {
f.write_str(x)
} else {
self.0.fmt(f)
}
}
}
impl fmt::Debug for DirectFBSurfaceCreateFlagsEXT {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const KNOWN: &[(Flags, &str)] = &[];
@ -3842,6 +3862,16 @@ impl fmt::Debug for PolygonMode {
}
}
}
impl fmt::Debug for PresentGravityFlagsEXT {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const KNOWN: &[(Flags, &str)] = &[
(PresentGravityFlagsEXT::MIN.0, "MIN"),
(PresentGravityFlagsEXT::MAX.0, "MAX"),
(PresentGravityFlagsEXT::CENTERED.0, "CENTERED"),
];
debug_flags(f, KNOWN, self.0)
}
}
impl fmt::Debug for PresentModeKHR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let name = match *self {
@ -3860,6 +3890,19 @@ impl fmt::Debug for PresentModeKHR {
}
}
}
impl fmt::Debug for PresentScalingFlagsEXT {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const KNOWN: &[(Flags, &str)] = &[
(PresentScalingFlagsEXT::ONE_TO_ONE.0, "ONE_TO_ONE"),
(
PresentScalingFlagsEXT::ASPECT_RATIO_STRETCH.0,
"ASPECT_RATIO_STRETCH",
),
(PresentScalingFlagsEXT::STRETCH.0, "STRETCH"),
];
debug_flags(f, KNOWN, self.0)
}
}
impl fmt::Debug for PrimitiveTopology {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let name = match *self {
@ -4744,17 +4787,17 @@ impl fmt::Debug for StructureType {
Self::VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT => {
Some("VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT")
}
Self::VIDEO_DECODE_H264_CAPABILITIES_EXT => Some("VIDEO_DECODE_H264_CAPABILITIES_EXT"),
Self::VIDEO_DECODE_H264_PICTURE_INFO_EXT => Some("VIDEO_DECODE_H264_PICTURE_INFO_EXT"),
Self::VIDEO_DECODE_H264_PROFILE_INFO_EXT => Some("VIDEO_DECODE_H264_PROFILE_INFO_EXT"),
Self::VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT => {
Some("VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT")
Self::VIDEO_DECODE_H264_CAPABILITIES_KHR => Some("VIDEO_DECODE_H264_CAPABILITIES_KHR"),
Self::VIDEO_DECODE_H264_PICTURE_INFO_KHR => Some("VIDEO_DECODE_H264_PICTURE_INFO_KHR"),
Self::VIDEO_DECODE_H264_PROFILE_INFO_KHR => Some("VIDEO_DECODE_H264_PROFILE_INFO_KHR"),
Self::VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR => {
Some("VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR")
}
Self::VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT => {
Some("VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT")
Self::VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR => {
Some("VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR")
}
Self::VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT => {
Some("VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT")
Self::VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR => {
Some("VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR")
}
Self::TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD => {
Some("TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD")
@ -5122,17 +5165,17 @@ impl fmt::Debug for StructureType {
Self::PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD => {
Some("PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD")
}
Self::VIDEO_DECODE_H265_CAPABILITIES_EXT => Some("VIDEO_DECODE_H265_CAPABILITIES_EXT"),
Self::VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT => {
Some("VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT")
Self::VIDEO_DECODE_H265_CAPABILITIES_KHR => Some("VIDEO_DECODE_H265_CAPABILITIES_KHR"),
Self::VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR => {
Some("VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR")
}
Self::VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT => {
Some("VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT")
Self::VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR => {
Some("VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR")
}
Self::VIDEO_DECODE_H265_PROFILE_INFO_EXT => Some("VIDEO_DECODE_H265_PROFILE_INFO_EXT"),
Self::VIDEO_DECODE_H265_PICTURE_INFO_EXT => Some("VIDEO_DECODE_H265_PICTURE_INFO_EXT"),
Self::VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT => {
Some("VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT")
Self::VIDEO_DECODE_H265_PROFILE_INFO_KHR => Some("VIDEO_DECODE_H265_PROFILE_INFO_KHR"),
Self::VIDEO_DECODE_H265_PICTURE_INFO_KHR => Some("VIDEO_DECODE_H265_PICTURE_INFO_KHR"),
Self::VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR => {
Some("VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR")
}
Self::DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR => {
Some("DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR")
@ -5334,6 +5377,25 @@ impl fmt::Debug for StructureType {
Self::PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT => {
Some("PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT")
}
Self::SURFACE_PRESENT_MODE_EXT => Some("SURFACE_PRESENT_MODE_EXT"),
Self::SURFACE_PRESENT_SCALING_CAPABILITIES_EXT => {
Some("SURFACE_PRESENT_SCALING_CAPABILITIES_EXT")
}
Self::SURFACE_PRESENT_MODE_COMPATIBILITY_EXT => {
Some("SURFACE_PRESENT_MODE_COMPATIBILITY_EXT")
}
Self::PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT => {
Some("PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT")
}
Self::SWAPCHAIN_PRESENT_FENCE_INFO_EXT => Some("SWAPCHAIN_PRESENT_FENCE_INFO_EXT"),
Self::SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT => {
Some("SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT")
}
Self::SWAPCHAIN_PRESENT_MODE_INFO_EXT => Some("SWAPCHAIN_PRESENT_MODE_INFO_EXT"),
Self::SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT => {
Some("SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT")
}
Self::RELEASE_SWAPCHAIN_IMAGES_INFO_EXT => Some("RELEASE_SWAPCHAIN_IMAGES_INFO_EXT"),
Self::PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV => {
Some("PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV")
}
@ -5766,6 +5828,8 @@ impl fmt::Debug for StructureType {
Self::RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT => {
Some("RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT")
}
Self::DIRECT_DRIVER_LOADING_INFO_LUNARG => Some("DIRECT_DRIVER_LOADING_INFO_LUNARG"),
Self::DIRECT_DRIVER_LOADING_LIST_LUNARG => Some("DIRECT_DRIVER_LOADING_LIST_LUNARG"),
Self::PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT => {
Some("PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT")
}
@ -5810,6 +5874,9 @@ impl fmt::Debug for StructureType {
Some("PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC")
}
Self::AMIGO_PROFILING_SUBMIT_INFO_SEC => Some("AMIGO_PROFILING_SUBMIT_INFO_SEC"),
Self::PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM => {
Some("PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM")
}
Self::PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV => {
Some("PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV")
}
@ -6322,8 +6389,11 @@ impl fmt::Debug for SwapchainCreateFlagsKHR {
),
(SwapchainCreateFlagsKHR::PROTECTED.0, "PROTECTED"),
(SwapchainCreateFlagsKHR::MUTABLE_FORMAT.0, "MUTABLE_FORMAT"),
(
SwapchainCreateFlagsKHR::DEFERRED_MEMORY_ALLOCATION_EXT.0,
"DEFERRED_MEMORY_ALLOCATION_EXT",
),
(SwapchainCreateFlagsKHR::RESERVED_4_EXT.0, "RESERVED_4_EXT"),
(SwapchainCreateFlagsKHR::RESERVED_3_SEC.0, "RESERVED_3_SEC"),
];
debug_flags(f, KNOWN, self.0)
}
@ -6554,14 +6624,8 @@ impl fmt::Debug for VideoCodecOperationFlagsKHR {
VideoCodecOperationFlagsKHR::ENCODE_H265_EXT.0,
"ENCODE_H265_EXT",
),
(
VideoCodecOperationFlagsKHR::DECODE_H264_EXT.0,
"DECODE_H264_EXT",
),
(
VideoCodecOperationFlagsKHR::DECODE_H265_EXT.0,
"DECODE_H265_EXT",
),
(VideoCodecOperationFlagsKHR::DECODE_H264.0, "DECODE_H264"),
(VideoCodecOperationFlagsKHR::DECODE_H265.0, "DECODE_H265"),
];
debug_flags(f, KNOWN, self.0)
}
@ -6614,19 +6678,19 @@ impl fmt::Debug for VideoDecodeFlagsKHR {
debug_flags(f, KNOWN, self.0)
}
}
impl fmt::Debug for VideoDecodeH264PictureLayoutFlagsEXT {
impl fmt::Debug for VideoDecodeH264PictureLayoutFlagsKHR {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
const KNOWN: &[(Flags, &str)] = &[
(
VideoDecodeH264PictureLayoutFlagsEXT::PROGRESSIVE.0,
VideoDecodeH264PictureLayoutFlagsKHR::PROGRESSIVE.0,
"PROGRESSIVE",
),
(
VideoDecodeH264PictureLayoutFlagsEXT::INTERLACED_INTERLEAVED_LINES.0,
VideoDecodeH264PictureLayoutFlagsKHR::INTERLACED_INTERLEAVED_LINES.0,
"INTERLACED_INTERLEAVED_LINES",
),
(
VideoDecodeH264PictureLayoutFlagsEXT::INTERLACED_SEPARATE_PLANES.0,
VideoDecodeH264PictureLayoutFlagsKHR::INTERLACED_SEPARATE_PLANES.0,
"INTERLACED_SEPARATE_PLANES",
),
];

1305
third_party/rust/ash/src/vk/definitions.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

55
third_party/rust/ash/src/vk/enums.rs поставляемый
Просмотреть файл

@ -966,7 +966,7 @@ impl Result {
pub const ERROR_OUT_OF_DEVICE_MEMORY: Self = Self(-2);
#[doc = "Initialization of an object has failed"]
pub const ERROR_INITIALIZATION_FAILED: Self = Self(-3);
#[doc = "The logical device has been lost. See <<devsandqueues-lost-device>>"]
#[doc = "The logical device has been lost. See <https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#devsandqueues-lost-device>"]
pub const ERROR_DEVICE_LOST: Self = Self(-4);
#[doc = "Mapping of a memory object has failed"]
pub const ERROR_MEMORY_MAP_FAILED: Self = Self(-5);
@ -990,40 +990,7 @@ impl Result {
impl ::std::error::Error for Result {}
impl fmt::Display for Result {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let name = match *self {
Self::SUCCESS => Some("Command completed successfully"),
Self::NOT_READY => Some("A fence or query has not yet completed"),
Self::TIMEOUT => Some("A wait operation has not completed in the specified time"),
Self::EVENT_SET => Some("An event is signaled"),
Self::EVENT_RESET => Some("An event is unsignaled"),
Self::INCOMPLETE => Some("A return array was too small for the result"),
Self::ERROR_OUT_OF_HOST_MEMORY => Some("A host memory allocation has failed"),
Self::ERROR_OUT_OF_DEVICE_MEMORY => Some("A device memory allocation has failed"),
Self::ERROR_INITIALIZATION_FAILED => Some("Initialization of an object has failed"),
Self::ERROR_DEVICE_LOST => {
Some("The logical device has been lost. See <<devsandqueues-lost-device>>")
}
Self::ERROR_MEMORY_MAP_FAILED => Some("Mapping of a memory object has failed"),
Self::ERROR_LAYER_NOT_PRESENT => Some("Layer specified does not exist"),
Self::ERROR_EXTENSION_NOT_PRESENT => Some("Extension specified does not exist"),
Self::ERROR_FEATURE_NOT_PRESENT => {
Some("Requested feature is not available on this device")
}
Self::ERROR_INCOMPATIBLE_DRIVER => Some("Unable to find a Vulkan driver"),
Self::ERROR_TOO_MANY_OBJECTS => {
Some("Too many objects of the type have already been created")
}
Self::ERROR_FORMAT_NOT_SUPPORTED => {
Some("Requested format is not supported on this device")
}
Self::ERROR_FRAGMENTED_POOL => Some(
"A requested pool allocation has failed due to fragmentation of the pool's memory",
),
Self::ERROR_UNKNOWN => {
Some("An unknown error has occurred, due to an implementation or application bug")
}
_ => None,
};
let name = match * self { Self :: SUCCESS => Some ("Command completed successfully") , Self :: NOT_READY => Some ("A fence or query has not yet completed") , Self :: TIMEOUT => Some ("A wait operation has not completed in the specified time") , Self :: EVENT_SET => Some ("An event is signaled") , Self :: EVENT_RESET => Some ("An event is unsignaled") , Self :: INCOMPLETE => Some ("A return array was too small for the result") , Self :: ERROR_OUT_OF_HOST_MEMORY => Some ("A host memory allocation has failed") , Self :: ERROR_OUT_OF_DEVICE_MEMORY => Some ("A device memory allocation has failed") , Self :: ERROR_INITIALIZATION_FAILED => Some ("Initialization of an object has failed") , Self :: ERROR_DEVICE_LOST => Some ("The logical device has been lost. See <https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#devsandqueues-lost-device>") , Self :: ERROR_MEMORY_MAP_FAILED => Some ("Mapping of a memory object has failed") , Self :: ERROR_LAYER_NOT_PRESENT => Some ("Layer specified does not exist") , Self :: ERROR_EXTENSION_NOT_PRESENT => Some ("Extension specified does not exist") , Self :: ERROR_FEATURE_NOT_PRESENT => Some ("Requested feature is not available on this device") , Self :: ERROR_INCOMPATIBLE_DRIVER => Some ("Unable to find a Vulkan driver") , Self :: ERROR_TOO_MANY_OBJECTS => Some ("Too many objects of the type have already been created") , Self :: ERROR_FORMAT_NOT_SUPPORTED => Some ("Requested format is not supported on this device") , Self :: ERROR_FRAGMENTED_POOL => Some ("A requested pool allocation has failed due to fragmentation of the pool's memory") , Self :: ERROR_UNKNOWN => Some ("An unknown error has occurred, due to an implementation or application bug") , _ => None , } ;
if let Some(x) = name {
fmt.write_str(x)
} else {
@ -1136,6 +1103,24 @@ impl RayTracingInvocationReorderModeNV {
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[repr(transparent)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkDirectDriverLoadingModeLUNARG.html>"]
pub struct DirectDriverLoadingModeLUNARG(pub(crate) i32);
impl DirectDriverLoadingModeLUNARG {
#[inline]
pub const fn from_raw(x: i32) -> Self {
Self(x)
}
#[inline]
pub const fn as_raw(self) -> i32 {
self.0
}
}
impl DirectDriverLoadingModeLUNARG {
pub const EXCLUSIVE: Self = Self(0);
pub const INCLUSIVE: Self = Self(1);
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[repr(transparent)]
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSemaphoreType.html>"]
pub struct SemaphoreType(pub(crate) i32);
impl SemaphoreType {

233
third_party/rust/ash/src/vk/extensions.rs поставляемый
Просмотреть файл

@ -1846,7 +1846,7 @@ impl KhrVideoQueueFn {
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_video_queue\0") }
}
pub const SPEC_VERSION: u32 = 7u32;
pub const SPEC_VERSION: u32 = 8u32;
}
#[allow(non_camel_case_types)]
pub type PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR = unsafe extern "system" fn(
@ -2248,7 +2248,7 @@ impl KhrVideoDecodeQueueFn {
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_video_decode_queue\0") }
}
pub const SPEC_VERSION: u32 = 6u32;
pub const SPEC_VERSION: u32 = 7u32;
}
#[allow(non_camel_case_types)]
pub type PFN_vkCmdDecodeVideoKHR = unsafe extern "system" fn(
@ -3165,18 +3165,18 @@ impl StructureType {
impl VideoCodecOperationFlagsKHR {
pub const ENCODE_H265_EXT: Self = Self(0b10_0000_0000_0000_0000);
}
impl ExtVideoDecodeH264Fn {
impl KhrVideoDecodeH264Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_video_decode_h264\0") }
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_video_decode_h264\0") }
}
pub const SPEC_VERSION: u32 = 7u32;
pub const SPEC_VERSION: u32 = 8u32;
}
#[derive(Clone)]
pub struct ExtVideoDecodeH264Fn {}
unsafe impl Send for ExtVideoDecodeH264Fn {}
unsafe impl Sync for ExtVideoDecodeH264Fn {}
impl ExtVideoDecodeH264Fn {
pub struct KhrVideoDecodeH264Fn {}
unsafe impl Send for KhrVideoDecodeH264Fn {}
unsafe impl Sync for KhrVideoDecodeH264Fn {}
impl KhrVideoDecodeH264Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
@ -3184,18 +3184,18 @@ impl ExtVideoDecodeH264Fn {
Self {}
}
}
#[doc = "Generated from 'VK_EXT_video_decode_h264'"]
#[doc = "Generated from 'VK_KHR_video_decode_h264'"]
impl StructureType {
pub const VIDEO_DECODE_H264_CAPABILITIES_EXT: Self = Self(1_000_040_000);
pub const VIDEO_DECODE_H264_PICTURE_INFO_EXT: Self = Self(1_000_040_001);
pub const VIDEO_DECODE_H264_PROFILE_INFO_EXT: Self = Self(1_000_040_003);
pub const VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT: Self = Self(1_000_040_004);
pub const VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT: Self = Self(1_000_040_005);
pub const VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT: Self = Self(1_000_040_006);
pub const VIDEO_DECODE_H264_CAPABILITIES_KHR: Self = Self(1_000_040_000);
pub const VIDEO_DECODE_H264_PICTURE_INFO_KHR: Self = Self(1_000_040_001);
pub const VIDEO_DECODE_H264_PROFILE_INFO_KHR: Self = Self(1_000_040_003);
pub const VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR: Self = Self(1_000_040_004);
pub const VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR: Self = Self(1_000_040_005);
pub const VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR: Self = Self(1_000_040_006);
}
#[doc = "Generated from 'VK_EXT_video_decode_h264'"]
#[doc = "Generated from 'VK_KHR_video_decode_h264'"]
impl VideoCodecOperationFlagsKHR {
pub const DECODE_H264_EXT: Self = Self(0b1);
pub const DECODE_H264: Self = Self(0b1);
}
impl AmdTextureGatherBiasLodFn {
#[inline]
@ -11682,18 +11682,18 @@ impl AmdExtension187Fn {
Self {}
}
}
impl ExtVideoDecodeH265Fn {
impl KhrVideoDecodeH265Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_video_decode_h265\0") }
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_video_decode_h265\0") }
}
pub const SPEC_VERSION: u32 = 5u32;
pub const SPEC_VERSION: u32 = 7u32;
}
#[derive(Clone)]
pub struct ExtVideoDecodeH265Fn {}
unsafe impl Send for ExtVideoDecodeH265Fn {}
unsafe impl Sync for ExtVideoDecodeH265Fn {}
impl ExtVideoDecodeH265Fn {
pub struct KhrVideoDecodeH265Fn {}
unsafe impl Send for KhrVideoDecodeH265Fn {}
unsafe impl Sync for KhrVideoDecodeH265Fn {}
impl KhrVideoDecodeH265Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
@ -11701,18 +11701,18 @@ impl ExtVideoDecodeH265Fn {
Self {}
}
}
#[doc = "Generated from 'VK_EXT_video_decode_h265'"]
#[doc = "Generated from 'VK_KHR_video_decode_h265'"]
impl StructureType {
pub const VIDEO_DECODE_H265_CAPABILITIES_EXT: Self = Self(1_000_187_000);
pub const VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT: Self = Self(1_000_187_001);
pub const VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT: Self = Self(1_000_187_002);
pub const VIDEO_DECODE_H265_PROFILE_INFO_EXT: Self = Self(1_000_187_003);
pub const VIDEO_DECODE_H265_PICTURE_INFO_EXT: Self = Self(1_000_187_004);
pub const VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT: Self = Self(1_000_187_005);
pub const VIDEO_DECODE_H265_CAPABILITIES_KHR: Self = Self(1_000_187_000);
pub const VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR: Self = Self(1_000_187_001);
pub const VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR: Self = Self(1_000_187_002);
pub const VIDEO_DECODE_H265_PROFILE_INFO_KHR: Self = Self(1_000_187_003);
pub const VIDEO_DECODE_H265_PICTURE_INFO_KHR: Self = Self(1_000_187_004);
pub const VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR: Self = Self(1_000_187_005);
}
#[doc = "Generated from 'VK_EXT_video_decode_h265'"]
#[doc = "Generated from 'VK_KHR_video_decode_h265'"]
impl VideoCodecOperationFlagsKHR {
pub const DECODE_H265_EXT: Self = Self(0b10);
pub const DECODE_H265: Self = Self(0b10);
}
impl KhrGlobalPriorityFn {
#[inline]
@ -15598,18 +15598,18 @@ impl ExtShaderAtomicFloat2Fn {
impl StructureType {
pub const PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT: Self = Self(1_000_273_000);
}
impl KhrExtension275Fn {
impl ExtSurfaceMaintenance1Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_extension_275\0") }
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_surface_maintenance1\0") }
}
pub const SPEC_VERSION: u32 = 0u32;
pub const SPEC_VERSION: u32 = 1u32;
}
#[derive(Clone)]
pub struct KhrExtension275Fn {}
unsafe impl Send for KhrExtension275Fn {}
unsafe impl Sync for KhrExtension275Fn {}
impl KhrExtension275Fn {
pub struct ExtSurfaceMaintenance1Fn {}
unsafe impl Send for ExtSurfaceMaintenance1Fn {}
unsafe impl Sync for ExtSurfaceMaintenance1Fn {}
impl ExtSurfaceMaintenance1Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
@ -15617,25 +15617,74 @@ impl KhrExtension275Fn {
Self {}
}
}
impl KhrExtension276Fn {
#[doc = "Generated from 'VK_EXT_surface_maintenance1'"]
impl StructureType {
pub const SURFACE_PRESENT_MODE_EXT: Self = Self(1_000_274_000);
pub const SURFACE_PRESENT_SCALING_CAPABILITIES_EXT: Self = Self(1_000_274_001);
pub const SURFACE_PRESENT_MODE_COMPATIBILITY_EXT: Self = Self(1_000_274_002);
}
impl ExtSwapchainMaintenance1Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_extension_276\0") }
unsafe {
::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_swapchain_maintenance1\0")
}
}
pub const SPEC_VERSION: u32 = 0u32;
pub const SPEC_VERSION: u32 = 1u32;
}
#[allow(non_camel_case_types)]
pub type PFN_vkReleaseSwapchainImagesEXT = unsafe extern "system" fn(
device: Device,
p_release_info: *const ReleaseSwapchainImagesInfoEXT,
) -> Result;
#[derive(Clone)]
pub struct KhrExtension276Fn {}
unsafe impl Send for KhrExtension276Fn {}
unsafe impl Sync for KhrExtension276Fn {}
impl KhrExtension276Fn {
pub struct ExtSwapchainMaintenance1Fn {
pub release_swapchain_images_ext: PFN_vkReleaseSwapchainImagesEXT,
}
unsafe impl Send for ExtSwapchainMaintenance1Fn {}
unsafe impl Sync for ExtSwapchainMaintenance1Fn {}
impl ExtSwapchainMaintenance1Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
{
Self {}
Self {
release_swapchain_images_ext: unsafe {
unsafe extern "system" fn release_swapchain_images_ext(
_device: Device,
_p_release_info: *const ReleaseSwapchainImagesInfoEXT,
) -> Result {
panic!(concat!(
"Unable to load ",
stringify!(release_swapchain_images_ext)
))
}
let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked(
b"vkReleaseSwapchainImagesEXT\0",
);
let val = _f(cname);
if val.is_null() {
release_swapchain_images_ext
} else {
::std::mem::transmute(val)
}
},
}
}
}
#[doc = "Generated from 'VK_EXT_swapchain_maintenance1'"]
impl StructureType {
pub const PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT: Self = Self(1_000_275_000);
pub const SWAPCHAIN_PRESENT_FENCE_INFO_EXT: Self = Self(1_000_275_001);
pub const SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT: Self = Self(1_000_275_002);
pub const SWAPCHAIN_PRESENT_MODE_INFO_EXT: Self = Self(1_000_275_003);
pub const SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT: Self = Self(1_000_275_004);
pub const RELEASE_SWAPCHAIN_IMAGES_INFO_EXT: Self = Self(1_000_275_005);
}
#[doc = "Generated from 'VK_EXT_swapchain_maintenance1'"]
impl SwapchainCreateFlagsKHR {
pub const DEFERRED_MEMORY_ALLOCATION_EXT: Self = Self(0b1000);
}
impl ExtShaderDemoteToHelperInvocationFn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
@ -22881,10 +22930,6 @@ impl SecExtension448Fn {
Self {}
}
}
#[doc = "Generated from 'VK_SEC_extension_448'"]
impl SwapchainCreateFlagsKHR {
pub const RESERVED_3_SEC: Self = Self(0b1000);
}
impl SecExtension449Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
@ -23945,18 +23990,20 @@ impl StructureType {
pub const RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT: Self = Self(1_000_458_002);
pub const RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT: Self = Self(1_000_458_003);
}
impl ExtExtension460Fn {
impl LunargDirectDriverLoadingFn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_extension_460\0") }
unsafe {
::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_LUNARG_direct_driver_loading\0")
}
}
pub const SPEC_VERSION: u32 = 0u32;
pub const SPEC_VERSION: u32 = 1u32;
}
#[derive(Clone)]
pub struct ExtExtension460Fn {}
unsafe impl Send for ExtExtension460Fn {}
unsafe impl Sync for ExtExtension460Fn {}
impl ExtExtension460Fn {
pub struct LunargDirectDriverLoadingFn {}
unsafe impl Send for LunargDirectDriverLoadingFn {}
unsafe impl Sync for LunargDirectDriverLoadingFn {}
impl LunargDirectDriverLoadingFn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
@ -23964,6 +24011,11 @@ impl ExtExtension460Fn {
Self {}
}
}
#[doc = "Generated from 'VK_LUNARG_direct_driver_loading'"]
impl StructureType {
pub const DIRECT_DRIVER_LOADING_INFO_LUNARG: Self = Self(1_000_459_000);
pub const DIRECT_DRIVER_LOADING_LIST_LUNARG: Self = Self(1_000_459_001);
}
impl ExtExtension461Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
@ -24882,18 +24934,22 @@ impl ExtExtension488Fn {
Self {}
}
}
impl QcomExtension489Fn {
impl QcomMultiviewPerViewViewportsFn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_QCOM_extension_489\0") }
unsafe {
::std::ffi::CStr::from_bytes_with_nul_unchecked(
b"VK_QCOM_multiview_per_view_viewports\0",
)
}
}
pub const SPEC_VERSION: u32 = 0u32;
pub const SPEC_VERSION: u32 = 1u32;
}
#[derive(Clone)]
pub struct QcomExtension489Fn {}
unsafe impl Send for QcomExtension489Fn {}
unsafe impl Sync for QcomExtension489Fn {}
impl QcomExtension489Fn {
pub struct QcomMultiviewPerViewViewportsFn {}
unsafe impl Send for QcomMultiviewPerViewViewportsFn {}
unsafe impl Sync for QcomMultiviewPerViewViewportsFn {}
impl QcomMultiviewPerViewViewportsFn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
@ -24901,6 +24957,11 @@ impl QcomExtension489Fn {
Self {}
}
}
#[doc = "Generated from 'VK_QCOM_multiview_per_view_viewports'"]
impl StructureType {
pub const PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM: Self =
Self(1_000_488_000);
}
impl NvExtension490Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
@ -25221,3 +25282,41 @@ impl NvExtension504Fn {
Self {}
}
}
impl ExtExtension505Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_extension_505\0") }
}
pub const SPEC_VERSION: u32 = 0u32;
}
#[derive(Clone)]
pub struct ExtExtension505Fn {}
unsafe impl Send for ExtExtension505Fn {}
unsafe impl Sync for ExtExtension505Fn {}
impl ExtExtension505Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
{
Self {}
}
}
impl NvExtension506Fn {
#[inline]
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_NV_extension_506\0") }
}
pub const SPEC_VERSION: u32 = 0u32;
}
#[derive(Clone)]
pub struct NvExtension506Fn {}
unsafe impl Send for NvExtension506Fn {}
unsafe impl Sync for NvExtension506Fn {}
impl NvExtension506Fn {
pub fn load<F>(mut _f: F) -> Self
where
F: FnMut(&::std::ffi::CStr) -> *const c_void,
{
Self {}
}
}

2
third_party/rust/naga/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -11,7 +11,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: "1.56.0"
toolchain: "1.63.0"
override: true
- uses: taiki-e/install-action@cargo-hack
- uses: taiki-e/install-action@cargo-minimal-versions

4
third_party/rust/naga/Cargo.toml поставляемый
Просмотреть файл

@ -10,7 +10,7 @@ keywords = ["shader", "SPIR-V", "GLSL", "MSL"]
license = "MIT OR Apache-2.0"
exclude = ["bin/**/*", "tests/**/*", "Cargo.lock", "target/**/*"]
resolver = "2"
rust-version = "1.56"
rust-version = "1.63"
[package.metadata.docs.rs]
all-features = true
@ -73,7 +73,7 @@ diff = "0.1"
ron = "~0.7.1"
serde = { version = "1.0", features = ["derive"] }
spirv = { version = "0.2", features = ["deserialize"] }
rspirv = "0.11"
rspirv = { version = "0.11", git = "https://github.com/gfx-rs/rspirv", rev = "b969f175d5663258b4891e44b76c1544da9661ab" }
env_logger = "0.9"
[workspace]

2
third_party/rust/naga/README.md поставляемый
Просмотреть файл

@ -4,7 +4,7 @@
[![Crates.io](https://img.shields.io/crates/v/naga.svg?label=naga)](https://crates.io/crates/naga)
[![Docs.rs](https://docs.rs/naga/badge.svg)](https://docs.rs/naga)
[![Build Status](https://github.com/gfx-rs/naga/workflows/pipeline/badge.svg)](https://github.com/gfx-rs/naga/actions)
![MSRV](https://img.shields.io/badge/rustc-1.56+-blue.svg)
![MSRV](https://img.shields.io/badge/rustc-1.63+-blue.svg)
[![codecov.io](https://codecov.io/gh/gfx-rs/naga/branch/master/graph/badge.svg?token=9VOKYO8BM2)](https://codecov.io/gh/gfx-rs/naga)
The shader translation library for the needs of [wgpu](https://github.com/gfx-rs/wgpu).

16
third_party/rust/naga/benches/criterion.rs поставляемый
Просмотреть файл

@ -10,7 +10,7 @@ fn gather_inputs(folder: &str, extension: &str) -> Vec<Box<[u8]>> {
for file_entry in read_dir {
match file_entry {
Ok(entry) => match entry.path().extension() {
Some(ostr) if &*ostr == extension => {
Some(ostr) if ostr == extension => {
let input = fs::read(entry.path()).unwrap_or_default();
list.push(input.into_boxed_slice());
}
@ -250,7 +250,9 @@ fn backends(c: &mut Criterion) {
entry_point: ep.name.clone(),
multiview: None,
};
match naga::back::glsl::Writer::new(
// might be `Err` if missing features
if let Ok(mut writer) = naga::back::glsl::Writer::new(
&mut string,
module,
info,
@ -258,13 +260,9 @@ fn backends(c: &mut Criterion) {
&pipeline_options,
naga::proc::BoundsCheckPolicies::default(),
) {
Ok(mut writer) => {
let _ = writer.write(); // can error if unsupported
}
Err(_) => {
// missing features
}
};
let _ = writer.write(); // might be `Err` if unsupported
}
string.clear();
}
}

95
third_party/rust/naga/src/arena.rs поставляемый
Просмотреть файл

@ -15,6 +15,15 @@ pub struct BadHandle {
pub index: usize,
}
impl BadHandle {
fn new<T>(handle: Handle<T>) -> Self {
Self {
kind: std::any::type_name::<T>(),
index: handle.index(),
}
}
}
/// A strongly typed reference to an arena item.
///
/// A `Handle` value can be used as an index into an [`Arena`] or [`UniqueArena`].
@ -123,6 +132,35 @@ pub struct Range<T> {
marker: PhantomData<T>,
}
impl<T> Range<T> {
pub(crate) const fn erase_type(self) -> Range<()> {
let Self { inner, marker: _ } = self;
Range {
inner,
marker: PhantomData,
}
}
}
// NOTE: Keep this diagnostic in sync with that of [`BadHandle`].
#[derive(Clone, Debug, thiserror::Error)]
#[error("Handle range {range:?} of {kind} is either not present, or inaccessible yet")]
pub struct BadRangeError {
// This error is used for many `Handle` types, but there's no point in making this generic, so
// we just flatten them all to `Handle<()>` here.
kind: &'static str,
range: Range<()>,
}
impl BadRangeError {
pub fn new<T>(range: Range<T>) -> Self {
Self {
kind: std::any::type_name::<T>(),
range: range.erase_type(),
}
}
}
impl<T> Clone for Range<T> {
fn clone(&self) -> Self {
Range {
@ -153,6 +191,15 @@ impl<T> Iterator for Range<T> {
}
}
impl<T> Range<T> {
pub fn new_from_bounds(first: Handle<T>, last: Handle<T>) -> Self {
Self {
inner: (first.index() as u32)..(last.index() as u32 + 1),
marker: Default::default(),
}
}
}
/// An arena holding some kind of component (e.g., type, constant,
/// instruction, etc.) that can be referenced.
///
@ -273,10 +320,9 @@ impl<T> Arena<T> {
}
pub fn try_get(&self, handle: Handle<T>) -> Result<&T, BadHandle> {
self.data.get(handle.index()).ok_or_else(|| BadHandle {
kind: std::any::type_name::<T>(),
index: handle.index(),
})
self.data
.get(handle.index())
.ok_or_else(|| BadHandle::new(handle))
}
/// Get a mutable reference to an element in the arena.
@ -311,6 +357,31 @@ impl<T> Arena<T> {
Span::default()
}
}
/// Assert that `handle` is valid for this arena.
pub fn check_contains_handle(&self, handle: Handle<T>) -> Result<(), BadHandle> {
if handle.index() < self.data.len() {
Ok(())
} else {
Err(BadHandle::new(handle))
}
}
/// Assert that `range` is valid for this arena.
pub fn check_contains_range(&self, range: &Range<T>) -> Result<(), BadRangeError> {
// Since `range.inner` is a `Range<u32>`, we only need to
// check that the start precedes the end, and that the end is
// in range.
if range.inner.start > range.inner.end
|| self
.check_contains_handle(Handle::new(range.inner.end.try_into().unwrap()))
.is_err()
{
Err(BadRangeError::new(range.clone()))
} else {
Ok(())
}
}
}
#[cfg(feature = "deserialize")]
@ -531,10 +602,18 @@ impl<T: Eq + hash::Hash> UniqueArena<T> {
/// Return this arena's value at `handle`, if that is a valid handle.
pub fn get_handle(&self, handle: Handle<T>) -> Result<&T, BadHandle> {
self.set.get_index(handle.index()).ok_or_else(|| BadHandle {
kind: std::any::type_name::<T>(),
index: handle.index(),
})
self.set
.get_index(handle.index())
.ok_or_else(|| BadHandle::new(handle))
}
/// Assert that `handle` is valid for this arena.
pub fn check_contains_handle(&self, handle: Handle<T>) -> Result<(), BadHandle> {
if handle.index() < self.set.len() {
Ok(())
} else {
Err(BadHandle::new(handle))
}
}
}

60
third_party/rust/naga/src/back/glsl/mod.rs поставляемый
Просмотреть файл

@ -1807,23 +1807,29 @@ impl<'a, W: Write> Writer<'a, W> {
for case in cases {
match case.value {
crate::SwitchValue::Integer(value) => {
writeln!(self.out, "{}case {}{}:", l2, value, type_postfix)?
write!(self.out, "{}case {}{}:", l2, value, type_postfix)?
}
crate::SwitchValue::Default => writeln!(self.out, "{}default:", l2)?,
crate::SwitchValue::Default => write!(self.out, "{}default:", l2)?,
}
let write_block_braces = !(case.fall_through && case.body.is_empty());
if write_block_braces {
writeln!(self.out, " {{")?;
} else {
writeln!(self.out)?;
}
for sta in case.body.iter() {
self.write_stmt(sta, ctx, l2.next())?;
}
// Write fallthrough comment if the case is fallthrough,
// otherwise write a break, if the case is not already
// broken out of at the end of its body.
if case.fall_through {
writeln!(self.out, "{}/* fallthrough */", l2.next())?;
} else if case.body.last().map_or(true, |s| !s.is_terminator()) {
if !case.fall_through && case.body.last().map_or(true, |s| !s.is_terminator()) {
writeln!(self.out, "{}break;", l2.next())?;
}
if write_block_braces {
writeln!(self.out, "{}}}", l2)?;
}
}
writeln!(self.out, "{}}}", level)?
@ -2519,7 +2525,7 @@ impl<'a, W: Write> Writer<'a, W> {
},
};
write!(self.out, "({}", operator)?;
write!(self.out, "{}(", operator)?;
}
}
@ -3138,12 +3144,32 @@ impl<'a, W: Write> Writer<'a, W> {
}
// Otherwise write just the expression (and the 1D hack if needed)
None => {
let uvec_size = match *ctx.info[coordinate].ty.inner_with(&self.module.types) {
TypeInner::Scalar {
kind: crate::ScalarKind::Uint,
..
} => Some(None),
TypeInner::Vector {
size,
kind: crate::ScalarKind::Uint,
..
} => Some(Some(size as u32)),
_ => None,
};
if tex_1d_hack {
write!(self.out, "ivec2(")?;
} else if uvec_size.is_some() {
match uvec_size {
Some(None) => write!(self.out, "int(")?,
Some(Some(size)) => write!(self.out, "ivec{}(", size)?,
_ => {}
}
}
self.write_expr(coordinate, ctx)?;
if tex_1d_hack {
write!(self.out, ", 0)")?;
} else if uvec_size.is_some() {
write!(self.out, ")")?;
}
}
}
@ -3608,13 +3634,6 @@ impl<'a, W: Write> Writer<'a, W> {
continue;
}
match self.module.types[var.ty].inner {
crate::TypeInner::Struct { .. } => match var.space {
crate::AddressSpace::Uniform | crate::AddressSpace::Storage { .. } => {
let name = self.reflection_names_globals[&handle].clone();
uniforms.insert(handle, name);
}
_ => (),
},
crate::TypeInner::Image { .. } => {
let tex_name = self.reflection_names_globals[&handle].clone();
match texture_mapping.entry(tex_name) {
@ -3629,7 +3648,13 @@ impl<'a, W: Write> Writer<'a, W> {
}
}
}
_ => {}
_ => match var.space {
crate::AddressSpace::Uniform | crate::AddressSpace::Storage { .. } => {
let name = self.reflection_names_globals[&handle].clone();
uniforms.insert(handle, name);
}
_ => (),
},
}
}
@ -3717,6 +3742,7 @@ const fn glsl_built_in(
Bi::VertexIndex => "uint(gl_VertexID)",
// fragment
Bi::FragDepth => "gl_FragDepth",
Bi::PointCoord => "gl_PointCoord",
Bi::FrontFacing => "gl_FrontFacing",
Bi::PrimitiveIndex => "uint(gl_PrimitiveID)",
Bi::SampleIndex => "gl_SampleID",

20
third_party/rust/naga/src/back/hlsl/conv.rs поставляемый
Просмотреть файл

@ -40,12 +40,12 @@ impl crate::TypeInner {
}
}
pub(super) fn try_size_hlsl(
pub(super) fn size_hlsl(
&self,
types: &crate::UniqueArena<crate::Type>,
constants: &crate::Arena<crate::Constant>,
) -> Result<u32, crate::arena::BadHandle> {
Ok(match *self {
) -> u32 {
match *self {
Self::Matrix {
columns,
rows,
@ -58,22 +58,20 @@ impl crate::TypeInner {
Self::Array { base, size, stride } => {
let count = match size {
crate::ArraySize::Constant(handle) => {
let constant = constants.try_get(handle)?;
constant.to_array_length().unwrap_or(1)
constants[handle].to_array_length().unwrap_or(1)
}
// A dynamically-sized array has to have at least one element
crate::ArraySize::Dynamic => 1,
};
let last_el_size = types[base].inner.try_size_hlsl(types, constants)?;
let last_el_size = types[base].inner.size_hlsl(types, constants);
((count - 1) * stride) + last_el_size
}
_ => self.try_size(constants)?,
})
_ => self.size(constants),
}
}
/// Used to generate the name of the wrapped type constructor
pub(super) fn hlsl_type_id<'a>(
&self,
base: crate::Handle<crate::Type>,
types: &crate::UniqueArena<crate::Type>,
constants: &crate::Arena<crate::Constant>,
@ -103,7 +101,7 @@ impl crate::TypeInner {
} => Cow::Owned(format!(
"array{}_{}_",
constants[size].to_array_length().unwrap(),
self.hlsl_type_id(base, types, constants, names)?
Self::hlsl_type_id(base, types, constants, names)?
)),
crate::TypeInner::Struct { .. } => {
Cow::Borrowed(&names[&crate::proc::NameKey::Type(base)])
@ -179,7 +177,7 @@ impl crate::BuiltIn {
Self::BaseInstance | Self::BaseVertex | Self::WorkGroupSize => {
return Err(Error::Unimplemented(format!("builtin {:?}", self)))
}
Self::ViewIndex => {
Self::ViewIndex | Self::PointCoord => {
return Err(Error::Custom(format!("Unsupported builtin {:?}", self)))
}
})

11
third_party/rust/naga/src/back/hlsl/help.rs поставляемый
Просмотреть файл

@ -274,7 +274,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
// Write function body
writeln!(self.out, "{{")?;
let array_coords = if wiq.arrayed { 1 } else { 0 };
let array_coords = usize::from(wiq.arrayed);
// extra parameter is the mip level count or the sample count
let extra_coords = match wiq.class {
crate::ImageClass::Storage { .. } => 0,
@ -358,7 +358,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
module: &crate::Module,
constructor: WrappedConstructor,
) -> BackendResult {
let name = module.types[constructor.ty].inner.hlsl_type_id(
let name = crate::TypeInner::hlsl_type_id(
constructor.ty,
&module.types,
&module.constants,
@ -927,7 +927,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
if let Some(crate::AddressSpace::Storage { .. }) = pointer_space {
if let Some(ty) = func_ctx.info[handle].ty.handle() {
write_wrapped_constructor(self, ty, module, func_ctx)?;
write_wrapped_constructor(self, ty, module)?;
}
}
@ -935,12 +935,11 @@ impl<'a, W: Write> super::Writer<'a, W> {
writer: &mut super::Writer<'_, W>,
ty: Handle<crate::Type>,
module: &crate::Module,
func_ctx: &FunctionCtx,
) -> BackendResult {
match module.types[ty].inner {
crate::TypeInner::Struct { ref members, .. } => {
for member in members {
write_wrapped_constructor(writer, member.ty, module, func_ctx)?;
write_wrapped_constructor(writer, member.ty, module)?;
}
let constructor = WrappedConstructor { ty };
@ -951,7 +950,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
}
}
crate::TypeInner::Array { base, .. } => {
write_wrapped_constructor(writer, base, module, func_ctx)?;
write_wrapped_constructor(writer, base, module)?;
}
_ => {}
};

55
third_party/rust/naga/src/back/hlsl/writer.rs поставляемый
Просмотреть файл

@ -829,10 +829,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
let ty_inner = &module.types[member.ty].inner;
last_offset = member.offset
+ ty_inner
.try_size_hlsl(&module.types, &module.constants)
.unwrap();
last_offset = member.offset + ty_inner.size_hlsl(&module.types, &module.constants);
// The indentation is only for readability
write!(self.out, "{}", back::INDENT)?;
@ -1825,18 +1822,47 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
for (i, case) in cases.iter().enumerate() {
match case.value {
crate::SwitchValue::Integer(value) => writeln!(
crate::SwitchValue::Integer(value) => write!(
self.out,
"{}case {}{}: {{",
"{}case {}{}:",
indent_level_1, value, type_postfix
)?,
crate::SwitchValue::Default => {
writeln!(self.out, "{}default: {{", indent_level_1)?
write!(self.out, "{}default:", indent_level_1)?
}
}
// FXC doesn't support fallthrough so we duplicate the body of the following case blocks
if case.fall_through {
// The new block is not only stylistic, it plays a role here:
// We might end up having to write the same case body
// multiple times due to FXC not supporting fallthrough.
// Therefore, some `Expression`s written by `Statement::Emit`
// will end up having the same name (`_expr<handle_index>`).
// So we need to put each case in its own scope.
let write_block_braces = !(case.fall_through && case.body.is_empty());
if write_block_braces {
writeln!(self.out, " {{")?;
} else {
writeln!(self.out)?;
}
// Although FXC does support a series of case clauses before
// a block[^yes], it does not support fallthrough from a
// non-empty case block to the next[^no]. If this case has a
// non-empty body with a fallthrough, emulate that by
// duplicating the bodies of all the cases it would fall
// into as extensions of this case's own body. This makes
// the HLSL output potentially quadratic in the size of the
// Naga IR.
//
// [^yes]: ```hlsl
// case 1:
// case 2: do_stuff()
// ```
// [^no]: ```hlsl
// case 1: do_this();
// case 2: do_that();
// ```
if case.fall_through && !case.body.is_empty() {
let curr_len = i + 1;
let end_case_idx = curr_len
+ cases
@ -1861,12 +1887,16 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
for sta in case.body.iter() {
self.write_stmt(module, sta, func_ctx, indent_level_2)?;
}
if case.body.last().map_or(true, |s| !s.is_terminator()) {
if !case.fall_through
&& case.body.last().map_or(true, |s| !s.is_terminator())
{
writeln!(self.out, "{}break;", indent_level_2)?;
}
}
writeln!(self.out, "{}}}", indent_level_1)?;
if write_block_braces {
writeln!(self.out, "{}}}", indent_level_1)?;
}
}
writeln!(self.out, "{}}}", level)?
@ -2395,8 +2425,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
},
};
write!(self.out, "{}", op_str)?;
write!(self.out, "{}(", op_str)?;
self.write_expr(module, expr, func_ctx)?;
write!(self.out, ")")?;
}
Expression::As {
expr,

7
third_party/rust/naga/src/back/msl/mod.rs поставляемый
Просмотреть файл

@ -156,8 +156,10 @@ pub enum Error {
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub enum EntryPointError {
#[error("global '{0}' doesn't have a binding")]
MissingBinding(String),
#[error("mapping of {0:?} is missing")]
MissingBinding(crate::ResourceBinding),
MissingBindTarget(crate::ResourceBinding),
#[error("mapping for push constants is missing")]
MissingPushConstants,
#[error("mapping for sizes buffer is missing")]
@ -303,7 +305,7 @@ impl Options {
index: 0,
interpolation: None,
}),
None => Err(EntryPointError::MissingBinding(res_binding.clone())),
None => Err(EntryPointError::MissingBindTarget(res_binding.clone())),
}
}
@ -391,6 +393,7 @@ impl ResolvedBinding {
Bi::VertexIndex => "vertex_id",
// fragment
Bi::FragDepth => "depth(any)",
Bi::PointCoord => "point_coord",
Bi::FrontFacing => "front_facing",
Bi::PrimitiveIndex => "primitive_id",
Bi::SampleIndex => "sample_id",

105
third_party/rust/naga/src/back/msl/writer.rs поставляемый
Просмотреть файл

@ -1442,7 +1442,7 @@ impl<W: Write> Writer<W> {
if offset.is_none() && !is_cube_map {
write!(self.out, ", {}::int2(0)", NAMESPACE)?;
}
let letter = ['x', 'y', 'z', 'w'][component as usize];
let letter = back::COMPONENTS[component as usize];
write!(self.out, ", {}::component::{}", NAMESPACE, letter)?;
}
}
@ -1500,8 +1500,9 @@ impl<W: Write> Writer<W> {
_ => return Err(Error::Validation),
},
};
write!(self.out, "{}", op_str)?;
write!(self.out, "{}(", op_str)?;
self.put_expression(expr, context, false)?;
write!(self.out, ")")?;
}
crate::Expression::Binary { op, left, right } => {
let op_str = crate::back::binary_operation_str(op);
@ -2545,19 +2546,30 @@ impl<W: Write> Writer<W> {
for case in cases.iter() {
match case.value {
crate::SwitchValue::Integer(value) => {
writeln!(self.out, "{}case {}{}: {{", lcase, value, type_postfix)?;
write!(self.out, "{}case {}{}:", lcase, value, type_postfix)?;
}
crate::SwitchValue::Default => {
writeln!(self.out, "{}default: {{", lcase)?;
write!(self.out, "{}default:", lcase)?;
}
}
let write_block_braces = !(case.fall_through && case.body.is_empty());
if write_block_braces {
writeln!(self.out, " {{")?;
} else {
writeln!(self.out)?;
}
self.put_block(lcase.next(), &case.body, context)?;
if !case.fall_through
&& case.body.last().map_or(true, |s| !s.is_terminator())
{
writeln!(self.out, "{}break;", lcase.next())?;
}
writeln!(self.out, "{}}}", lcase)?;
if write_block_braces {
writeln!(self.out, "{}}}", lcase)?;
}
}
writeln!(self.out, "{}}}", level)?;
}
@ -3387,33 +3399,52 @@ impl<W: Write> Writer<W> {
if fun_info[var_handle].is_empty() {
continue;
}
if let Some(ref br) = var.binding {
let good = match options.per_stage_map[ep.stage].resources.get(br) {
Some(target) => {
let binding_ty = match module.types[var.ty].inner {
crate::TypeInner::BindingArray { base, .. } => {
&module.types[base].inner
}
ref ty => ty,
};
match *binding_ty {
crate::TypeInner::Image { .. } => target.texture.is_some(),
crate::TypeInner::Sampler { .. } => target.sampler.is_some(),
_ => target.buffer.is_some(),
match var.space {
crate::AddressSpace::Uniform
| crate::AddressSpace::Storage { .. }
| crate::AddressSpace::Handle => {
let br = match var.binding {
Some(ref br) => br,
None => {
let var_name = var.name.clone().unwrap_or_default();
ep_error =
Some(super::EntryPointError::MissingBinding(var_name));
break;
}
};
let good = match options.per_stage_map[ep.stage].resources.get(br) {
Some(target) => {
let binding_ty = match module.types[var.ty].inner {
crate::TypeInner::BindingArray { base, .. } => {
&module.types[base].inner
}
ref ty => ty,
};
match *binding_ty {
crate::TypeInner::Image { .. } => target.texture.is_some(),
crate::TypeInner::Sampler { .. } => {
target.sampler.is_some()
}
_ => target.buffer.is_some(),
}
}
None => false,
};
if !good {
ep_error =
Some(super::EntryPointError::MissingBindTarget(br.clone()));
break;
}
None => false,
};
if !good {
ep_error = Some(super::EntryPointError::MissingBinding(br.clone()));
break;
}
}
if var.space == crate::AddressSpace::PushConstant {
if let Err(e) = options.resolve_push_constants(ep.stage) {
ep_error = Some(e);
break;
crate::AddressSpace::PushConstant => {
if let Err(e) = options.resolve_push_constants(ep.stage) {
ep_error = Some(e);
break;
}
}
crate::AddressSpace::Function
| crate::AddressSpace::Private
| crate::AddressSpace::WorkGroup => {}
}
}
if supports_array_length {
@ -3955,12 +3986,13 @@ fn test_stack_size() {
{
// check expression stack
let mut addresses = usize::MAX..0usize;
let mut addresses_start = usize::MAX;
let mut addresses_end = 0usize;
for pointer in writer.put_expression_stack_pointers {
addresses.start = addresses.start.min(pointer as usize);
addresses.end = addresses.end.max(pointer as usize);
addresses_start = addresses_start.min(pointer as usize);
addresses_end = addresses_end.max(pointer as usize);
}
let stack_size = addresses.end - addresses.start;
let stack_size = addresses_end - addresses_start;
// check the size (in debug only)
// last observed macOS value: 20528 (CI)
if !(11000..=25000).contains(&stack_size) {
@ -3970,12 +4002,13 @@ fn test_stack_size() {
{
// check block stack
let mut addresses = usize::MAX..0usize;
let mut addresses_start = usize::MAX;
let mut addresses_end = 0usize;
for pointer in writer.put_block_stack_pointers {
addresses.start = addresses.start.min(pointer as usize);
addresses.end = addresses.end.max(pointer as usize);
addresses_start = addresses_start.min(pointer as usize);
addresses_end = addresses_end.max(pointer as usize);
}
let stack_size = addresses.end - addresses.start;
let stack_size = addresses_end - addresses_start;
// check the size (in debug only)
// last observed macOS value: 19152 (CI)
if !(9500..=20000).contains(&stack_size) {

97
third_party/rust/naga/src/back/spv/block.rs поставляемый
Просмотреть файл

@ -1680,32 +1680,37 @@ impl<'w> BlockContext<'w> {
spirv::SelectionControl::NONE,
));
let default_id = self.gen_id();
let mut default_id = None;
// id of previous empty fall-through case
let mut last_id = None;
let mut reached_default = false;
let mut raw_cases = Vec::with_capacity(cases.len());
let mut case_ids = Vec::with_capacity(cases.len());
for case in cases.iter() {
// take id of previous empty fall-through case or generate a new one
let label_id = last_id.take().unwrap_or_else(|| self.gen_id());
if case.fall_through && case.body.is_empty() {
last_id = Some(label_id);
}
case_ids.push(label_id);
match case.value {
crate::SwitchValue::Integer(value) => {
let label_id = self.gen_id();
// No cases should be added after the default case is encountered
// since the default case catches all
if !reached_default {
raw_cases.push(super::instructions::Case {
value: value as Word,
label_id,
});
}
case_ids.push(label_id);
raw_cases.push(super::instructions::Case {
value: value as Word,
label_id,
});
}
crate::SwitchValue::Default => {
case_ids.push(default_id);
reached_default = true;
default_id = Some(label_id);
}
}
}
let default_id = default_id.unwrap();
self.function.consume(
block,
Instruction::switch(selector_id, default_id, &raw_cases),
@ -1716,7 +1721,12 @@ impl<'w> BlockContext<'w> {
..loop_context
};
for (i, (case, label_id)) in cases.iter().zip(case_ids.iter()).enumerate() {
for (i, (case, label_id)) in cases
.iter()
.zip(case_ids.iter())
.filter(|&(case, _)| !(case.fall_through && case.body.is_empty()))
.enumerate()
{
let case_finish_id = if case.fall_through {
case_ids[i + 1]
} else {
@ -1732,17 +1742,6 @@ impl<'w> BlockContext<'w> {
)?;
}
// If no default was encountered write a empty block to satisfy the presence of
// a block the default label
if !reached_default {
self.write_block(
default_id,
&[],
BlockExit::Branch { target: merge_id },
inner_context,
)?;
}
block = Block::new(merge_id);
}
crate::Statement::Loop {
@ -2079,8 +2078,50 @@ impl<'w> BlockContext<'w> {
value_id,
)
}
crate::AtomicFunction::Exchange { compare: Some(_) } => {
return Err(Error::FeatureNotImplemented("atomic CompareExchange"));
crate::AtomicFunction::Exchange { compare: Some(cmp) } => {
let scalar_type_id = match *value_inner {
crate::TypeInner::Scalar { kind, width } => {
self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind,
width,
pointer_space: None,
}))
}
_ => unimplemented!(),
};
let bool_type_id =
self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Bool,
width: crate::BOOL_WIDTH,
pointer_space: None,
}));
let cas_result_id = self.gen_id();
let equality_result_id = self.gen_id();
let mut cas_instr = Instruction::new(spirv::Op::AtomicCompareExchange);
cas_instr.set_type(scalar_type_id);
cas_instr.set_result(cas_result_id);
cas_instr.add_operand(pointer_id);
cas_instr.add_operand(scope_constant_id);
cas_instr.add_operand(semantics_id); // semantics if equal
cas_instr.add_operand(semantics_id); // semantics if not equal
cas_instr.add_operand(value_id);
cas_instr.add_operand(self.cached[cmp]);
block.body.push(cas_instr);
block.body.push(Instruction::binary(
spirv::Op::IEqual,
bool_type_id,
equality_result_id,
cas_result_id,
self.cached[cmp],
));
Instruction::composite_construct(
result_type_id,
id,
&[cas_result_id, equality_result_id],
)
}
};

18
third_party/rust/naga/src/back/spv/image.rs поставляемый
Просмотреть файл

@ -317,6 +317,22 @@ impl<'w> BlockContext<'w> {
let array_index_i32_id = self.cached[array_index];
let reconciled_array_index_id = if component_kind == crate::ScalarKind::Sint {
array_index_i32_id
} else if component_kind == crate::ScalarKind::Uint {
let u32_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Uint,
width: 4,
pointer_space: None,
}));
let reconciled_id = self.gen_id();
block.body.push(Instruction::unary(
spirv::Op::Bitcast,
u32_id,
reconciled_id,
array_index_i32_id,
));
reconciled_id
} else {
let component_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
@ -1017,7 +1033,7 @@ impl<'w> BlockContext<'w> {
Id::D3 => 3,
};
let extended_size_type_id = {
let array_coords = if arrayed { 1 } else { 0 };
let array_coords = usize::from(arrayed);
let vector_size = match dim_coords + array_coords {
2 => Some(crate::VectorSize::Bi),
3 => Some(crate::VectorSize::Tri),

Просмотреть файл

@ -1231,6 +1231,7 @@ impl Writer {
Bi::VertexIndex => BuiltIn::VertexIndex,
// fragment
Bi::FragDepth => BuiltIn::FragDepth,
Bi::PointCoord => BuiltIn::PointCoord,
Bi::FrontFacing => BuiltIn::FrontFacing,
Bi::PrimitiveIndex => {
self.require_any(

115
third_party/rust/naga/src/back/wgsl/writer.rs поставляемый
Просмотреть файл

@ -452,11 +452,11 @@ impl<W: Write> Writer<W> {
/// Adds no trailing or leading whitespace
fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
match *inner {
TypeInner::Vector { size, kind, .. } => write!(
TypeInner::Vector { size, kind, width } => write!(
self.out,
"vec{}<{}>",
back::vector_size_str(size),
scalar_kind_str(kind),
scalar_kind_str(kind, width),
)?,
TypeInner::Sampler { comparison: false } => {
write!(self.out, "sampler")?;
@ -478,7 +478,7 @@ impl<W: Write> Writer<W> {
Ic::Sampled { kind, multi } => (
"",
if multi { "multisampled_" } else { "" },
scalar_kind_str(kind),
scalar_kind_str(kind, 4),
"",
),
Ic::Depth { multi } => {
@ -508,11 +508,11 @@ impl<W: Write> Writer<W> {
write!(self.out, "<{}{}>", format_str, storage_str)?;
}
}
TypeInner::Scalar { kind, .. } => {
write!(self.out, "{}", scalar_kind_str(kind))?;
TypeInner::Scalar { kind, width } => {
write!(self.out, "{}", scalar_kind_str(kind, width))?;
}
TypeInner::Atomic { kind, .. } => {
write!(self.out, "atomic<{}>", scalar_kind_str(kind))?;
TypeInner::Atomic { kind, width } => {
write!(self.out, "atomic<{}>", scalar_kind_str(kind, width))?;
}
TypeInner::Array {
base,
@ -582,12 +582,12 @@ impl<W: Write> Writer<W> {
TypeInner::ValuePointer {
size: None,
kind,
width: _,
width,
space,
} => {
let (address, maybe_access) = address_space_str(space);
if let Some(space) = address {
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(kind))?;
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(kind, width))?;
if let Some(access) = maybe_access {
write!(self.out, ", {}", access)?;
}
@ -602,7 +602,7 @@ impl<W: Write> Writer<W> {
TypeInner::ValuePointer {
size: Some(size),
kind,
width: _,
width,
space,
} => {
let (address, maybe_access) = address_space_str(space);
@ -612,7 +612,7 @@ impl<W: Write> Writer<W> {
"ptr<{}, vec{}<{}>",
space,
back::vector_size_str(size),
scalar_kind_str(kind)
scalar_kind_str(kind, width)
)?;
if let Some(access) = maybe_access {
write!(self.out, ", {}", access)?;
@ -880,25 +880,47 @@ impl<W: Write> Writer<W> {
};
let l2 = level.next();
if !cases.is_empty() {
for case in cases {
match case.value {
crate::SwitchValue::Integer(value) => {
writeln!(self.out, "{}case {}{}: {{", l2, value, type_postfix)?;
let mut new_case = true;
for case in cases {
if case.fall_through && !case.body.is_empty() {
// TODO: we could do the same workaround as we did for the HLSL backend
return Err(Error::Unimplemented(
"fall-through switch case block".into(),
));
}
match case.value {
crate::SwitchValue::Integer(value) => {
if new_case {
write!(self.out, "{}case ", l2)?;
}
crate::SwitchValue::Default => {
writeln!(self.out, "{}default: {{", l2)?;
write!(self.out, "{}{}", value, type_postfix)?;
}
crate::SwitchValue::Default => {
if new_case {
if case.fall_through {
write!(self.out, "{}case ", l2)?;
} else {
write!(self.out, "{}", l2)?;
}
}
write!(self.out, "default")?;
}
}
for sta in case.body.iter() {
self.write_stmt(module, sta, func_ctx, l2.next())?;
}
new_case = !case.fall_through;
if case.fall_through {
writeln!(self.out, "{}fallthrough;", l2.next())?;
}
if case.fall_through {
write!(self.out, ", ")?;
} else {
writeln!(self.out, ": {{")?;
}
for sta in case.body.iter() {
self.write_stmt(module, sta, func_ctx, l2.next())?;
}
if !case.fall_through {
writeln!(self.out, "{}}}", l2)?;
}
}
@ -1402,17 +1424,24 @@ impl<W: Write> Writer<W> {
} => {
let inner = func_ctx.info[expr].ty.inner_with(&module.types);
match *inner {
TypeInner::Matrix { columns, rows, .. } => {
TypeInner::Matrix {
columns,
rows,
width,
..
} => {
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
write!(
self.out,
"mat{}x{}<f32>",
"mat{}x{}<{}>",
back::vector_size_str(columns),
back::vector_size_str(rows)
back::vector_size_str(rows),
scalar_kind_str
)?;
}
TypeInner::Vector { size, .. } => {
TypeInner::Vector { size, width, .. } => {
let vector_size_str = back::vector_size_str(size);
let scalar_kind_str = scalar_kind_str(kind);
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
if convert.is_some() {
write!(self.out, "vec{}<{}>", vector_size_str, scalar_kind_str)?;
} else {
@ -1423,11 +1452,12 @@ impl<W: Write> Writer<W> {
)?;
}
}
TypeInner::Scalar { .. } => {
TypeInner::Scalar { width, .. } => {
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
if convert.is_some() {
write!(self.out, "{}", scalar_kind_str(kind))?
write!(self.out, "{}", scalar_kind_str)?
} else {
write!(self.out, "bitcast<{}>", scalar_kind_str(kind))?
write!(self.out, "bitcast<{}>", scalar_kind_str)?
}
}
_ => {
@ -1443,8 +1473,8 @@ impl<W: Write> Writer<W> {
}
Expression::Splat { size, value } => {
let inner = func_ctx.info[value].ty.inner_with(&module.types);
let scalar_kind = match *inner {
crate::TypeInner::Scalar { kind, .. } => kind,
let (scalar_kind, scalar_width) = match *inner {
crate::TypeInner::Scalar { kind, width } => (kind, width),
_ => {
return Err(Error::Unimplemented(format!(
"write_expr expression::splat {:?}",
@ -1452,7 +1482,7 @@ impl<W: Write> Writer<W> {
)));
}
};
let scalar = scalar_kind_str(scalar_kind);
let scalar = scalar_kind_str(scalar_kind, scalar_width);
let size = back::vector_size_str(size);
write!(self.out, "vec{}<{}>(", size, scalar)?;
@ -1888,7 +1918,6 @@ const fn builtin_str(built_in: crate::BuiltIn) -> Option<&'static str> {
Bi::LocalInvocationIndex => Some("local_invocation_index"),
Bi::GlobalInvocationId => Some("global_invocation_id"),
Bi::WorkGroupId => Some("workgroup_id"),
Bi::WorkGroupSize => Some("workgroup_size"),
Bi::NumWorkGroups => Some("num_workgroups"),
Bi::SampleIndex => Some("sample_index"),
Bi::SampleMask => Some("sample_mask"),
@ -1909,14 +1938,16 @@ const fn image_dimension_str(dim: crate::ImageDimension) -> &'static str {
}
}
const fn scalar_kind_str(kind: crate::ScalarKind) -> &'static str {
const fn scalar_kind_str(kind: crate::ScalarKind, width: u8) -> &'static str {
use crate::ScalarKind as Sk;
match kind {
Sk::Float => "f32",
Sk::Sint => "i32",
Sk::Uint => "u32",
Sk::Bool => "bool",
match (kind, width) {
(Sk::Float, 8) => "f64",
(Sk::Float, 4) => "f32",
(Sk::Sint, 4) => "i32",
(Sk::Uint, 4) => "u32",
(Sk::Bool, 1) => "bool",
_ => unreachable!(),
}
}

Просмотреть файл

@ -224,12 +224,12 @@ impl<'a> ConstantSolver<'a> {
ScalarValue::Sint(a),
ScalarValue::Sint(b),
ScalarValue::Sint(c),
) => ScalarValue::Sint(a.max(b).min(c)),
) => ScalarValue::Sint(a.clamp(b, c)),
(
ScalarValue::Uint(a),
ScalarValue::Uint(b),
ScalarValue::Uint(c),
) => ScalarValue::Uint(a.max(b).min(c)),
) => ScalarValue::Uint(a.clamp(b, c)),
(
ScalarValue::Float(a),
ScalarValue::Float(b),
@ -739,8 +739,11 @@ mod tests {
let res3_inner = &constants[res3].inner;
match res3_inner {
ConstantInner::Composite { ty, components } => {
match *res3_inner {
ConstantInner::Composite {
ref ty,
ref components,
} => {
assert_eq!(*ty, vec_ty);
let mut components_iter = components.iter().copied();
assert_eq!(
@ -933,8 +936,11 @@ mod tests {
let res1_inner = &constants[res1].inner;
match res1_inner {
ConstantInner::Composite { ty, components } => {
match *res1_inner {
ConstantInner::Composite {
ref ty,
ref components,
} => {
assert_eq!(*ty, vec_ty);
let mut components_iter = components.iter().copied();
assert_eq!(

Просмотреть файл

@ -34,7 +34,10 @@ impl ExprPos {
/// Returns an lhs position if the current position is lhs otherwise AccessBase
const fn maybe_access_base(&self, constant_index: bool) -> Self {
match *self {
ExprPos::Lhs => *self,
ExprPos::Lhs
| ExprPos::AccessBase {
constant_index: false,
} => *self,
_ => ExprPos::AccessBase { constant_index },
}
}
@ -476,7 +479,7 @@ impl Context {
) -> Result<(Option<Handle<Expression>>, Span)> {
let HirExpr { ref kind, meta } = stmt.hir_exprs[expr];
log::debug!("Lowering {:?}", expr);
log::debug!("Lowering {:?} (kind {:?}, pos {:?})", expr, kind, pos);
let handle = match *kind {
HirExprKind::Access { base, index } => {
@ -537,9 +540,7 @@ impl Context {
pointer
}
HirExprKind::Select { base, ref field } => {
let base = self
.lower_expect_inner(stmt, parser, base, pos.maybe_access_base(true), body)?
.0;
let base = self.lower_expect_inner(stmt, parser, base, pos, body)?.0;
parser.field_selection(self, pos, body, base, field, meta)?
}

2
third_party/rust/naga/src/front/glsl/mod.rs поставляемый
Просмотреть файл

@ -105,7 +105,7 @@ impl ShaderMetadata {
self.version = 0;
self.profile = Profile::Core;
self.stage = stage;
self.workgroup_size = [if stage == ShaderStage::Compute { 1 } else { 0 }; 3];
self.workgroup_size = [u32::from(stage == ShaderStage::Compute); 3];
self.early_fragment_tests = false;
self.extensions.clear();
}

Просмотреть файл

@ -128,6 +128,16 @@ impl Parser {
mutable: false,
storage: StorageQualifier::Input,
},
"gl_PointCoord" => BuiltInData {
inner: TypeInner::Vector {
size: VectorSize::Bi,
kind: ScalarKind::Float,
width: 4,
},
builtin: BuiltIn::PointCoord,
mutable: false,
storage: StorageQualifier::Input,
},
"gl_GlobalInvocationID"
| "gl_NumWorkGroups"
| "gl_WorkGroupSize"

Просмотреть файл

@ -137,6 +137,7 @@ pub(super) fn map_builtin(word: spirv::Word, invariant: bool) -> Result<crate::B
Some(Bi::VertexIndex) => crate::BuiltIn::VertexIndex,
// fragment
Some(Bi::FragDepth) => crate::BuiltIn::FragDepth,
Some(Bi::PointCoord) => crate::BuiltIn::PointCoord,
Some(Bi::FrontFacing) => crate::BuiltIn::FrontFacing,
Some(Bi::PrimitiveId) => crate::BuiltIn::PrimitiveIndex,
Some(Bi::SampleId) => crate::BuiltIn::SampleIndex,

Просмотреть файл

@ -32,7 +32,6 @@ pub fn map_built_in(word: &str, span: Span) -> Result<crate::BuiltIn, Error<'_>>
"local_invocation_id" => crate::BuiltIn::LocalInvocationId,
"local_invocation_index" => crate::BuiltIn::LocalInvocationIndex,
"workgroup_id" => crate::BuiltIn::WorkGroupId,
"workgroup_size" => crate::BuiltIn::WorkGroupSize,
"num_workgroups" => crate::BuiltIn::NumWorkGroups,
_ => return Err(Error::UnknownBuiltin(span)),
})
@ -97,17 +96,11 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<crate::StorageFormat
pub fn get_scalar_type(word: &str) -> Option<(crate::ScalarKind, crate::Bytes)> {
match word {
"f16" => Some((crate::ScalarKind::Float, 2)),
// "f16" => Some((crate::ScalarKind::Float, 2)),
"f32" => Some((crate::ScalarKind::Float, 4)),
"f64" => Some((crate::ScalarKind::Float, 8)),
"i8" => Some((crate::ScalarKind::Sint, 1)),
"i16" => Some((crate::ScalarKind::Sint, 2)),
"i32" => Some((crate::ScalarKind::Sint, 4)),
"i64" => Some((crate::ScalarKind::Sint, 8)),
"u8" => Some((crate::ScalarKind::Uint, 1)),
"u16" => Some((crate::ScalarKind::Uint, 2)),
"u32" => Some((crate::ScalarKind::Uint, 4)),
"u64" => Some((crate::ScalarKind::Uint, 8)),
"bool" => Some((crate::ScalarKind::Bool, crate::BOOL_WIDTH)),
_ => None,
}

172
third_party/rust/naga/src/front/wgsl/mod.rs поставляемый
Просмотреть файл

@ -279,10 +279,7 @@ impl<'a> Error<'a> {
Error::UnknownScalarType(ref bad_span) => ParseError {
message: format!("unknown scalar type: '{}'", &source[bad_span.clone()]),
labels: vec![(bad_span.clone(), "unknown scalar type".into())],
notes: vec!["Valid scalar types are f16, f32, f64, \
i8, i16, i32, i64, \
u8, u16, u32, u64, bool"
.into()],
notes: vec!["Valid scalar types are f32, f64, i32, u32, bool".into()],
},
Error::BadTextureSampleType {
ref span,
@ -1513,13 +1510,20 @@ impl Parser {
lexer.span_from(initial)
}
fn parse_switch_value<'a>(lexer: &mut Lexer<'a>, uint: bool) -> Result<i32, Error<'a>> {
let token_span = lexer.next();
match token_span.0 {
Token::Number(Ok(Number::U32(num))) if uint => Ok(num as i32),
Token::Number(Ok(Number::I32(num))) if !uint => Ok(num),
Token::Number(Err(e)) => Err(Error::BadNumber(token_span.1, e)),
_ => Err(Error::Unexpected(token_span.1, ExpectedToken::Integer)),
fn parse_switch_value<'a>(
lexer: &mut Lexer<'a>,
uint: bool,
) -> Result<crate::SwitchValue, Error<'a>> {
match lexer.next() {
(Token::Word("default"), _) => Ok(crate::SwitchValue::Default),
(Token::Number(Ok(Number::U32(num))), _) if uint => {
Ok(crate::SwitchValue::Integer(num as i32))
}
(Token::Number(Ok(Number::I32(num))), _) if !uint => {
Ok(crate::SwitchValue::Integer(num))
}
(Token::Number(Err(e)), span) => Err(Error::BadNumber(span, e)),
(_, span) => Err(Error::Unexpected(span, ExpectedToken::Integer)),
}
}
@ -1626,8 +1630,13 @@ impl Parser {
let expression = match *ctx.resolve_type(value)? {
crate::TypeInner::Scalar { kind, width } => crate::Expression::AtomicResult {
kind,
width,
ty: ctx.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar { kind, width },
},
NagaSpan::UNDEFINED,
),
comparison: false,
},
_ => return Err(Error::InvalidAtomicOperandType(value_span)),
@ -1857,9 +1866,48 @@ impl Parser {
let expression = match *ctx.resolve_type(value)? {
crate::TypeInner::Scalar { kind, width } => {
let bool_ty = ctx.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar {
kind: crate::ScalarKind::Bool,
width: crate::BOOL_WIDTH,
},
},
NagaSpan::UNDEFINED,
);
let scalar_ty = ctx.types.insert(
crate::Type {
name: None,
inner: crate::TypeInner::Scalar { kind, width },
},
NagaSpan::UNDEFINED,
);
let struct_ty = ctx.types.insert(
crate::Type {
name: Some("__atomic_compare_exchange_result".to_string()),
inner: crate::TypeInner::Struct {
members: vec![
crate::StructMember {
name: Some("old_value".to_string()),
ty: scalar_ty,
binding: None,
offset: 0,
},
crate::StructMember {
name: Some("exchanged".to_string()),
ty: bool_ty,
binding: None,
offset: 4,
},
],
span: 8,
},
},
NagaSpan::UNDEFINED,
);
crate::Expression::AtomicResult {
kind,
width,
ty: struct_ty,
comparison: true,
}
}
@ -3576,34 +3624,6 @@ impl Parser {
Ok(())
}
fn parse_switch_case_body<'a, 'out>(
&mut self,
lexer: &mut Lexer<'a>,
mut context: StatementContext<'a, '_, 'out>,
) -> Result<(bool, crate::Block), Error<'a>> {
let mut body = crate::Block::new();
// Push a new lexical scope for the switch case body
context.symbol_table.push_scope();
lexer.expect(Token::Paren('{'))?;
let fall_through = loop {
// default statements
if lexer.skip(Token::Word("fallthrough")) {
lexer.expect(Token::Separator(';'))?;
lexer.expect(Token::Paren('}'))?;
break true;
}
if lexer.skip(Token::Paren('}')) {
break false;
}
self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
};
// Pop the switch case body lexical scope
context.symbol_table.pop_scope();
Ok((fall_through, body))
}
fn parse_statement<'a, 'out>(
&mut self,
lexer: &mut Lexer<'a>,
@ -3619,26 +3639,9 @@ impl Parser {
return Ok(());
}
(Token::Paren('{'), _) => {
self.push_rule_span(Rule::Block, lexer);
// Push a new lexical scope for the block statement
context.symbol_table.push_scope();
let _ = lexer.next();
let mut statements = crate::Block::new();
while !lexer.skip(Token::Paren('}')) {
self.parse_statement(
lexer,
context.reborrow(),
&mut statements,
is_uniform_control_flow,
)?;
}
// Pop the block statement lexical scope
context.symbol_table.pop_scope();
self.pop_rule_span(lexer);
let span = NagaSpan::from(self.pop_rule_span(lexer));
block.push(crate::Statement::Block(statements), span);
let body = self.parse_block(lexer, context, is_uniform_control_flow)?;
let span = self.pop_rule_span(lexer);
block.push(crate::Statement::Block(body), NagaSpan::from(span));
return Ok(());
}
(Token::Word(word), _) => {
@ -3945,37 +3948,34 @@ impl Parser {
break value;
}
cases.push(crate::SwitchCase {
value: crate::SwitchValue::Integer(value),
value,
body: crate::Block::new(),
fall_through: true,
});
};
let (fall_through, body) =
self.parse_switch_case_body(lexer, context.reborrow())?;
let body =
self.parse_block(lexer, context.reborrow(), false)?;
cases.push(crate::SwitchCase {
value: crate::SwitchValue::Integer(value),
value,
body,
fall_through,
fall_through: false,
});
}
(Token::Word("default"), _) => {
lexer.skip(Token::Separator(':'));
let (fall_through, body) =
self.parse_switch_case_body(lexer, context.reborrow())?;
let body =
self.parse_block(lexer, context.reborrow(), false)?;
cases.push(crate::SwitchCase {
value: crate::SwitchValue::Default,
body,
fall_through,
fall_through: false,
});
}
(Token::Paren('}'), _) => break,
other => {
return Err(Error::Unexpected(
other.1,
ExpectedToken::SwitchItem,
))
(_, span) => {
return Err(Error::Unexpected(span, ExpectedToken::SwitchItem))
}
}
}
@ -3993,7 +3993,6 @@ impl Parser {
lexer,
context.as_expression(&mut body, &mut emitter),
)?;
lexer.expect(Token::Paren('{'))?;
body.extend(emitter.finish(context.expressions));
Ok(condition)
})?;
@ -4007,14 +4006,8 @@ impl Parser {
},
NagaSpan::from(span),
);
// Push a lexical scope for the while loop body
context.symbol_table.push_scope();
while !lexer.skip(Token::Paren('}')) {
self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
}
// Pop the while loop body lexical scope
context.symbol_table.pop_scope();
body.extend_block(self.parse_block(lexer, context.reborrow(), false)?);
Some(crate::Statement::Loop {
body,
@ -4093,11 +4086,9 @@ impl Parser {
}
lexer.expect(Token::Paren(')'))?;
}
lexer.expect(Token::Paren('{'))?;
while !lexer.skip(Token::Paren('}')) {
self.parse_statement(lexer, context.reborrow(), &mut body, false)?;
}
body.extend_block(self.parse_block(lexer, context.reborrow(), false)?);
// Pop the for loop lexical scope
context.symbol_table.pop_scope();
@ -4306,6 +4297,7 @@ impl Parser {
})
}
/// compound_statement
fn parse_block<'a>(
&mut self,
lexer: &mut Lexer<'a>,
@ -4326,7 +4318,7 @@ impl Parser {
is_uniform_control_flow,
)?;
}
//Pop the block lexical scope
// Pop the block lexical scope
context.symbol_table.pop_scope();
self.pop_rule_span(lexer);

Просмотреть файл

@ -397,13 +397,13 @@ fn parse_dec_float(input: &str, kind: Option<FloatKind>) -> Result<Number, Numbe
None => {
let num = input.parse::<f64>().unwrap(); // will never fail
num.is_finite()
.then(|| Number::AbstractFloat(num))
.then_some(Number::AbstractFloat(num))
.ok_or(NumberError::NotRepresentable)
}
Some(FloatKind::F32) => {
let num = input.parse::<f32>().unwrap(); // will never fail
num.is_finite()
.then(|| Number::F32(num))
.then_some(Number::F32(num))
.ok_or(NumberError::NotRepresentable)
}
Some(FloatKind::F16) => Err(NumberError::UnimplementedF16),

23
third_party/rust/naga/src/front/wgsl/tests.rs поставляемый
Просмотреть файл

@ -249,8 +249,7 @@ fn parse_switch() {
var pos: f32;
switch (3) {
case 0, 1: { pos = 0.0; }
case 2: { pos = 1.0; fallthrough; }
case 3: {}
case 2: { pos = 1.0; }
default: { pos = 3.0; }
}
}
@ -267,8 +266,7 @@ fn parse_switch_optional_colon_in_case() {
var pos: f32;
switch (3) {
case 0, 1 { pos = 0.0; }
case 2 { pos = 1.0; fallthrough; }
case 3 {}
case 2 { pos = 1.0; }
default { pos = 3.0; }
}
}
@ -277,6 +275,23 @@ fn parse_switch_optional_colon_in_case() {
.unwrap();
}
#[test]
fn parse_switch_default_in_case() {
parse_str(
"
fn main() {
var pos: f32;
switch (3) {
case 0, 1: { pos = 0.0; }
case 2: {}
case default, 3: { pos = 3.0; }
}
}
",
)
.unwrap();
}
#[test]
fn parse_parentheses_switch() {
parse_str(

212
third_party/rust/naga/src/keywords/wgsl.rs поставляемый
Просмотреть файл

@ -5,8 +5,9 @@ Keywords for [WGSL][wgsl] (WebGPU Shading Language).
*/
// https://gpuweb.github.io/gpuweb/wgsl/#keyword-summary
// last sync: https://github.com/gpuweb/gpuweb/blob/39f2321f547c8f0b7f473cf1d47fba30b1691303/wgsl/index.bs
pub const RESERVED: &[&str] = &[
// type-defining
// Type-defining Keywords
"array",
"atomic",
"bool",
@ -22,11 +23,9 @@ pub const RESERVED: &[&str] = &[
"mat4x2",
"mat4x3",
"mat4x4",
"override",
"ptr",
"sampler",
"sampler_comparison",
"struct",
"texture_1d",
"texture_2d",
"texture_2d_array",
@ -47,7 +46,7 @@ pub const RESERVED: &[&str] = &[
"vec2",
"vec3",
"vec4",
// other
// Other Keywords
"bitcast",
"break",
"case",
@ -58,68 +57,29 @@ pub const RESERVED: &[&str] = &[
"discard",
"else",
"enable",
"fallthrough",
"false",
"fn",
"for",
"function",
"if",
"let",
"loop",
"private",
"override",
"return",
"storage",
"static_assert",
"struct",
"switch",
"true",
"type",
"uniform",
"var",
"while",
"workgroup",
// reserved
"AppendStructuredBuffer",
"BlendState",
"Buffer",
"ByteAddressBuffer",
// Reserved Words
"CompileShader",
"ComputeShader",
"ConsumeStructuredBuffer",
"DepthStencilState",
"DepthStencilView",
"DomainShader",
"GeometryShader",
"Hullshader",
"InputPatch",
"LineStream",
"NULL",
"OutputPatch",
"PixelShader",
"PointStream",
"RWBuffer",
"RWByteAddressBuffer",
"RWStructuredBuffer",
"RWTexture1D",
"RWTexture1DArray",
"RWTexture2D",
"RWTexture2DArray",
"RWTexture3D",
"RasterizerState",
"RenderTargetView",
"SamplerComparisonState",
"SamplerState",
"Self",
"StructuredBuffer",
"Texture1D",
"Texture1DArray",
"Texture2D",
"Texture2DArray",
"Texture2DMS",
"Texture2DMSArray",
"Texture3D",
"TextureCube",
"TextureCubeArray",
"TriangleStream",
"VertexShader",
"abstract",
"active",
"alignas",
@ -128,17 +88,13 @@ pub const RESERVED: &[&str] = &[
"asm",
"asm_fragment",
"async",
"atomic_uint",
"attribute",
"auto",
"await",
"become",
"bf16",
"binding_array",
"cast",
"catch",
"cbuffer",
"char",
"class",
"co_await",
"co_return",
@ -160,7 +116,6 @@ pub const RESERVED: &[&str] = &[
"demote",
"demote_to_helper",
"do",
"dword",
"dynamic_cast",
"enum",
"explicit",
@ -168,50 +123,18 @@ pub const RESERVED: &[&str] = &[
"extends",
"extern",
"external",
"f64",
"fallthrough",
"filter",
"final",
"finally",
"fixed",
"friend",
"from",
"fvec2",
"fvec3",
"fvec4",
"fxgroup",
"get",
"goto",
"groupshared",
"handle",
"highp",
"hvec2",
"hvec3",
"hvec4",
"i16",
"i64",
"i8",
"iimage1D",
"iimage1DArray",
"iimage2D",
"iimage2DArray",
"iimage2DMS",
"iimage2DMSArray",
"iimage2DRect",
"iimage3D",
"iimageBuffer",
"iimageCube",
"iimageCubeArray",
"image1D",
"image1DArray",
"image2D",
"image2DArray",
"image2DMS",
"image2DMSArray",
"image2DRect",
"image3D",
"imageBuffer",
"imageCube",
"imageCubeArray",
"impl",
"implements",
"import",
@ -219,40 +142,11 @@ pub const RESERVED: &[&str] = &[
"inout",
"instanceof",
"interface",
"invariant",
"isampler1D",
"isampler1DArray",
"isampler2D",
"isampler2DArray",
"isampler2DMS",
"isampler2DMSArray",
"isampler2DRect",
"isampler3D",
"isamplerBuffer",
"isamplerCube",
"isamplerCubeArray",
"isubpassInput",
"isubpassInputMS",
"itexture1D",
"itexture1DArray",
"itexture2D",
"itexture2DArray",
"itexture2DMS",
"itexture2DMSArray",
"itexture2DRect",
"itexture3D",
"itextureBuffer",
"itextureCube",
"itextureCubeArray",
"layout",
"line",
"lineadj",
"lowp",
"macro",
"macro_rules",
"mat",
"match",
"matrix",
"mediump",
"meta",
"mod",
@ -277,7 +171,6 @@ pub const RESERVED: &[&str] = &[
"pass",
"patch",
"pixelfragment",
"point",
"precise",
"precision",
"premerge",
@ -293,28 +186,6 @@ pub const RESERVED: &[&str] = &[
"requires",
"resource",
"restrict",
"row_major",
"samper",
"sampler1D",
"sampler1DArray",
"sampler1DArrayShadow",
"sampler1DShadow",
"sampler2D",
"sampler2DArray",
"sampler2DArrayShadow",
"sampler2DMS",
"sampler2DMSArray",
"sampler2DRect",
"sampler2DRectShadow",
"sampler2DShadow",
"sampler3D",
"sampler3DRect",
"samplerBuffer",
"samplerCube",
"samplerCubeArray",
"samplerCubeArrayShadow",
"samplerCubeShadow",
"samplerShadow",
"self",
"set",
"shared",
@ -322,100 +193,33 @@ pub const RESERVED: &[&str] = &[
"sizeof",
"smooth",
"snorm",
"stateblock",
"stateblock_state",
"static",
"static_assert",
"static_cast",
"std",
"string",
"subpassInput",
"subpassInputMS",
"subroutine",
"super",
"superp",
"target",
"tbuffer",
"technique",
"technique10",
"technique11",
"template",
"texture1D",
"texture1DArray",
"texture2D",
"texture2DArray",
"texture2DMS",
"texture2DMSArray",
"texture2DRect",
"texture3D",
"textureBuffer",
"textureCube",
"textureCubeArray",
"this",
"thread_local",
"throw",
"trait",
"triangle",
"triangleadj",
"try",
"typedef",
"typeid",
"typename",
"typeof",
"u16",
"u64",
"u8",
"uimage1D",
"uimage1DArray",
"uimage2D",
"uimage2DArray",
"uimage2DMS",
"uimage2DMSArray",
"uimage2DRect",
"uimage3D",
"uimageBuffer",
"uimageCube",
"uimageCubeArray",
"union",
"unless",
"unorm",
"unsafe",
"unsigned",
"unsized",
"usampler1D",
"usampler1DArray",
"usampler2D",
"usampler2DArray",
"usampler2DMS",
"usampler2DMSArray",
"usampler2DRect",
"usampler3D",
"usamplerBuffer",
"usamplerCube",
"usamplerCubeArray",
"use",
"using",
"usubpassInput",
"usubpassInputMS",
"utexture1D",
"utexture1DArray",
"utexture2D",
"utexture2DArray",
"utexture2DMS",
"utexture2DMSArray",
"utexture2DRect",
"utexture3D",
"utextureBuffer",
"utextureCube",
"utextureCubeArray",
"varying",
"vec",
"vector",
"vertexfragment",
"virtual",
"void",
"volatile",
"wchar_t",
"wgsl",
"where",
"with",

32
third_party/rust/naga/src/lib.rs поставляемый
Просмотреть файл

@ -192,6 +192,7 @@ tree.
clippy::unneeded_field_pattern,
clippy::match_like_matches_macro,
clippy::if_same_then_else,
clippy::collapsible_if,
clippy::derive_partial_eq_without_eq
)]
#![warn(
@ -202,7 +203,7 @@ tree.
clippy::pattern_type_mismatch,
clippy::missing_const_for_fn
)]
#![deny(clippy::panic)]
#![cfg_attr(not(test), deny(clippy::panic))]
mod arena;
pub mod back;
@ -246,6 +247,7 @@ pub(crate) type NamedExpressions = FastHashMap<Handle<Expression>, String>;
/// - GLSL: `layout(early_fragment_tests) in;`
/// - HLSL: `Attribute earlydepthstencil`
/// - SPIR-V: `ExecutionMode EarlyFragmentTests`
/// - WGSL: `@early_depth_test`
///
/// For more, see:
/// - <https://www.khronos.org/opengl/wiki/Early_Fragment_Test#Explicit_specification>
@ -265,6 +267,7 @@ pub struct EarlyDepthTest {
/// - `depth_any` option behaves as if the layout qualifier was not present.
/// - HLSL: `SV_DepthGreaterEqual`/`SV_DepthLessEqual`/`SV_Depth`
/// - SPIR-V: `ExecutionMode Depth<Greater/Less/Unchanged>`
/// - WGSL: `@early_depth_test(greater_equal/less_equal/unchanged)`
///
/// For more, see:
/// - <https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_conservative_depth.txt>
@ -337,6 +340,7 @@ pub enum BuiltIn {
VertexIndex,
// fragment
FragDepth,
PointCoord,
FrontFacing,
PrimitiveIndex,
SampleIndex,
@ -1259,7 +1263,7 @@ pub enum Expression {
/// Load a value indirectly.
///
/// For [`TypeInner::Atomic`] the result is a corresponding scalar.
/// For other types behind the pointer<T>, the result is T.
/// For other types behind the `pointer<T>`, the result is `T`.
Load { pointer: Handle<Expression> },
/// Sample a point from a sampled or a depth image.
ImageSample {
@ -1399,11 +1403,7 @@ pub enum Expression {
/// Result of calling another function.
CallResult(Handle<Function>),
/// Result of an atomic operation.
AtomicResult {
kind: ScalarKind,
width: Bytes,
comparison: bool,
},
AtomicResult { ty: Handle<Type>, comparison: bool },
/// Get the length of an array.
/// The expression must resolve to a pointer to an array with a dynamic size.
///
@ -1464,6 +1464,22 @@ pub enum Statement {
reject: Block,
},
/// Conditionally executes one of multiple blocks, based on the value of the selector.
///
/// Each case must have a distinct [`value`], exactly one of which must be
/// [`Default`]. The `Default` may appear at any position, and covers all
/// values not explicitly appearing in other cases. A `Default` appearing in
/// the midst of the list of cases does not shadow the cases that follow.
///
/// Some backend languages don't support fallthrough (HLSL due to FXC,
/// WGSL), and may translate fallthrough cases in the IR by duplicating
/// code. However, all backend languages do support cases selected by
/// multiple values, like `case 1: case 2: case 3: { ... }`. This is
/// represented in the IR as a series of fallthrough cases with empty
/// bodies, except for the last.
///
/// [`value`]: SwitchCase::value
/// [`body`]: SwitchCase::body
/// [`Default`]: SwitchValue::Default
Switch {
selector: Handle<Expression>, //int
cases: Vec<SwitchCase>,
@ -1547,7 +1563,7 @@ pub enum Statement {
///
/// For [`TypeInner::Atomic`] type behind the pointer, the value
/// has to be a corresponding scalar.
/// For other types behind the pointer<T>, the value is T.
/// For other types behind the `pointer<T>`, the value is `T`.
///
/// This statement is a barrier for any operations on the
/// `Expression::LocalVariable` or `Expression::GlobalVariable`

9
third_party/rust/naga/src/proc/layouter.rs поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
use crate::arena::{Arena, BadHandle, Handle, UniqueArena};
use crate::arena::{Arena, Handle, UniqueArena};
use std::{fmt::Display, num::NonZeroU32, ops};
/// A newtype struct where its only valid values are powers of 2
@ -130,8 +130,6 @@ pub enum LayoutErrorInner {
InvalidStructMemberType(u32, Handle<crate::Type>),
#[error("Type width must be a power of two")]
NonPowerOfTwoWidth,
#[error("Array size is a bad handle")]
BadHandle(#[from] BadHandle),
}
#[derive(Clone, Copy, Debug, PartialEq, thiserror::Error)]
@ -175,10 +173,7 @@ impl Layouter {
use crate::TypeInner as Ti;
for (ty_handle, ty) in types.iter().skip(self.layouts.len()) {
let size = ty
.inner
.try_size(constants)
.map_err(|error| LayoutErrorInner::BadHandle(error).with(ty_handle))?;
let size = ty.inner.size(constants);
let layout = match ty.inner {
Ti::Scalar { width, .. } | Ti::Atomic { width, .. } => {
let alignment = Alignment::new(width as u32)

19
third_party/rust/naga/src/proc/mod.rs поставляемый
Просмотреть файл

@ -97,11 +97,9 @@ impl super::TypeInner {
}
}
pub fn try_size(
&self,
constants: &super::Arena<super::Constant>,
) -> Result<u32, crate::arena::BadHandle> {
Ok(match *self {
/// Get the size of this type.
pub fn size(&self, constants: &super::Arena<super::Constant>) -> u32 {
match *self {
Self::Scalar { kind: _, width } | Self::Atomic { kind: _, width } => width as u32,
Self::Vector {
size,
@ -122,8 +120,7 @@ impl super::TypeInner {
} => {
let count = match size {
super::ArraySize::Constant(handle) => {
let constant = constants.try_get(handle)?;
constant.to_array_length().unwrap_or(1)
constants[handle].to_array_length().unwrap_or(1)
}
// A dynamically-sized array has to have at least one element
super::ArraySize::Dynamic => 1,
@ -132,13 +129,7 @@ impl super::TypeInner {
}
Self::Struct { span, .. } => span,
Self::Image { .. } | Self::Sampler { .. } | Self::BindingArray { .. } => 0,
})
}
/// Get the size of this type. Panics if the `constants` doesn't contain
/// a referenced handle. This may not happen in a properly validated IR module.
pub fn size(&self, constants: &super::Arena<super::Constant>) -> u32 {
self.try_size(constants).unwrap()
}
}
/// Return the canonical form of `self`, or `None` if it's already in

47
third_party/rust/naga/src/proc/typifier.rs поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
use crate::arena::{Arena, BadHandle, Handle, UniqueArena};
use crate::arena::{Arena, Handle, UniqueArena};
use thiserror::Error;
@ -162,8 +162,6 @@ impl crate::ConstantInner {
#[derive(Clone, Debug, Error, PartialEq)]
pub enum ResolveError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Index {index} is out of bounds for expression {expr:?}")]
OutOfBoundsIndex {
expr: Handle<crate::Expression>,
@ -195,8 +193,6 @@ pub enum ResolveError {
IncompatibleOperands(String),
#[error("Function argument {0} doesn't exist")]
FunctionArgumentNotFound(u32),
#[error("Expression {0:?} depends on expressions that follow")]
ExpressionForwardDependency(Handle<crate::Expression>),
}
pub struct ResolveContext<'a> {
@ -403,20 +399,15 @@ impl<'a> ResolveContext<'a> {
}
}
}
crate::Expression::Constant(h) => {
let constant = self.constants.try_get(h)?;
match constant.inner {
crate::ConstantInner::Scalar { width, ref value } => {
TypeResolution::Value(Ti::Scalar {
kind: value.scalar_kind(),
width,
})
}
crate::ConstantInner::Composite { ty, components: _ } => {
TypeResolution::Handle(ty)
}
crate::Expression::Constant(h) => match self.constants[h].inner {
crate::ConstantInner::Scalar { width, ref value } => {
TypeResolution::Value(Ti::Scalar {
kind: value.scalar_kind(),
width,
})
}
}
crate::ConstantInner::Composite { ty, components: _ } => TypeResolution::Handle(ty),
},
crate::Expression::Splat { size, value } => match *past(value)?.inner_with(types) {
Ti::Scalar { kind, width } => {
TypeResolution::Value(Ti::Vector { size, kind, width })
@ -450,7 +441,7 @@ impl<'a> ResolveContext<'a> {
TypeResolution::Handle(arg.ty)
}
crate::Expression::GlobalVariable(h) => {
let var = self.global_vars.try_get(h)?;
let var = &self.global_vars[h];
if var.space == crate::AddressSpace::Handle {
TypeResolution::Handle(var.ty)
} else {
@ -461,7 +452,7 @@ impl<'a> ResolveContext<'a> {
}
}
crate::Expression::LocalVariable(h) => {
let var = self.local_vars.try_get(h)?;
let var = &self.local_vars[h];
TypeResolution::Value(Ti::Pointer {
base: var.ty,
space: crate::AddressSpace::Function,
@ -644,21 +635,7 @@ impl<'a> ResolveContext<'a> {
| crate::BinaryOperator::ShiftLeft
| crate::BinaryOperator::ShiftRight => past(left)?.clone(),
},
crate::Expression::AtomicResult {
kind,
width,
comparison,
} => {
if comparison {
TypeResolution::Value(Ti::Vector {
size: crate::VectorSize::Bi,
kind,
width,
})
} else {
TypeResolution::Value(Ti::Scalar { kind, width })
}
}
crate::Expression::AtomicResult { ty, .. } => TypeResolution::Handle(ty),
crate::Expression::Select { accept, .. } => past(accept)?.clone(),
crate::Expression::Derivative { axis: _, expr } => past(expr)?.clone(),
crate::Expression::Relational { fun, argument } => match fun {

9
third_party/rust/naga/src/valid/analyzer.rs поставляемый
Просмотреть файл

@ -10,7 +10,7 @@ use super::{CallError, ExpressionError, FunctionError, ModuleInfo, ShaderStages,
use crate::span::{AddSpan as _, WithSpan};
use crate::{
arena::{Arena, Handle},
proc::{ResolveContext, ResolveError, TypeResolution},
proc::{ResolveContext, TypeResolution},
};
use std::ops;
@ -706,12 +706,7 @@ impl FunctionInfo {
},
};
let ty = resolve_context.resolve(expression, |h| {
self.expressions
.get(h.index())
.map(|ei| &ei.ty)
.ok_or(ResolveError::ExpressionForwardDependency(h))
})?;
let ty = resolve_context.resolve(expression, |h| Ok(&self[h].ty))?;
self.expressions[handle.index()] = ExpressionInfo {
uniformity,
ref_count: 0,

7
third_party/rust/naga/src/valid/compose.rs поставляемый
Просмотреть файл

@ -4,13 +4,11 @@ use crate::{
proc::TypeResolution,
};
use crate::arena::{BadHandle, Handle};
use crate::arena::Handle;
#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum ComposeError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Composing of type {0:?} can't be done")]
Type(Handle<crate::Type>),
#[error("Composing expects {expected} components but {given} were given")]
@ -28,8 +26,7 @@ pub fn validate_compose(
) -> Result<(), ComposeError> {
use crate::TypeInner as Ti;
let self_ty = type_arena.get_handle(self_ty_handle)?;
match self_ty.inner {
match type_arena[self_ty_handle].inner {
// vectors are composed from scalars or other vectors
Ti::Vector { size, kind, width } => {
let mut total = 0;

151
third_party/rust/naga/src/valid/expression.rs поставляемый
Просмотреть файл

@ -1,10 +1,16 @@
#[cfg(feature = "validate")]
use super::{compose::validate_compose, FunctionInfo, ShaderStages, TypeFlags};
use std::ops::Index;
#[cfg(feature = "validate")]
use super::{
compose::validate_compose, validate_atomic_compare_exchange_struct, FunctionInfo, ShaderStages,
TypeFlags,
};
#[cfg(feature = "validate")]
use crate::arena::UniqueArena;
use crate::{
arena::{BadHandle, Handle},
arena::Handle,
proc::{IndexableLengthError, ResolveError},
};
@ -15,10 +21,6 @@ pub enum ExpressionError {
DoesntExist,
#[error("Used by a statement before it was introduced into the scope by any of the dominating blocks")]
NotInScope,
#[error("Depends on {0:?}, which has not been processed yet")]
ForwardDependency(Handle<crate::Expression>),
#[error(transparent)]
BadDependency(#[from] BadHandle),
#[error("Base type {0:?} is not compatible with this expression")]
InvalidBaseType(Handle<crate::Expression>),
#[error("Accessing with index {0:?} can't be done")]
@ -115,8 +117,8 @@ pub enum ExpressionError {
WrongArgumentCount(crate::MathFunction),
#[error("Argument [{1}] to {0:?} as expression {2:?} has an invalid type.")]
InvalidArgumentType(crate::MathFunction, u32, Handle<crate::Expression>),
#[error("Atomic result type can't be {0:?} of {1} bytes")]
InvalidAtomicResultType(crate::ScalarKind, crate::Bytes),
#[error("Atomic result type can't be {0:?}")]
InvalidAtomicResultType(Handle<crate::Type>),
#[error("Shader requires capability {0:?}")]
MissingCapabilities(super::Capabilities),
}
@ -129,15 +131,19 @@ struct ExpressionTypeResolver<'a> {
}
#[cfg(feature = "validate")]
impl<'a> ExpressionTypeResolver<'a> {
fn resolve(
&self,
handle: Handle<crate::Expression>,
) -> Result<&'a crate::TypeInner, ExpressionError> {
impl<'a> Index<Handle<crate::Expression>> for ExpressionTypeResolver<'a> {
type Output = crate::TypeInner;
#[allow(clippy::panic)]
fn index(&self, handle: Handle<crate::Expression>) -> &Self::Output {
if handle < self.root {
Ok(self.info[handle].ty.inner_with(self.types))
self.info[handle].ty.inner_with(self.types)
} else {
Err(ExpressionError::ForwardDependency(handle))
// `Validator::validate_module_handles` should have caught this.
panic!(
"Depends on {:?}, which has not been processed yet",
self.root
)
}
}
}
@ -163,7 +169,7 @@ impl super::Validator {
let stages = match *expression {
E::Access { base, index } => {
let base_type = resolver.resolve(base)?;
let base_type = &resolver[base];
// See the documentation for `Expression::Access`.
let dynamic_indexing_restricted = match *base_type {
Ti::Vector { .. } => false,
@ -176,7 +182,7 @@ impl super::Validator {
return Err(ExpressionError::InvalidBaseType(base));
}
};
match *resolver.resolve(index)? {
match resolver[index] {
//TODO: only allow one of these
Ti::Scalar {
kind: Sk::Sint | Sk::Uint,
@ -254,7 +260,7 @@ impl super::Validator {
Ok(limit)
}
let limit = resolve_index_limit(module, base, resolver.resolve(base)?, true)?;
let limit = resolve_index_limit(module, base, &resolver[base], true)?;
if index >= limit {
return Err(ExpressionError::IndexOutOfBounds(
base,
@ -263,11 +269,8 @@ impl super::Validator {
}
ShaderStages::all()
}
E::Constant(handle) => {
let _ = module.constants.try_get(handle)?;
ShaderStages::all()
}
E::Splat { size: _, value } => match *resolver.resolve(value)? {
E::Constant(_handle) => ShaderStages::all(),
E::Splat { size: _, value } => match resolver[value] {
Ti::Scalar { .. } => ShaderStages::all(),
ref other => {
log::error!("Splat scalar type {:?}", other);
@ -279,7 +282,7 @@ impl super::Validator {
vector,
pattern,
} => {
let vec_size = match *resolver.resolve(vector)? {
let vec_size = match resolver[vector] {
Ti::Vector { size: vec_size, .. } => vec_size,
ref other => {
log::error!("Swizzle vector type {:?}", other);
@ -294,11 +297,6 @@ impl super::Validator {
ShaderStages::all()
}
E::Compose { ref components, ty } => {
for &handle in components {
if handle >= root {
return Err(ExpressionError::ForwardDependency(handle));
}
}
validate_compose(
ty,
&module.constants,
@ -313,16 +311,10 @@ impl super::Validator {
}
ShaderStages::all()
}
E::GlobalVariable(handle) => {
let _ = module.global_variables.try_get(handle)?;
ShaderStages::all()
}
E::LocalVariable(handle) => {
let _ = function.local_variables.try_get(handle)?;
ShaderStages::all()
}
E::GlobalVariable(_handle) => ShaderStages::all(),
E::LocalVariable(_handle) => ShaderStages::all(),
E::Load { pointer } => {
match *resolver.resolve(pointer)? {
match resolver[pointer] {
Ti::Pointer { base, .. }
if self.types[base.index()]
.flags
@ -365,7 +357,7 @@ impl super::Validator {
return Err(ExpressionError::InvalidImageArrayIndex);
}
if let Some(expr) = array_index {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Sint,
width: _,
@ -384,6 +376,10 @@ impl super::Validator {
kind: crate::ScalarKind::Float,
multi: false,
} => false,
crate::ImageClass::Sampled {
kind: crate::ScalarKind::Uint | crate::ScalarKind::Sint,
multi: false,
} if gather.is_some() => false,
crate::ImageClass::Depth { multi: false } => true,
_ => return Err(ExpressionError::InvalidImageClass(class)),
};
@ -401,7 +397,7 @@ impl super::Validator {
crate::ImageDimension::D2 => 2,
crate::ImageDimension::D3 | crate::ImageDimension::Cube => 3,
};
match *resolver.resolve(coordinate)? {
match resolver[coordinate] {
Ti::Scalar {
kind: Sk::Float, ..
} if num_components == 1 => {}
@ -439,7 +435,7 @@ impl super::Validator {
// check depth reference type
if let Some(expr) = depth_ref {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Float, ..
} => {}
@ -476,7 +472,7 @@ impl super::Validator {
crate::SampleLevel::Auto => ShaderStages::FRAGMENT,
crate::SampleLevel::Zero => ShaderStages::all(),
crate::SampleLevel::Exact(expr) => {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Float, ..
} => {}
@ -485,7 +481,7 @@ impl super::Validator {
ShaderStages::all()
}
crate::SampleLevel::Bias(expr) => {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Float, ..
} => {}
@ -494,7 +490,7 @@ impl super::Validator {
ShaderStages::all()
}
crate::SampleLevel::Gradient { x, y } => {
match *resolver.resolve(x)? {
match resolver[x] {
Ti::Scalar {
kind: Sk::Float, ..
} if num_components == 1 => {}
@ -507,7 +503,7 @@ impl super::Validator {
return Err(ExpressionError::InvalidSampleLevelGradientType(dim, x))
}
}
match *resolver.resolve(y)? {
match resolver[y] {
Ti::Scalar {
kind: Sk::Float, ..
} if num_components == 1 => {}
@ -538,7 +534,7 @@ impl super::Validator {
arrayed,
dim,
} => {
match resolver.resolve(coordinate)?.image_storage_coordinates() {
match resolver[coordinate].image_storage_coordinates() {
Some(coord_dim) if coord_dim == dim => {}
_ => {
return Err(ExpressionError::InvalidImageCoordinateType(
@ -550,7 +546,7 @@ impl super::Validator {
return Err(ExpressionError::InvalidImageArrayIndex);
}
if let Some(expr) = array_index {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Sint,
width: _,
@ -562,7 +558,7 @@ impl super::Validator {
match (sample, class.is_multisampled()) {
(None, false) => {}
(Some(sample), true) => {
if resolver.resolve(sample)?.scalar_kind() != Some(Sk::Sint) {
if resolver[sample].scalar_kind() != Some(Sk::Sint) {
return Err(ExpressionError::InvalidImageOtherIndexType(
sample,
));
@ -576,7 +572,7 @@ impl super::Validator {
match (level, class.is_mipmapped()) {
(None, false) => {}
(Some(level), true) => {
if resolver.resolve(level)?.scalar_kind() != Some(Sk::Sint) {
if resolver[level].scalar_kind() != Some(Sk::Sint) {
return Err(ExpressionError::InvalidImageOtherIndexType(level));
}
}
@ -610,7 +606,7 @@ impl super::Validator {
}
E::Unary { op, expr } => {
use crate::UnaryOperator as Uo;
let inner = resolver.resolve(expr)?;
let inner = &resolver[expr];
match (op, inner.scalar_kind()) {
(_, Some(Sk::Sint | Sk::Bool))
//TODO: restrict Negate for bools?
@ -625,8 +621,8 @@ impl super::Validator {
}
E::Binary { op, left, right } => {
use crate::BinaryOperator as Bo;
let left_inner = resolver.resolve(left)?;
let right_inner = resolver.resolve(right)?;
let left_inner = &resolver[left];
let right_inner = &resolver[right];
let good = match op {
Bo::Add | Bo::Subtract => match *left_inner {
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
@ -807,9 +803,9 @@ impl super::Validator {
accept,
reject,
} => {
let accept_inner = resolver.resolve(accept)?;
let reject_inner = resolver.resolve(reject)?;
let condition_good = match *resolver.resolve(condition)? {
let accept_inner = &resolver[accept];
let reject_inner = &resolver[reject];
let condition_good = match resolver[condition] {
Ti::Scalar {
kind: Sk::Bool,
width: _,
@ -839,7 +835,7 @@ impl super::Validator {
ShaderStages::all()
}
E::Derivative { axis: _, expr } => {
match *resolver.resolve(expr)? {
match resolver[expr] {
Ti::Scalar {
kind: Sk::Float, ..
}
@ -852,7 +848,7 @@ impl super::Validator {
}
E::Relational { fun, argument } => {
use crate::RelationalFunction as Rf;
let argument_inner = resolver.resolve(argument)?;
let argument_inner = &resolver[argument];
match fun {
Rf::All | Rf::Any => match *argument_inner {
Ti::Vector { kind: Sk::Bool, .. } => {}
@ -885,10 +881,11 @@ impl super::Validator {
} => {
use crate::MathFunction as Mf;
let arg_ty = resolver.resolve(arg)?;
let arg1_ty = arg1.map(|expr| resolver.resolve(expr)).transpose()?;
let arg2_ty = arg2.map(|expr| resolver.resolve(expr)).transpose()?;
let arg3_ty = arg3.map(|expr| resolver.resolve(expr)).transpose()?;
let resolve = |arg| &resolver[arg];
let arg_ty = resolve(arg);
let arg1_ty = arg1.map(resolve);
let arg2_ty = arg2.map(resolve);
let arg3_ty = arg3.map(resolve);
match fun {
Mf::Abs => {
if arg1_ty.is_some() | arg2_ty.is_some() | arg3_ty.is_some() {
@ -1372,7 +1369,7 @@ impl super::Validator {
kind,
convert,
} => {
let base_width = match *resolver.resolve(expr)? {
let base_width = match resolver[expr] {
crate::TypeInner::Scalar { width, .. }
| crate::TypeInner::Vector { width, .. }
| crate::TypeInner::Matrix { width, .. } => width,
@ -1385,25 +1382,33 @@ impl super::Validator {
ShaderStages::all()
}
E::CallResult(function) => other_infos[function.index()].available_stages,
E::AtomicResult {
kind,
width,
comparison: _,
} => {
let good = match kind {
crate::ScalarKind::Uint | crate::ScalarKind::Sint => {
self.check_width(kind, width)
E::AtomicResult { ty, comparison } => {
let scalar_predicate = |ty: &crate::TypeInner| match ty {
&crate::TypeInner::Scalar {
kind: kind @ (crate::ScalarKind::Uint | crate::ScalarKind::Sint),
width,
} => self.check_width(kind, width),
_ => false,
};
let good = match &module.types[ty].inner {
ty if !comparison => scalar_predicate(ty),
&crate::TypeInner::Struct { ref members, .. } if comparison => {
validate_atomic_compare_exchange_struct(
&module.types,
members,
scalar_predicate,
)
}
_ => false,
};
if !good {
return Err(ExpressionError::InvalidAtomicResultType(kind, width));
return Err(ExpressionError::InvalidAtomicResultType(ty));
}
ShaderStages::all()
}
E::ArrayLength(expr) => match *resolver.resolve(expr)? {
E::ArrayLength(expr) => match resolver[expr] {
Ti::Pointer { base, .. } => {
let base_ty = resolver.types.get_handle(base)?;
let base_ty = &resolver.types[base];
if let Ti::Array {
size: crate::ArraySize::Dynamic,
..

57
third_party/rust/naga/src/valid/function.rs поставляемый
Просмотреть файл

@ -1,6 +1,9 @@
use crate::arena::Handle;
#[cfg(feature = "validate")]
use crate::arena::{Arena, UniqueArena};
use crate::arena::{BadHandle, Handle};
#[cfg(feature = "validate")]
use super::validate_atomic_compare_exchange_struct;
use super::{
analyzer::{UniformityDisruptor, UniformityRequirements},
@ -16,8 +19,6 @@ use bit_set::BitSet;
#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum CallError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("The callee is declared after the caller")]
ForwardDeclaredFunction,
#[error("Argument {index} expression is invalid")]
@ -66,8 +67,6 @@ pub enum LocalVariableError {
#[derive(Clone, Debug, thiserror::Error)]
#[cfg_attr(test, derive(PartialEq))]
pub enum FunctionError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Expression {handle:?} is invalid")]
Expression {
handle: Handle<crate::Expression>,
@ -200,11 +199,8 @@ impl<'a> BlockContext<'a> {
BlockContext { abilities, ..*self }
}
fn get_expression(
&self,
handle: Handle<crate::Expression>,
) -> Result<&'a crate::Expression, FunctionError> {
Ok(self.expressions.try_get(handle)?)
fn get_expression(&self, handle: Handle<crate::Expression>) -> &'a crate::Expression {
&self.expressions[handle]
}
fn resolve_type_impl(
@ -254,11 +250,7 @@ impl super::Validator {
result: Option<Handle<crate::Expression>>,
context: &BlockContext,
) -> Result<super::ShaderStages, WithSpan<CallError>> {
let fun = context
.functions
.try_get(function)
.map_err(CallError::BadHandle)
.map_err(WithSpan::new)?;
let fun = &context.functions[function];
if fun.arguments.len() != arguments.len() {
return Err(CallError::ArgumentCount {
required: fun.arguments.len(),
@ -363,12 +355,26 @@ impl super::Validator {
.into_other());
}
match context.expressions[result] {
//TODO: support atomic result with comparison
crate::Expression::AtomicResult {
kind,
width,
comparison: false,
} if kind == ptr_kind && width == ptr_width => {}
crate::Expression::AtomicResult { ty, comparison }
if {
let scalar_predicate = |ty: &crate::TypeInner| {
*ty == crate::TypeInner::Scalar {
kind: ptr_kind,
width: ptr_width,
}
};
match &context.types[ty].inner {
ty if !comparison => scalar_predicate(ty),
&crate::TypeInner::Struct { ref members, .. } if comparison => {
validate_atomic_compare_exchange_struct(
context.types,
members,
scalar_predicate,
)
}
_ => false,
}
} => {}
_ => {
return Err(AtomicError::ResultTypeMismatch(result)
.with_span_handle(result, context.expressions)
@ -672,14 +678,14 @@ impl super::Validator {
} => {
//Note: this code uses a lot of `FunctionError::InvalidImageStore`,
// and could probably be refactored.
let var = match *context.get_expression(image).map_err(|e| e.with_span())? {
let var = match *context.get_expression(image) {
crate::Expression::GlobalVariable(var_handle) => {
&context.global_vars[var_handle]
}
// We're looking at a binding index situation, so punch through the index and look at the global behind it.
crate::Expression::Access { base, .. }
| crate::Expression::AccessIndex { base, .. } => {
match *context.get_expression(base).map_err(|e| e.with_span())? {
match *context.get_expression(base) {
crate::Expression::GlobalVariable(var_handle) => {
&context.global_vars[var_handle]
}
@ -882,10 +888,7 @@ impl super::Validator {
#[cfg(feature = "validate")]
for (index, argument) in fun.arguments.iter().enumerate() {
let ty = module.types.get_handle(argument.ty).map_err(|err| {
FunctionError::from(err).with_span_handle(argument.ty, &module.types)
})?;
match ty.inner.pointer_space() {
match module.types[argument.ty].inner.pointer_space() {
Some(
crate::AddressSpace::Private
| crate::AddressSpace::Function

616
third_party/rust/naga/src/valid/handles.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,616 @@
//! Implementation of [`super::Validator::validate_module_handles`].
use crate::{
arena::{BadHandle, BadRangeError},
Handle,
};
#[cfg(feature = "validate")]
use crate::{Arena, UniqueArena};
#[cfg(feature = "validate")]
use super::{TypeError, ValidationError};
#[cfg(feature = "validate")]
use std::{convert::TryInto, hash::Hash, num::NonZeroU32};
#[cfg(feature = "validate")]
impl super::Validator {
/// Validates that all handles within `module` are:
///
/// * Valid, in the sense that they contain indices within each arena structure inside the
/// [`crate::Module`] type.
/// * No arena contents contain any items that have forward dependencies; that is, the value
/// associated with a handle only may contain references to handles in the same arena that
/// were constructed before it.
///
/// By validating the above conditions, we free up subsequent logic to assume that handle
/// accesses are infallible.
///
/// # Errors
///
/// Errors returned by this method are intentionally sparse, for simplicity of implementation.
/// It is expected that only buggy frontends or fuzzers should ever emit IR that fails this
/// validation pass.
pub(super) fn validate_module_handles(module: &crate::Module) -> Result<(), ValidationError> {
let &crate::Module {
ref constants,
ref entry_points,
ref functions,
ref global_variables,
ref types,
} = module;
// NOTE: Types being first is important. All other forms of validation depend on this.
for (this_handle, ty) in types.iter() {
let &crate::Type {
ref name,
ref inner,
} = ty;
let validate_array_size = |size| {
match size {
crate::ArraySize::Constant(constant) => {
let &crate::Constant {
name: _,
specialization: _,
ref inner,
} = constants.try_get(constant)?;
if !matches!(inner, &crate::ConstantInner::Scalar { .. }) {
return Err(ValidationError::Type {
handle: this_handle,
name: name.clone().unwrap_or_default(),
source: TypeError::InvalidArraySizeConstant(constant),
});
}
}
crate::ArraySize::Dynamic => (),
};
Ok(this_handle)
};
match *inner {
crate::TypeInner::Scalar { .. }
| crate::TypeInner::Vector { .. }
| crate::TypeInner::Matrix { .. }
| crate::TypeInner::ValuePointer { .. }
| crate::TypeInner::Atomic { .. }
| crate::TypeInner::Image { .. }
| crate::TypeInner::Sampler { .. } => (),
crate::TypeInner::Pointer { base, space: _ } => {
this_handle.check_dep(base)?;
}
crate::TypeInner::Array {
base,
size,
stride: _,
}
| crate::TypeInner::BindingArray { base, size } => {
this_handle.check_dep(base)?;
validate_array_size(size)?;
}
crate::TypeInner::Struct {
ref members,
span: _,
} => {
this_handle.check_dep_iter(members.iter().map(|m| m.ty))?;
}
}
}
let validate_type = |handle| Self::validate_type_handle(handle, types);
for (this_handle, constant) in constants.iter() {
let &crate::Constant {
name: _,
specialization: _,
ref inner,
} = constant;
match *inner {
crate::ConstantInner::Scalar { .. } => (),
crate::ConstantInner::Composite { ty, ref components } => {
validate_type(ty)?;
this_handle.check_dep_iter(components.iter().copied())?;
}
}
}
let validate_constant = |handle| Self::validate_constant_handle(handle, constants);
for (_handle, global_variable) in global_variables.iter() {
let &crate::GlobalVariable {
name: _,
space: _,
binding: _,
ty,
init,
} = global_variable;
validate_type(ty)?;
if let Some(init_expr) = init {
validate_constant(init_expr)?;
}
}
let validate_function = |function: &_| -> Result<_, InvalidHandleError> {
let &crate::Function {
name: _,
ref arguments,
ref result,
ref local_variables,
ref expressions,
ref named_expressions,
ref body,
} = function;
for arg in arguments.iter() {
let &crate::FunctionArgument {
name: _,
ty,
binding: _,
} = arg;
validate_type(ty)?;
}
if let &Some(crate::FunctionResult { ty, binding: _ }) = result {
validate_type(ty)?;
}
for (_handle, local_variable) in local_variables.iter() {
let &crate::LocalVariable { name: _, ty, init } = local_variable;
validate_type(ty)?;
if let Some(init_constant) = init {
validate_constant(init_constant)?;
}
}
for handle in named_expressions.keys().copied() {
Self::validate_expression_handle(handle, expressions)?;
}
for handle_and_expr in expressions.iter() {
Self::validate_expression_handles(
handle_and_expr,
constants,
types,
local_variables,
global_variables,
functions,
)?;
}
Self::validate_block_handles(body, expressions, functions)?;
Ok(())
};
for entry_point in entry_points.iter() {
validate_function(&entry_point.function)?;
}
for (_function_handle, function) in functions.iter() {
validate_function(function)?;
}
Ok(())
}
fn validate_type_handle(
handle: Handle<crate::Type>,
types: &UniqueArena<crate::Type>,
) -> Result<(), InvalidHandleError> {
handle.check_valid_for_uniq(types).map(|_| ())
}
fn validate_constant_handle(
handle: Handle<crate::Constant>,
constants: &Arena<crate::Constant>,
) -> Result<(), InvalidHandleError> {
handle.check_valid_for(constants).map(|_| ())
}
fn validate_expression_handle(
handle: Handle<crate::Expression>,
expressions: &Arena<crate::Expression>,
) -> Result<(), InvalidHandleError> {
handle.check_valid_for(expressions).map(|_| ())
}
fn validate_function_handle(
handle: Handle<crate::Function>,
functions: &Arena<crate::Function>,
) -> Result<(), InvalidHandleError> {
handle.check_valid_for(functions).map(|_| ())
}
fn validate_expression_handles(
(handle, expression): (Handle<crate::Expression>, &crate::Expression),
constants: &Arena<crate::Constant>,
types: &UniqueArena<crate::Type>,
local_variables: &Arena<crate::LocalVariable>,
global_variables: &Arena<crate::GlobalVariable>,
functions: &Arena<crate::Function>,
) -> Result<(), InvalidHandleError> {
let validate_constant = |handle| Self::validate_constant_handle(handle, constants);
let validate_type = |handle| Self::validate_type_handle(handle, types);
match *expression {
crate::Expression::Access { base, index } => {
handle.check_dep(base)?.check_dep(index)?;
}
crate::Expression::AccessIndex { base, .. } => {
handle.check_dep(base)?;
}
crate::Expression::Constant(constant) => {
validate_constant(constant)?;
}
crate::Expression::Splat { value, .. } => {
handle.check_dep(value)?;
}
crate::Expression::Swizzle { vector, .. } => {
handle.check_dep(vector)?;
}
crate::Expression::Compose { ty, ref components } => {
validate_type(ty)?;
handle.check_dep_iter(components.iter().copied())?;
}
crate::Expression::FunctionArgument(_arg_idx) => (),
crate::Expression::GlobalVariable(global_variable) => {
global_variable.check_valid_for(global_variables)?;
}
crate::Expression::LocalVariable(local_variable) => {
local_variable.check_valid_for(local_variables)?;
}
crate::Expression::Load { pointer } => {
handle.check_dep(pointer)?;
}
crate::Expression::ImageSample {
image,
sampler,
gather: _,
coordinate,
array_index,
offset,
level,
depth_ref,
} => {
if let Some(offset) = offset {
validate_constant(offset)?;
}
handle
.check_dep(image)?
.check_dep(sampler)?
.check_dep(coordinate)?
.check_dep_opt(array_index)?;
match level {
crate::SampleLevel::Auto | crate::SampleLevel::Zero => (),
crate::SampleLevel::Exact(expr) => {
handle.check_dep(expr)?;
}
crate::SampleLevel::Bias(expr) => {
handle.check_dep(expr)?;
}
crate::SampleLevel::Gradient { x, y } => {
handle.check_dep(x)?.check_dep(y)?;
}
};
handle.check_dep_opt(depth_ref)?;
}
crate::Expression::ImageLoad {
image,
coordinate,
array_index,
sample,
level,
} => {
handle
.check_dep(image)?
.check_dep(coordinate)?
.check_dep_opt(array_index)?
.check_dep_opt(sample)?
.check_dep_opt(level)?;
}
crate::Expression::ImageQuery { image, query } => {
handle.check_dep(image)?;
match query {
crate::ImageQuery::Size { level } => {
handle.check_dep_opt(level)?;
}
crate::ImageQuery::NumLevels
| crate::ImageQuery::NumLayers
| crate::ImageQuery::NumSamples => (),
};
}
crate::Expression::Unary {
op: _,
expr: operand,
} => {
handle.check_dep(operand)?;
}
crate::Expression::Binary { op: _, left, right } => {
handle.check_dep(left)?.check_dep(right)?;
}
crate::Expression::Select {
condition,
accept,
reject,
} => {
handle
.check_dep(condition)?
.check_dep(accept)?
.check_dep(reject)?;
}
crate::Expression::Derivative {
axis: _,
expr: argument,
} => {
handle.check_dep(argument)?;
}
crate::Expression::Relational { fun: _, argument } => {
handle.check_dep(argument)?;
}
crate::Expression::Math {
fun: _,
arg,
arg1,
arg2,
arg3,
} => {
handle
.check_dep(arg)?
.check_dep_opt(arg1)?
.check_dep_opt(arg2)?
.check_dep_opt(arg3)?;
}
crate::Expression::As {
expr: input,
kind: _,
convert: _,
} => {
handle.check_dep(input)?;
}
crate::Expression::CallResult(function) => {
Self::validate_function_handle(function, functions)?;
}
crate::Expression::AtomicResult { .. } => (),
crate::Expression::ArrayLength(array) => {
handle.check_dep(array)?;
}
}
Ok(())
}
fn validate_block_handles(
block: &crate::Block,
expressions: &Arena<crate::Expression>,
functions: &Arena<crate::Function>,
) -> Result<(), InvalidHandleError> {
let validate_block = |block| Self::validate_block_handles(block, expressions, functions);
let validate_expr = |handle| Self::validate_expression_handle(handle, expressions);
let validate_expr_opt = |handle_opt| {
if let Some(handle) = handle_opt {
validate_expr(handle)?;
}
Ok(())
};
block.iter().try_for_each(|stmt| match *stmt {
crate::Statement::Emit(ref expr_range) => {
expr_range.check_valid_for(expressions)?;
Ok(())
}
crate::Statement::Block(ref block) => {
validate_block(block)?;
Ok(())
}
crate::Statement::If {
condition,
ref accept,
ref reject,
} => {
validate_expr(condition)?;
validate_block(accept)?;
validate_block(reject)?;
Ok(())
}
crate::Statement::Switch {
selector,
ref cases,
} => {
validate_expr(selector)?;
for &crate::SwitchCase {
value: _,
ref body,
fall_through: _,
} in cases
{
validate_block(body)?;
}
Ok(())
}
crate::Statement::Loop {
ref body,
ref continuing,
break_if,
} => {
validate_block(body)?;
validate_block(continuing)?;
validate_expr_opt(break_if)?;
Ok(())
}
crate::Statement::Return { value } => validate_expr_opt(value),
crate::Statement::Store { pointer, value } => {
validate_expr(pointer)?;
validate_expr(value)?;
Ok(())
}
crate::Statement::ImageStore {
image,
coordinate,
array_index,
value,
} => {
validate_expr(image)?;
validate_expr(coordinate)?;
validate_expr_opt(array_index)?;
validate_expr(value)?;
Ok(())
}
crate::Statement::Atomic {
pointer,
fun,
value,
result,
} => {
validate_expr(pointer)?;
match fun {
crate::AtomicFunction::Add
| crate::AtomicFunction::Subtract
| crate::AtomicFunction::And
| crate::AtomicFunction::ExclusiveOr
| crate::AtomicFunction::InclusiveOr
| crate::AtomicFunction::Min
| crate::AtomicFunction::Max => (),
crate::AtomicFunction::Exchange { compare } => validate_expr_opt(compare)?,
};
validate_expr(value)?;
validate_expr(result)?;
Ok(())
}
crate::Statement::Call {
function,
ref arguments,
result,
} => {
Self::validate_function_handle(function, functions)?;
for arg in arguments.iter().copied() {
validate_expr(arg)?;
}
validate_expr_opt(result)?;
Ok(())
}
crate::Statement::Break
| crate::Statement::Continue
| crate::Statement::Kill
| crate::Statement::Barrier(_) => Ok(()),
})
}
}
#[cfg(feature = "validate")]
impl From<BadHandle> for ValidationError {
fn from(source: BadHandle) -> Self {
Self::InvalidHandle(source.into())
}
}
#[cfg(feature = "validate")]
impl From<FwdDepError> for ValidationError {
fn from(source: FwdDepError) -> Self {
Self::InvalidHandle(source.into())
}
}
#[cfg(feature = "validate")]
impl From<BadRangeError> for ValidationError {
fn from(source: BadRangeError) -> Self {
Self::InvalidHandle(source.into())
}
}
#[derive(Clone, Debug, thiserror::Error)]
pub enum InvalidHandleError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error(transparent)]
ForwardDependency(#[from] FwdDepError),
#[error(transparent)]
BadRange(#[from] BadRangeError),
}
#[derive(Clone, Debug, thiserror::Error)]
#[error(
"{subject:?} of kind depends on {depends_on:?} of kind {depends_on_kind}, which has not been \
processed yet"
)]
pub struct FwdDepError {
// This error is used for many `Handle` types, but there's no point in making this generic, so
// we just flatten them all to `Handle<()>` here.
subject: Handle<()>,
subject_kind: &'static str,
depends_on: Handle<()>,
depends_on_kind: &'static str,
}
#[cfg(feature = "validate")]
impl<T> Handle<T> {
/// Check that `self` is valid within `arena` using [`Arena::check_contains_handle`].
pub(self) fn check_valid_for(self, arena: &Arena<T>) -> Result<(), InvalidHandleError> {
arena.check_contains_handle(self)?;
Ok(())
}
/// Check that `self` is valid within `arena` using [`UniqueArena::check_contains_handle`].
pub(self) fn check_valid_for_uniq(
self,
arena: &UniqueArena<T>,
) -> Result<(), InvalidHandleError>
where
T: Eq + Hash,
{
arena.check_contains_handle(self)?;
Ok(())
}
/// Check that `depends_on` was constructed before `self` by comparing handle indices.
///
/// If `self` is a valid handle (i.e., it has been validated using [`Self::check_valid_for`])
/// and this function returns [`Ok`], then it may be assumed that `depends_on` is also valid.
/// In [`naga`](crate)'s current arena-based implementation, this is useful for validating
/// recursive definitions of arena-based values in linear time.
///
/// # Errors
///
/// If `depends_on`'s handle is from the same [`Arena`] as `self'`s, but not constructed earlier
/// than `self`'s, this function returns an error.
pub(self) fn check_dep(self, depends_on: Self) -> Result<Self, FwdDepError> {
if depends_on < self {
Ok(self)
} else {
let erase_handle_type = |handle: Handle<_>| {
Handle::new(NonZeroU32::new(handle.index().try_into().unwrap()).unwrap())
};
Err(FwdDepError {
subject: erase_handle_type(self),
subject_kind: std::any::type_name::<T>(),
depends_on: erase_handle_type(depends_on),
depends_on_kind: std::any::type_name::<T>(),
})
}
}
/// Like [`Self::check_dep`], except for [`Option`]al handle values.
pub(self) fn check_dep_opt(self, depends_on: Option<Self>) -> Result<Self, FwdDepError> {
self.check_dep_iter(depends_on.into_iter())
}
/// Like [`Self::check_dep`], except for [`Iterator`]s over handle values.
pub(self) fn check_dep_iter(
self,
depends_on: impl Iterator<Item = Self>,
) -> Result<Self, FwdDepError> {
for handle in depends_on {
self.check_dep(handle)?;
}
Ok(self)
}
}
#[cfg(feature = "validate")]
impl<T> crate::arena::Range<T> {
pub(self) fn check_valid_for(&self, arena: &Arena<T>) -> Result<(), BadRangeError> {
arena.check_contains_range(self)
}
}

61
third_party/rust/naga/src/valid/interface.rs поставляемый
Просмотреть файл

@ -2,7 +2,7 @@ use super::{
analyzer::{FunctionInfo, GlobalUse},
Capabilities, Disalignment, FunctionError, ModuleInfo,
};
use crate::arena::{BadHandle, Handle, UniqueArena};
use crate::arena::{Handle, UniqueArena};
use crate::span::{AddSpan as _, MapErrWithSpan as _, SpanProvider as _, WithSpan};
use bit_set::BitSet;
@ -12,8 +12,6 @@ const MAX_WORKGROUP_SIZE: u32 = 0x4000;
#[derive(Clone, Debug, thiserror::Error)]
pub enum GlobalVariableError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("Usage isn't compatible with address space {0:?}")]
InvalidUsage(crate::AddressSpace),
#[error("Type isn't compatible with address space {0:?}")]
@ -107,6 +105,9 @@ struct VaryingContext<'a> {
location_mask: &'a mut BitSet,
built_ins: &'a mut crate::FastHashSet<crate::BuiltIn>,
capabilities: Capabilities,
#[cfg(feature = "validate")]
flags: super::ValidationFlags,
}
impl VaryingContext<'_> {
@ -176,6 +177,15 @@ impl VaryingContext<'_> {
width,
},
),
Bi::PointCoord => (
self.stage == St::Fragment && !self.output,
*ty_inner
== Ti::Vector {
size: Vs::Bi,
kind: Sk::Float,
width,
},
),
Bi::Position { .. } => (
match self.stage {
St::Vertex => self.output,
@ -284,7 +294,10 @@ impl VaryingContext<'_> {
return Err(VaryingError::NotIOShareableType(ty));
}
if !self.location_mask.insert(location as usize) {
return Err(VaryingError::BindingCollision { location });
#[cfg(feature = "validate")]
if self.flags.contains(super::ValidationFlags::BINDINGS) {
return Err(VaryingError::BindingCollision { location });
}
}
let needs_interpolation = match self.stage {
@ -336,8 +349,15 @@ impl VaryingContext<'_> {
let span_context = self.types.get_span_context(ty);
match member.binding {
None => {
return Err(VaryingError::MemberMissingBinding(index as u32)
.with_span_context(span_context))
#[cfg(feature = "validate")]
if self.flags.contains(super::ValidationFlags::BINDINGS) {
return Err(VaryingError::MemberMissingBinding(
index as u32,
)
.with_span_context(span_context));
}
#[cfg(not(feature = "validate"))]
let _ = index;
}
// TODO: shouldn't this be validate?
Some(ref binding) => self
@ -346,7 +366,13 @@ impl VaryingContext<'_> {
}
}
}
_ => return Err(VaryingError::MissingBinding.with_span()),
_ =>
{
#[cfg(feature = "validate")]
if self.flags.contains(super::ValidationFlags::BINDINGS) {
return Err(VaryingError::MissingBinding.with_span());
}
}
}
Ok(())
}
@ -364,10 +390,7 @@ impl super::Validator {
use super::TypeFlags;
log::debug!("var {:?}", var);
let type_info = self.types.get(var.ty.index()).ok_or_else(|| BadHandle {
kind: "type",
index: var.ty.index(),
})?;
let type_info = &self.types[var.ty.index()];
let (required_type_flags, is_resource) = match var.space {
crate::AddressSpace::Function => {
@ -441,7 +464,9 @@ impl super::Validator {
}
if is_resource != var.binding.is_some() {
return Err(GlobalVariableError::InvalidBinding);
if self.flags.contains(super::ValidationFlags::BINDINGS) {
return Err(GlobalVariableError::InvalidBinding);
}
}
Ok(())
@ -502,6 +527,9 @@ impl super::Validator {
location_mask: &mut self.location_mask,
built_ins: &mut argument_built_ins,
capabilities: self.capabilities,
#[cfg(feature = "validate")]
flags: self.flags,
};
ctx.validate(fa.ty, fa.binding.as_ref())
.map_err_inner(|e| EntryPointError::Argument(index as u32, e).with_span())?;
@ -518,6 +546,9 @@ impl super::Validator {
location_mask: &mut self.location_mask,
built_ins: &mut result_built_ins,
capabilities: self.capabilities,
#[cfg(feature = "validate")]
flags: self.flags,
};
ctx.validate(fr.ty, fr.binding.as_ref())
.map_err_inner(|e| EntryPointError::Result(e).with_span())?;
@ -571,8 +602,10 @@ impl super::Validator {
self.bind_group_masks.push(BitSet::new());
}
if !self.bind_group_masks[bind.group as usize].insert(bind.binding as usize) {
return Err(EntryPointError::BindingCollision(var_handle)
.with_span_handle(var_handle, &module.global_variables));
if self.flags.contains(super::ValidationFlags::BINDINGS) {
return Err(EntryPointError::BindingCollision(var_handle)
.with_span_handle(var_handle, &module.global_variables));
}
}
}
}

40
third_party/rust/naga/src/valid/mod.rs поставляемый
Просмотреть файл

@ -6,6 +6,7 @@ mod analyzer;
mod compose;
mod expression;
mod function;
mod handles;
mod interface;
mod r#type;
@ -13,7 +14,7 @@ mod r#type;
use crate::arena::{Arena, UniqueArena};
use crate::{
arena::{BadHandle, Handle},
arena::Handle,
proc::{LayoutError, Layouter},
FastHashSet,
};
@ -31,6 +32,8 @@ pub use function::{CallError, FunctionError, LocalVariableError};
pub use interface::{EntryPointError, GlobalVariableError, VaryingError};
pub use r#type::{Disalignment, TypeError, TypeFlags};
use self::handles::InvalidHandleError;
bitflags::bitflags! {
/// Validation flags.
///
@ -66,6 +69,9 @@ bitflags::bitflags! {
/// Constants.
#[cfg(feature = "validate")]
const CONSTANTS = 0x10;
/// Group, binding, and location attributes.
#[cfg(feature = "validate")]
const BINDINGS = 0x20;
}
}
@ -143,8 +149,6 @@ pub struct Validator {
#[derive(Clone, Debug, thiserror::Error)]
pub enum ConstantError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("The type doesn't match the constant")]
InvalidType,
#[error("The component handle {0:?} can not be resolved")]
@ -157,6 +161,8 @@ pub enum ConstantError {
#[derive(Clone, Debug, thiserror::Error)]
pub enum ValidationError {
#[error(transparent)]
InvalidHandle(#[from] InvalidHandleError),
#[error(transparent)]
Layouter(#[from] LayoutError),
#[error("Type {handle:?} '{name}' is invalid")]
@ -220,17 +226,17 @@ impl crate::TypeInner {
const fn image_storage_coordinates(&self) -> Option<crate::ImageDimension> {
match *self {
Self::Scalar {
kind: crate::ScalarKind::Sint,
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
..
} => Some(crate::ImageDimension::D1),
Self::Vector {
size: crate::VectorSize::Bi,
kind: crate::ScalarKind::Sint,
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
..
} => Some(crate::ImageDimension::D2),
Self::Vector {
size: crate::VectorSize::Tri,
kind: crate::ScalarKind::Sint,
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
..
} => Some(crate::ImageDimension::D3),
_ => None,
@ -280,7 +286,7 @@ impl Validator {
}
}
crate::ConstantInner::Composite { ty, ref components } => {
match types.get_handle(ty)?.inner {
match types[ty].inner {
crate::TypeInner::Array {
size: crate::ArraySize::Constant(size_handle),
..
@ -313,6 +319,9 @@ impl Validator {
self.reset();
self.reset_types(module.types.len());
#[cfg(feature = "validate")]
Self::validate_module_handles(module).map_err(|e| e.with_span())?;
self.layouter
.update(&module.types, &module.constants)
.map_err(|e| {
@ -412,3 +421,20 @@ impl Validator {
Ok(mod_info)
}
}
#[cfg(feature = "validate")]
fn validate_atomic_compare_exchange_struct(
types: &UniqueArena<crate::Type>,
members: &[crate::StructMember],
scalar_predicate: impl FnOnce(&crate::TypeInner) -> bool,
) -> bool {
members.len() == 2
&& members[0].name.as_deref() == Some("old_value")
&& scalar_predicate(&types[members[0].ty].inner)
&& members[1].name.as_deref() == Some("exchanged")
&& types[members[1].ty].inner
== crate::TypeInner::Scalar {
kind: crate::ScalarKind::Bool,
width: crate::BOOL_WIDTH,
}
}

6
third_party/rust/naga/src/valid/type.rs поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
use super::Capabilities;
use crate::{
arena::{Arena, BadHandle, Handle, UniqueArena},
arena::{Arena, Handle, UniqueArena},
proc::Alignment,
};
@ -88,8 +88,6 @@ pub enum Disalignment {
#[derive(Clone, Debug, thiserror::Error)]
pub enum TypeError {
#[error(transparent)]
BadHandle(#[from] BadHandle),
#[error("The {0:?} scalar width {1} is not supported")]
InvalidWidth(crate::ScalarKind, crate::Bytes),
#[error("The {0:?} scalar width {1} is not supported for an atomic")]
@ -418,7 +416,7 @@ impl super::Validator {
let sized_flag = match size {
crate::ArraySize::Constant(const_handle) => {
let constant = constants.try_get(const_handle)?;
let constant = &constants[const_handle];
let length_is_positive = match *constant {
crate::Constant {
specialization: Some(_),

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"70b60e663e9ad3847924f1a5aa12e88b634aae3a1dff92b691c1c7586e520b75","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"3b9180c91a30ffaffaddaa734ee99e7a0e68b1da1bf3963eae447fa69cfae2ef","src/command/bind.rs":"88ca2bedfcd8392efc960f39ca8506024af495dcf1852cf16ae28fbadbdf748d","src/command/bundle.rs":"9420e25cf05f28170cce81df0d20e67f4dbe5b54588c0541e01008dde4bf7b45","src/command/clear.rs":"cc118937b7a0b05225a2417db2f11bb95a095b0ca63561db092a8dfab35d9158","src/command/compute.rs":"f2a08528e39e3cc7049757e9d63d591c8adc9bffa3af66d57eee0e6ab7bc3015","src/command/draw.rs":"ac3541fb46435dd1687b24b24d9896104adde8f662111f232b7b4e8e34a869ea","src/command/memory_init.rs":"347117a84f35927de91e7ab4cc69d19b5b4507a942596c0c725f27b50c428b1e","src/command/mod.rs":"31623431b6dc1c061dedcb838949d4c81d4e95d5516be47524d53b3d2faef3e6","src/command/query.rs":"2c107b22806a003808da2f886ecc74764b016851b7a6cec8caf21385a2e25dee","src/command/render.rs":"d62d2ec5344312f78714d294ffc53686f993accd84925af29700073dc1d1b117","src/command/transfer.rs":"5321de8440653e3c69970816d3df8e628ae31fc7c5a03125f1cc8ed244e13f68","src/conv.rs":"c4506a7f715461d67c2bcfef002f13d3e75d10b2e4f18b0ab9ea8d5bdeb7bc61","src/device/life.rs":"5f58817365cf8b0a76cab83fdb50b3ee69a15b2bd868bc3702c7c29f3189326c","src/device/mod.rs":"5019dcbdda406700b3e7121055eba7936b8cd403517e5711fabaf1421f8fd6a6","src/device/queue.rs":"883a0bd1c8d3cddc46393e9eeb76bedce9ce48d1467a767d9839db7934252ad9","src/device/trace.rs":"9c03f5ec06cae37f294179a2285e2af7a5497db8a5572bf1dbe50136943d69be","src/error.rs":"7e914b25a2b9578672eb4a8b52c778ad947e12e0f24b44a8453cda48a249b39c","src/hub.rs":"1be76bb6c1cae694e891d6798789ed9748535b42b042f44cad09d939dbc802c1","src/id.rs":"608dfbdc118905638762d0a16e4f69b0ecae16bbe20accead2d7d9b7e7281dda","src/init_tracker/buffer.rs":"a0ebf54a1e6d269c7b4aa0ac7bb8b04fd2cea3221a1d058ff33cb683b2aea3e9","src/init_tracker/mod.rs":"0867f79f83555390d0982d1dc6dcf0d4340e10cb89aa633d3c3ecc45deb3c78c","src/init_tracker/texture.rs":"11de3b1968829aec1f165930d9e4f946d6c02c7994ce32925a62f883820aa1e3","src/instance.rs":"12f4204755c67eaf82013142c4e6ff8e3ad4e74adf07c00f7d20caa1fd2a09e6","src/lib.rs":"206c07ef386628a9b8e0f8ad45415c9eb9b55418c3636cc9e6aba63eb6ed5978","src/pipeline.rs":"38e9fff13e7e152378e95dc13822dab62542d4b172f006a34d84eebb70bed0f7","src/present.rs":"7c00b8bc3475d9a100adf5c9e9d0af823aa14b626e923f87ec988022bd4766d1","src/resource.rs":"c23933592838688d86986a0f6c449df6eaefa8b770e10c512d849a7a497b92a7","src/track/buffer.rs":"0b7a8c6acfe55e3f45dd1e7ef1b3ee8bd4844f61bbabf62aa4f0c391b822803c","src/track/metadata.rs":"9565f700661e81fd534a751a0e3d26022238ad8784cc868333da7030b3571473","src/track/mod.rs":"995a8cd73499a26b593d0a419630681ea7942cec8db132ae8a13baf69fe13cdc","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"34942ecdf81b05b75892c891c87e065329870459ff8edfca1f99ec9533c334aa","src/track/texture.rs":"7d38b2f4e0cdb3e56ce1e777d8bca4d73ef40e21c56e11fedd69dc27e789256d","src/validation.rs":"03d3a99410c5f6ec937358206ea76eafff31823ebbe443ab71facf8a8b6a95e8"},"package":null}
{"files":{"Cargo.toml":"f60e44d9830853a7ed495f083d9aa032987a85ef07b84fdb9efe6d0aab7dba41","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/binding_model.rs":"3b9180c91a30ffaffaddaa734ee99e7a0e68b1da1bf3963eae447fa69cfae2ef","src/command/bind.rs":"88ca2bedfcd8392efc960f39ca8506024af495dcf1852cf16ae28fbadbdf748d","src/command/bundle.rs":"9420e25cf05f28170cce81df0d20e67f4dbe5b54588c0541e01008dde4bf7b45","src/command/clear.rs":"cc118937b7a0b05225a2417db2f11bb95a095b0ca63561db092a8dfab35d9158","src/command/compute.rs":"f2a08528e39e3cc7049757e9d63d591c8adc9bffa3af66d57eee0e6ab7bc3015","src/command/draw.rs":"ac3541fb46435dd1687b24b24d9896104adde8f662111f232b7b4e8e34a869ea","src/command/memory_init.rs":"347117a84f35927de91e7ab4cc69d19b5b4507a942596c0c725f27b50c428b1e","src/command/mod.rs":"31623431b6dc1c061dedcb838949d4c81d4e95d5516be47524d53b3d2faef3e6","src/command/query.rs":"2c107b22806a003808da2f886ecc74764b016851b7a6cec8caf21385a2e25dee","src/command/render.rs":"d62d2ec5344312f78714d294ffc53686f993accd84925af29700073dc1d1b117","src/command/transfer.rs":"5321de8440653e3c69970816d3df8e628ae31fc7c5a03125f1cc8ed244e13f68","src/conv.rs":"c4506a7f715461d67c2bcfef002f13d3e75d10b2e4f18b0ab9ea8d5bdeb7bc61","src/device/life.rs":"5f58817365cf8b0a76cab83fdb50b3ee69a15b2bd868bc3702c7c29f3189326c","src/device/mod.rs":"e55e6508c1e268fc6509b5a7c504cf6b208492a30dcabb15ac428c9459e455d2","src/device/queue.rs":"62f473e01320f334f72ee2b06bcfb0c070c945d1785dee1e42ca80a69e9f31d1","src/device/trace.rs":"9c03f5ec06cae37f294179a2285e2af7a5497db8a5572bf1dbe50136943d69be","src/error.rs":"7e914b25a2b9578672eb4a8b52c778ad947e12e0f24b44a8453cda48a249b39c","src/hub.rs":"1be76bb6c1cae694e891d6798789ed9748535b42b042f44cad09d939dbc802c1","src/id.rs":"10e101272faf04495b25e37284b0c7620392bb8ee7f2a82247d8e0a858087d04","src/init_tracker/buffer.rs":"a0ebf54a1e6d269c7b4aa0ac7bb8b04fd2cea3221a1d058ff33cb683b2aea3e9","src/init_tracker/mod.rs":"0867f79f83555390d0982d1dc6dcf0d4340e10cb89aa633d3c3ecc45deb3c78c","src/init_tracker/texture.rs":"11de3b1968829aec1f165930d9e4f946d6c02c7994ce32925a62f883820aa1e3","src/instance.rs":"12f4204755c67eaf82013142c4e6ff8e3ad4e74adf07c00f7d20caa1fd2a09e6","src/lib.rs":"206c07ef386628a9b8e0f8ad45415c9eb9b55418c3636cc9e6aba63eb6ed5978","src/pipeline.rs":"38e9fff13e7e152378e95dc13822dab62542d4b172f006a34d84eebb70bed0f7","src/present.rs":"7c00b8bc3475d9a100adf5c9e9d0af823aa14b626e923f87ec988022bd4766d1","src/resource.rs":"0ae6b65c8ece54f04bef98451a348571d9757360bd95d765c84832ac811ddaff","src/track/buffer.rs":"0b7a8c6acfe55e3f45dd1e7ef1b3ee8bd4844f61bbabf62aa4f0c391b822803c","src/track/metadata.rs":"9565f700661e81fd534a751a0e3d26022238ad8784cc868333da7030b3571473","src/track/mod.rs":"995a8cd73499a26b593d0a419630681ea7942cec8db132ae8a13baf69fe13cdc","src/track/range.rs":"5bbfed6e103b3234d9de8e42057022da6d628c2cc1db6bb51b88f87f2d8adf8b","src/track/stateless.rs":"34942ecdf81b05b75892c891c87e065329870459ff8edfca1f99ec9533c334aa","src/track/texture.rs":"7d38b2f4e0cdb3e56ce1e777d8bca4d73ef40e21c56e11fedd69dc27e789256d","src/validation.rs":"432c83c310c655781ba6a053e1a48c4b79e6450610c1c4dee715845efc11e76b"},"package":null}

3
third_party/rust/wgpu-core/Cargo.toml поставляемый
Просмотреть файл

@ -45,7 +45,6 @@ serial-pass = ["serde", "wgt/serde", "arrayvec/serde"]
id32 = []
# Enable `ShaderModuleSource::Wgsl`
wgsl = ["naga/wgsl-in"]
vulkan-portability = ["hal/vulkan"]
# Features that are intended to work on all platforms.
portable_features = ["gles", "strict_asserts", "trace", "replay", "serial-pass", "id32", "wgsl"]
@ -68,7 +67,7 @@ thiserror = "1"
[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e7fc8e6"
rev = "e98bd92"
version = "0.10"
features = ["clone", "span", "validate"]

Просмотреть файл

@ -1170,6 +1170,12 @@ impl<A: HalApi> Device<A> {
self.require_features(wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO)?;
}
if desc.lod_min_clamp < 0.0 || desc.lod_max_clamp < desc.lod_min_clamp {
return Err(resource::CreateSamplerError::InvalidLodClamp(
desc.lod_min_clamp..desc.lod_max_clamp,
));
}
let lod_clamp = if desc.lod_min_clamp > 0.0 || desc.lod_max_clamp < 32.0 {
Some(desc.lod_min_clamp..desc.lod_max_clamp)
} else {

Просмотреть файл

@ -595,7 +595,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
let (mut texture_guard, _) = hub.textures.write(&mut token); // For clear we need write access to the texture. TODO: Can we acquire write lock later?
let dst = texture_guard.get_mut(destination.texture).unwrap();
let dst = texture_guard
.get_mut(destination.texture)
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
let (selector, dst_base, texture_format) =
extract_texture_selector(destination, size, dst)?;
@ -707,6 +709,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
// Re-get `dst` immutably here, so that the mutable borrow of the
// `texture_guard.get_mut` above ends in time for the `clear_texture`
// call above. Since we've held `texture_guard` the whole time, we know
// the texture hasn't gone away in the mean time, so we can unwrap.
let dst = texture_guard.get(destination.texture).unwrap();
let transition = trackers
.textures

5
third_party/rust/wgpu-core/src/id.rs поставляемый
Просмотреть файл

@ -172,7 +172,6 @@ pub(crate) struct Valid<I>(pub I);
/// need to construct `Id` values directly, or access their components, like the
/// WGPU recording player, may use this trait to do so.
pub trait TypedId: Copy {
fn as_raw(&self) -> NonZeroId;
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self;
fn unzip(self) -> (Index, Epoch, Backend);
fn into_raw(self) -> NonZeroId;
@ -180,10 +179,6 @@ pub trait TypedId: Copy {
#[allow(trivial_numeric_casts)]
impl<T> TypedId for Id<T> {
fn as_raw(&self) -> NonZeroId {
self.0
}
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
assert_eq!(0, epoch >> EPOCH_BITS);
assert_eq!(0, (index as IdType) >> INDEX_BITS);

2
third_party/rust/wgpu-core/src/resource.rs поставляемый
Просмотреть файл

@ -701,6 +701,8 @@ pub struct Sampler<A: hal::Api> {
pub enum CreateSamplerError {
#[error(transparent)]
Device(#[from] DeviceError),
#[error("invalid lod clamp lod_min_clamp:{} lod_max_clamp:{}, must satisfy lod_min_clamp >= 0 and lod_max_clamp >= lod_min_clamp ", .0.start, .0.end)]
InvalidLodClamp(Range<f32>),
#[error("invalid anisotropic clamp {0}, must be one of 1, 2, 4, 8 or 16")]
InvalidClamp(u8),
#[error("cannot create any more samplers")]

41
third_party/rust/wgpu-core/src/validation.rs поставляемый
Просмотреть файл

@ -212,10 +212,10 @@ pub enum BindingError {
#[derive(Clone, Debug, Error)]
pub enum FilteringError {
#[error("integer textures can't be sampled")]
#[error("integer textures can't be sampled with a filtering sampler")]
Integer,
#[error("non-filterable float texture")]
NonFilterable,
#[error("non-filterable float textures can't be sampled with a filtering sampler")]
Float,
}
#[derive(Clone, Debug, Error)]
@ -1049,27 +1049,22 @@ impl Interface {
assert!(texture_layout.visibility.contains(stage_bit));
assert!(sampler_layout.visibility.contains(stage_bit));
let error = match texture_layout.ty {
wgt::BindingType::Texture {
sample_type: wgt::TextureSampleType::Float { filterable },
..
} => match sampler_layout.ty {
wgt::BindingType::Sampler(wgt::SamplerBindingType::Filtering)
if !filterable =>
{
Some(FilteringError::NonFilterable)
}
_ => None,
},
wgt::BindingType::Texture {
sample_type: wgt::TextureSampleType::Sint,
..
let sampler_filtering = matches!(
sampler_layout.ty,
wgt::BindingType::Sampler(wgt::SamplerBindingType::Filtering)
);
let texture_sample_type = match texture_layout.ty {
BindingType::Texture { sample_type, .. } => sample_type,
_ => unreachable!(),
};
let error = match (sampler_filtering, texture_sample_type) {
(true, wgt::TextureSampleType::Float { filterable: false }) => {
Some(FilteringError::Float)
}
| wgt::BindingType::Texture {
sample_type: wgt::TextureSampleType::Uint,
..
} => Some(FilteringError::Integer),
_ => None, // unreachable, really
(true, wgt::TextureSampleType::Sint) => Some(FilteringError::Integer),
(true, wgt::TextureSampleType::Uint) => Some(FilteringError::Integer),
_ => None,
};
if let Some(error) = error {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

6
third_party/rust/wgpu-hal/Cargo.toml поставляемый
Просмотреть файл

@ -63,7 +63,7 @@ block = { version = "0.1", optional = true }
foreign-types = { version = "0.3", optional = true }
# backend: Vulkan
ash = { version = "0.37.1", optional = true }
ash = { version = "0.37.2", optional = true }
gpu-alloc = { version = "0.5", optional = true }
gpu-descriptor = { version = "0.2", optional = true }
smallvec = { version = "1", optional = true, features = ["union"] }
@ -111,14 +111,14 @@ android_system_properties = "0.1.1"
[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e7fc8e6"
rev = "e98bd92"
version = "0.10"
features = ["clone"]
# DEV dependencies
[dev-dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e7fc8e6"
rev = "e98bd92"
version = "0.10"
features = ["wgsl-in"]

49
third_party/rust/wgpu-hal/src/dx12/command.rs поставляемый
Просмотреть файл

@ -228,20 +228,34 @@ impl super::CommandEncoder {
impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
let list = match self.free_lists.pop() {
Some(list) => {
list.reset(self.allocator, native::PipelineState::null());
list
let list = loop {
if let Some(list) = self.free_lists.pop() {
let reset_result = list
.reset(self.allocator, native::PipelineState::null())
.into_result();
if reset_result.is_ok() {
break Some(list);
} else {
unsafe {
list.destroy();
}
}
} else {
break None;
}
None => self
.device
};
let list = if let Some(list) = list {
list
} else {
self.device
.create_graphics_command_list(
native::CmdListType::Direct,
self.allocator,
native::PipelineState::null(),
0,
)
.into_device_result("Create command list")?,
.into_device_result("Create command list")?
};
if let Some(label) = label {
@ -256,18 +270,29 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
unsafe fn discard_encoding(&mut self) {
if let Some(list) = self.list.take() {
list.close();
self.free_lists.push(list);
if list.close().into_result().is_ok() {
self.free_lists.push(list);
} else {
unsafe {
list.destroy();
}
}
}
}
unsafe fn end_encoding(&mut self) -> Result<super::CommandBuffer, crate::DeviceError> {
let raw = self.list.take().unwrap();
raw.close();
Ok(super::CommandBuffer { raw })
let closed = raw.close().into_result().is_ok();
Ok(super::CommandBuffer { raw, closed })
}
unsafe fn reset_all<I: Iterator<Item = super::CommandBuffer>>(&mut self, command_buffers: I) {
for cmd_buf in command_buffers {
self.free_lists.push(cmd_buf.raw);
if cmd_buf.closed {
self.free_lists.push(cmd_buf.raw);
} else {
unsafe {
cmd_buf.raw.destroy();
}
}
}
self.allocator.reset();
}

1
third_party/rust/wgpu-hal/src/dx12/mod.rs поставляемый
Просмотреть файл

@ -367,6 +367,7 @@ impl fmt::Debug for CommandEncoder {
#[derive(Debug)]
pub struct CommandBuffer {
raw: native::GraphicsCommandList,
closed: bool,
}
unsafe impl Send for CommandBuffer {}

48
third_party/rust/wgpu-hal/src/gles/conv.rs поставляемый
Просмотреть файл

@ -439,6 +439,52 @@ pub(super) fn is_sampler(glsl_uniform_type: u32) -> bool {
}
}
pub(super) fn is_image(glsl_uniform_type: u32) -> bool {
match glsl_uniform_type {
glow::INT_IMAGE_1D
| glow::INT_IMAGE_1D_ARRAY
| glow::INT_IMAGE_2D
| glow::INT_IMAGE_2D_ARRAY
| glow::INT_IMAGE_2D_MULTISAMPLE
| glow::INT_IMAGE_2D_MULTISAMPLE_ARRAY
| glow::INT_IMAGE_2D_RECT
| glow::INT_IMAGE_3D
| glow::INT_IMAGE_CUBE
| glow::INT_IMAGE_CUBE_MAP_ARRAY
| glow::UNSIGNED_INT_IMAGE_1D
| glow::UNSIGNED_INT_IMAGE_1D_ARRAY
| glow::UNSIGNED_INT_IMAGE_2D
| glow::UNSIGNED_INT_IMAGE_2D_ARRAY
| glow::UNSIGNED_INT_IMAGE_2D_MULTISAMPLE
| glow::UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY
| glow::UNSIGNED_INT_IMAGE_2D_RECT
| glow::UNSIGNED_INT_IMAGE_3D
| glow::UNSIGNED_INT_IMAGE_CUBE
| glow::UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY
| glow::IMAGE_1D
| glow::IMAGE_1D_ARRAY
| glow::IMAGE_2D
| glow::IMAGE_2D_ARRAY
| glow::IMAGE_2D_MULTISAMPLE
| glow::IMAGE_2D_MULTISAMPLE_ARRAY
| glow::IMAGE_2D_RECT
| glow::IMAGE_3D
| glow::IMAGE_CUBE
| glow::IMAGE_CUBE_MAP_ARRAY => true,
_ => false,
}
}
pub(super) fn is_atomic_counter(glsl_uniform_type: u32) -> bool {
glsl_uniform_type == glow::UNSIGNED_INT_ATOMIC_COUNTER
}
pub(super) fn is_opaque_type(glsl_uniform_type: u32) -> bool {
is_sampler(glsl_uniform_type)
|| is_image(glsl_uniform_type)
|| is_atomic_counter(glsl_uniform_type)
}
pub(super) fn uniform_byte_size(glsl_uniform_type: u32) -> u32 {
match glsl_uniform_type {
glow::FLOAT | glow::INT => 4,
@ -448,6 +494,6 @@ pub(super) fn uniform_byte_size(glsl_uniform_type: u32) -> u32 {
glow::FLOAT_MAT2 => 16,
glow::FLOAT_MAT3 => 36,
glow::FLOAT_MAT4 => 64,
_ => panic!("Unsupported uniform datatype!"),
_ => panic!("Unsupported uniform datatype! {glsl_uniform_type:#X}"),
}
}

Просмотреть файл

@ -372,7 +372,8 @@ impl super::Device {
}
}
let mut uniforms: [super::UniformDesc; super::MAX_PUSH_CONSTANTS] = Default::default();
let mut uniforms: [super::UniformDesc; super::MAX_PUSH_CONSTANTS] =
[None; super::MAX_PUSH_CONSTANTS].map(|_: Option<()>| Default::default());
let count = unsafe { gl.get_active_uniforms(program) };
let mut offset = 0;
@ -380,7 +381,7 @@ impl super::Device {
let glow::ActiveUniform { utype, name, .. } =
unsafe { gl.get_active_uniform(program, uniform) }.unwrap();
if conv::is_sampler(utype) {
if conv::is_opaque_type(utype) {
continue;
}

2
third_party/rust/wgpu-hal/src/gles/mod.rs поставляемый
Просмотреть файл

@ -95,7 +95,7 @@ const MAX_TEXTURE_SLOTS: usize = 16;
const MAX_SAMPLERS: usize = 16;
const MAX_VERTEX_ATTRIBUTES: usize = 16;
const ZERO_BUFFER_SIZE: usize = 256 << 10;
const MAX_PUSH_CONSTANTS: usize = 16;
const MAX_PUSH_CONSTANTS: usize = 64;
impl crate::Api for Api {
type Instance = Instance;

Просмотреть файл

@ -5,6 +5,10 @@ use parking_lot::Mutex;
use std::{collections::BTreeMap, ffi::CStr, sync::Arc};
fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
vk::FormatFeatureFlags::SAMPLED_IMAGE | vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT
}
//TODO: const fn?
fn indexing_features() -> wgt::Features {
wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
@ -172,9 +176,7 @@ impl PhysicalDeviceFeatures {
//.shader_resource_residency(requested_features.contains(wgt::Features::SHADER_RESOURCE_RESIDENCY))
.geometry_shader(requested_features.contains(wgt::Features::SHADER_PRIMITIVE_INDEX))
.build(),
descriptor_indexing: if enabled_extensions
.contains(&vk::ExtDescriptorIndexingFn::name())
{
descriptor_indexing: if requested_features.intersects(indexing_features()) {
Some(
vk::PhysicalDeviceDescriptorIndexingFeaturesEXT::builder()
.shader_sampled_image_array_non_uniform_indexing(
@ -229,7 +231,9 @@ impl PhysicalDeviceFeatures {
} else {
None
},
image_robustness: if enabled_extensions.contains(&vk::ExtImageRobustnessFn::name()) {
image_robustness: if effective_api_version >= vk::API_VERSION_1_3
|| enabled_extensions.contains(&vk::ExtImageRobustnessFn::name())
{
Some(
vk::PhysicalDeviceImageRobustnessFeaturesEXT::builder()
.robust_image_access(private_caps.robust_image_access)
@ -325,7 +329,6 @@ impl PhysicalDeviceFeatures {
| Df::VERTEX_STORAGE
| Df::FRAGMENT_STORAGE
| Df::DEPTH_TEXTURE_AND_BUFFER_COPIES
| Df::WEBGPU_TEXTURE_FORMAT_SUPPORT
| Df::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED
| Df::UNRESTRICTED_INDEX_BUFFER
| Df::INDIRECT_EXECUTION;
@ -412,7 +415,7 @@ impl PhysicalDeviceFeatures {
//if caps.supports_extension(vk::ExtSamplerFilterMinmaxFn::name()) {
features.set(
F::MULTI_DRAW_INDIRECT_COUNT,
caps.supports_extension(khr::DrawIndirectCount::name()),
caps.supports_extension(vk::KhrDrawIndirectCountFn::name()),
);
features.set(
F::CONSERVATIVE_RASTERIZATION,
@ -487,17 +490,31 @@ impl PhysicalDeviceFeatures {
);
}
features.set(
F::DEPTH32FLOAT_STENCIL8,
let supports_depth_format = |format| {
supports_format(
instance,
phd,
vk::Format::D32_SFLOAT_S8_UINT,
format,
vk::ImageTiling::OPTIMAL,
vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT,
),
depth_stencil_required_flags(),
)
};
let texture_s8 = supports_depth_format(vk::Format::S8_UINT);
let texture_d32 = supports_depth_format(vk::Format::D32_SFLOAT);
let texture_d24_s8 = supports_depth_format(vk::Format::D24_UNORM_S8_UINT);
let texture_d32_s8 = supports_depth_format(vk::Format::D32_SFLOAT_S8_UINT);
let stencil8 = texture_s8 || texture_d24_s8;
let depth24_plus_stencil8 = texture_d24_s8 || texture_d32_s8;
dl_flags.set(
Df::WEBGPU_TEXTURE_FORMAT_SUPPORT,
stencil8 && depth24_plus_stencil8 && texture_d32,
);
features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8);
(features, dl_flags)
}
@ -554,78 +571,118 @@ impl PhysicalDeviceCapabilities {
fn get_required_extensions(&self, requested_features: wgt::Features) -> Vec<&'static CStr> {
let mut extensions = Vec::new();
extensions.push(khr::Swapchain::name());
// Note that quite a few extensions depend on the `VK_KHR_get_physical_device_properties2` instance extension.
// We enable `VK_KHR_get_physical_device_properties2` unconditionally (if available).
// Require `VK_KHR_swapchain`
extensions.push(vk::KhrSwapchainFn::name());
if self.effective_api_version < vk::API_VERSION_1_1 {
extensions.push(vk::KhrMaintenance1Fn::name());
extensions.push(vk::KhrMaintenance2Fn::name());
// `VK_KHR_storage_buffer_storage_class` required for Naga on Vulkan 1.0 devices
extensions.push(vk::KhrStorageBufferStorageClassFn::name());
// Below Vulkan 1.1 we can get multiview from an extension
if requested_features.contains(wgt::Features::MULTIVIEW) {
extensions.push(vk::KhrMultiviewFn::name());
// Require either `VK_KHR_maintenance1` or `VK_AMD_negative_viewport_height`
if self.supports_extension(vk::KhrMaintenance1Fn::name()) {
extensions.push(vk::KhrMaintenance1Fn::name());
} else {
// `VK_AMD_negative_viewport_height` is obsoleted by `VK_KHR_maintenance1` and must not be enabled alongside it
extensions.push(vk::AmdNegativeViewportHeightFn::name());
}
// `VK_AMD_negative_viewport_height` is obsoleted by `VK_KHR_maintenance1` and must not be enabled alongside `VK_KHR_maintenance1` or a 1.1+ device.
if !self.supports_extension(vk::KhrMaintenance1Fn::name()) {
extensions.push(vk::AmdNegativeViewportHeightFn::name());
// Optional `VK_KHR_maintenance2`
if self.supports_extension(vk::KhrMaintenance2Fn::name()) {
extensions.push(vk::KhrMaintenance2Fn::name());
}
// Require `VK_KHR_storage_buffer_storage_class`
extensions.push(vk::KhrStorageBufferStorageClassFn::name());
// Require `VK_KHR_multiview` if the associated feature was requested
if requested_features.contains(wgt::Features::MULTIVIEW) {
extensions.push(vk::KhrMultiviewFn::name());
}
}
if self.effective_api_version < vk::API_VERSION_1_2 {
// Optional `VK_KHR_imageless_framebuffer`
if self.supports_extension(vk::KhrImagelessFramebufferFn::name()) {
extensions.push(vk::KhrImagelessFramebufferFn::name());
extensions.push(vk::KhrImageFormatListFn::name()); // Required for `KhrImagelessFramebufferFn`
// Require `VK_KHR_image_format_list` due to it being a dependency
extensions.push(vk::KhrImageFormatListFn::name());
// Require `VK_KHR_maintenance2` due to it being a dependency
if self.effective_api_version < vk::API_VERSION_1_1 {
extensions.push(vk::KhrMaintenance2Fn::name());
}
}
// This extension is core in Vulkan 1.2
// Optional `VK_KHR_driver_properties`
if self.supports_extension(vk::KhrDriverPropertiesFn::name()) {
extensions.push(vk::KhrDriverPropertiesFn::name());
}
extensions.push(vk::ExtSamplerFilterMinmaxFn::name());
extensions.push(vk::KhrTimelineSemaphoreFn::name());
// Optional `VK_KHR_timeline_semaphore`
if self.supports_extension(vk::KhrTimelineSemaphoreFn::name()) {
extensions.push(vk::KhrTimelineSemaphoreFn::name());
}
// Require `VK_EXT_descriptor_indexing` if one of the associated features was requested
if requested_features.intersects(indexing_features()) {
extensions.push(vk::ExtDescriptorIndexingFn::name());
// Require `VK_KHR_maintenance3` due to it being a dependency
if self.effective_api_version < vk::API_VERSION_1_1 {
extensions.push(vk::KhrMaintenance3Fn::name());
}
}
// Require `VK_KHR_shader_float16_int8` and `VK_KHR_16bit_storage` if the associated feature was requested
if requested_features.contains(wgt::Features::SHADER_FLOAT16) {
extensions.push(vk::KhrShaderFloat16Int8Fn::name());
// `VK_KHR_16bit_storage` requires `VK_KHR_storage_buffer_storage_class`, however we require that one already
if self.effective_api_version < vk::API_VERSION_1_1 {
extensions.push(vk::Khr16bitStorageFn::name());
}
}
//extensions.push(vk::KhrSamplerMirrorClampToEdgeFn::name());
//extensions.push(vk::ExtSamplerFilterMinmaxFn::name());
}
if self.effective_api_version < vk::API_VERSION_1_3 {
// Optional `VK_EXT_image_robustness`
if self.supports_extension(vk::ExtImageRobustnessFn::name()) {
extensions.push(vk::ExtImageRobustnessFn::name());
}
}
// Optional `VK_EXT_robustness2`
if self.supports_extension(vk::ExtRobustness2Fn::name()) {
extensions.push(vk::ExtRobustness2Fn::name());
}
// Require `VK_KHR_draw_indirect_count` if the associated feature was requested
// Even though Vulkan 1.2 has promoted the extension to core, we must require the extension to avoid
// large amounts of spaghetti involved with using PhysicalDeviceVulkan12Features.
if requested_features.contains(wgt::Features::MULTI_DRAW_INDIRECT_COUNT) {
extensions.push(vk::KhrDrawIndirectCountFn::name());
}
// Require `VK_EXT_conservative_rasterization` if the associated feature was requested
if requested_features.contains(wgt::Features::CONSERVATIVE_RASTERIZATION) {
extensions.push(vk::ExtConservativeRasterizationFn::name());
}
// Require `VK_EXT_depth_clip_enable` if the associated feature was requested
if requested_features.contains(wgt::Features::DEPTH_CLIP_CONTROL) {
extensions.push(vk::ExtDepthClipEnableFn::name());
}
// Require `VK_KHR_portability_subset` on macOS/iOS
#[cfg(any(target_os = "macos", target_os = "ios"))]
extensions.push(vk::KhrPortabilitySubsetFn::name());
// Require `VK_EXT_texture_compression_astc_hdr` if the associated feature was requested
if requested_features.contains(wgt::Features::TEXTURE_COMPRESSION_ASTC_HDR) {
extensions.push(vk::ExtTextureCompressionAstcHdrFn::name());
}
if requested_features.contains(wgt::Features::SHADER_FLOAT16) {
extensions.push(vk::KhrShaderFloat16Int8Fn::name());
extensions.push(vk::Khr16bitStorageFn::name());
}
extensions
}
@ -762,13 +819,12 @@ impl super::InstanceShared {
self.get_physical_device_properties
{
// Get these now to avoid borrowing conflicts later
let supports_descriptor_indexing =
capabilities.supports_extension(vk::ExtDescriptorIndexingFn::name());
let supports_driver_properties = capabilities.properties.api_version
>= vk::API_VERSION_1_2
let supports_descriptor_indexing = self.driver_api_version >= vk::API_VERSION_1_2
|| capabilities.supports_extension(vk::ExtDescriptorIndexingFn::name());
let supports_driver_properties = self.driver_api_version >= vk::API_VERSION_1_2
|| capabilities.supports_extension(vk::KhrDriverPropertiesFn::name());
let mut builder = vk::PhysicalDeviceProperties2::builder();
let mut builder = vk::PhysicalDeviceProperties2KHR::builder();
if supports_descriptor_indexing {
let next = capabilities
@ -1002,27 +1058,27 @@ impl super::Instance {
.timeline_semaphore
.map_or(false, |ext| ext.timeline_semaphore != 0),
},
texture_d24: unsafe {
self.shared
.raw
.get_physical_device_format_properties(phd, vk::Format::X8_D24_UNORM_PACK32)
.optimal_tiling_features
.contains(vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT)
},
texture_d24_s8: unsafe {
self.shared
.raw
.get_physical_device_format_properties(phd, vk::Format::D24_UNORM_S8_UINT)
.optimal_tiling_features
.contains(vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT)
},
texture_s8: unsafe {
self.shared
.raw
.get_physical_device_format_properties(phd, vk::Format::S8_UINT)
.optimal_tiling_features
.contains(vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT)
},
texture_d24: supports_format(
&self.shared.raw,
phd,
vk::Format::X8_D24_UNORM_PACK32,
vk::ImageTiling::OPTIMAL,
depth_stencil_required_flags(),
),
texture_d24_s8: supports_format(
&self.shared.raw,
phd,
vk::Format::D24_UNORM_S8_UINT,
vk::ImageTiling::OPTIMAL,
depth_stencil_required_flags(),
),
texture_s8: supports_format(
&self.shared.raw,
phd,
vk::Format::S8_UINT,
vk::ImageTiling::OPTIMAL,
depth_stencil_required_flags(),
),
non_coherent_map_mask: phd_capabilities.properties.limits.non_coherent_atom_size - 1,
can_present: true,
//TODO: make configurable
@ -1411,10 +1467,10 @@ impl crate::Adapter<super::Api> for super::Adapter {
Tfc::SAMPLED_LINEAR,
features.contains(vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR),
);
flags.set(
Tfc::SAMPLED_MINMAX,
features.contains(vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_MINMAX),
);
// flags.set(
// Tfc::SAMPLED_MINMAX,
// features.contains(vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_MINMAX),
// );
flags.set(
Tfc::STORAGE | Tfc::STORAGE_READ_WRITE,
features.contains(vk::FormatFeatureFlags::STORAGE_IMAGE),
@ -1437,15 +1493,11 @@ impl crate::Adapter<super::Api> for super::Adapter {
);
flags.set(
Tfc::COPY_SRC,
features.intersects(
vk::FormatFeatureFlags::TRANSFER_SRC | vk::FormatFeatureFlags::BLIT_SRC,
),
features.intersects(vk::FormatFeatureFlags::TRANSFER_SRC),
);
flags.set(
Tfc::COPY_DST,
features.intersects(
vk::FormatFeatureFlags::TRANSFER_DST | vk::FormatFeatureFlags::BLIT_DST,
),
features.intersects(vk::FormatFeatureFlags::TRANSFER_DST),
);
// Vulkan is very permissive about MSAA
flags.set(Tfc::MULTISAMPLE_RESOLVE, !format.describe().is_compressed());

Просмотреть файл

@ -153,6 +153,7 @@ impl super::Instance {
pub fn required_extensions(
entry: &ash::Entry,
_driver_api_version: u32,
flags: crate::InstanceFlags,
) -> Result<Vec<&'static CStr>, crate::InstanceError> {
let instance_extensions = entry
@ -164,6 +165,8 @@ impl super::Instance {
// Check our extensions against the available extensions
let mut extensions: Vec<&'static CStr> = Vec::new();
// VK_KHR_surface
extensions.push(khr::Surface::name());
// Platform-specific WSI extensions
@ -172,29 +175,40 @@ impl super::Instance {
not(target_os = "android"),
not(target_os = "macos")
)) {
// VK_KHR_xlib_surface
extensions.push(khr::XlibSurface::name());
// VK_KHR_xcb_surface
extensions.push(khr::XcbSurface::name());
// VK_KHR_wayland_surface
extensions.push(khr::WaylandSurface::name());
}
if cfg!(target_os = "android") {
// VK_KHR_android_surface
extensions.push(khr::AndroidSurface::name());
}
if cfg!(target_os = "windows") {
// VK_KHR_win32_surface
extensions.push(khr::Win32Surface::name());
}
if cfg!(target_os = "macos") {
// VK_EXT_metal_surface
extensions.push(ext::MetalSurface::name());
}
if flags.contains(crate::InstanceFlags::DEBUG) {
// VK_EXT_debug_utils
extensions.push(ext::DebugUtils::name());
}
extensions.push(vk::KhrGetPhysicalDeviceProperties2Fn::name());
// VK_EXT_swapchain_colorspace
// Provid wide color gamut
extensions.push(vk::ExtSwapchainColorspaceFn::name());
// VK_KHR_get_physical_device_properties2
// Even though the extension was promoted to Vulkan 1.1, we still require the extension
// so that we don't have to conditionally use the functions provided by the 1.1 instance
extensions.push(vk::KhrGetPhysicalDeviceProperties2Fn::name());
// Only keep available extensions.
extensions.retain(|&ext| {
if instance_extensions.iter().any(|inst_ext| {
@ -262,19 +276,16 @@ impl super::Instance {
None
};
// We can't use any of Vulkan-1.1+ abilities on Vk 1.0 instance,
// so disabling this query helps.
let get_physical_device_properties = if driver_api_version >= vk::API_VERSION_1_1
&& extensions.contains(&khr::GetPhysicalDeviceProperties2::name())
{
log::info!("Enabling device properties2");
Some(khr::GetPhysicalDeviceProperties2::new(
&entry,
&raw_instance,
))
} else {
None
};
let get_physical_device_properties =
if extensions.contains(&khr::GetPhysicalDeviceProperties2::name()) {
log::info!("Enabling device properties2");
Some(khr::GetPhysicalDeviceProperties2::new(
&entry,
&raw_instance,
))
} else {
None
};
Ok(Self {
shared: Arc::new(super::InstanceShared {
@ -519,7 +530,7 @@ impl crate::Instance<super::Api> for super::Instance {
},
);
let extensions = Self::required_extensions(&entry, desc.flags)?;
let extensions = Self::required_extensions(&entry, driver_api_version, desc.flags)?;
let instance_layers = entry.enumerate_instance_layer_properties().map_err(|e| {
log::info!("enumerate_instance_layer_properties: {:?}", e);

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"578dd177eb3fbce10c928d2800e3b433c36e092ff57305c916bdeb17602b8990","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"49b663315b42255315e393c7406de643525d9562219715634630db9b811c77c9"},"package":null}
{"files":{"Cargo.toml":"578dd177eb3fbce10c928d2800e3b433c36e092ff57305c916bdeb17602b8990","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"b5e5bde17ab66efd8b8707c0460e55984e70abeec03c3b913ab90991c844a596"},"package":null}

1
third_party/rust/wgpu-types/src/lib.rs поставляемый
Просмотреть файл

@ -3847,6 +3847,7 @@ pub enum PresentMode {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub enum CompositeAlphaMode {
/// Chooses either `Opaque` or `Inherit` automaticallydepending on the
/// `alpha_mode` that the current surface can support.