Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/wgpu/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/wgpu/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"e813a2e6eafc5201be20df1e359eb73d482ca4311e41a488f78dd83abc0c2614","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","Makefile":"416f06b5e6b93962775f1423f7bb38dbdaadfbf3628c28824b620a527fac41a0","README.md":"1e9b72809941c693cd534cf73a705b31c8351af7bccfb245222bd8a3ebe2159d","src/backend/direct.rs":"31df9574071796069e06013df252705deb0df72b0000ee6477c5404746e2cb79","src/backend/mod.rs":"2603cc214a6eb4dbbe9ce72d487b76bf3091c40410a031cf828aba55689384c6","src/backend/web.rs":"8000a4435bfe4bc71b7aa4a90626c0e234845d8130a33931bcb1d2e1ebeee0a3","src/context.rs":"d7f67d29c4a3b17f8fc65f066a0e60108bfd3d644484cd524c2ade02219ce976","src/lib.rs":"c6a72c41510133eeaadcacc97441bd0bf71d60de338ace21108860c85d42a7c2","src/macros.rs":"721c5f67bc5a54d6dbd6fc7bdfb68d5f865d40d64a91129652ae75f1f28650ba","src/util/belt.rs":"0526f9d7e3cc7770a971f2e50c895ebb00992effb778c3209be675ec025e0513","src/util/device.rs":"bf49a9d2d89ecfe5b422c48b226d0ff61508c3370de324e9123f54feba35ec09","src/util/encoder.rs":"52d0c46fd5ca6c2f80149da18444448ce90c1d76a603ee61a0d47a784e1f3f15","src/util/indirect.rs":"e895429d037ca0720bc0ab8f5912c5fa9510f24fa57c9b3f5ec6b3e283789aaa","src/util/init.rs":"e28d6db4bd5be84ad53f8cd0f9481ff941e8e6131648fc7afaa27c2dc55555b8","src/util/mod.rs":"0504276b0edcc5b6e5ffec108fc4af1b6fa5eabe24beefa6ad81cd81c15130e0"},"package":"752e44d3998ef35f71830dd1ad3da513e628e2e4d4aedb0ab580f850827a0b41"}
|
||||
317
third-party/vendor/wgpu/Cargo.toml
vendored
Normal file
317
third-party/vendor/wgpu/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wgpu"
|
||||
version = "0.17.2"
|
||||
authors = ["wgpu developers"]
|
||||
exclude = ["Cargo.lock"]
|
||||
description = "Rusty WebGPU API wrapper"
|
||||
homepage = "https://wgpu.rs/"
|
||||
readme = "README.md"
|
||||
keywords = ["graphics"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/gfx-rs/wgpu"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
]
|
||||
targets = [
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-pc-windows-msvc",
|
||||
"wasm32-unknown-unknown",
|
||||
]
|
||||
|
||||
[lib]
|
||||
|
||||
[dependencies.arrayvec]
|
||||
version = "0.7"
|
||||
|
||||
[dependencies.cfg-if]
|
||||
version = "1"
|
||||
|
||||
[dependencies.log]
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.naga]
|
||||
version = "0.13.0"
|
||||
features = ["clone"]
|
||||
optional = true
|
||||
|
||||
[dependencies.parking_lot]
|
||||
version = ">=0.11,<0.13"
|
||||
|
||||
[dependencies.profiling]
|
||||
version = "1"
|
||||
default-features = false
|
||||
|
||||
[dependencies.raw-window-handle]
|
||||
version = "0.5"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.smallvec]
|
||||
version = "1"
|
||||
|
||||
[dependencies.static_assertions]
|
||||
version = "1.1.0"
|
||||
|
||||
[dependencies.wgc]
|
||||
version = "0.17"
|
||||
features = [
|
||||
"raw-window-handle",
|
||||
"gles",
|
||||
]
|
||||
optional = true
|
||||
package = "wgpu-core"
|
||||
|
||||
[dependencies.wgt]
|
||||
version = "0.17"
|
||||
package = "wgpu-types"
|
||||
|
||||
[dev-dependencies.naga]
|
||||
version = "0.13.0"
|
||||
features = ["wgsl-in"]
|
||||
|
||||
[features]
|
||||
angle = ["wgc/angle"]
|
||||
default = ["wgsl"]
|
||||
expose-ids = []
|
||||
fragile-send-sync-non-atomic-wasm = [
|
||||
"hal/fragile-send-sync-non-atomic-wasm",
|
||||
"wgc/fragile-send-sync-non-atomic-wasm",
|
||||
"wgt/fragile-send-sync-non-atomic-wasm",
|
||||
]
|
||||
glsl = ["naga/glsl-in"]
|
||||
replay = [
|
||||
"serde",
|
||||
"wgc/replay",
|
||||
]
|
||||
spirv = ["naga/spv-in"]
|
||||
strict_asserts = [
|
||||
"wgc?/strict_asserts",
|
||||
"wgt/strict_asserts",
|
||||
]
|
||||
trace = [
|
||||
"serde",
|
||||
"wgc/trace",
|
||||
]
|
||||
vulkan-portability = ["wgc/vulkan"]
|
||||
webgl = [
|
||||
"hal",
|
||||
"wgc",
|
||||
]
|
||||
wgsl = ["wgc?/wgsl"]
|
||||
|
||||
[target."cfg(all(not(target_arch = \"wasm32\"), unix, not(target_os = \"ios\"), not(target_os = \"macos\")))".dependencies.hal]
|
||||
version = "0.17"
|
||||
features = ["renderdoc"]
|
||||
package = "wgpu-hal"
|
||||
|
||||
[target."cfg(any(not(target_arch = \"wasm32\"), target_os = \"emscripten\"))".dependencies.hal]
|
||||
version = "0.17"
|
||||
package = "wgpu-hal"
|
||||
|
||||
[target."cfg(any(not(target_arch = \"wasm32\"), target_os = \"emscripten\"))".dependencies.wgc]
|
||||
version = "0.17"
|
||||
features = [
|
||||
"raw-window-handle",
|
||||
"gles",
|
||||
]
|
||||
package = "wgpu-core"
|
||||
|
||||
[target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.wgc]
|
||||
version = "0.17"
|
||||
features = ["metal"]
|
||||
package = "wgpu-core"
|
||||
|
||||
[target."cfg(any(windows, all(unix, not(target_os = \"emscripten\"), not(target_os = \"ios\"), not(target_os = \"macos\"))))".dependencies.wgc]
|
||||
version = "0.17"
|
||||
features = ["vulkan"]
|
||||
package = "wgpu-core"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.hal]
|
||||
version = "0.17"
|
||||
optional = true
|
||||
package = "wgpu-hal"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.js-sys]
|
||||
version = "0.3.64"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.naga]
|
||||
version = "0.13.0"
|
||||
features = ["wgsl-out"]
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.parking_lot]
|
||||
version = ">=0.11,<0.13"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
|
||||
version = "0.2.87"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures]
|
||||
version = "0.4.34"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies.web-sys]
|
||||
version = "0.3.65"
|
||||
features = [
|
||||
"Document",
|
||||
"Navigator",
|
||||
"Node",
|
||||
"NodeList",
|
||||
"Gpu",
|
||||
"GpuAdapter",
|
||||
"GpuAddressMode",
|
||||
"GpuAutoLayoutMode",
|
||||
"GpuBindGroup",
|
||||
"GpuBindGroupDescriptor",
|
||||
"GpuBindGroupEntry",
|
||||
"GpuBindGroupLayout",
|
||||
"GpuBindGroupLayoutDescriptor",
|
||||
"GpuBindGroupLayoutEntry",
|
||||
"GpuBlendComponent",
|
||||
"GpuBlendFactor",
|
||||
"GpuBlendOperation",
|
||||
"GpuBlendState",
|
||||
"GpuBuffer",
|
||||
"GpuBufferBinding",
|
||||
"GpuBufferBindingLayout",
|
||||
"GpuBufferBindingType",
|
||||
"GpuBufferDescriptor",
|
||||
"GpuCanvasAlphaMode",
|
||||
"GpuCanvasContext",
|
||||
"GpuCanvasConfiguration",
|
||||
"GpuColorDict",
|
||||
"GpuColorTargetState",
|
||||
"GpuCommandBuffer",
|
||||
"GpuCommandBufferDescriptor",
|
||||
"GpuCommandEncoder",
|
||||
"GpuCommandEncoderDescriptor",
|
||||
"GpuCompareFunction",
|
||||
"GpuCompilationInfo",
|
||||
"GpuCompilationMessage",
|
||||
"GpuCompilationMessageType",
|
||||
"GpuComputePassDescriptor",
|
||||
"GpuComputePassEncoder",
|
||||
"GpuComputePipeline",
|
||||
"GpuComputePipelineDescriptor",
|
||||
"GpuCullMode",
|
||||
"GpuDepthStencilState",
|
||||
"GpuDevice",
|
||||
"GpuDeviceDescriptor",
|
||||
"GpuDeviceLostInfo",
|
||||
"GpuDeviceLostReason",
|
||||
"GpuError",
|
||||
"GpuErrorFilter",
|
||||
"GpuExtent3dDict",
|
||||
"GpuFeatureName",
|
||||
"GpuFilterMode",
|
||||
"GpuFragmentState",
|
||||
"GpuFrontFace",
|
||||
"GpuImageCopyBuffer",
|
||||
"GpuImageCopyExternalImage",
|
||||
"GpuImageCopyTexture",
|
||||
"GpuImageCopyTextureTagged",
|
||||
"GpuImageDataLayout",
|
||||
"GpuIndexFormat",
|
||||
"GpuLoadOp",
|
||||
"gpu_map_mode",
|
||||
"GpuMipmapFilterMode",
|
||||
"GpuMultisampleState",
|
||||
"GpuObjectDescriptorBase",
|
||||
"GpuOrigin2dDict",
|
||||
"GpuOrigin3dDict",
|
||||
"GpuOutOfMemoryError",
|
||||
"GpuPipelineDescriptorBase",
|
||||
"GpuPipelineLayout",
|
||||
"GpuPipelineLayoutDescriptor",
|
||||
"GpuPowerPreference",
|
||||
"GpuPrimitiveState",
|
||||
"GpuPrimitiveTopology",
|
||||
"GpuProgrammableStage",
|
||||
"GpuQuerySet",
|
||||
"GpuQuerySetDescriptor",
|
||||
"GpuQueryType",
|
||||
"GpuQueue",
|
||||
"GpuRenderBundle",
|
||||
"GpuRenderBundleDescriptor",
|
||||
"GpuRenderBundleEncoder",
|
||||
"GpuRenderBundleEncoderDescriptor",
|
||||
"GpuRenderPassColorAttachment",
|
||||
"GpuRenderPassDepthStencilAttachment",
|
||||
"GpuRenderPassDescriptor",
|
||||
"GpuRenderPassEncoder",
|
||||
"GpuRenderPipeline",
|
||||
"GpuRenderPipelineDescriptor",
|
||||
"GpuRequestAdapterOptions",
|
||||
"GpuSampler",
|
||||
"GpuSamplerBindingLayout",
|
||||
"GpuSamplerBindingType",
|
||||
"GpuSamplerDescriptor",
|
||||
"GpuShaderModule",
|
||||
"GpuShaderModuleDescriptor",
|
||||
"GpuStencilFaceState",
|
||||
"GpuStencilOperation",
|
||||
"GpuStorageTextureAccess",
|
||||
"GpuStorageTextureBindingLayout",
|
||||
"GpuStoreOp",
|
||||
"GpuSupportedFeatures",
|
||||
"GpuSupportedLimits",
|
||||
"GpuTexture",
|
||||
"GpuTextureAspect",
|
||||
"GpuTextureBindingLayout",
|
||||
"GpuTextureDescriptor",
|
||||
"GpuTextureDimension",
|
||||
"GpuTextureFormat",
|
||||
"GpuTextureSampleType",
|
||||
"GpuTextureView",
|
||||
"GpuTextureViewDescriptor",
|
||||
"GpuTextureViewDimension",
|
||||
"GpuUncapturedErrorEvent",
|
||||
"GpuUncapturedErrorEventInit",
|
||||
"GpuValidationError",
|
||||
"GpuVertexAttribute",
|
||||
"GpuVertexBufferLayout",
|
||||
"GpuVertexFormat",
|
||||
"GpuVertexState",
|
||||
"GpuVertexStepMode",
|
||||
"HtmlCanvasElement",
|
||||
"OffscreenCanvas",
|
||||
"ImageBitmap",
|
||||
"ImageBitmapRenderingContext",
|
||||
"Window",
|
||||
"WorkerGlobalScope",
|
||||
"WorkerNavigator",
|
||||
]
|
||||
|
||||
[target."cfg(windows)".dependencies.hal]
|
||||
version = "0.17"
|
||||
features = [
|
||||
"dxc_shader_compiler",
|
||||
"renderdoc",
|
||||
"windows_rs",
|
||||
]
|
||||
package = "wgpu-hal"
|
||||
|
||||
[target."cfg(windows)".dependencies.wgc]
|
||||
version = "0.17"
|
||||
features = [
|
||||
"dx11",
|
||||
"dx12",
|
||||
]
|
||||
package = "wgpu-core"
|
||||
176
third-party/vendor/wgpu/LICENSE.APACHE
vendored
Normal file
176
third-party/vendor/wgpu/LICENSE.APACHE
vendored
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
21
third-party/vendor/wgpu/LICENSE.MIT
vendored
Normal file
21
third-party/vendor/wgpu/LICENSE.MIT
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 The gfx-rs developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
20
third-party/vendor/wgpu/Makefile
vendored
Normal file
20
third-party/vendor/wgpu/Makefile
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# This Makefile generates SPIR-V shaders from GLSL shaders in the examples.
|
||||
|
||||
shader_compiler = glslangValidator
|
||||
|
||||
# All input shaders.
|
||||
glsls = $(wildcard examples/*/*.vert examples/*/*.frag examples/*/*.comp)
|
||||
|
||||
# All SPIR-V targets.
|
||||
spirvs = $(addsuffix .spv,$(glsls))
|
||||
|
||||
.PHONY: default
|
||||
default: $(spirvs)
|
||||
|
||||
# Rule for making a SPIR-V target.
|
||||
$(spirvs): %.spv: %
|
||||
$(shader_compiler) -V $< -o $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(spirvs)
|
||||
60
third-party/vendor/wgpu/README.md
vendored
Normal file
60
third-party/vendor/wgpu/README.md
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<img align="right" width="25%" src="https://raw.githubusercontent.com/gfx-rs/wgpu/master/logo.png">
|
||||
|
||||
wgpu-rs is an idiomatic Rust wrapper over [wgpu-core](https://github.com/gfx-rs/wgpu). It's designed to be suitable for general purpose graphics and computation needs of Rust community.
|
||||
|
||||
wgpu-rs can target both the natively supported backends and Wasm directly.
|
||||
|
||||
See our [gallery](https://wgpu.rs/#showcase) and the [wiki page](https://github.com/gfx-rs/wgpu/wiki/Users) for the list of libraries and applications using `wgpu-rs`.
|
||||
|
||||
## Usage
|
||||
|
||||
### How to Run Examples
|
||||
|
||||
All examples are located under the [examples](examples) directory.
|
||||
|
||||
These examples use the default syntax for running examples, as found in the [Cargo](https://doc.rust-lang.org/cargo/reference/manifest.html#examples) documentation. For example, to run the `cube` example:
|
||||
|
||||
```bash
|
||||
cargo run --bin cube
|
||||
```
|
||||
|
||||
The `hello*` examples show bare-bones setup without any helper code. For `hello-compute`, pass 4 numbers separated by spaces as arguments:
|
||||
|
||||
```bash
|
||||
cargo run --bin hello-compute 1 2 3 4
|
||||
```
|
||||
|
||||
The following environment variables can be used to configure how the framework examples run:
|
||||
|
||||
- `WGPU_BACKEND`
|
||||
|
||||
Options: `vulkan`, `metal`, `dx11`, `dx12`, `gl`, `webgpu`
|
||||
|
||||
If unset a default backend is chosen based on what is supported
|
||||
by your system.
|
||||
|
||||
- `WGPU_POWER_PREF`
|
||||
|
||||
Options: `low`, `high`
|
||||
|
||||
If unset a low power adapter is preferred.
|
||||
|
||||
- `WGPU_ADAPTER_NAME`
|
||||
|
||||
Select a specific adapter by specifying a substring of the adapter name.
|
||||
|
||||
#### Run Examples on the Web (`wasm32-unknown-unknown`)
|
||||
|
||||
See [wiki article](https://github.com/gfx-rs/wgpu/wiki/Running-on-the-Web-with-WebGPU-and-WebGL).
|
||||
|
||||
## Shaders
|
||||
|
||||
[WGSL](https://gpuweb.github.io/gpuweb/wgsl/) is the main shading language of WebGPU.
|
||||
|
||||
Users can run the [naga](https://github.com/gfx-rs/naga) binary in the following way to convert their SPIR-V shaders to WGSL:
|
||||
|
||||
```bash
|
||||
cargo run -- <input.spv> <output.wgsl>
|
||||
```
|
||||
|
||||
In addition, SPIR-V can be used by enabling the `spirv` feature and GLSL can be enabled by enabling the `glsl` feature at the cost of slightly increased build times.
|
||||
3121
third-party/vendor/wgpu/src/backend/direct.rs
vendored
Normal file
3121
third-party/vendor/wgpu/src/backend/direct.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
23
third-party/vendor/wgpu/src/backend/mod.rs
vendored
Normal file
23
third-party/vendor/wgpu/src/backend/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
mod web;
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", feature = "webgl"))
|
||||
))]
|
||||
pub(crate) use web::Context;
|
||||
|
||||
#[cfg(any(
|
||||
not(target_arch = "wasm32"),
|
||||
target_os = "emscripten",
|
||||
feature = "webgl"
|
||||
))]
|
||||
mod direct;
|
||||
#[cfg(any(
|
||||
not(target_arch = "wasm32"),
|
||||
target_os = "emscripten",
|
||||
feature = "webgl"
|
||||
))]
|
||||
pub(crate) use direct::Context;
|
||||
3318
third-party/vendor/wgpu/src/backend/web.rs
vendored
Normal file
3318
third-party/vendor/wgpu/src/backend/web.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
4021
third-party/vendor/wgpu/src/context.rs
vendored
Normal file
4021
third-party/vendor/wgpu/src/context.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
5069
third-party/vendor/wgpu/src/lib.rs
vendored
Normal file
5069
third-party/vendor/wgpu/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
93
third-party/vendor/wgpu/src/macros.rs
vendored
Normal file
93
third-party/vendor/wgpu/src/macros.rs
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
//! Convenience macros
|
||||
|
||||
/// Macro to produce an array of [`VertexAttribute`](crate::VertexAttribute).
|
||||
///
|
||||
/// Output has type: `[VertexAttribute; _]`. Usage is as follows:
|
||||
/// ```
|
||||
/// # use wgpu::vertex_attr_array;
|
||||
/// let attrs = vertex_attr_array![0 => Float32x2, 1 => Float32, 2 => Uint16x4];
|
||||
/// ```
|
||||
/// This example specifies a list of three [`VertexAttribute`](crate::VertexAttribute),
|
||||
/// each with the given `shader_location` and `format`.
|
||||
/// Offsets are calculated automatically.
|
||||
#[macro_export]
|
||||
macro_rules! vertex_attr_array {
|
||||
($($loc:expr => $fmt:ident),* $(,)?) => {
|
||||
$crate::vertex_attr_array!([] ; 0; $($loc => $fmt ,)*)
|
||||
};
|
||||
([$($t:expr,)*] ; $off:expr ;) => { [$($t,)*] };
|
||||
([$($t:expr,)*] ; $off:expr ; $loc:expr => $item:ident, $($ll:expr => $ii:ident ,)*) => {
|
||||
$crate::vertex_attr_array!(
|
||||
[$($t,)*
|
||||
$crate::VertexAttribute {
|
||||
format: $crate::VertexFormat :: $item,
|
||||
offset: $off,
|
||||
shader_location: $loc,
|
||||
},];
|
||||
$off + $crate::VertexFormat :: $item.size();
|
||||
$($ll => $ii ,)*
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vertex_attr_array() {
|
||||
let attrs = vertex_attr_array![0 => Float32x2, 3 => Uint16x4];
|
||||
// VertexAttribute does not support PartialEq, so we cannot test directly
|
||||
assert_eq!(attrs.len(), 2);
|
||||
assert_eq!(attrs[0].offset, 0);
|
||||
assert_eq!(attrs[0].shader_location, 0);
|
||||
assert_eq!(attrs[1].offset, std::mem::size_of::<(f32, f32)>() as u64);
|
||||
assert_eq!(attrs[1].shader_location, 3);
|
||||
}
|
||||
|
||||
/// Macro to load a SPIR-V module statically.
|
||||
///
|
||||
/// It ensures the word alignment as well as the magic number.
|
||||
///
|
||||
/// Return type: [`crate::ShaderModuleDescriptor`]
|
||||
#[macro_export]
|
||||
#[cfg(feature = "spirv")]
|
||||
macro_rules! include_spirv {
|
||||
($($token:tt)*) => {
|
||||
{
|
||||
//log::info!("including '{}'", $($token)*);
|
||||
$crate::ShaderModuleDescriptor {
|
||||
label: Some($($token)*),
|
||||
source: $crate::util::make_spirv(include_bytes!($($token)*)),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro to load raw SPIR-V data statically, for use with [`Features::SPIRV_SHADER_PASSTHROUGH`].
|
||||
///
|
||||
/// It ensures the word alignment as well as the magic number.
|
||||
///
|
||||
/// [`Features::SPIRV_SHADER_PASSTHROUGH`]: crate::Features::SPIRV_SHADER_PASSTHROUGH
|
||||
#[macro_export]
|
||||
macro_rules! include_spirv_raw {
|
||||
($($token:tt)*) => {
|
||||
{
|
||||
//log::info!("including '{}'", $($token)*);
|
||||
$crate::ShaderModuleDescriptorSpirV {
|
||||
label: Some($($token)*),
|
||||
source: $crate::util::make_spirv_raw(include_bytes!($($token)*)),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro to load a WGSL module statically.
|
||||
#[macro_export]
|
||||
macro_rules! include_wgsl {
|
||||
($($token:tt)*) => {
|
||||
{
|
||||
//log::info!("including '{}'", $($token)*);
|
||||
$crate::ShaderModuleDescriptor {
|
||||
label: Some($($token)*),
|
||||
source: $crate::ShaderSource::Wgsl(include_str!($($token)*).into()),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
183
third-party/vendor/wgpu/src/util/belt.rs
vendored
Normal file
183
third-party/vendor/wgpu/src/util/belt.rs
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
use crate::{
|
||||
util::align_to, Buffer, BufferAddress, BufferDescriptor, BufferSize, BufferUsages,
|
||||
BufferViewMut, CommandEncoder, Device, MapMode,
|
||||
};
|
||||
use std::fmt;
|
||||
use std::sync::{mpsc, Arc};
|
||||
|
||||
struct Chunk {
|
||||
buffer: Arc<Buffer>,
|
||||
size: BufferAddress,
|
||||
offset: BufferAddress,
|
||||
}
|
||||
|
||||
/// Efficiently performs many buffer writes by sharing and reusing temporary buffers.
|
||||
///
|
||||
/// Internally it uses a ring-buffer of staging buffers that are sub-allocated.
|
||||
/// It has an advantage over [`Queue::write_buffer()`] in a way that it returns a mutable slice,
|
||||
/// which you can fill to avoid an extra data copy.
|
||||
///
|
||||
/// Using a staging belt is slightly complicated, and generally goes as follows:
|
||||
/// 1. Write to buffers that need writing to using [`StagingBelt::write_buffer()`].
|
||||
/// 2. Call [`StagingBelt::finish()`].
|
||||
/// 3. Submit all command encoders that were used in step 1.
|
||||
/// 4. Call [`StagingBelt::recall()`].
|
||||
///
|
||||
/// [`Queue::write_buffer()`]: crate::Queue::write_buffer
|
||||
pub struct StagingBelt {
|
||||
chunk_size: BufferAddress,
|
||||
/// Chunks into which we are accumulating data to be transferred.
|
||||
active_chunks: Vec<Chunk>,
|
||||
/// Chunks that have scheduled transfers already; they are unmapped and some
|
||||
/// command encoder has one or more `copy_buffer_to_buffer` commands with them
|
||||
/// as source.
|
||||
closed_chunks: Vec<Chunk>,
|
||||
/// Chunks that are back from the GPU and ready to be mapped for write and put
|
||||
/// into `active_chunks`.
|
||||
free_chunks: Vec<Chunk>,
|
||||
/// When closed chunks are mapped again, the map callback sends them here.
|
||||
sender: mpsc::Sender<Chunk>,
|
||||
/// Free chunks are received here to be put on `self.free_chunks`.
|
||||
receiver: mpsc::Receiver<Chunk>,
|
||||
}
|
||||
|
||||
impl StagingBelt {
|
||||
/// Create a new staging belt.
|
||||
///
|
||||
/// The `chunk_size` is the unit of internal buffer allocation; writes will be
|
||||
/// sub-allocated within each chunk. Therefore, for optimal use of memory, the
|
||||
/// chunk size should be:
|
||||
///
|
||||
/// * larger than the largest single [`StagingBelt::write_buffer()`] operation;
|
||||
/// * 1-4 times less than the total amount of data uploaded per submission
|
||||
/// (per [`StagingBelt::finish()`]); and
|
||||
/// * bigger is better, within these bounds.
|
||||
pub fn new(chunk_size: BufferAddress) -> Self {
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
StagingBelt {
|
||||
chunk_size,
|
||||
active_chunks: Vec::new(),
|
||||
closed_chunks: Vec::new(),
|
||||
free_chunks: Vec::new(),
|
||||
sender,
|
||||
receiver,
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate the staging belt slice of `size` to be uploaded into the `target` buffer
|
||||
/// at the specified offset.
|
||||
///
|
||||
/// The upload will be placed into the provided command encoder. This encoder
|
||||
/// must be submitted after [`StagingBelt::finish()`] is called and before
|
||||
/// [`StagingBelt::recall()`] is called.
|
||||
///
|
||||
/// If the `size` is greater than the size of any free internal buffer, a new buffer
|
||||
/// will be allocated for it. Therefore, the `chunk_size` passed to [`StagingBelt::new()`]
|
||||
/// should ideally be larger than every such size.
|
||||
pub fn write_buffer(
|
||||
&mut self,
|
||||
encoder: &mut CommandEncoder,
|
||||
target: &Buffer,
|
||||
offset: BufferAddress,
|
||||
size: BufferSize,
|
||||
device: &Device,
|
||||
) -> BufferViewMut {
|
||||
let mut chunk = if let Some(index) = self
|
||||
.active_chunks
|
||||
.iter()
|
||||
.position(|chunk| chunk.offset + size.get() <= chunk.size)
|
||||
{
|
||||
self.active_chunks.swap_remove(index)
|
||||
} else {
|
||||
self.receive_chunks(); // ensure self.free_chunks is up to date
|
||||
|
||||
if let Some(index) = self
|
||||
.free_chunks
|
||||
.iter()
|
||||
.position(|chunk| size.get() <= chunk.size)
|
||||
{
|
||||
self.free_chunks.swap_remove(index)
|
||||
} else {
|
||||
let size = self.chunk_size.max(size.get());
|
||||
Chunk {
|
||||
buffer: Arc::new(device.create_buffer(&BufferDescriptor {
|
||||
label: Some("(wgpu internal) StagingBelt staging buffer"),
|
||||
size,
|
||||
usage: BufferUsages::MAP_WRITE | BufferUsages::COPY_SRC,
|
||||
mapped_at_creation: true,
|
||||
})),
|
||||
size,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
encoder.copy_buffer_to_buffer(&chunk.buffer, chunk.offset, target, offset, size.get());
|
||||
let old_offset = chunk.offset;
|
||||
chunk.offset = align_to(chunk.offset + size.get(), crate::MAP_ALIGNMENT);
|
||||
|
||||
self.active_chunks.push(chunk);
|
||||
self.active_chunks
|
||||
.last()
|
||||
.unwrap()
|
||||
.buffer
|
||||
.slice(old_offset..old_offset + size.get())
|
||||
.get_mapped_range_mut()
|
||||
}
|
||||
|
||||
/// Prepare currently mapped buffers for use in a submission.
|
||||
///
|
||||
/// This must be called before the command encoder(s) provided to
|
||||
/// [`StagingBelt::write_buffer()`] are submitted.
|
||||
///
|
||||
/// At this point, all the partially used staging buffers are closed (cannot be used for
|
||||
/// further writes) until after [`StagingBelt::recall()`] is called *and* the GPU is done
|
||||
/// copying the data from them.
|
||||
pub fn finish(&mut self) {
|
||||
for chunk in self.active_chunks.drain(..) {
|
||||
chunk.buffer.unmap();
|
||||
self.closed_chunks.push(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
/// Recall all of the closed buffers back to be reused.
|
||||
///
|
||||
/// This must only be called after the command encoder(s) provided to
|
||||
/// [`StagingBelt::write_buffer()`] are submitted. Additional calls are harmless.
|
||||
/// Not calling this as soon as possible may result in increased buffer memory usage.
|
||||
pub fn recall(&mut self) {
|
||||
self.receive_chunks();
|
||||
|
||||
let sender = &self.sender;
|
||||
for chunk in self.closed_chunks.drain(..) {
|
||||
let sender = sender.clone();
|
||||
chunk
|
||||
.buffer
|
||||
.clone()
|
||||
.slice(..)
|
||||
.map_async(MapMode::Write, move |_| {
|
||||
let _ = sender.send(chunk);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Move all chunks that the GPU is done with (and are now mapped again)
|
||||
/// from `self.receiver` to `self.free_chunks`.
|
||||
fn receive_chunks(&mut self) {
|
||||
while let Ok(mut chunk) = self.receiver.try_recv() {
|
||||
chunk.offset = 0;
|
||||
self.free_chunks.push(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for StagingBelt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("StagingBelt")
|
||||
.field("chunk_size", &self.chunk_size)
|
||||
.field("active_chunks", &self.active_chunks.len())
|
||||
.field("closed_chunks", &self.closed_chunks.len())
|
||||
.field("free_chunks", &self.free_chunks.len())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
145
third-party/vendor/wgpu/src/util/device.rs
vendored
Normal file
145
third-party/vendor/wgpu/src/util/device.rs
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/// Describes a [Buffer](crate::Buffer) when allocating.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct BufferInitDescriptor<'a> {
|
||||
/// Debug label of a buffer. This will show up in graphics debuggers for easy identification.
|
||||
pub label: crate::Label<'a>,
|
||||
/// Contents of a buffer on creation.
|
||||
pub contents: &'a [u8],
|
||||
/// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation
|
||||
/// will panic.
|
||||
pub usage: crate::BufferUsages,
|
||||
}
|
||||
|
||||
/// Utility methods not meant to be in the main API.
|
||||
pub trait DeviceExt {
|
||||
/// Creates a [Buffer](crate::Buffer) with data to initialize it.
|
||||
fn create_buffer_init(&self, desc: &BufferInitDescriptor) -> crate::Buffer;
|
||||
|
||||
/// Upload an entire texture and its mipmaps from a source buffer.
|
||||
///
|
||||
/// Expects all mipmaps to be tightly packed in the data buffer.
|
||||
///
|
||||
/// If the texture is a 2DArray texture, uploads each layer in order, expecting
|
||||
/// each layer and its mips to be tightly packed.
|
||||
///
|
||||
/// Example:
|
||||
/// Layer0Mip0 Layer0Mip1 Layer0Mip2 ... Layer1Mip0 Layer1Mip1 Layer1Mip2 ...
|
||||
///
|
||||
/// Implicitly adds the `COPY_DST` usage if it is not present in the descriptor,
|
||||
/// as it is required to be able to upload the data to the gpu.
|
||||
fn create_texture_with_data(
|
||||
&self,
|
||||
queue: &crate::Queue,
|
||||
desc: &crate::TextureDescriptor,
|
||||
data: &[u8],
|
||||
) -> crate::Texture;
|
||||
}
|
||||
|
||||
impl DeviceExt for crate::Device {
|
||||
fn create_buffer_init(&self, descriptor: &BufferInitDescriptor<'_>) -> crate::Buffer {
|
||||
// Skip mapping if the buffer is zero sized
|
||||
if descriptor.contents.is_empty() {
|
||||
let wgt_descriptor = crate::BufferDescriptor {
|
||||
label: descriptor.label,
|
||||
size: 0,
|
||||
usage: descriptor.usage,
|
||||
mapped_at_creation: false,
|
||||
};
|
||||
|
||||
self.create_buffer(&wgt_descriptor)
|
||||
} else {
|
||||
let unpadded_size = descriptor.contents.len() as crate::BufferAddress;
|
||||
// Valid vulkan usage is
|
||||
// 1. buffer size must be a multiple of COPY_BUFFER_ALIGNMENT.
|
||||
// 2. buffer size must be greater than 0.
|
||||
// Therefore we round the value up to the nearest multiple, and ensure it's at least COPY_BUFFER_ALIGNMENT.
|
||||
let align_mask = crate::COPY_BUFFER_ALIGNMENT - 1;
|
||||
let padded_size =
|
||||
((unpadded_size + align_mask) & !align_mask).max(crate::COPY_BUFFER_ALIGNMENT);
|
||||
|
||||
let wgt_descriptor = crate::BufferDescriptor {
|
||||
label: descriptor.label,
|
||||
size: padded_size,
|
||||
usage: descriptor.usage,
|
||||
mapped_at_creation: true,
|
||||
};
|
||||
|
||||
let buffer = self.create_buffer(&wgt_descriptor);
|
||||
|
||||
buffer.slice(..).get_mapped_range_mut()[..unpadded_size as usize]
|
||||
.copy_from_slice(descriptor.contents);
|
||||
buffer.unmap();
|
||||
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
fn create_texture_with_data(
|
||||
&self,
|
||||
queue: &crate::Queue,
|
||||
desc: &crate::TextureDescriptor,
|
||||
data: &[u8],
|
||||
) -> crate::Texture {
|
||||
// Implicitly add the COPY_DST usage
|
||||
let mut desc = desc.to_owned();
|
||||
desc.usage |= crate::TextureUsages::COPY_DST;
|
||||
let texture = self.create_texture(&desc);
|
||||
|
||||
// Will return None only if it's a combined depth-stencil format
|
||||
// If so, default to 4, validation will fail later anyway since the depth or stencil
|
||||
// aspect needs to be written to individually
|
||||
let block_size = desc.format.block_size(None).unwrap_or(4);
|
||||
let (block_width, block_height) = desc.format.block_dimensions();
|
||||
let layer_iterations = desc.array_layer_count();
|
||||
|
||||
let mut binary_offset = 0;
|
||||
for layer in 0..layer_iterations {
|
||||
for mip in 0..desc.mip_level_count {
|
||||
let mut mip_size = desc.mip_level_size(mip).unwrap();
|
||||
// copying layers separately
|
||||
if desc.dimension != wgt::TextureDimension::D3 {
|
||||
mip_size.depth_or_array_layers = 1;
|
||||
}
|
||||
|
||||
// When uploading mips of compressed textures and the mip is supposed to be
|
||||
// a size that isn't a multiple of the block size, the mip needs to be uploaded
|
||||
// as its "physical size" which is the size rounded up to the nearest block size.
|
||||
let mip_physical = mip_size.physical_size(desc.format);
|
||||
|
||||
// All these calculations are performed on the physical size as that's the
|
||||
// data that exists in the buffer.
|
||||
let width_blocks = mip_physical.width / block_width;
|
||||
let height_blocks = mip_physical.height / block_height;
|
||||
|
||||
let bytes_per_row = width_blocks * block_size;
|
||||
let data_size = bytes_per_row * height_blocks * mip_size.depth_or_array_layers;
|
||||
|
||||
let end_offset = binary_offset + data_size as usize;
|
||||
|
||||
queue.write_texture(
|
||||
crate::ImageCopyTexture {
|
||||
texture: &texture,
|
||||
mip_level: mip,
|
||||
origin: crate::Origin3d {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: layer,
|
||||
},
|
||||
aspect: wgt::TextureAspect::All,
|
||||
},
|
||||
&data[binary_offset..end_offset],
|
||||
crate::ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(bytes_per_row),
|
||||
rows_per_image: Some(height_blocks),
|
||||
},
|
||||
mip_physical,
|
||||
);
|
||||
|
||||
binary_offset = end_offset;
|
||||
}
|
||||
}
|
||||
|
||||
texture
|
||||
}
|
||||
}
|
||||
202
third-party/vendor/wgpu/src/util/encoder.rs
vendored
Normal file
202
third-party/vendor/wgpu/src/util/encoder.rs
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use wgt::{BufferAddress, DynamicOffset, IndexFormat};
|
||||
|
||||
use crate::{BindGroup, Buffer, BufferSlice, RenderBundleEncoder, RenderPass, RenderPipeline};
|
||||
|
||||
/// Methods shared by [`RenderPass`] and [`RenderBundleEncoder`].
|
||||
pub trait RenderEncoder<'a> {
|
||||
/// Sets the active bind group for a given bind group index. The bind group layout
|
||||
/// in the active pipeline when any `draw()` function is called must match the layout of this bind group.
|
||||
///
|
||||
/// If the bind group have dynamic offsets, provide them in order of their declaration.
|
||||
fn set_bind_group(&mut self, index: u32, bind_group: &'a BindGroup, offsets: &[DynamicOffset]);
|
||||
|
||||
/// Sets the active render pipeline.
|
||||
///
|
||||
/// Subsequent draw calls will exhibit the behavior defined by `pipeline`.
|
||||
fn set_pipeline(&mut self, pipeline: &'a RenderPipeline);
|
||||
|
||||
/// Sets the active index buffer.
|
||||
///
|
||||
/// Subsequent calls to [`draw_indexed`](RenderEncoder::draw_indexed) on this [`RenderEncoder`] will
|
||||
/// use `buffer` as the source index buffer.
|
||||
fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat);
|
||||
|
||||
/// Assign a vertex buffer to a slot.
|
||||
///
|
||||
/// Subsequent calls to [`draw`] and [`draw_indexed`] on this
|
||||
/// [`RenderEncoder`] will use `buffer` as one of the source vertex buffers.
|
||||
///
|
||||
/// The `slot` refers to the index of the matching descriptor in
|
||||
/// [VertexState::buffers](crate::VertexState::buffers).
|
||||
///
|
||||
/// [`draw`]: RenderEncoder::draw
|
||||
/// [`draw_indexed`]: RenderEncoder::draw_indexed
|
||||
fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>);
|
||||
|
||||
/// Draws primitives from the active vertex buffer(s).
|
||||
///
|
||||
/// The active vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
|
||||
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
|
||||
|
||||
/// Draws indexed primitives using the active index buffer and the active vertex buffers.
|
||||
///
|
||||
/// The active index buffer can be set with [`RenderEncoder::set_index_buffer`], while the active
|
||||
/// vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||
|
||||
/// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
|
||||
///
|
||||
/// The active vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
|
||||
///
|
||||
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
|
||||
fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress);
|
||||
|
||||
/// Draws indexed primitives using the active index buffer and the active vertex buffers,
|
||||
/// based on the contents of the `indirect_buffer`.
|
||||
///
|
||||
/// The active index buffer can be set with [`RenderEncoder::set_index_buffer`], while the active
|
||||
/// vertex buffers can be set with [`RenderEncoder::set_vertex_buffer`].
|
||||
///
|
||||
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
|
||||
fn draw_indexed_indirect(
|
||||
&mut self,
|
||||
indirect_buffer: &'a Buffer,
|
||||
indirect_offset: BufferAddress,
|
||||
);
|
||||
|
||||
/// [`wgt::Features::PUSH_CONSTANTS`] must be enabled on the device in order to call this function.
|
||||
///
|
||||
/// Set push constant data.
|
||||
///
|
||||
/// Offset is measured in bytes, but must be a multiple of [`wgt::PUSH_CONSTANT_ALIGNMENT`].
|
||||
///
|
||||
/// Data size must be a multiple of 4 and must be aligned to the 4s, so we take an array of u32.
|
||||
/// For example, with an offset of 4 and an array of `[u32; 3]`, that will write to the range
|
||||
/// of 4..16.
|
||||
///
|
||||
/// For each byte in the range of push constant data written, the union of the stages of all push constant
|
||||
/// ranges that covers that byte must be exactly `stages`. There's no good way of explaining this simply,
|
||||
/// so here are some examples:
|
||||
///
|
||||
/// ```text
|
||||
/// For the given ranges:
|
||||
/// - 0..4 Vertex
|
||||
/// - 4..8 Fragment
|
||||
/// ```
|
||||
///
|
||||
/// You would need to upload this in two set_push_constants calls. First for the `Vertex` range, second for the `Fragment` range.
|
||||
///
|
||||
/// ```text
|
||||
/// For the given ranges:
|
||||
/// - 0..8 Vertex
|
||||
/// - 4..12 Fragment
|
||||
/// ```
|
||||
///
|
||||
/// You would need to upload this in three set_push_constants calls. First for the `Vertex` only range 0..4, second
|
||||
/// for the `Vertex | Fragment` range 4..8, third for the `Fragment` range 8..12.
|
||||
fn set_push_constants(&mut self, stages: wgt::ShaderStages, offset: u32, data: &[u8]);
|
||||
}
|
||||
|
||||
impl<'a> RenderEncoder<'a> for RenderPass<'a> {
|
||||
#[inline(always)]
|
||||
fn set_bind_group(&mut self, index: u32, bind_group: &'a BindGroup, offsets: &[DynamicOffset]) {
|
||||
Self::set_bind_group(self, index, bind_group, offsets);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
|
||||
Self::set_pipeline(self, pipeline);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat) {
|
||||
Self::set_index_buffer(self, buffer_slice, index_format);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
|
||||
Self::set_vertex_buffer(self, slot, buffer_slice);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
|
||||
Self::draw(self, vertices, instances);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
|
||||
Self::draw_indexed(self, indices, base_vertex, instances);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
|
||||
Self::draw_indirect(self, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indexed_indirect(
|
||||
&mut self,
|
||||
indirect_buffer: &'a Buffer,
|
||||
indirect_offset: BufferAddress,
|
||||
) {
|
||||
Self::draw_indexed_indirect(self, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_push_constants(&mut self, stages: wgt::ShaderStages, offset: u32, data: &[u8]) {
|
||||
Self::set_push_constants(self, stages, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RenderEncoder<'a> for RenderBundleEncoder<'a> {
|
||||
#[inline(always)]
|
||||
fn set_bind_group(&mut self, index: u32, bind_group: &'a BindGroup, offsets: &[DynamicOffset]) {
|
||||
Self::set_bind_group(self, index, bind_group, offsets);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_pipeline(&mut self, pipeline: &'a RenderPipeline) {
|
||||
Self::set_pipeline(self, pipeline);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_index_buffer(&mut self, buffer_slice: BufferSlice<'a>, index_format: IndexFormat) {
|
||||
Self::set_index_buffer(self, buffer_slice, index_format);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_vertex_buffer(&mut self, slot: u32, buffer_slice: BufferSlice<'a>) {
|
||||
Self::set_vertex_buffer(self, slot, buffer_slice);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>) {
|
||||
Self::draw(self, vertices, instances);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
|
||||
Self::draw_indexed(self, indices, base_vertex, instances);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
|
||||
Self::draw_indirect(self, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn draw_indexed_indirect(
|
||||
&mut self,
|
||||
indirect_buffer: &'a Buffer,
|
||||
indirect_offset: BufferAddress,
|
||||
) {
|
||||
Self::draw_indexed_indirect(self, indirect_buffer, indirect_offset);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_push_constants(&mut self, stages: wgt::ShaderStages, offset: u32, data: &[u8]) {
|
||||
Self::set_push_constants(self, stages, offset, data);
|
||||
}
|
||||
}
|
||||
81
third-party/vendor/wgpu/src/util/indirect.rs
vendored
Normal file
81
third-party/vendor/wgpu/src/util/indirect.rs
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/// The structure expected in `indirect_buffer` for [`RenderEncoder::draw_indirect`](crate::util::RenderEncoder::draw_indirect).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct DrawIndirect {
|
||||
/// The number of vertices to draw.
|
||||
pub vertex_count: u32,
|
||||
/// The number of instances to draw.
|
||||
pub instance_count: u32,
|
||||
/// The Index of the first vertex to draw.
|
||||
pub base_vertex: u32,
|
||||
/// The instance ID of the first instance to draw.
|
||||
/// Has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`](crate::Features::INDIRECT_FIRST_INSTANCE) is enabled.
|
||||
pub base_instance: u32,
|
||||
}
|
||||
|
||||
impl DrawIndirect {
|
||||
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
unsafe {
|
||||
std::mem::transmute(std::slice::from_raw_parts(
|
||||
self as *const _ as *const u8,
|
||||
std::mem::size_of::<Self>(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The structure expected in `indirect_buffer` for [`RenderEncoder::draw_indexed_indirect`](crate::util::RenderEncoder::draw_indexed_indirect).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct DrawIndexedIndirect {
|
||||
/// The number of vertices to draw.
|
||||
pub vertex_count: u32,
|
||||
/// The number of instances to draw.
|
||||
pub instance_count: u32,
|
||||
/// The base index within the index buffer.
|
||||
pub base_index: u32,
|
||||
/// The value added to the vertex index before indexing into the vertex buffer.
|
||||
pub vertex_offset: i32,
|
||||
/// The instance ID of the first instance to draw.
|
||||
/// Has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`](crate::Features::INDIRECT_FIRST_INSTANCE) is enabled.
|
||||
pub base_instance: u32,
|
||||
}
|
||||
|
||||
impl DrawIndexedIndirect {
|
||||
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
unsafe {
|
||||
std::mem::transmute(std::slice::from_raw_parts(
|
||||
self as *const _ as *const u8,
|
||||
std::mem::size_of::<Self>(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The structure expected in `indirect_buffer` for [`ComputePass::dispatch_workgroups_indirect`](crate::ComputePass::dispatch_workgroups_indirect).
|
||||
///
|
||||
/// x, y and z denote the number of work groups to dispatch in each dimension.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct DispatchIndirect {
|
||||
/// The number of work groups in X dimension.
|
||||
pub x: u32,
|
||||
/// The number of work groups in Y dimension.
|
||||
pub y: u32,
|
||||
/// The number of work groups in Z dimension.
|
||||
pub z: u32,
|
||||
}
|
||||
|
||||
impl DispatchIndirect {
|
||||
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
unsafe {
|
||||
std::mem::transmute(std::slice::from_raw_parts(
|
||||
self as *const _ as *const u8,
|
||||
std::mem::size_of::<Self>(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
116
third-party/vendor/wgpu/src/util/init.rs
vendored
Normal file
116
third-party/vendor/wgpu/src/util/init.rs
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
use wgt::{Backends, PowerPreference, RequestAdapterOptions};
|
||||
|
||||
use crate::{Adapter, Instance, Surface};
|
||||
|
||||
#[cfg(any(not(target_arch = "wasm32"), feature = "wgc"))]
|
||||
pub use wgc::instance::parse_backends_from_comma_list;
|
||||
/// Always returns WEBGPU on wasm over webgpu.
|
||||
#[cfg(all(target_arch = "wasm32", not(feature = "wgc")))]
|
||||
pub fn parse_backends_from_comma_list(_string: &str) -> Backends {
|
||||
Backends::BROWSER_WEBGPU
|
||||
}
|
||||
|
||||
/// Get a set of backend bits from the environment variable WGPU_BACKEND.
|
||||
pub fn backend_bits_from_env() -> Option<Backends> {
|
||||
std::env::var("WGPU_BACKEND")
|
||||
.as_deref()
|
||||
.map(str::to_lowercase)
|
||||
.ok()
|
||||
.as_deref()
|
||||
.map(parse_backends_from_comma_list)
|
||||
}
|
||||
|
||||
/// Get a power preference from the environment variable WGPU_POWER_PREF
|
||||
pub fn power_preference_from_env() -> Option<PowerPreference> {
|
||||
Some(
|
||||
match std::env::var("WGPU_POWER_PREF")
|
||||
.as_deref()
|
||||
.map(str::to_lowercase)
|
||||
.as_deref()
|
||||
{
|
||||
Ok("low") => PowerPreference::LowPower,
|
||||
Ok("high") => PowerPreference::HighPerformance,
|
||||
_ => return None,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialize the adapter obeying the WGPU_ADAPTER_NAME environment variable.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn initialize_adapter_from_env(
|
||||
instance: &Instance,
|
||||
compatible_surface: Option<&Surface>,
|
||||
) -> Option<Adapter> {
|
||||
let desired_adapter_name = std::env::var("WGPU_ADAPTER_NAME")
|
||||
.as_deref()
|
||||
.map(str::to_lowercase)
|
||||
.ok()?;
|
||||
|
||||
let adapters = instance.enumerate_adapters(Backends::all());
|
||||
|
||||
let mut chosen_adapter = None;
|
||||
for adapter in adapters {
|
||||
let info = adapter.get_info();
|
||||
|
||||
if let Some(surface) = compatible_surface {
|
||||
if !adapter.is_surface_supported(surface) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if info.name.to_lowercase().contains(&desired_adapter_name) {
|
||||
chosen_adapter = Some(adapter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Some(chosen_adapter.expect("WGPU_ADAPTER_NAME set but no matching adapter found!"))
|
||||
}
|
||||
|
||||
/// Initialize the adapter obeying the WGPU_ADAPTER_NAME environment variable.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn initialize_adapter_from_env(
|
||||
_instance: &Instance,
|
||||
_compatible_surface: Option<&Surface>,
|
||||
) -> Option<Adapter> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Initialize the adapter obeying the WGPU_ADAPTER_NAME environment variable and if it doesn't exist fall back on a default adapter.
|
||||
pub async fn initialize_adapter_from_env_or_default(
|
||||
instance: &Instance,
|
||||
compatible_surface: Option<&Surface>,
|
||||
) -> Option<Adapter> {
|
||||
match initialize_adapter_from_env(instance, compatible_surface) {
|
||||
Some(a) => Some(a),
|
||||
None => {
|
||||
instance
|
||||
.request_adapter(&RequestAdapterOptions {
|
||||
power_preference: power_preference_from_env().unwrap_or_default(),
|
||||
force_fallback_adapter: false,
|
||||
compatible_surface,
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Choose which DX12 shader compiler to use from the environment variable `WGPU_DX12_COMPILER`.
|
||||
///
|
||||
/// Possible values are `dxc` and `fxc`. Case insensitive.
|
||||
pub fn dx12_shader_compiler_from_env() -> Option<wgt::Dx12Compiler> {
|
||||
Some(
|
||||
match std::env::var("WGPU_DX12_COMPILER")
|
||||
.as_deref()
|
||||
.map(str::to_lowercase)
|
||||
.as_deref()
|
||||
{
|
||||
Ok("dxc") => wgt::Dx12Compiler::Dxc {
|
||||
dxil_path: None,
|
||||
dxc_path: None,
|
||||
},
|
||||
Ok("fxc") => wgt::Dx12Compiler::Fxc,
|
||||
_ => return None,
|
||||
},
|
||||
)
|
||||
}
|
||||
143
third-party/vendor/wgpu/src/util/mod.rs
vendored
Normal file
143
third-party/vendor/wgpu/src/util/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//! Utility structures and functions that are built on top of the main `wgpu` API.
|
||||
//!
|
||||
//! Nothing in this module is a part of the WebGPU API specification;
|
||||
//! they are unique to the `wgpu` library.
|
||||
|
||||
mod belt;
|
||||
mod device;
|
||||
mod encoder;
|
||||
mod indirect;
|
||||
mod init;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
mem::{align_of, size_of},
|
||||
ptr::copy_nonoverlapping,
|
||||
};
|
||||
|
||||
pub use belt::StagingBelt;
|
||||
pub use device::{BufferInitDescriptor, DeviceExt};
|
||||
pub use encoder::RenderEncoder;
|
||||
pub use indirect::*;
|
||||
pub use init::*;
|
||||
pub use wgt::math::*;
|
||||
|
||||
/// Treat the given byte slice as a SPIR-V module.
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
/// This function panics if:
|
||||
///
|
||||
/// - Input length isn't multiple of 4
|
||||
/// - Input is longer than [`usize::max_value`]
|
||||
/// - Input is empty
|
||||
/// - SPIR-V magic number is missing from beginning of stream
|
||||
#[cfg(feature = "spirv")]
|
||||
pub fn make_spirv(data: &[u8]) -> super::ShaderSource {
|
||||
super::ShaderSource::SpirV(make_spirv_raw(data))
|
||||
}
|
||||
|
||||
/// Version of make_spirv intended for use with [`Device::create_shader_module_spirv`].
|
||||
/// Returns raw slice instead of ShaderSource.
|
||||
///
|
||||
/// [`Device::create_shader_module_spirv`]: crate::Device::create_shader_module_spirv
|
||||
pub fn make_spirv_raw(data: &[u8]) -> Cow<[u32]> {
|
||||
const MAGIC_NUMBER: u32 = 0x0723_0203;
|
||||
assert_eq!(
|
||||
data.len() % size_of::<u32>(),
|
||||
0,
|
||||
"data size is not a multiple of 4"
|
||||
);
|
||||
assert_ne!(data.len(), 0, "data size must be larger than zero");
|
||||
|
||||
//If the data happens to be aligned, directly use the byte array,
|
||||
// otherwise copy the byte array in an owned vector and use that instead.
|
||||
let mut words = if data.as_ptr().align_offset(align_of::<u32>()) == 0 {
|
||||
let (pre, words, post) = unsafe { data.align_to::<u32>() };
|
||||
debug_assert!(pre.is_empty());
|
||||
debug_assert!(post.is_empty());
|
||||
Cow::from(words)
|
||||
} else {
|
||||
let mut words = vec![0u32; data.len() / size_of::<u32>()];
|
||||
unsafe {
|
||||
copy_nonoverlapping(data.as_ptr(), words.as_mut_ptr() as *mut u8, data.len());
|
||||
}
|
||||
Cow::from(words)
|
||||
};
|
||||
|
||||
// Before checking if the data starts with the magic, check if it starts
|
||||
// with the magic in non-native endianness, own & swap the data if so.
|
||||
if words[0] == MAGIC_NUMBER.swap_bytes() {
|
||||
for word in Cow::to_mut(&mut words) {
|
||||
*word = word.swap_bytes();
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
words[0], MAGIC_NUMBER,
|
||||
"wrong magic word {:x}. Make sure you are using a binary SPIRV file.",
|
||||
words[0]
|
||||
);
|
||||
|
||||
words
|
||||
}
|
||||
|
||||
/// CPU accessible buffer used to download data back from the GPU.
|
||||
pub struct DownloadBuffer(
|
||||
Arc<super::Buffer>,
|
||||
Box<dyn crate::context::BufferMappedRange>,
|
||||
);
|
||||
|
||||
impl DownloadBuffer {
|
||||
/// Asynchronously read the contents of a buffer.
|
||||
pub fn read_buffer(
|
||||
device: &super::Device,
|
||||
queue: &super::Queue,
|
||||
buffer: &super::BufferSlice,
|
||||
callback: impl FnOnce(Result<Self, super::BufferAsyncError>) + Send + 'static,
|
||||
) {
|
||||
let size = match buffer.size {
|
||||
Some(size) => size.into(),
|
||||
None => buffer.buffer.map_context.lock().total_size - buffer.offset,
|
||||
};
|
||||
|
||||
let download = Arc::new(device.create_buffer(&super::BufferDescriptor {
|
||||
size,
|
||||
usage: super::BufferUsages::COPY_DST | super::BufferUsages::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
label: None,
|
||||
}));
|
||||
|
||||
let mut encoder =
|
||||
device.create_command_encoder(&super::CommandEncoderDescriptor { label: None });
|
||||
encoder.copy_buffer_to_buffer(buffer.buffer, buffer.offset, &download, 0, size);
|
||||
let command_buffer: super::CommandBuffer = encoder.finish();
|
||||
queue.submit(Some(command_buffer));
|
||||
|
||||
download
|
||||
.clone()
|
||||
.slice(..)
|
||||
.map_async(super::MapMode::Read, move |result| {
|
||||
if let Err(e) = result {
|
||||
callback(Err(e));
|
||||
return;
|
||||
}
|
||||
|
||||
let mapped_range = super::DynContext::buffer_get_mapped_range(
|
||||
&*download.context,
|
||||
&download.id,
|
||||
download.data.as_ref(),
|
||||
0..size,
|
||||
);
|
||||
callback(Ok(Self(download, mapped_range)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for DownloadBuffer {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
self.1.slice()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue