Backed out changeset 4fd09aad97af (bug 1876389) for causing webgpu failures on test_command_buffer_creation.html. CLOSED TREE
This commit is contained in:
@@ -25,9 +25,9 @@ git = "https://github.com/franziskuskiefer/cose-rust"
|
||||
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2"]
|
||||
[source."git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"]
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/glandium/mio?rev=9a2ef335c366044ffe73b1c4acabe50a1daefe05"]
|
||||
|
||||
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -1157,7 +1157,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "d3d12"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2#87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e#f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"libloading",
|
||||
@@ -3791,7 +3791,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
|
||||
[[package]]
|
||||
name = "naga"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2#87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e#f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bit-set",
|
||||
@@ -6403,7 +6403,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-core"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2#87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e#f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bit-vec",
|
||||
@@ -6429,7 +6429,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-hal"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2#87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e#f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"arrayvec",
|
||||
@@ -6467,7 +6467,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wgpu-types"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=87b6513df32e8a9c588962ba8509019c277438e2#87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e#f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"js-sys",
|
||||
|
||||
@@ -192,7 +192,133 @@ class PresentationData {
|
||||
~PresentationData() { MOZ_COUNT_DTOR(PresentationData); }
|
||||
};
|
||||
|
||||
WebGPUParent::WebGPUParent() : mContext(ffi::wgpu_server_new(this)) {
|
||||
static void FreeAdapter(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_adapter_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeAdapter");
|
||||
}
|
||||
}
|
||||
static void FreeDevice(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_device_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeDevice");
|
||||
}
|
||||
}
|
||||
static void FreeShaderModule(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_shader_module_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeShaderModule");
|
||||
}
|
||||
}
|
||||
static void FreePipelineLayout(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_pipeline_layout_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreePipelineLayout");
|
||||
}
|
||||
}
|
||||
static void FreeBindGroupLayout(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_bind_group_layout_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeBindGroupLayout");
|
||||
}
|
||||
}
|
||||
static void FreeBindGroup(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_bind_group_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeBindGroup");
|
||||
}
|
||||
}
|
||||
static void FreeCommandBuffer(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_command_buffer_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeCommandBuffer");
|
||||
}
|
||||
}
|
||||
static void FreeRenderBundle(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_render_bundle_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeRenderBundle");
|
||||
}
|
||||
}
|
||||
static void FreeRenderPipeline(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_render_pipeline_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeRenderPipeline");
|
||||
}
|
||||
}
|
||||
static void FreeComputePipeline(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_compute_pipeline_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeComputePipeline");
|
||||
}
|
||||
}
|
||||
static void FreeBuffer(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_buffer_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeBuffer");
|
||||
}
|
||||
}
|
||||
static void FreeTexture(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_texture_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeTexture");
|
||||
}
|
||||
}
|
||||
static void FreeTextureView(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_texture_view_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeTextureView");
|
||||
}
|
||||
}
|
||||
static void FreeSampler(RawId id, void* param) {
|
||||
ipc::ByteBuf byteBuf;
|
||||
wgpu_server_sampler_free(id, ToFFI(&byteBuf));
|
||||
if (!static_cast<WebGPUParent*>(param)->SendDropAction(std::move(byteBuf))) {
|
||||
NS_ERROR("Unable FreeSampler");
|
||||
}
|
||||
}
|
||||
static void FreeSurface(RawId id, void* param) {
|
||||
Unused << id;
|
||||
Unused << param;
|
||||
}
|
||||
|
||||
static ffi::WGPUIdentityRecyclerFactory MakeFactory(void* param) {
|
||||
ffi::WGPUIdentityRecyclerFactory factory;
|
||||
PodZero(&factory);
|
||||
factory.param = param;
|
||||
factory.free_adapter = FreeAdapter;
|
||||
factory.free_device = FreeDevice;
|
||||
factory.free_pipeline_layout = FreePipelineLayout;
|
||||
factory.free_shader_module = FreeShaderModule;
|
||||
factory.free_bind_group_layout = FreeBindGroupLayout;
|
||||
factory.free_bind_group = FreeBindGroup;
|
||||
factory.free_command_buffer = FreeCommandBuffer;
|
||||
factory.free_render_bundle = FreeRenderBundle;
|
||||
factory.free_render_pipeline = FreeRenderPipeline;
|
||||
factory.free_compute_pipeline = FreeComputePipeline;
|
||||
factory.free_buffer = FreeBuffer;
|
||||
factory.free_texture = FreeTexture;
|
||||
factory.free_texture_view = FreeTextureView;
|
||||
factory.free_sampler = FreeSampler;
|
||||
factory.free_surface = FreeSurface;
|
||||
return factory;
|
||||
}
|
||||
|
||||
WebGPUParent::WebGPUParent()
|
||||
: mContext(ffi::wgpu_server_new(MakeFactory(this), this)) {
|
||||
mTimer.Start(base::TimeDelta::FromMilliseconds(POLL_TIME_MS), this,
|
||||
&WebGPUParent::MaintainDevices);
|
||||
}
|
||||
|
||||
@@ -17,45 +17,46 @@ default = []
|
||||
[dependencies.wgc]
|
||||
package = "wgpu-core"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
# TODO: remove the replay feature on the next update containing https://github.com/gfx-rs/wgpu/pull/5182
|
||||
features = ["serde", "replay", "trace", "strict_asserts", "wgsl", "api_log_info"]
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
#Note: "replay" shouldn't ideally be needed,
|
||||
# but it allows us to serialize everything across IPC.
|
||||
features = ["replay", "trace", "serial-pass", "strict_asserts", "wgsl", "api_log_info"]
|
||||
|
||||
# We want the wgpu-core Metal backend on macOS and iOS.
|
||||
# (We should consider also enabling "vulkan" for Vulkan Portability.)
|
||||
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
|
||||
package = "wgpu-core"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
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 = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
features = ["dx12"]
|
||||
|
||||
# We want the wgpu-core Vulkan backend on Linux and Windows.
|
||||
[target.'cfg(any(windows, all(unix, not(any(target_os = "macos", target_os = "ios")))))'.dependencies.wgc]
|
||||
package = "wgpu-core"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
features = ["vulkan"]
|
||||
|
||||
[dependencies.wgt]
|
||||
package = "wgpu-types"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
|
||||
[dependencies.wgh]
|
||||
package = "wgpu-hal"
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
|
||||
[target.'cfg(windows)'.dependencies.d3d12]
|
||||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
rev = "f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3"
|
||||
|
||||
@@ -30,26 +30,6 @@ typedef uint64_t WGPUOption_SamplerId;
|
||||
typedef uint64_t WGPUOption_SurfaceId;
|
||||
typedef uint64_t WGPUOption_TextureViewId;
|
||||
typedef uint64_t WGPUOption_QuerySetId;
|
||||
|
||||
typedef uint64_t WGPUAdapterId;
|
||||
typedef uint64_t WGPUBindGroupId;
|
||||
typedef uint64_t WGPUBindGroupLayoutId;
|
||||
typedef uint64_t WGPUBufferId;
|
||||
typedef uint64_t WGPUCommandBufferId;
|
||||
typedef uint64_t WGPUCommandEncoderId;
|
||||
typedef uint64_t WGPUComputePipelineId;
|
||||
typedef uint64_t WGPUDeviceId;
|
||||
typedef uint64_t WGPUPipelineLayoutId;
|
||||
typedef uint64_t WGPUQuerySetId;
|
||||
typedef uint64_t WGPUQueueId;
|
||||
typedef uint64_t WGPURenderBundleId;
|
||||
typedef uint64_t WGPURenderPipelineId;
|
||||
typedef uint64_t WGPUSamplerId;
|
||||
typedef uint64_t WGPUShaderModuleId;
|
||||
typedef uint64_t WGPUStagingBufferId;
|
||||
typedef uint64_t WGPUSurfaceId;
|
||||
typedef uint64_t WGPUTextureId;
|
||||
typedef uint64_t WGPUTextureViewId;
|
||||
"""
|
||||
include_version = true
|
||||
braces = "SameLine"
|
||||
|
||||
@@ -20,11 +20,11 @@ origin:
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: commit 87b6513df32e8a9c588962ba8509019c277438e2
|
||||
release: f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e (2024-01-19T21:42:19Z).
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
revision: 87b6513df32e8a9c588962ba8509019c277438e2
|
||||
revision: f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e
|
||||
|
||||
license: ['MIT', 'Apache-2.0']
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ use wgc::{id, identity::IdentityManager};
|
||||
use wgt::{Backend, TextureFormat};
|
||||
|
||||
pub use wgc::command::{compute_ffi::*, render_ffi::*};
|
||||
use wgc::id::markers;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
||||
@@ -265,20 +264,20 @@ pub struct RenderBundleEncoderDescriptor<'a> {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct IdentityHub {
|
||||
adapters: IdentityManager<markers::Adapter>,
|
||||
devices: IdentityManager<markers::Device>,
|
||||
buffers: IdentityManager<markers::Buffer>,
|
||||
command_buffers: IdentityManager<markers::CommandBuffer>,
|
||||
render_bundles: IdentityManager<markers::RenderBundle>,
|
||||
bind_group_layouts: IdentityManager<markers::BindGroupLayout>,
|
||||
pipeline_layouts: IdentityManager<markers::PipelineLayout>,
|
||||
bind_groups: IdentityManager<markers::BindGroup>,
|
||||
shader_modules: IdentityManager<markers::ShaderModule>,
|
||||
compute_pipelines: IdentityManager<markers::ComputePipeline>,
|
||||
render_pipelines: IdentityManager<markers::RenderPipeline>,
|
||||
textures: IdentityManager<markers::Texture>,
|
||||
texture_views: IdentityManager<markers::TextureView>,
|
||||
samplers: IdentityManager<markers::Sampler>,
|
||||
adapters: IdentityManager<wgc::id::AdapterId>,
|
||||
devices: IdentityManager<wgc::id::DeviceId>,
|
||||
buffers: IdentityManager<wgc::id::BufferId>,
|
||||
command_buffers: IdentityManager<wgc::id::CommandBufferId>,
|
||||
render_bundles: IdentityManager<wgc::id::RenderBundleId>,
|
||||
bind_group_layouts: IdentityManager<wgc::id::BindGroupLayoutId>,
|
||||
pipeline_layouts: IdentityManager<wgc::id::PipelineLayoutId>,
|
||||
bind_groups: IdentityManager<wgc::id::BindGroupId>,
|
||||
shader_modules: IdentityManager<wgc::id::ShaderModuleId>,
|
||||
compute_pipelines: IdentityManager<wgc::id::ComputePipelineId>,
|
||||
render_pipelines: IdentityManager<wgc::id::RenderPipelineId>,
|
||||
textures: IdentityManager<wgc::id::TextureId>,
|
||||
texture_views: IdentityManager<wgc::id::TextureViewId>,
|
||||
samplers: IdentityManager<wgc::id::SamplerId>,
|
||||
}
|
||||
|
||||
impl Default for IdentityHub {
|
||||
@@ -308,7 +307,7 @@ impl ImplicitLayout<'_> {
|
||||
pipeline: identities.pipeline_layouts.process(backend),
|
||||
bind_groups: Cow::Owned(
|
||||
(0..8) // hal::MAX_BIND_GROUPS
|
||||
.map(|_| Some(identities.bind_group_layouts.process(backend)))
|
||||
.map(|_| identities.bind_group_layouts.process(backend))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
@@ -634,7 +633,6 @@ pub extern "C" fn wgpu_client_make_encoder_id(
|
||||
.select(backend)
|
||||
.command_buffers
|
||||
.process(backend)
|
||||
.transmute()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -652,8 +650,7 @@ pub extern "C" fn wgpu_client_create_command_encoder(
|
||||
.lock()
|
||||
.select(backend)
|
||||
.command_buffers
|
||||
.process(backend)
|
||||
.transmute();
|
||||
.process(backend);
|
||||
|
||||
let action = DeviceAction::CreateCommandEncoder(id, desc.map_label(|_| label));
|
||||
*bb = make_byte_buf(&action);
|
||||
@@ -1151,7 +1148,7 @@ pub unsafe extern "C" fn wgpu_client_create_compute_pipeline(
|
||||
let implicit = ImplicitLayout::new(identities.select(backend), backend);
|
||||
ptr::write(implicit_pipeline_layout_id, Some(implicit.pipeline));
|
||||
for (i, bgl_id) in implicit.bind_groups.iter().enumerate() {
|
||||
*implicit_bind_group_layout_ids.add(i) = *bgl_id;
|
||||
*implicit_bind_group_layout_ids.add(i) = Some(*bgl_id);
|
||||
}
|
||||
Some(implicit)
|
||||
}
|
||||
@@ -1194,7 +1191,7 @@ pub unsafe extern "C" fn wgpu_client_create_render_pipeline(
|
||||
let implicit = ImplicitLayout::new(identities.select(backend), backend);
|
||||
ptr::write(implicit_pipeline_layout_id, Some(implicit.pipeline));
|
||||
for (i, bgl_id) in implicit.bind_groups.iter().enumerate() {
|
||||
*implicit_bind_group_layout_ids.add(i) = *bgl_id;
|
||||
*implicit_bind_group_layout_ids.add(i) = Some(*bgl_id);
|
||||
}
|
||||
Some(implicit)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use wgc::id;
|
||||
|
||||
pub type FactoryParam = *mut std::ffi::c_void;
|
||||
|
||||
//TODO: remove this in favor of `DropAction` that could be sent over IPC.
|
||||
#[repr(C)]
|
||||
pub struct IdentityRecyclerFactory {
|
||||
param: FactoryParam,
|
||||
free_adapter: extern "C" fn(id::AdapterId, FactoryParam),
|
||||
free_device: extern "C" fn(id::DeviceId, FactoryParam),
|
||||
free_pipeline_layout: extern "C" fn(id::PipelineLayoutId, FactoryParam),
|
||||
free_shader_module: extern "C" fn(id::ShaderModuleId, FactoryParam),
|
||||
free_bind_group_layout: extern "C" fn(id::BindGroupLayoutId, FactoryParam),
|
||||
free_bind_group: extern "C" fn(id::BindGroupId, FactoryParam),
|
||||
free_command_buffer: extern "C" fn(id::CommandBufferId, FactoryParam),
|
||||
free_render_bundle: extern "C" fn(id::RenderBundleId, FactoryParam),
|
||||
free_render_pipeline: extern "C" fn(id::RenderPipelineId, FactoryParam),
|
||||
free_compute_pipeline: extern "C" fn(id::ComputePipelineId, FactoryParam),
|
||||
free_query_set: extern "C" fn(id::QuerySetId, FactoryParam),
|
||||
free_buffer: extern "C" fn(id::BufferId, FactoryParam),
|
||||
free_staging_buffer: extern "C" fn(id::StagingBufferId, FactoryParam),
|
||||
free_texture: extern "C" fn(id::TextureId, FactoryParam),
|
||||
free_texture_view: extern "C" fn(id::TextureViewId, FactoryParam),
|
||||
free_sampler: extern "C" fn(id::SamplerId, FactoryParam),
|
||||
free_surface: extern "C" fn(id::SurfaceId, FactoryParam),
|
||||
}
|
||||
|
||||
impl<I: wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I> for IdentityRecyclerFactory {
|
||||
type Input = I;
|
||||
fn input_to_id(id_in: Self::Input) -> I {
|
||||
id_in
|
||||
}
|
||||
fn autogenerate_ids() -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl wgc::identity::GlobalIdentityHandlerFactory for IdentityRecyclerFactory {}
|
||||
|
||||
@@ -9,6 +9,7 @@ pub use wgc::command::{compute_ffi::*, render_ffi::*};
|
||||
|
||||
pub mod client;
|
||||
pub mod error;
|
||||
pub mod identity;
|
||||
pub mod server;
|
||||
|
||||
pub use wgc::device::trace::Command as CommandEncoderAction;
|
||||
@@ -112,7 +113,7 @@ pub struct AdapterInformation<S> {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
struct ImplicitLayout<'a> {
|
||||
pipeline: id::PipelineLayoutId,
|
||||
bind_groups: Cow<'a, [Option<id::BindGroupLayoutId>]>,
|
||||
bind_groups: Cow<'a, [id::BindGroupLayoutId]>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
use crate::{
|
||||
error::{ErrMsg, ErrorBuffer, ErrorBufferType},
|
||||
identity::IdentityRecyclerFactory,
|
||||
wgpu_string, AdapterInformation, ByteBuf, CommandEncoderAction, DeviceAction, DropAction,
|
||||
QueueWriteAction, SwapChainId, TextureAction,
|
||||
};
|
||||
@@ -74,20 +75,23 @@ fn restrict_limits(limits: wgt::Limits) -> wgt::Limits {
|
||||
|
||||
// hide wgc's global in private
|
||||
pub struct Global {
|
||||
global: wgc::global::Global,
|
||||
global: wgc::global::Global<IdentityRecyclerFactory>,
|
||||
#[allow(dead_code)]
|
||||
owner: *mut c_void,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Global {
|
||||
type Target = wgc::global::Global;
|
||||
type Target = wgc::global::Global<IdentityRecyclerFactory>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.global
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_server_new(owner: *mut c_void) -> *mut Global {
|
||||
pub extern "C" fn wgpu_server_new(
|
||||
factory: IdentityRecyclerFactory,
|
||||
owner: *mut c_void,
|
||||
) -> *mut Global {
|
||||
log::info!("Initializing WGPU server");
|
||||
let backends_pref = static_prefs::pref!("dom.webgpu.wgpu-backend").to_string();
|
||||
let backends = if backends_pref.is_empty() {
|
||||
@@ -114,6 +118,7 @@ pub extern "C" fn wgpu_server_new(owner: *mut c_void) -> *mut Global {
|
||||
|
||||
let global = wgc::global::Global::new(
|
||||
"wgpu",
|
||||
factory,
|
||||
wgt::InstanceDescriptor {
|
||||
backends,
|
||||
flags: instance_flags,
|
||||
@@ -188,8 +193,8 @@ pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
|
||||
&& desc.AdapterLuid.LowPart == adapter_luid.unwrap().low_part
|
||||
&& desc.AdapterLuid.HighPart == adapter_luid.unwrap().high_part
|
||||
{
|
||||
let adapter_id = global
|
||||
.create_adapter_from_hal::<wgh::api::Dx12>(adapter, Some(id.unwrap().clone()));
|
||||
let adapter_id =
|
||||
global.create_adapter_from_hal::<wgh::api::Dx12>(adapter, id.unwrap().clone());
|
||||
return ids.iter().position(|&i| i == adapter_id).unwrap() as i8;
|
||||
}
|
||||
}
|
||||
@@ -200,7 +205,10 @@ pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
|
||||
return -1;
|
||||
}
|
||||
|
||||
match global.request_adapter(desc, wgc::instance::AdapterInputs::IdSet(ids)) {
|
||||
match global.request_adapter(
|
||||
desc,
|
||||
wgc::instance::AdapterInputs::IdSet(ids, |i| i.backend()),
|
||||
) {
|
||||
Ok(id) => ids.iter().position(|&i| i == id).unwrap() as i8,
|
||||
Err(e) => {
|
||||
error_buf.init(e);
|
||||
@@ -288,7 +296,7 @@ pub unsafe extern "C" fn wgpu_server_adapter_request_device(
|
||||
// TODO: in https://github.com/gfx-rs/wgpu/pull/3626/files#diff-033343814319f5a6bd781494692ea626f06f6c3acc0753a12c867b53a646c34eR97
|
||||
// which introduced the queue id parameter, the queue id is also the device id. I don't know how applicable this is to
|
||||
// other situations (this one in particular).
|
||||
let (_, _, error) = gfx_select!(self_id => global.adapter_request_device(self_id, &desc, trace_path, Some(new_id), Some(new_id.transmute())));
|
||||
let (_, _, error) = gfx_select!(self_id => global.adapter_request_device(self_id, &desc, trace_path, new_id, new_id));
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -310,11 +318,7 @@ pub extern "C" fn wgpu_server_device_drop(global: &Global, self_id: id::DeviceId
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wgpu_server_set_device_lost_callback(
|
||||
global: &Global,
|
||||
self_id: id::DeviceId,
|
||||
callback: wgc::device::DeviceLostClosureC,
|
||||
) {
|
||||
pub unsafe extern "C" fn wgpu_server_set_device_lost_callback(global: &Global, self_id: id::DeviceId, callback: wgc::device::DeviceLostClosureC) {
|
||||
gfx_select!(self_id => global.device_set_device_lost_closure(self_id, wgc::device::DeviceLostClosure::from_c(callback)));
|
||||
}
|
||||
|
||||
@@ -387,7 +391,7 @@ pub extern "C" fn wgpu_server_device_create_shader_module(
|
||||
|
||||
let (_, error) = gfx_select!(
|
||||
self_id => global.device_create_shader_module(
|
||||
self_id, &desc, source, Some(module_id)
|
||||
self_id, &desc, source, module_id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -422,7 +426,7 @@ pub extern "C" fn wgpu_server_device_create_buffer(
|
||||
message: "Out of memory",
|
||||
r#type: ErrorBufferType::OutOfMemory,
|
||||
});
|
||||
gfx_select!(self_id => global.create_buffer_error(Some(buffer_id), label));
|
||||
gfx_select!(self_id => global.create_buffer_error(buffer_id, label));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -432,8 +436,7 @@ pub extern "C" fn wgpu_server_device_create_buffer(
|
||||
usage,
|
||||
mapped_at_creation,
|
||||
};
|
||||
let (_, error) =
|
||||
gfx_select!(self_id => global.device_create_buffer(self_id, &desc, Some(buffer_id)));
|
||||
let (_, error) = gfx_select!(self_id => global.device_create_buffer(self_id, &desc, buffer_id));
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -531,10 +534,7 @@ pub extern "C" fn wgpu_server_buffer_drop(global: &Global, self_id: id::BufferId
|
||||
|
||||
#[allow(unused_variables)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_server_get_device_fence_handle(
|
||||
global: &Global,
|
||||
device_id: id::DeviceId,
|
||||
) -> *mut c_void {
|
||||
pub extern "C" fn wgpu_server_get_device_fence_handle(global: &Global, device_id: id::DeviceId) -> *mut c_void {
|
||||
assert!(device_id.backend() == wgt::Backend::Dx12);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -622,7 +622,7 @@ impl Global {
|
||||
|| desc.size.height > max
|
||||
|| desc.size.depth_or_array_layers > max
|
||||
{
|
||||
gfx_select!(self_id => self.create_texture_error(Some(id), desc.label));
|
||||
gfx_select!(self_id => self.create_texture_error(id, desc.label));
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Out of memory",
|
||||
r#type: ErrorBufferType::OutOfMemory,
|
||||
@@ -709,7 +709,7 @@ impl Global {
|
||||
hal_texture,
|
||||
self_id,
|
||||
&desc,
|
||||
Some(id),
|
||||
id,
|
||||
)
|
||||
};
|
||||
if let Some(err) = error {
|
||||
@@ -719,60 +719,52 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
let (_, error) = self.device_create_texture::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_texture::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateSampler(id, desc) => {
|
||||
let (_, error) = self.device_create_sampler::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_sampler::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateBindGroupLayout(id, desc) => {
|
||||
let (_, error) =
|
||||
self.device_create_bind_group_layout::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_bind_group_layout::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::RenderPipelineGetBindGroupLayout(pipeline_id, index, bgl_id) => {
|
||||
let (_, error) = self.render_pipeline_get_bind_group_layout::<A>(
|
||||
pipeline_id,
|
||||
index,
|
||||
Some(bgl_id),
|
||||
);
|
||||
let (_, error) =
|
||||
self.render_pipeline_get_bind_group_layout::<A>(pipeline_id, index, bgl_id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::ComputePipelineGetBindGroupLayout(pipeline_id, index, bgl_id) => {
|
||||
let (_, error) = self.compute_pipeline_get_bind_group_layout::<A>(
|
||||
pipeline_id,
|
||||
index,
|
||||
Some(bgl_id),
|
||||
);
|
||||
let (_, error) =
|
||||
self.compute_pipeline_get_bind_group_layout::<A>(pipeline_id, index, bgl_id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreatePipelineLayout(id, desc) => {
|
||||
let (_, error) = self.device_create_pipeline_layout::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_pipeline_layout::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateBindGroup(id, desc) => {
|
||||
let (_, error) = self.device_create_bind_group::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_bind_group::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateShaderModule(id, desc, code) => {
|
||||
let source = wgc::pipeline::ShaderModuleSource::Wgsl(code);
|
||||
let (_, error) =
|
||||
self.device_create_shader_module::<A>(self_id, &desc, source, Some(id));
|
||||
let (_, error) = self.device_create_shader_module::<A>(self_id, &desc, source, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -781,15 +773,11 @@ impl Global {
|
||||
let implicit_ids = implicit
|
||||
.as_ref()
|
||||
.map(|imp| wgc::device::ImplicitPipelineIds {
|
||||
root_id: Some(imp.pipeline),
|
||||
root_id: imp.pipeline,
|
||||
group_ids: &imp.bind_groups,
|
||||
});
|
||||
let (_, error) = self.device_create_compute_pipeline::<A>(
|
||||
self_id,
|
||||
&desc,
|
||||
Some(id),
|
||||
implicit_ids,
|
||||
);
|
||||
let (_, error) =
|
||||
self.device_create_compute_pipeline::<A>(self_id, &desc, id, implicit_ids);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -798,26 +786,26 @@ impl Global {
|
||||
let implicit_ids = implicit
|
||||
.as_ref()
|
||||
.map(|imp| wgc::device::ImplicitPipelineIds {
|
||||
root_id: Some(imp.pipeline),
|
||||
root_id: imp.pipeline,
|
||||
group_ids: &imp.bind_groups,
|
||||
});
|
||||
let (_, error) =
|
||||
self.device_create_render_pipeline::<A>(self_id, &desc, Some(id), implicit_ids);
|
||||
self.device_create_render_pipeline::<A>(self_id, &desc, id, implicit_ids);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateRenderBundle(id, encoder, desc) => {
|
||||
let (_, error) = self.render_bundle_encoder_finish::<A>(encoder, &desc, Some(id));
|
||||
let (_, error) = self.render_bundle_encoder_finish::<A>(encoder, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
DeviceAction::CreateRenderBundleError(buffer_id, label) => {
|
||||
self.create_render_bundle_error::<A>(Some(buffer_id), label);
|
||||
self.create_render_bundle_error::<A>(buffer_id, label);
|
||||
}
|
||||
DeviceAction::CreateCommandEncoder(id, desc) => {
|
||||
let (_, error) = self.device_create_command_encoder::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.device_create_command_encoder::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -839,7 +827,7 @@ impl Global {
|
||||
) {
|
||||
match action {
|
||||
TextureAction::CreateView(id, desc) => {
|
||||
let (_, error) = self.texture_create_view::<A>(self_id, &desc, Some(id));
|
||||
let (_, error) = self.texture_create_view::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -1027,7 +1015,7 @@ pub extern "C" fn wgpu_server_device_create_encoder(
|
||||
|
||||
let desc = desc.map_label(|_| label);
|
||||
let (_, error) =
|
||||
gfx_select!(self_id => global.device_create_command_encoder(self_id, &desc, Some(new_id)));
|
||||
gfx_select!(self_id => global.device_create_command_encoder(self_id, &desc, new_id));
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -1072,8 +1060,7 @@ pub unsafe extern "C" fn wgpu_server_encoder_copy_texture_to_buffer(
|
||||
buffer: dst_buffer,
|
||||
layout: dst_layout.into_wgt(),
|
||||
};
|
||||
if let Err(err) = gfx_select!(self_id => global.command_encoder_copy_texture_to_buffer(self_id, source, &destination, size))
|
||||
{
|
||||
if let Err(err) = gfx_select!(self_id => global.command_encoder_copy_texture_to_buffer(self_id, source, &destination, size)) {
|
||||
error_buf.init(err);
|
||||
}
|
||||
}
|
||||
@@ -1176,7 +1163,10 @@ pub extern "C" fn wgpu_server_render_pipeline_drop(global: &Global, self_id: id:
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_server_texture_destroy(global: &Global, self_id: id::TextureId) {
|
||||
pub extern "C" fn wgpu_server_texture_destroy(
|
||||
global: &Global,
|
||||
self_id: id::TextureId,
|
||||
) {
|
||||
let _ = gfx_select!(self_id => global.texture_destroy(self_id));
|
||||
}
|
||||
|
||||
@@ -1203,7 +1193,7 @@ pub extern "C" fn wgpu_server_compute_pipeline_get_bind_group_layout(
|
||||
assign_id: id::BindGroupLayoutId,
|
||||
mut error_buf: ErrorBuffer,
|
||||
) {
|
||||
let (_, error) = gfx_select!(self_id => global.compute_pipeline_get_bind_group_layout(self_id, index, Some(assign_id)));
|
||||
let (_, error) = gfx_select!(self_id => global.compute_pipeline_get_bind_group_layout(self_id, index, assign_id));
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
@@ -1217,7 +1207,7 @@ pub extern "C" fn wgpu_server_render_pipeline_get_bind_group_layout(
|
||||
assign_id: id::BindGroupLayoutId,
|
||||
mut error_buf: ErrorBuffer,
|
||||
) {
|
||||
let (_, error) = gfx_select!(self_id => global.render_pipeline_get_bind_group_layout(self_id, index, Some(assign_id)));
|
||||
let (_, error) = gfx_select!(self_id => global.render_pipeline_get_bind_group_layout(self_id, index, assign_id));
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
|
||||
@@ -1302,10 +1302,9 @@ who = [
|
||||
"Nicolas Silva <nical@fastmail.com>",
|
||||
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
|
||||
"Erich Gubler <erichdongubler@gmail.com>",
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
]
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.0 -> 0.19.0@git:87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
delta = "0.7.0 -> 0.19.0@git:f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
importable = false
|
||||
|
||||
[[audits.darling]]
|
||||
@@ -2598,13 +2597,13 @@ delta = "0.13.0 -> 0.14.0"
|
||||
|
||||
[[audits.naga]]
|
||||
who = [
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
"Nicolas Silva <nical@fastmail.com>",
|
||||
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
|
||||
"Erich Gubler <erichdongubler@gmail.com>",
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
]
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.14.0 -> 0.19.0@git:87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
delta = "0.14.0 -> 0.19.0@git:f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
importable = false
|
||||
|
||||
[[audits.net2]]
|
||||
@@ -4385,13 +4384,13 @@ delta = "0.17.0 -> 0.18.0"
|
||||
|
||||
[[audits.wgpu-core]]
|
||||
who = [
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
"Nicolas Silva <nical@fastmail.com>",
|
||||
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
|
||||
"Erich Gubler <erichdongubler@gmail.com>",
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
]
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0 -> 0.19.0@git:87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
delta = "0.18.0 -> 0.19.0@git:f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
importable = false
|
||||
|
||||
[[audits.wgpu-hal]]
|
||||
@@ -4439,13 +4438,13 @@ delta = "0.17.0 -> 0.18.0"
|
||||
|
||||
[[audits.wgpu-hal]]
|
||||
who = [
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
"Nicolas Silva <nical@fastmail.com>",
|
||||
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
|
||||
"Erich Gubler <erichdongubler@gmail.com>",
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
]
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0 -> 0.19.0@git:87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
delta = "0.18.0 -> 0.19.0@git:f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
importable = false
|
||||
|
||||
[[audits.wgpu-types]]
|
||||
@@ -4493,13 +4492,13 @@ delta = "0.17.0 -> 0.18.0"
|
||||
|
||||
[[audits.wgpu-types]]
|
||||
who = [
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
"Nicolas Silva <nical@fastmail.com>",
|
||||
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
|
||||
"Erich Gubler <erichdongubler@gmail.com>",
|
||||
"Jim Blandy <jimb@red-bean.com>",
|
||||
]
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.18.0 -> 0.19.0@git:87b6513df32e8a9c588962ba8509019c277438e2"
|
||||
delta = "0.18.0 -> 0.19.0@git:f9509bcf9ec2b63a64eb7fea93f7f44cd5ae4d2e"
|
||||
importable = false
|
||||
|
||||
[[audits.whatsys]]
|
||||
|
||||
2
third_party/rust/d3d12/.cargo-checksum.json
vendored
2
third_party/rust/d3d12/.cargo-checksum.json
vendored
@@ -1 +1 @@
|
||||
{"files":{"CHANGELOG.md":"45fa76b0e5bc51721887147000e9e78a5934cb04d1ad628e501ef2082763d353","Cargo.toml":"1108efc3deca25c270c3f8631abca07e7e696aace92d324ef8b83503cb2edbc3","README.md":"76cee3209f773a62535de6c9724b53f158406359f35b4d48b17ac3747b6c102e","src/com.rs":"cfc8f5692162b4cbf9bf370959ad0be08a40a7e9026b5511ca0065ffe33f72ab","src/command_allocator.rs":"ef01059a661749470f3772d188fe0fab0f002e1d154facdab4b9b2932f4b2d93","src/command_list.rs":"8723f3b755b721e0dbb234bd604956c1b7922a2368231197495daa3fa6548e63","src/debug.rs":"aa33b98f7c3e71cba75fc42c6ca9af72d96b45122422c16e48525e24590c57bf","src/descriptor.rs":"fea0b820de1566b54d17d8d0c67e6f5a2126eda19526397eb710ff7d6db9db9e","src/device.rs":"c1dd479aabd22bced0d407523d60629ad1da439fb47ad89fe7b48bae1c4b23e5","src/dxgi.rs":"1516186845b91bf3df813a29b4a0e00a85ca5649fb7a2755da43fba984c41a42","src/heap.rs":"dae2380684896c97e97ed022929f79ce2cc4f5418a3ec34883086f7c88f423d0","src/lib.rs":"612e2f471b84502d219da3fb86ee13f3cbd6faf17d77407bab6c84e51ec424d0","src/pso.rs":"ff819c321536695e34a3be9a6051cf3e57765049a4a2035db6ab27add5a7978a","src/query.rs":"ff61a2b76a108afc1f082724bb9b07ac8b52afbe97356e0fcf6df0ff7e53e07d","src/queue.rs":"bd32813d0b8a3bedf3223b69ade9f9c799a138a9e27d970f86435d9ce32d1557","src/resource.rs":"8989cdb7c3ee0687c826047f39f85148459d9219754f20a970bf8aaa09b96e27","src/sync.rs":"5c287fb7498242a397eb1f08887be9cff9b48dc7cb13af5792cce5f7182b55f8"},"package":null}
|
||||
{"files":{"CHANGELOG.md":"45fa76b0e5bc51721887147000e9e78a5934cb04d1ad628e501ef2082763d353","Cargo.toml":"1108efc3deca25c270c3f8631abca07e7e696aace92d324ef8b83503cb2edbc3","README.md":"76cee3209f773a62535de6c9724b53f158406359f35b4d48b17ac3747b6c102e","src/com.rs":"cfc8f5692162b4cbf9bf370959ad0be08a40a7e9026b5511ca0065ffe33f72ab","src/command_allocator.rs":"ef01059a661749470f3772d188fe0fab0f002e1d154facdab4b9b2932f4b2d93","src/command_list.rs":"8723f3b755b721e0dbb234bd604956c1b7922a2368231197495daa3fa6548e63","src/debug.rs":"67c8eb966cf349038f79c691e42b5d86cd8fc63c40d10cc279172400d56db6dc","src/descriptor.rs":"fea0b820de1566b54d17d8d0c67e6f5a2126eda19526397eb710ff7d6db9db9e","src/device.rs":"c1dd479aabd22bced0d407523d60629ad1da439fb47ad89fe7b48bae1c4b23e5","src/dxgi.rs":"1516186845b91bf3df813a29b4a0e00a85ca5649fb7a2755da43fba984c41a42","src/heap.rs":"dae2380684896c97e97ed022929f79ce2cc4f5418a3ec34883086f7c88f423d0","src/lib.rs":"612e2f471b84502d219da3fb86ee13f3cbd6faf17d77407bab6c84e51ec424d0","src/pso.rs":"ff819c321536695e34a3be9a6051cf3e57765049a4a2035db6ab27add5a7978a","src/query.rs":"ff61a2b76a108afc1f082724bb9b07ac8b52afbe97356e0fcf6df0ff7e53e07d","src/queue.rs":"bd32813d0b8a3bedf3223b69ade9f9c799a138a9e27d970f86435d9ce32d1557","src/resource.rs":"8989cdb7c3ee0687c826047f39f85148459d9219754f20a970bf8aaa09b96e27","src/sync.rs":"5c287fb7498242a397eb1f08887be9cff9b48dc7cb13af5792cce5f7182b55f8"},"package":null}
|
||||
15
third_party/rust/d3d12/src/debug.rs
vendored
15
third_party/rust/d3d12/src/debug.rs
vendored
@@ -1,10 +1,7 @@
|
||||
use crate::com::ComPtr;
|
||||
use winapi::um::d3d12sdklayers;
|
||||
#[cfg(any(feature = "libloading", feature = "implicit-link"))]
|
||||
use winapi::Interface as _;
|
||||
use winapi::{
|
||||
shared::{minwindef::TRUE, winerror::S_OK},
|
||||
um::d3d12sdklayers,
|
||||
};
|
||||
|
||||
pub type Debug = ComPtr<d3d12sdklayers::ID3D12Debug>;
|
||||
|
||||
@@ -43,14 +40,4 @@ impl Debug {
|
||||
pub fn enable_layer(&self) {
|
||||
unsafe { self.EnableDebugLayer() }
|
||||
}
|
||||
|
||||
pub fn enable_gpu_based_validation(&self) -> bool {
|
||||
let (ptr, hr) = unsafe { self.cast::<d3d12sdklayers::ID3D12Debug1>() };
|
||||
if hr == S_OK {
|
||||
unsafe { ptr.SetEnableGPUBasedValidation(TRUE) };
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
third_party/rust/naga/.cargo-checksum.json
vendored
2
third_party/rust/naga/.cargo-checksum.json
vendored
File diff suppressed because one or more lines are too long
2
third_party/rust/naga/Cargo.toml
vendored
2
third_party/rust/naga/Cargo.toml
vendored
@@ -48,7 +48,7 @@ harness = false
|
||||
[dependencies]
|
||||
arrayvec = "0.7"
|
||||
bit-set = "0.5"
|
||||
bitflags = "2.4"
|
||||
bitflags = "2.2"
|
||||
log = "0.4"
|
||||
num-traits = "0.2"
|
||||
rustc-hash = "1.1.0"
|
||||
|
||||
63
third_party/rust/naga/src/front/glsl/error.rs
vendored
63
third_party/rust/naga/src/front/glsl/error.rs
vendored
@@ -1,11 +1,7 @@
|
||||
use super::token::TokenValue;
|
||||
use crate::{proc::ConstantEvaluatorError, Span};
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use codespan_reporting::files::SimpleFile;
|
||||
use codespan_reporting::term;
|
||||
use pp_rs::token::PreprocessorError;
|
||||
use std::borrow::Cow;
|
||||
use termcolor::{NoColor, WriteColor};
|
||||
use thiserror::Error;
|
||||
|
||||
fn join_with_comma(list: &[ExpectedToken]) -> String {
|
||||
@@ -22,7 +18,7 @@ fn join_with_comma(list: &[ExpectedToken]) -> String {
|
||||
}
|
||||
|
||||
/// One of the expected tokens returned in [`InvalidToken`](ErrorKind::InvalidToken).
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ExpectedToken {
|
||||
/// A specific token was expected.
|
||||
Token(TokenValue),
|
||||
@@ -59,7 +55,7 @@ impl std::fmt::Display for ExpectedToken {
|
||||
}
|
||||
|
||||
/// Information about the cause of an error.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[derive(Debug, Error)]
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub enum ErrorKind {
|
||||
/// Whilst parsing as encountered an unexpected EOF.
|
||||
@@ -127,7 +123,7 @@ impl From<ConstantEvaluatorError> for ErrorKind {
|
||||
}
|
||||
|
||||
/// Error returned during shader parsing.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[derive(Debug, Error)]
|
||||
#[error("{kind}")]
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub struct Error {
|
||||
@@ -136,56 +132,3 @@ pub struct Error {
|
||||
/// Holds information about the range of the source code where the error happened.
|
||||
pub meta: Span,
|
||||
}
|
||||
|
||||
/// A collection of errors returned during shader parsing.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub struct ParseError {
|
||||
pub errors: Vec<Error>,
|
||||
}
|
||||
|
||||
impl ParseError {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
|
||||
self.emit_to_writer_with_path(writer, source, "glsl");
|
||||
}
|
||||
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl WriteColor, source: &str, path: &str) {
|
||||
let path = path.to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = codespan_reporting::term::Config::default();
|
||||
|
||||
for err in &self.errors {
|
||||
let mut diagnostic = Diagnostic::error().with_message(err.kind.to_string());
|
||||
|
||||
if let Some(range) = err.meta.to_range() {
|
||||
diagnostic = diagnostic.with_labels(vec![Label::primary((), range)]);
|
||||
}
|
||||
|
||||
term::emit(writer, &config, &files, &diagnostic).expect("cannot write error");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emit_to_string(&self, source: &str) -> String {
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
self.emit_to_writer(&mut writer, source);
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
self.errors.iter().try_for_each(|e| write!(f, "{e:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for ParseError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Error>> for ParseError {
|
||||
fn from(errors: Vec<Error>) -> Self {
|
||||
Self { errors }
|
||||
}
|
||||
}
|
||||
|
||||
8
third_party/rust/naga/src/front/glsl/mod.rs
vendored
8
third_party/rust/naga/src/front/glsl/mod.rs
vendored
@@ -13,7 +13,7 @@ To begin, take a look at the documentation for the [`Frontend`].
|
||||
*/
|
||||
|
||||
pub use ast::{Precision, Profile};
|
||||
pub use error::{Error, ErrorKind, ExpectedToken, ParseError};
|
||||
pub use error::{Error, ErrorKind, ExpectedToken};
|
||||
pub use token::TokenValue;
|
||||
|
||||
use crate::{proc::Layouter, FastHashMap, FastHashSet, Handle, Module, ShaderStage, Span, Type};
|
||||
@@ -196,7 +196,7 @@ impl Frontend {
|
||||
&mut self,
|
||||
options: &Options,
|
||||
source: &str,
|
||||
) -> std::result::Result<Module, ParseError> {
|
||||
) -> std::result::Result<Module, Vec<Error>> {
|
||||
self.reset(options.stage);
|
||||
|
||||
let lexer = lex::Lexer::new(source, &options.defines);
|
||||
@@ -207,12 +207,12 @@ impl Frontend {
|
||||
if self.errors.is_empty() {
|
||||
Ok(module)
|
||||
} else {
|
||||
Err(std::mem::take(&mut self.errors).into())
|
||||
Err(std::mem::take(&mut self.errors))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
self.errors.push(e);
|
||||
Err(std::mem::take(&mut self.errors).into())
|
||||
Err(std::mem::take(&mut self.errors))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::{
|
||||
ast::Profile,
|
||||
error::ExpectedToken,
|
||||
error::{Error, ErrorKind, ParseError},
|
||||
error::{Error, ErrorKind},
|
||||
token::TokenValue,
|
||||
Frontend, Options, Span,
|
||||
};
|
||||
@@ -21,12 +21,10 @@ fn version() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::InvalidVersion(99000),
|
||||
meta: Span::new(9, 14)
|
||||
}],
|
||||
},
|
||||
vec![Error {
|
||||
kind: ErrorKind::InvalidVersion(99000),
|
||||
meta: Span::new(9, 14)
|
||||
}],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -37,12 +35,10 @@ fn version() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::InvalidVersion(449),
|
||||
meta: Span::new(9, 12)
|
||||
}]
|
||||
},
|
||||
vec![Error {
|
||||
kind: ErrorKind::InvalidVersion(449),
|
||||
meta: Span::new(9, 12)
|
||||
}]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -53,12 +49,10 @@ fn version() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::InvalidProfile("smart".into()),
|
||||
meta: Span::new(13, 18),
|
||||
}]
|
||||
},
|
||||
vec![Error {
|
||||
kind: ErrorKind::InvalidProfile("smart".into()),
|
||||
meta: Span::new(13, 18),
|
||||
}]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -69,21 +63,19 @@ fn version() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![
|
||||
Error {
|
||||
kind: ErrorKind::PreprocessorError(PreprocessorError::UnexpectedHash,),
|
||||
meta: Span::new(27, 28),
|
||||
},
|
||||
Error {
|
||||
kind: ErrorKind::InvalidToken(
|
||||
TokenValue::Identifier("version".into()),
|
||||
vec![ExpectedToken::Eof]
|
||||
),
|
||||
meta: Span::new(28, 35)
|
||||
}
|
||||
]
|
||||
},
|
||||
vec![
|
||||
Error {
|
||||
kind: ErrorKind::PreprocessorError(PreprocessorError::UnexpectedHash,),
|
||||
meta: Span::new(27, 28),
|
||||
},
|
||||
Error {
|
||||
kind: ErrorKind::InvalidToken(
|
||||
TokenValue::Identifier("version".into()),
|
||||
vec![ExpectedToken::Eof]
|
||||
),
|
||||
meta: Span::new(28, 35)
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
// valid versions
|
||||
@@ -455,12 +447,10 @@ fn functions() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::SemanticError("Function already defined".into()),
|
||||
meta: Span::new(134, 152),
|
||||
}]
|
||||
},
|
||||
vec![Error {
|
||||
kind: ErrorKind::SemanticError("Function already defined".into()),
|
||||
meta: Span::new(134, 152),
|
||||
}]
|
||||
);
|
||||
|
||||
println!();
|
||||
@@ -636,12 +626,10 @@ fn implicit_conversions() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::SemanticError("Unknown function \'test\'".into()),
|
||||
meta: Span::new(156, 165),
|
||||
}]
|
||||
},
|
||||
vec![Error {
|
||||
kind: ErrorKind::SemanticError("Unknown function \'test\'".into()),
|
||||
meta: Span::new(156, 165),
|
||||
}]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@@ -660,12 +648,10 @@ fn implicit_conversions() {
|
||||
)
|
||||
.err()
|
||||
.unwrap(),
|
||||
ParseError {
|
||||
errors: vec![Error {
|
||||
kind: ErrorKind::SemanticError("Ambiguous best function for \'test\'".into()),
|
||||
meta: Span::new(158, 165),
|
||||
}]
|
||||
}
|
||||
vec![Error {
|
||||
kind: ErrorKind::SemanticError("Ambiguous best function for \'test\'".into()),
|
||||
meta: Span::new(158, 165),
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ pub struct Token {
|
||||
///
|
||||
/// This type is exported since it's returned in the
|
||||
/// [`InvalidToken`](super::ErrorKind::InvalidToken) error.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TokenValue {
|
||||
Identifier(String),
|
||||
|
||||
|
||||
25
third_party/rust/naga/src/front/spv/error.rs
vendored
25
third_party/rust/naga/src/front/spv/error.rs
vendored
@@ -1,9 +1,5 @@
|
||||
use super::ModuleState;
|
||||
use crate::arena::Handle;
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use codespan_reporting::files::SimpleFile;
|
||||
use codespan_reporting::term;
|
||||
use termcolor::{NoColor, WriteColor};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
@@ -131,24 +127,3 @@ pub enum Error {
|
||||
)]
|
||||
NonBindingArrayOfImageOrSamplers,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
|
||||
self.emit_to_writer_with_path(writer, source, "glsl");
|
||||
}
|
||||
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl WriteColor, source: &str, path: &str) {
|
||||
let path = path.to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = codespan_reporting::term::Config::default();
|
||||
let diagnostic = Diagnostic::error().with_message(format!("{self:?}"));
|
||||
|
||||
term::emit(writer, &config, &files, &diagnostic).expect("cannot write error");
|
||||
}
|
||||
|
||||
pub fn emit_to_string(&self, source: &str) -> String {
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
self.emit_to_writer(&mut writer, source);
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
6
third_party/rust/naga/src/lib.rs
vendored
6
third_party/rust/naga/src/lib.rs
vendored
@@ -687,7 +687,8 @@ pub enum ImageClass {
|
||||
}
|
||||
|
||||
/// A data type declared in the module.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "clone", derive(Clone))]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
@@ -699,7 +700,8 @@ pub struct Type {
|
||||
}
|
||||
|
||||
/// Enum with additional information, depending on the kind of type.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "clone", derive(Clone))]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
|
||||
197
third_party/rust/naga/src/proc/constant_evaluator.rs
vendored
197
third_party/rust/naga/src/proc/constant_evaluator.rs
vendored
@@ -97,7 +97,7 @@ macro_rules! gen_component_wise_extractor {
|
||||
.and_then(|comps| Ok(handler(comps)?.into())),
|
||||
)+
|
||||
&Expression::Compose { ty, ref components } => match &eval.types[ty].inner {
|
||||
&TypeInner::Vector { size, scalar } => match scalar.kind {
|
||||
&TypeInner::Vector { size: _, scalar } => match scalar.kind {
|
||||
$(ScalarKind::$scalar_kind)|* => {
|
||||
let first_ty = ty;
|
||||
let mut component_groups =
|
||||
@@ -132,7 +132,7 @@ macro_rules! gen_component_wise_extractor {
|
||||
let component_groups = component_groups.into_inner().unwrap();
|
||||
let mut new_components =
|
||||
ArrayVec::<_, { crate::VectorSize::MAX }>::new();
|
||||
for idx in 0..(size as u8).into() {
|
||||
for idx in 0..N {
|
||||
let group = component_groups
|
||||
.iter()
|
||||
.map(|cs| cs[idx])
|
||||
@@ -222,34 +222,6 @@ gen_component_wise_extractor! {
|
||||
],
|
||||
}
|
||||
|
||||
gen_component_wise_extractor! {
|
||||
component_wise_concrete_int -> ConcreteInt,
|
||||
literals: [
|
||||
U32 => U32: u32,
|
||||
I32 => I32: i32,
|
||||
],
|
||||
scalar_kinds: [
|
||||
Sint,
|
||||
Uint,
|
||||
],
|
||||
}
|
||||
|
||||
gen_component_wise_extractor! {
|
||||
component_wise_signed -> Signed,
|
||||
literals: [
|
||||
AbstractFloat => AbstractFloat: f64,
|
||||
AbstractInt => AbstractInt: i64,
|
||||
F32 => F32: f32,
|
||||
I32 => I32: i32,
|
||||
],
|
||||
scalar_kinds: [
|
||||
Sint,
|
||||
AbstractInt,
|
||||
Float,
|
||||
AbstractFloat,
|
||||
],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Behavior {
|
||||
Wgsl,
|
||||
@@ -837,9 +809,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
));
|
||||
}
|
||||
|
||||
// NOTE: We try to match the declaration order of `MathFunction` here.
|
||||
match fun {
|
||||
// comparison
|
||||
crate::MathFunction::Abs => {
|
||||
component_wise_scalar(self, span, [arg], |args| match args {
|
||||
Scalar::AbstractFloat([e]) => Ok(Scalar::AbstractFloat([e.abs()])),
|
||||
@@ -849,14 +819,27 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
Scalar::U32([e]) => Ok(Scalar::U32([e])), // TODO: just re-use the expression, ezpz
|
||||
})
|
||||
}
|
||||
crate::MathFunction::Min => {
|
||||
component_wise_scalar!(self, span, [arg, arg1.unwrap()], |e1, e2| {
|
||||
Ok([e1.min(e2)])
|
||||
})
|
||||
crate::MathFunction::Acos => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.acos()]) })
|
||||
}
|
||||
crate::MathFunction::Max => {
|
||||
component_wise_scalar!(self, span, [arg, arg1.unwrap()], |e1, e2| {
|
||||
Ok([e1.max(e2)])
|
||||
crate::MathFunction::Acosh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.acosh()]) })
|
||||
}
|
||||
crate::MathFunction::Asin => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.asin()]) })
|
||||
}
|
||||
crate::MathFunction::Asinh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.asinh()]) })
|
||||
}
|
||||
crate::MathFunction::Atan => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.atan()]) })
|
||||
}
|
||||
crate::MathFunction::Atanh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.atanh()]) })
|
||||
}
|
||||
crate::MathFunction::Pow => {
|
||||
component_wise_float!(self, span, [arg, arg1.unwrap()], |e1, e2| {
|
||||
Ok([e1.powf(e2)])
|
||||
})
|
||||
}
|
||||
crate::MathFunction::Clamp => {
|
||||
@@ -873,61 +856,12 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
}
|
||||
)
|
||||
}
|
||||
crate::MathFunction::Saturate => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.clamp(0., 1.)]) })
|
||||
}
|
||||
|
||||
// trigonometry
|
||||
crate::MathFunction::Cos => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.cos()]) })
|
||||
}
|
||||
crate::MathFunction::Cosh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.cosh()]) })
|
||||
}
|
||||
crate::MathFunction::Sin => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sin()]) })
|
||||
}
|
||||
crate::MathFunction::Sinh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sinh()]) })
|
||||
}
|
||||
crate::MathFunction::Tan => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.tan()]) })
|
||||
}
|
||||
crate::MathFunction::Tanh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.tanh()]) })
|
||||
}
|
||||
crate::MathFunction::Acos => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.acos()]) })
|
||||
}
|
||||
crate::MathFunction::Asin => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.asin()]) })
|
||||
}
|
||||
crate::MathFunction::Atan => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.atan()]) })
|
||||
}
|
||||
crate::MathFunction::Asinh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.asinh()]) })
|
||||
}
|
||||
crate::MathFunction::Acosh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.acosh()]) })
|
||||
}
|
||||
crate::MathFunction::Atanh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.atanh()]) })
|
||||
}
|
||||
crate::MathFunction::Radians => {
|
||||
component_wise_float!(self, span, [arg], |e1| { Ok([e1.to_radians()]) })
|
||||
}
|
||||
crate::MathFunction::Degrees => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.to_degrees()]) })
|
||||
}
|
||||
|
||||
// decomposition
|
||||
crate::MathFunction::Ceil => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.ceil()]) })
|
||||
}
|
||||
crate::MathFunction::Floor => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.floor()]) })
|
||||
}
|
||||
crate::MathFunction::Round => {
|
||||
// TODO: Use `f{32,64}.round_ties_even()` when available on stable. This polyfill
|
||||
// is shamelessly [~~stolen from~~ inspired by `ndarray-image`][polyfill source],
|
||||
@@ -954,92 +888,29 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
Float::F32([e]) => Ok(Float::F32([(round_ties_even(e as f64) as f32)])),
|
||||
})
|
||||
}
|
||||
crate::MathFunction::Fract => {
|
||||
component_wise_float!(self, span, [arg], |e| {
|
||||
// N.B., Rust's definition of `fract` is `e - e.trunc()`, so we can't use that
|
||||
// here.
|
||||
Ok([e - e.floor()])
|
||||
})
|
||||
crate::MathFunction::Saturate => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.clamp(0., 1.)]) })
|
||||
}
|
||||
crate::MathFunction::Trunc => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.trunc()]) })
|
||||
crate::MathFunction::Sin => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sin()]) })
|
||||
}
|
||||
|
||||
// exponent
|
||||
crate::MathFunction::Exp => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.exp()]) })
|
||||
crate::MathFunction::Sinh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sinh()]) })
|
||||
}
|
||||
crate::MathFunction::Exp2 => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.exp2()]) })
|
||||
crate::MathFunction::Tan => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.tan()]) })
|
||||
}
|
||||
crate::MathFunction::Log => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.ln()]) })
|
||||
crate::MathFunction::Tanh => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.tanh()]) })
|
||||
}
|
||||
crate::MathFunction::Log2 => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.log2()]) })
|
||||
}
|
||||
crate::MathFunction::Pow => {
|
||||
component_wise_float!(self, span, [arg, arg1.unwrap()], |e1, e2| {
|
||||
Ok([e1.powf(e2)])
|
||||
})
|
||||
}
|
||||
|
||||
// computational
|
||||
crate::MathFunction::Sign => {
|
||||
component_wise_signed!(self, span, [arg], |e| { Ok([e.signum()]) })
|
||||
}
|
||||
crate::MathFunction::Fma => {
|
||||
component_wise_float!(
|
||||
self,
|
||||
span,
|
||||
[arg, arg1.unwrap(), arg2.unwrap()],
|
||||
|e1, e2, e3| { Ok([e1.mul_add(e2, e3)]) }
|
||||
)
|
||||
crate::MathFunction::Sqrt => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sqrt()]) })
|
||||
}
|
||||
crate::MathFunction::Step => {
|
||||
component_wise_float!(self, span, [arg, arg1.unwrap()], |edge, x| {
|
||||
Ok([if edge <= x { 1.0 } else { 0.0 }])
|
||||
})
|
||||
}
|
||||
crate::MathFunction::Sqrt => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([e.sqrt()]) })
|
||||
}
|
||||
crate::MathFunction::InverseSqrt => {
|
||||
component_wise_float!(self, span, [arg], |e| { Ok([1. / e.sqrt()]) })
|
||||
}
|
||||
|
||||
// bits
|
||||
crate::MathFunction::CountTrailingZeros => {
|
||||
component_wise_concrete_int!(self, span, [arg], |e| {
|
||||
#[allow(clippy::useless_conversion)]
|
||||
Ok([e
|
||||
.trailing_zeros()
|
||||
.try_into()
|
||||
.expect("bit count overflowed 32 bits, somehow!?")])
|
||||
})
|
||||
}
|
||||
crate::MathFunction::CountLeadingZeros => {
|
||||
component_wise_concrete_int!(self, span, [arg], |e| {
|
||||
#[allow(clippy::useless_conversion)]
|
||||
Ok([e
|
||||
.leading_zeros()
|
||||
.try_into()
|
||||
.expect("bit count overflowed 32 bits, somehow!?")])
|
||||
})
|
||||
}
|
||||
crate::MathFunction::CountOneBits => {
|
||||
component_wise_concrete_int!(self, span, [arg], |e| {
|
||||
#[allow(clippy::useless_conversion)]
|
||||
Ok([e
|
||||
.count_ones()
|
||||
.try_into()
|
||||
.expect("bit count overflowed 32 bits, somehow!?")])
|
||||
})
|
||||
}
|
||||
crate::MathFunction::ReverseBits => {
|
||||
component_wise_concrete_int!(self, span, [arg], |e| { Ok([e.reverse_bits()]) })
|
||||
}
|
||||
|
||||
fun => Err(ConstantEvaluatorError::NotImplemented(format!(
|
||||
"{fun:?} built-in function"
|
||||
))),
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"92c0bcfb5bf68fb55acb6e7b826ec07c1cfdd6d53b057c16a5c698e044ea228e","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/any_surface.rs":"108de0dd618beefbe18119ccc2b1d5910d6f6e16ace1c67cfd135f33f721a145","src/binding_model.rs":"b3a57236d6a554f2ef604135ba35c09ae9c99108486a3be87471c1dfd792321d","src/command/bind.rs":"a37f042484b65d9fdea4cdab3667381623ee9a8943a6d32683d410b92736d306","src/command/bundle.rs":"91513a3be0adf46a9f3454b6a3d00ff6686729eb91fe9dd6d732cbfa1ff6d1d8","src/command/clear.rs":"b20e93c4b8cb47062b38e472f78d28d9ec00fd1169b17a87094be7f9d1c995e1","src/command/compute.rs":"84c4ea6dde64893562aeddd16869ed02187145b8438775fd4419a1e6657e2b63","src/command/draw.rs":"e8a664fc248e273e8c0e4aaeb645010b3f4ec61d29d858137f31f6f653c86542","src/command/memory_init.rs":"6ec93b9e2eb21edaa534e60770b4ba95735e9de61e74d827bc492df8e3639449","src/command/mod.rs":"d6a66a5796bd824be72af2c8d3ece59a507090c61cb50e9856eb4c70a28945e2","src/command/query.rs":"dffc843746b10ba9a50b8a2b92a59b407b56a845619a96d72a5883588fcb50f0","src/command/render.rs":"e6e5eaafccdb5ea7e4c61e324ef8670ee5c7cf424bbf257e56f6f78d5b19046b","src/command/transfer.rs":"9f3d7a0500fafc4066d62f3ecbda6f9cbb9d3254a9d8fd509ed73aeb963e198c","src/conv.rs":"7e3ffe33b47a6fd3617aabf9f11cc68f1ccbee2c7343b8dbbcd0e8f3447e1ad8","src/device/any_device.rs":"f12aae9636b8634334b6e49875a8034bfcbc1db79ef898a3a19a803648be7369","src/device/bgl.rs":"292a0f07121aec78e86e0125d08785072bd4b7e763c99975b581b342ac4fcaa3","src/device/global.rs":"9e4287265a5b3a813d9c66cb8fe3c7b92d30ff07f98dfa14e79c06dc20fadc5f","src/device/life.rs":"1c6829b6d7ca9571d46282e0b3fbc4c747bfa0ef61cf57b1072998c8b1b04e9d","src/device/mod.rs":"fff41f92e1a9f6660e18dc30452d9911ca827701bb8303af2ae06f1c1e1a795f","src/device/queue.rs":"2ffc477d1bebb35a1fc8e46f4ca2c5ef50a4eb6034968f076062461b2e678699","src/device/resource.rs":"03f198d5660755dda69e770943be4f809542f61a14f16649c0151fb8ae076618","src/device/trace.rs":"9deb1b083165e07253b4928ac2f564aba06f9089c3aca1c0a1d438d87d981542","src/error.rs":"e3b6b7a69877437f4e46af7f0e8ca1db1822beae7c8448db41c2bae0f64b2bb4","src/global.rs":"0966475959706650fd036a18d51441a8e14c3ef10107db617f597614ca47e50a","src/hal_api.rs":"56ef4891dab63f834bab7a1c2ed64f71ba34d503420e1c963e5771d45f119cf5","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"a180281fba7426d681eaa937b94e8f424a5f658ebfcad309ab0f0e912b4764c2","src/id.rs":"875dc5afefc6387ed5ce37253def84f15085a700e8c8f4a7ebd1a63eeded1a49","src/identity.rs":"c6a719389d71bb11c9ceaeadb0496f8b4c6ad24e35597e12b40980ad7ad72f10","src/init_tracker/buffer.rs":"61eb9cfaa312135b7a937ff6a3117f531b5b7323fae6553a41d6de9bc106d7e0","src/init_tracker/mod.rs":"43d98d2b2ebf92b3b77c5bd049c66e29a021020b2ab2c1676de56fd305b6a115","src/init_tracker/texture.rs":"030fd594bf9948fad391390d85c5e1fec7eaf67b6e812c60f2dd59bc4fda8fd5","src/instance.rs":"eed17891b58ccbf1b983e745febe815998d30a73ea712f07449b5130d50afbe5","src/lib.rs":"b2cf7a6d4acc800e12b6162c0a876e866d0e9b76ef98e90fb985eadedf6fb66d","src/pipeline.rs":"1a47caded7956da1b4f2cf22bc8a41a29941f1608ea2a58b0ac16edecce7eed0","src/pool.rs":"8c88d86763bc465bf628157c62db9641f6789ece684cc4a20a2fdf50d37e0e16","src/present.rs":"e2d6708f174df750a94f46d81b676f3ea3ee2f2c547a19717f2678ae2822d3c2","src/registry.rs":"dbc9310a24a843cf6b94a4bab78b0bb5f325e18c1f3c19c94d4f12b4f29e8598","src/resource.rs":"68ab78d4b0fa26033b750a9da02de7cb019935f9fba9a5a184a9bb6ce0332830","src/snatch.rs":"dd514e1954137eec4a0753a3670e8180796ac9c9ff770a1ca1813863debce823","src/storage.rs":"1624457eacbe27be5116fe23d2653cf609ba4fe16977daadd1a770556dbf9134","src/track/buffer.rs":"15cb7f7e4423a829d9ccd6f1cb71811a7c0aa40c32da342ad7a84f724d891ce7","src/track/metadata.rs":"c8b420da9fd491b822530c67a7de2d69c74339542a80aabb829408fb8cef7a62","src/track/mod.rs":"80739f73903b8ebd518586e22c4b6cf3f71b8a5d4435b3d0cc276beb9aa55d32","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"f3355a91716901e578b5382220f8f5ea4e38770648514b140ed8d7f895c98dea","src/track/texture.rs":"b800c4d8c19d716a9cc0d30b67c9b9a310436cda6ae4a6ff4251b4973ebe06cb","src/validation.rs":"613c58c3601f36d6aa5986cea01f30497c6bd4ceb990824904d101b2327941a9"},"package":null}
|
||||
{"files":{"Cargo.toml":"8c08a31db95798345f8d6836b3f9cbe49b002362c6e4f6ac2d5ec57a4d5e067d","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"a99478d7f63fb41429e3834f4d0e5cd333f94ba1834c68295f929170e16987de","src/any_surface.rs":"108de0dd618beefbe18119ccc2b1d5910d6f6e16ace1c67cfd135f33f721a145","src/binding_model.rs":"3749ac3bb0fb2604729d22614c5c6983aa65f4e32dd2400f23c27db563fca664","src/command/bind.rs":"a37f042484b65d9fdea4cdab3667381623ee9a8943a6d32683d410b92736d306","src/command/bundle.rs":"095fa5c9ec22c708bd9193fcb3c87e4731cc219013e1168caad20caadb579b52","src/command/clear.rs":"437c5c9916e123d3f3905f5ac40499d9cd755b8e2fd89c4497718335faeb40ad","src/command/compute.rs":"9fd61336ca2946694d1f611d2b7b92f215a9176d88275cfab64a2ae80d264ac9","src/command/draw.rs":"25600c64b31a5fe52d8705a2102ca66b86073a99221d69c734f50be5717225a1","src/command/memory_init.rs":"6ec93b9e2eb21edaa534e60770b4ba95735e9de61e74d827bc492df8e3639449","src/command/mod.rs":"a4170bae20979fce9fbce71a82ebe22ec48ce39fc70dfbba848247e169bbde72","src/command/query.rs":"51313e41595f808b53c24a2257863a68f930bd10b0d50d306e7ea5d44115e78c","src/command/render.rs":"e59b269f5760e93b466c332340080a92cea349c9e7203d28cafe9e9d448c6aab","src/command/transfer.rs":"4798cb1cdc9829fb972b17c5bd37f5e54a0b053a96477dc79a7371e49d1facb6","src/conv.rs":"7e3ffe33b47a6fd3617aabf9f11cc68f1ccbee2c7343b8dbbcd0e8f3447e1ad8","src/device/any_device.rs":"f12aae9636b8634334b6e49875a8034bfcbc1db79ef898a3a19a803648be7369","src/device/bgl.rs":"292a0f07121aec78e86e0125d08785072bd4b7e763c99975b581b342ac4fcaa3","src/device/global.rs":"f1e1b8296a9f5254b62546062f9e37eb58616a40a367a63749fe80ba4a33ffd6","src/device/life.rs":"c409083438fd2e4bb432cc559720b8ceafeb91ef31437e308993eeff239fc94d","src/device/mod.rs":"eca2e5796eac077ce00ef1e853e881450a463404061e68475b532c01ccc0b850","src/device/queue.rs":"cef9043ca951dba20b144f37e52c23945004bf393d1e3e6f85dd35a19bacea38","src/device/resource.rs":"19c8b50fd16663b994003653f426e11894e3269cd5e486975bccbdd0d65e6df0","src/device/trace.rs":"9a8ec674567a8866a6bd1ed2ad06e474bd2504ed91f228d3040cb6db18fe5f2b","src/error.rs":"64add26c7b8f3695ac4b76dd497266b7e14b307509d4edece602c496833a6890","src/global.rs":"26e8cb27b5d8db4b4d503c3bd7d09c90a8786e8304eb6ab4f72b3546664267e5","src/hal_api.rs":"b348147701efc7daf5126e25027a2562f5866ae8289eba907f7c7d250f0fd7f0","src/hash_utils.rs":"e8d484027c7ce81978e4679a5e20af9416ab7d2fa595f1ca95992b29d625b0ca","src/hub.rs":"c2b2e575bbe0683640f3ead5ca828dee1c13fdc12a7b3e4c7fc9e716cef6dac4","src/id.rs":"2c73422b2b5f0ce4a5bc3fce79bb3d3a370cda7aa6680c2239829ffc5a85d869","src/identity.rs":"0701f6f41e754dde2bebc567a87c25b353dfab40b79a322990dbfa477739ab8c","src/init_tracker/buffer.rs":"61eb9cfaa312135b7a937ff6a3117f531b5b7323fae6553a41d6de9bc106d7e0","src/init_tracker/mod.rs":"43d98d2b2ebf92b3b77c5bd049c66e29a021020b2ab2c1676de56fd305b6a115","src/init_tracker/texture.rs":"030fd594bf9948fad391390d85c5e1fec7eaf67b6e812c60f2dd59bc4fda8fd5","src/instance.rs":"ad28cdba959eef0b72faaa2ba78c69db17e74b23a1ad2c5a359ef160786e34c8","src/lib.rs":"b90f903bc555fbdf563e6ef55672ff4292f5c6d434844e9d592fe5827c5879e1","src/pipeline.rs":"78c6d88667a1e2105356d7634cfb554998b3f3c9912d4e3abeca0eb2dd5e939b","src/pool.rs":"8c88d86763bc465bf628157c62db9641f6789ece684cc4a20a2fdf50d37e0e16","src/present.rs":"4bb768555f853d6cfb63f914520da31bc95c0000ab41ab04ff7a85e14a21454e","src/registry.rs":"c96b815b08ed7e6e3097b4de71878f4c838f07d619a60d2ba282f4ec9face934","src/resource.rs":"b6e16f95d6d131ab81451667399533429135bdb25da25433e1ce40791597372e","src/snatch.rs":"dd514e1954137eec4a0753a3670e8180796ac9c9ff770a1ca1813863debce823","src/storage.rs":"39eecf5aa0745e559985ce6b42c2eb5775ae277786f74311814eab426aa173af","src/track/buffer.rs":"c5ae73d1d84bcfb5a17c31f43de661cd0bf931e15e9fd92ad18fd31a88b05330","src/track/metadata.rs":"f8994ad91db7f3bb1b7f8b8b0f6884753d733ce28238b36f31da2230706f848e","src/track/mod.rs":"02bac3cf2e53af45f79646817e85da8e4072d576438036a44b41ce1744e02d64","src/track/range.rs":"2a15794e79b0470d5ba6b3267173a42f34312878e1cb288f198d2854a7888e53","src/track/stateless.rs":"b0a73ce9bc37afc8c3524e109749df0104229e9cfd1a040408ea59aab598113d","src/track/texture.rs":"769d87975b2fa0f6ca5794b7eaa203b2d6a00dea452783e6105ca7daf141490f","src/validation.rs":"613c58c3601f36d6aa5986cea01f30497c6bd4ceb990824904d101b2327941a9"},"package":null}
|
||||
17
third_party/rust/wgpu-core/Cargo.toml
vendored
17
third_party/rust/wgpu-core/Cargo.toml
vendored
@@ -49,10 +49,6 @@ rustc-hash = "1.1"
|
||||
smallvec = "1"
|
||||
thiserror = "1"
|
||||
|
||||
[dependencies.bytemuck]
|
||||
version = "1.14"
|
||||
optional = true
|
||||
|
||||
[dependencies.hal]
|
||||
version = "0.19.0"
|
||||
path = "../wgpu-hal"
|
||||
@@ -98,28 +94,27 @@ fragile-send-sync-non-atomic-wasm = [
|
||||
"wgt/fragile-send-sync-non-atomic-wasm",
|
||||
]
|
||||
gles = ["hal/gles"]
|
||||
glsl = ["naga/glsl-in"]
|
||||
link = ["hal/link"]
|
||||
metal = ["hal/metal"]
|
||||
renderdoc = ["hal/renderdoc"]
|
||||
replay = [
|
||||
"serde",
|
||||
"wgt/replay",
|
||||
"arrayvec/serde",
|
||||
"naga/deserialize",
|
||||
]
|
||||
resource_log_info = []
|
||||
serde = [
|
||||
"dep:serde",
|
||||
serial-pass = [
|
||||
"serde",
|
||||
"wgt/serde",
|
||||
"arrayvec/serde",
|
||||
]
|
||||
spirv = [
|
||||
"naga/spv-in",
|
||||
"dep:bytemuck",
|
||||
]
|
||||
strict_asserts = ["wgt/strict_asserts"]
|
||||
trace = [
|
||||
"ron",
|
||||
"serde",
|
||||
"wgt/trace",
|
||||
"arrayvec/serde",
|
||||
"naga/serialize",
|
||||
]
|
||||
vulkan = ["hal/vulkan"]
|
||||
|
||||
65
third_party/rust/wgpu-core/src/binding_model.rs
vendored
65
third_party/rust/wgpu-core/src/binding_model.rs
vendored
@@ -6,11 +6,14 @@ use crate::{
|
||||
},
|
||||
error::{ErrorFormatter, PrettyError},
|
||||
hal_api::HalApi,
|
||||
id::{BindGroupLayoutId, BufferId, SamplerId, TextureId, TextureViewId},
|
||||
id::{
|
||||
BindGroupId, BindGroupLayoutId, BufferId, PipelineLayoutId, SamplerId, TextureId,
|
||||
TextureViewId,
|
||||
},
|
||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log,
|
||||
snatch::{SnatchGuard, Snatchable},
|
||||
snatch::SnatchGuard,
|
||||
track::{BindGroupStates, UsageConflict},
|
||||
validation::{MissingBufferUsageError, MissingTextureUsageError},
|
||||
Label,
|
||||
@@ -18,9 +21,9 @@ use crate::{
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(feature = "replay")]
|
||||
use serde::Deserialize;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(feature = "trace")]
|
||||
use serde::Serialize;
|
||||
|
||||
use std::{borrow::Cow, ops::Range, sync::Arc};
|
||||
@@ -403,7 +406,8 @@ impl BindingTypeMaxCountValidator {
|
||||
|
||||
/// Bindable resource and the slot to bind it to.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BindGroupEntry<'a> {
|
||||
/// Slot for which binding provides resource. Corresponds to an entry of the same
|
||||
/// binding index in the [`BindGroupLayoutDescriptor`].
|
||||
@@ -414,7 +418,8 @@ pub struct BindGroupEntry<'a> {
|
||||
|
||||
/// Describes a group of bindings and the resources to be bound.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BindGroupDescriptor<'a> {
|
||||
/// Debug label of the bind group.
|
||||
///
|
||||
@@ -428,7 +433,8 @@ pub struct BindGroupDescriptor<'a> {
|
||||
|
||||
/// Describes a [`BindGroupLayout`].
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct BindGroupLayoutDescriptor<'a> {
|
||||
/// Debug label of the bind group layout.
|
||||
///
|
||||
@@ -438,7 +444,7 @@ pub struct BindGroupLayoutDescriptor<'a> {
|
||||
pub entries: Cow<'a, [wgt::BindGroupLayoutEntry]>,
|
||||
}
|
||||
|
||||
pub type BindGroupLayouts<A> = crate::storage::Storage<BindGroupLayout<A>>;
|
||||
pub type BindGroupLayouts<A> = crate::storage::Storage<BindGroupLayout<A>, BindGroupLayoutId>;
|
||||
|
||||
/// Bind group layout.
|
||||
#[derive(Debug)]
|
||||
@@ -455,7 +461,7 @@ pub struct BindGroupLayout<A: HalApi> {
|
||||
pub(crate) origin: bgl::Origin,
|
||||
#[allow(unused)]
|
||||
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
|
||||
pub(crate) info: ResourceInfo<BindGroupLayout<A>>,
|
||||
pub(crate) info: ResourceInfo<BindGroupLayoutId>,
|
||||
pub(crate) label: String,
|
||||
}
|
||||
|
||||
@@ -479,16 +485,14 @@ impl<A: HalApi> Drop for BindGroupLayout<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for BindGroupLayout<A> {
|
||||
impl<A: HalApi> Resource<BindGroupLayoutId> for BindGroupLayout<A> {
|
||||
const TYPE: ResourceType = "BindGroupLayout";
|
||||
|
||||
type Marker = crate::id::markers::BindGroupLayout;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<BindGroupLayoutId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupLayoutId> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@@ -578,7 +582,8 @@ pub enum PushConstantUploadError {
|
||||
///
|
||||
/// A `PipelineLayoutDescriptor` can be used to create a pipeline layout.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct PipelineLayoutDescriptor<'a> {
|
||||
/// Debug label of the pipeine layout.
|
||||
///
|
||||
@@ -601,7 +606,7 @@ pub struct PipelineLayoutDescriptor<'a> {
|
||||
pub struct PipelineLayout<A: HalApi> {
|
||||
pub(crate) raw: Option<A::PipelineLayout>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<PipelineLayout<A>>,
|
||||
pub(crate) info: ResourceInfo<PipelineLayoutId>,
|
||||
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout<A>>, { hal::MAX_BIND_GROUPS }>,
|
||||
pub(crate) push_constant_ranges: ArrayVec<wgt::PushConstantRange, { SHADER_STAGE_COUNT }>,
|
||||
}
|
||||
@@ -715,23 +720,22 @@ impl<A: HalApi> PipelineLayout<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for PipelineLayout<A> {
|
||||
impl<A: HalApi> Resource<PipelineLayoutId> for PipelineLayout<A> {
|
||||
const TYPE: ResourceType = "PipelineLayout";
|
||||
|
||||
type Marker = crate::id::markers::PipelineLayout;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<PipelineLayoutId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<PipelineLayoutId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BufferBinding {
|
||||
pub buffer_id: BufferId,
|
||||
pub offset: wgt::BufferAddress,
|
||||
@@ -741,7 +745,8 @@ pub struct BufferBinding {
|
||||
// Note: Duplicated in `wgpu-rs` as `BindingResource`
|
||||
// They're different enough that it doesn't make sense to share a common type
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum BindingResource<'a> {
|
||||
Buffer(BufferBinding),
|
||||
BufferArray(Cow<'a, [BufferBinding]>),
|
||||
@@ -828,10 +833,10 @@ pub(crate) fn buffer_binding_type_alignment(
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BindGroup<A: HalApi> {
|
||||
pub(crate) raw: Snatchable<A::BindGroup>,
|
||||
pub(crate) raw: Option<A::BindGroup>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) layout: Arc<BindGroupLayout<A>>,
|
||||
pub(crate) info: ResourceInfo<BindGroup<A>>,
|
||||
pub(crate) info: ResourceInfo<BindGroupId>,
|
||||
pub(crate) used: BindGroupStates<A>,
|
||||
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction<A>>,
|
||||
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction<A>>,
|
||||
@@ -869,7 +874,7 @@ impl<A: HalApi> BindGroup<A> {
|
||||
for texture in &self.used_texture_ranges {
|
||||
let _ = texture.texture.raw(guard)?;
|
||||
}
|
||||
self.raw.get(guard)
|
||||
self.raw.as_ref()
|
||||
}
|
||||
pub(crate) fn validate_dynamic_bindings(
|
||||
&self,
|
||||
@@ -920,16 +925,14 @@ impl<A: HalApi> BindGroup<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for BindGroup<A> {
|
||||
impl<A: HalApi> Resource<BindGroupId> for BindGroup<A> {
|
||||
const TYPE: ResourceType = "BindGroup";
|
||||
|
||||
type Marker = crate::id::markers::BindGroup;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<BindGroupId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
225
third_party/rust/wgpu-core/src/command/bundle.rs
vendored
225
third_party/rust/wgpu-core/src/command/bundle.rs
vendored
@@ -94,9 +94,9 @@ use crate::{
|
||||
error::{ErrorFormatter, PrettyError},
|
||||
hal_api::HalApi,
|
||||
hub::Hub,
|
||||
id,
|
||||
id::{self, RenderBundleId},
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||
pipeline::{self, PipelineFlags, RenderPipeline},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log,
|
||||
track::RenderBundleScope,
|
||||
@@ -110,94 +110,10 @@ use thiserror::Error;
|
||||
|
||||
use hal::CommandEncoder as _;
|
||||
|
||||
/// https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-draw
|
||||
fn validate_draw(
|
||||
vertex: &[Option<VertexState>],
|
||||
step: &[VertexStep],
|
||||
first_vertex: u32,
|
||||
vertex_count: u32,
|
||||
first_instance: u32,
|
||||
instance_count: u32,
|
||||
) -> Result<(), DrawError> {
|
||||
let vertices_end = first_vertex as u64 + vertex_count as u64;
|
||||
let instances_end = first_instance as u64 + instance_count as u64;
|
||||
|
||||
for (idx, (vbs, step)) in vertex.iter().zip(step).enumerate() {
|
||||
let Some(vbs) = vbs else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let stride_count = match step.mode {
|
||||
wgt::VertexStepMode::Vertex => vertices_end,
|
||||
wgt::VertexStepMode::Instance => instances_end,
|
||||
};
|
||||
|
||||
if stride_count == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let offset = (stride_count - 1) * step.stride + step.last_stride;
|
||||
let limit = vbs.range.end - vbs.range.start;
|
||||
if offset > limit {
|
||||
return Err(DrawError::VertexOutOfBounds {
|
||||
step_mode: step.mode,
|
||||
offset,
|
||||
limit,
|
||||
slot: idx as u32,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// See https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-drawindexed
|
||||
fn validate_indexed_draw(
|
||||
vertex: &[Option<VertexState>],
|
||||
step: &[VertexStep],
|
||||
index_state: &IndexState,
|
||||
first_index: u32,
|
||||
index_count: u32,
|
||||
first_instance: u32,
|
||||
instance_count: u32,
|
||||
) -> Result<(), DrawError> {
|
||||
let last_index = first_index as u64 + index_count as u64;
|
||||
let index_limit = index_state.limit();
|
||||
if last_index <= index_limit {
|
||||
return Err(DrawError::IndexBeyondLimit {
|
||||
last_index,
|
||||
index_limit,
|
||||
});
|
||||
}
|
||||
|
||||
let stride_count = first_instance as u64 + instance_count as u64;
|
||||
for (idx, (vbs, step)) in vertex.iter().zip(step).enumerate() {
|
||||
let Some(vbs) = vbs else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if stride_count == 0 || step.mode != wgt::VertexStepMode::Instance {
|
||||
continue;
|
||||
}
|
||||
|
||||
let offset = (stride_count - 1) * step.stride + step.last_stride;
|
||||
let limit = vbs.range.end - vbs.range.start;
|
||||
if offset > limit {
|
||||
return Err(DrawError::VertexOutOfBounds {
|
||||
step_mode: step.mode,
|
||||
offset,
|
||||
limit,
|
||||
slot: idx as u32,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Describes a [`RenderBundleEncoder`].
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct RenderBundleEncoderDescriptor<'a> {
|
||||
/// Debug label of the render bundle encoder.
|
||||
///
|
||||
@@ -225,7 +141,7 @@ pub struct RenderBundleEncoderDescriptor<'a> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct RenderBundleEncoder {
|
||||
base: BasePass<RenderCommand>,
|
||||
parent_id: id::DeviceId,
|
||||
@@ -234,9 +150,9 @@ pub struct RenderBundleEncoder {
|
||||
pub(crate) is_stencil_read_only: bool,
|
||||
|
||||
// Resource binding dedupe state.
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_bind_groups: BindGroupStateChange,
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_pipeline: StateChange<id::RenderPipelineId>,
|
||||
}
|
||||
|
||||
@@ -579,21 +495,28 @@ impl RenderBundleEncoder {
|
||||
};
|
||||
let pipeline = state.pipeline(scope)?;
|
||||
let used_bind_groups = pipeline.used_bind_groups;
|
||||
|
||||
validate_draw(
|
||||
&state.vertex[..],
|
||||
&pipeline.steps,
|
||||
first_vertex,
|
||||
vertex_count,
|
||||
first_instance,
|
||||
instance_count,
|
||||
).map_pass_err(scope)?;
|
||||
|
||||
if instance_count > 0 && vertex_count > 0 {
|
||||
commands.extend(state.flush_vertices());
|
||||
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
|
||||
commands.push(command);
|
||||
let vertex_limits = state.vertex_limits(pipeline);
|
||||
let last_vertex = first_vertex as u64 + vertex_count as u64;
|
||||
if last_vertex > vertex_limits.vertex_limit {
|
||||
return Err(DrawError::VertexBeyondLimit {
|
||||
last_vertex,
|
||||
vertex_limit: vertex_limits.vertex_limit,
|
||||
slot: vertex_limits.vertex_limit_slot,
|
||||
})
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
let last_instance = first_instance as u64 + instance_count as u64;
|
||||
if last_instance > vertex_limits.instance_limit {
|
||||
return Err(DrawError::InstanceBeyondLimit {
|
||||
last_instance,
|
||||
instance_limit: vertex_limits.instance_limit,
|
||||
slot: vertex_limits.instance_limit_slot,
|
||||
})
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
commands.extend(state.flush_vertices());
|
||||
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
|
||||
commands.push(command);
|
||||
}
|
||||
RenderCommand::DrawIndexed {
|
||||
index_count,
|
||||
@@ -613,23 +536,30 @@ impl RenderBundleEncoder {
|
||||
Some(ref index) => index,
|
||||
None => return Err(DrawError::MissingIndexBuffer).map_pass_err(scope),
|
||||
};
|
||||
|
||||
validate_indexed_draw(
|
||||
&state.vertex[..],
|
||||
&pipeline.steps,
|
||||
index,
|
||||
first_index,
|
||||
index_count,
|
||||
first_instance,
|
||||
instance_count,
|
||||
).map_pass_err(scope)?;
|
||||
|
||||
if instance_count > 0 && index_count > 0 {
|
||||
commands.extend(state.flush_index());
|
||||
commands.extend(state.flush_vertices());
|
||||
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
|
||||
commands.push(command);
|
||||
//TODO: validate that base_vertex + max_index() is within the provided range
|
||||
let vertex_limits = state.vertex_limits(pipeline);
|
||||
let index_limit = index.limit();
|
||||
let last_index = first_index as u64 + index_count as u64;
|
||||
if last_index > index_limit {
|
||||
return Err(DrawError::IndexBeyondLimit {
|
||||
last_index,
|
||||
index_limit,
|
||||
})
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
let last_instance = first_instance as u64 + instance_count as u64;
|
||||
if last_instance > vertex_limits.instance_limit {
|
||||
return Err(DrawError::InstanceBeyondLimit {
|
||||
last_instance,
|
||||
instance_limit: vertex_limits.instance_limit,
|
||||
slot: vertex_limits.instance_limit_slot,
|
||||
})
|
||||
.map_pass_err(scope);
|
||||
}
|
||||
commands.extend(state.flush_index());
|
||||
commands.extend(state.flush_vertices());
|
||||
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
|
||||
commands.push(command);
|
||||
}
|
||||
RenderCommand::MultiDrawIndirect {
|
||||
buffer_id,
|
||||
@@ -832,7 +762,7 @@ pub struct RenderBundle<A: HalApi> {
|
||||
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
|
||||
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
|
||||
pub(super) context: RenderPassContext,
|
||||
pub(crate) info: ResourceInfo<RenderBundle<A>>,
|
||||
pub(crate) info: ResourceInfo<RenderBundleId>,
|
||||
discard_hal_labels: bool,
|
||||
}
|
||||
|
||||
@@ -1067,16 +997,14 @@ impl<A: HalApi> RenderBundle<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for RenderBundle<A> {
|
||||
impl<A: HalApi> Resource<RenderBundleId> for RenderBundle<A> {
|
||||
const TYPE: ResourceType = "RenderBundle";
|
||||
|
||||
type Marker = crate::id::markers::RenderBundle;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<RenderBundleId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderBundleId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -1185,6 +1113,18 @@ struct BindState<A: HalApi> {
|
||||
is_dirty: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VertexLimitState {
|
||||
/// Length of the shortest vertex rate vertex buffer
|
||||
vertex_limit: u64,
|
||||
/// Buffer slot which the shortest vertex rate vertex buffer is bound to
|
||||
vertex_limit_slot: u32,
|
||||
/// Length of the shortest instance rate vertex buffer
|
||||
instance_limit: u64,
|
||||
/// Buffer slot which the shortest instance rate vertex buffer is bound to
|
||||
instance_limit_slot: u32,
|
||||
}
|
||||
|
||||
/// The bundle's current pipeline, and some cached information needed for validation.
|
||||
struct PipelineState<A: HalApi> {
|
||||
/// The pipeline
|
||||
@@ -1192,7 +1132,7 @@ struct PipelineState<A: HalApi> {
|
||||
|
||||
/// How this pipeline's vertex shader traverses each vertex buffer, indexed
|
||||
/// by vertex buffer slot number.
|
||||
steps: Vec<VertexStep>,
|
||||
steps: Vec<pipeline::VertexStep>,
|
||||
|
||||
/// Ranges of push constants this pipeline uses, copied from the pipeline
|
||||
/// layout.
|
||||
@@ -1277,6 +1217,35 @@ struct State<A: HalApi> {
|
||||
}
|
||||
|
||||
impl<A: HalApi> State<A> {
|
||||
fn vertex_limits(&self, pipeline: &PipelineState<A>) -> VertexLimitState {
|
||||
let mut vert_state = VertexLimitState {
|
||||
vertex_limit: u32::MAX as u64,
|
||||
vertex_limit_slot: 0,
|
||||
instance_limit: u32::MAX as u64,
|
||||
instance_limit_slot: 0,
|
||||
};
|
||||
for (idx, (vbs, step)) in self.vertex.iter().zip(&pipeline.steps).enumerate() {
|
||||
if let Some(ref vbs) = *vbs {
|
||||
let limit = (vbs.range.end - vbs.range.start) / step.stride;
|
||||
match step.mode {
|
||||
wgt::VertexStepMode::Vertex => {
|
||||
if limit < vert_state.vertex_limit {
|
||||
vert_state.vertex_limit = limit;
|
||||
vert_state.vertex_limit_slot = idx as _;
|
||||
}
|
||||
}
|
||||
wgt::VertexStepMode::Instance => {
|
||||
if limit < vert_state.instance_limit {
|
||||
vert_state.instance_limit = limit;
|
||||
vert_state.instance_limit_slot = idx as _;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vert_state
|
||||
}
|
||||
|
||||
/// Return the id of the current pipeline, if any.
|
||||
fn pipeline_id(&self) -> Option<id::RenderPipelineId> {
|
||||
self.pipeline.as_ref().map(|p| p.pipeline.as_info().id())
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{BufferId, CommandEncoderId, DeviceId, TextureId},
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::{MemoryInitKind, TextureInitRange},
|
||||
resource::{Resource, Texture, TextureClearMode},
|
||||
track::{TextureSelector, TextureTracker},
|
||||
@@ -70,7 +71,7 @@ whereas subesource range specified start {subresource_base_array_layer} and coun
|
||||
Device(#[from] DeviceError),
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_clear_buffer<A: HalApi>(
|
||||
&self,
|
||||
command_encoder_id: CommandEncoderId,
|
||||
|
||||
@@ -18,6 +18,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label, id,
|
||||
id::DeviceId,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::MemoryInitKind,
|
||||
pipeline,
|
||||
resource::{self},
|
||||
@@ -28,9 +29,9 @@ use crate::{
|
||||
};
|
||||
|
||||
use hal::CommandEncoder as _;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(any(feature = "serial-pass", feature = "replay"))]
|
||||
use serde::Deserialize;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(any(feature = "serial-pass", feature = "trace"))]
|
||||
use serde::Serialize;
|
||||
|
||||
use thiserror::Error;
|
||||
@@ -39,7 +40,14 @@ use std::{fmt, mem, str};
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "trace"),
|
||||
derive(serde::Serialize)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "replay"),
|
||||
derive(serde::Deserialize)
|
||||
)]
|
||||
pub enum ComputeCommand {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
@@ -90,16 +98,16 @@ pub enum ComputeCommand {
|
||||
EndPipelineStatisticsQuery,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct ComputePass {
|
||||
base: BasePass<ComputeCommand>,
|
||||
parent_id: id::CommandEncoderId,
|
||||
timestamp_writes: Option<ComputePassTimestampWrites>,
|
||||
|
||||
// Resource binding dedupe state.
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_bind_groups: BindGroupStateChange,
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_pipeline: StateChange<id::ComputePipelineId>,
|
||||
}
|
||||
|
||||
@@ -143,7 +151,8 @@ impl fmt::Debug for ComputePass {
|
||||
/// Describes the writing of timestamp values in a compute pass.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
pub struct ComputePassTimestampWrites {
|
||||
/// The query set to write the timestamps to.
|
||||
pub query_set: id::QuerySetId,
|
||||
@@ -304,7 +313,7 @@ impl<A: HalApi> State<A> {
|
||||
&mut self,
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
base_trackers: &mut Tracker<A>,
|
||||
bind_group_guard: &Storage<BindGroup<A>>,
|
||||
bind_group_guard: &Storage<BindGroup<A>, id::BindGroupId>,
|
||||
indirect_buffer: Option<id::BufferId>,
|
||||
snatch_guard: &SnatchGuard,
|
||||
) -> Result<(), UsageConflict> {
|
||||
@@ -339,7 +348,7 @@ impl<A: HalApi> State<A> {
|
||||
|
||||
// Common routines between render/compute
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_run_compute_pass<A: HalApi>(
|
||||
&self,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
|
||||
27
third_party/rust/wgpu-core/src/command/draw.rs
vendored
27
third_party/rust/wgpu-core/src/command/draw.rs
vendored
@@ -8,7 +8,7 @@ use crate::{
|
||||
track::UsageConflict,
|
||||
validation::{MissingBufferUsageError, MissingTextureUsageError},
|
||||
};
|
||||
use wgt::{BufferAddress, BufferSize, Color, VertexStepMode};
|
||||
use wgt::{BufferAddress, BufferSize, Color};
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
use thiserror::Error;
|
||||
@@ -33,13 +33,6 @@ pub enum DrawError {
|
||||
vertex_limit: u64,
|
||||
slot: u32,
|
||||
},
|
||||
#[error("{step_mode:?} buffer out of bounds at slot {slot}. Offset {offset} beyond limit {limit}. Did you bind the correct `Vertex` step-rate vertex buffer?")]
|
||||
VertexOutOfBounds {
|
||||
step_mode: VertexStepMode,
|
||||
offset: u64,
|
||||
limit: u64,
|
||||
slot: u32,
|
||||
},
|
||||
#[error("Instance {last_instance} extends beyond limit {instance_limit} imposed by the buffer in slot {slot}. Did you bind the correct `Instance` step-rate vertex buffer?")]
|
||||
InstanceBeyondLimit {
|
||||
last_instance: u64,
|
||||
@@ -126,7 +119,14 @@ impl crate::error::PrettyError for RenderCommandError {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "trace"),
|
||||
derive(serde::Serialize)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "replay"),
|
||||
derive(serde::Deserialize)
|
||||
)]
|
||||
pub struct Rect<T> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
@@ -136,7 +136,14 @@ pub struct Rect<T> {
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "trace"),
|
||||
derive(serde::Serialize)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "replay"),
|
||||
derive(serde::Deserialize)
|
||||
)]
|
||||
pub enum RenderCommand {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
|
||||
34
third_party/rust/wgpu-core/src/command/mod.rs
vendored
34
third_party/rust/wgpu-core/src/command/mod.rs
vendored
@@ -27,7 +27,10 @@ use crate::snatch::SnatchGuard;
|
||||
use crate::init_tracker::BufferInitTrackerAction;
|
||||
use crate::resource::{Resource, ResourceInfo, ResourceType};
|
||||
use crate::track::{Tracker, UsageScope};
|
||||
use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label};
|
||||
use crate::{
|
||||
api_log, global::Global, hal_api::HalApi, id, identity::GlobalIdentityHandlerFactory,
|
||||
resource_log, Label,
|
||||
};
|
||||
|
||||
use hal::CommandEncoder as _;
|
||||
use parking_lot::Mutex;
|
||||
@@ -137,7 +140,7 @@ pub struct CommandBuffer<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
limits: wgt::Limits,
|
||||
support_clear_texture: bool,
|
||||
pub(crate) info: ResourceInfo<CommandBuffer<A>>,
|
||||
pub(crate) info: ResourceInfo<CommandBufferId>,
|
||||
pub(crate) data: Mutex<Option<CommandBufferMutable<A>>>,
|
||||
}
|
||||
|
||||
@@ -252,7 +255,7 @@ impl<A: HalApi> CommandBuffer<A> {
|
||||
id: id::CommandEncoderId,
|
||||
) -> Result<Arc<Self>, CommandEncoderError> {
|
||||
let storage = hub.command_buffers.read();
|
||||
match storage.get(id.transmute()) {
|
||||
match storage.get(id) {
|
||||
Ok(cmd_buf) => match cmd_buf.data.lock().as_ref().unwrap().status {
|
||||
CommandEncoderStatus::Recording => Ok(cmd_buf.clone()),
|
||||
CommandEncoderStatus::Finished => Err(CommandEncoderError::NotRecording),
|
||||
@@ -293,16 +296,14 @@ impl<A: HalApi> CommandBuffer<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for CommandBuffer<A> {
|
||||
impl<A: HalApi> Resource<CommandBufferId> for CommandBuffer<A> {
|
||||
const TYPE: ResourceType = "CommandBuffer";
|
||||
|
||||
type Marker = crate::id::markers::CommandBuffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<CommandBufferId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<CommandBufferId> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@@ -337,7 +338,14 @@ pub struct BasePassRef<'a, C> {
|
||||
/// [`InsertDebugMarker`]: RenderCommand::InsertDebugMarker
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "trace"),
|
||||
derive(serde::Serialize)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
any(feature = "serial-pass", feature = "replay"),
|
||||
derive(serde::Deserialize)
|
||||
)]
|
||||
pub struct BasePass<C> {
|
||||
pub label: Option<String>,
|
||||
|
||||
@@ -407,7 +415,7 @@ pub enum CommandEncoderError {
|
||||
Device(#[from] DeviceError),
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_finish<A: HalApi>(
|
||||
&self,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
@@ -417,7 +425,7 @@ impl Global {
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let error = match hub.command_buffers.get(encoder_id.transmute()) {
|
||||
let error = match hub.command_buffers.get(encoder_id) {
|
||||
Ok(cmd_buf) => {
|
||||
let mut cmd_buf_data = cmd_buf.data.lock();
|
||||
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||
@@ -443,7 +451,7 @@ impl Global {
|
||||
Err(_) => Some(CommandEncoderError::Invalid),
|
||||
};
|
||||
|
||||
(encoder_id.transmute(), error)
|
||||
(encoder_id, error)
|
||||
}
|
||||
|
||||
pub fn command_encoder_push_debug_group<A: HalApi>(
|
||||
@@ -699,7 +707,7 @@ impl PrettyError for PassErrorScope {
|
||||
// This error is not in the error chain, only notes are needed
|
||||
match *self {
|
||||
Self::Pass(id) => {
|
||||
fmt.command_buffer_label(&id.transmute());
|
||||
fmt.command_buffer_label(&id);
|
||||
}
|
||||
Self::SetBindGroup(id) => {
|
||||
fmt.bind_group_label(&id);
|
||||
|
||||
11
third_party/rust/wgpu-core/src/command/query.rs
vendored
11
third_party/rust/wgpu-core/src/command/query.rs
vendored
@@ -7,7 +7,8 @@ use crate::{
|
||||
device::DeviceError,
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{self, Id},
|
||||
id::{self, Id, TypedId},
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::QuerySet,
|
||||
storage::Storage,
|
||||
@@ -48,7 +49,7 @@ impl<A: HalApi> QueryResetMap<A> {
|
||||
pub fn reset_queries(
|
||||
&mut self,
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
query_set_storage: &Storage<QuerySet<A>>,
|
||||
query_set_storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
backend: wgt::Backend,
|
||||
) -> Result<(), id::QuerySetId> {
|
||||
for (query_set_id, (state, epoch)) in self.map.drain() {
|
||||
@@ -313,7 +314,7 @@ impl<A: HalApi> QuerySet<A> {
|
||||
|
||||
pub(super) fn end_occlusion_query<A: HalApi>(
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
storage: &Storage<QuerySet<A>>,
|
||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||
) -> Result<(), QueryUseError> {
|
||||
if let Some((query_set_id, query_index)) = active_query.take() {
|
||||
@@ -330,7 +331,7 @@ pub(super) fn end_occlusion_query<A: HalApi>(
|
||||
|
||||
pub(super) fn end_pipeline_statistics_query<A: HalApi>(
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
storage: &Storage<QuerySet<A>>,
|
||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||
) -> Result<(), QueryUseError> {
|
||||
if let Some((query_set_id, query_index)) = active_query.take() {
|
||||
@@ -345,7 +346,7 @@ pub(super) fn end_pipeline_statistics_query<A: HalApi>(
|
||||
}
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_write_timestamp<A: HalApi>(
|
||||
&self,
|
||||
command_encoder_id: id::CommandEncoderId,
|
||||
|
||||
141
third_party/rust/wgpu-core/src/command/render.rs
vendored
141
third_party/rust/wgpu-core/src/command/render.rs
vendored
@@ -1,5 +1,4 @@
|
||||
use crate::resource::Resource;
|
||||
use crate::snatch::SnatchGuard;
|
||||
use crate::{
|
||||
api_log,
|
||||
binding_model::BindError,
|
||||
@@ -20,6 +19,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
hal_label, id,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction},
|
||||
pipeline::{self, PipelineFlags},
|
||||
resource::{Buffer, QuerySet, Texture, TextureView, TextureViewNotRenderableReason},
|
||||
@@ -39,9 +39,9 @@ use wgt::{
|
||||
TextureViewDimension, VertexStepMode,
|
||||
};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(any(feature = "serial-pass", feature = "replay"))]
|
||||
use serde::Deserialize;
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg(any(feature = "serial-pass", feature = "trace"))]
|
||||
use serde::Serialize;
|
||||
|
||||
use std::sync::Arc;
|
||||
@@ -55,7 +55,8 @@ use super::{
|
||||
/// Operation to perform to the output attachment at the start of a renderpass.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum LoadOp {
|
||||
/// Clear the output attachment with the clear color. Clearing is faster than loading.
|
||||
@@ -67,7 +68,8 @@ pub enum LoadOp {
|
||||
/// Operation to perform to the output attachment at the end of a renderpass.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum StoreOp {
|
||||
/// Discards the content of the render target.
|
||||
@@ -81,7 +83,8 @@ pub enum StoreOp {
|
||||
/// Describes an individual channel within a render pass, such as color, depth, or stencil.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
pub struct PassChannel<V> {
|
||||
/// Operation to perform to the output attachment at the start of a
|
||||
/// renderpass.
|
||||
@@ -118,7 +121,8 @@ impl<V> PassChannel<V> {
|
||||
/// Describes a color attachment to a render pass.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
pub struct RenderPassColorAttachment {
|
||||
/// The view to use as an attachment.
|
||||
pub view: id::TextureViewId,
|
||||
@@ -131,7 +135,8 @@ pub struct RenderPassColorAttachment {
|
||||
/// Describes a depth/stencil attachment to a render pass.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
pub struct RenderPassDepthStencilAttachment {
|
||||
/// The view to use as an attachment.
|
||||
pub view: id::TextureViewId,
|
||||
@@ -182,7 +187,8 @@ impl RenderPassDepthStencilAttachment {
|
||||
/// Location to write a timestamp to (beginning or end of the pass).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum RenderPassTimestampLocation {
|
||||
Beginning = 0,
|
||||
@@ -192,7 +198,8 @@ pub enum RenderPassTimestampLocation {
|
||||
/// Describes the writing of timestamp values in a render pass.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "trace"), derive(Serialize))]
|
||||
#[cfg_attr(any(feature = "serial-pass", feature = "replay"), derive(Deserialize))]
|
||||
pub struct RenderPassTimestampWrites {
|
||||
/// The query set to write the timestamp to.
|
||||
pub query_set: id::QuerySetId,
|
||||
@@ -216,7 +223,7 @@ pub struct RenderPassDescriptor<'a> {
|
||||
pub occlusion_query_set: Option<id::QuerySetId>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "serial-pass", derive(Deserialize, Serialize))]
|
||||
pub struct RenderPass {
|
||||
base: BasePass<RenderCommand>,
|
||||
parent_id: id::CommandEncoderId,
|
||||
@@ -226,9 +233,9 @@ pub struct RenderPass {
|
||||
occlusion_query_set_id: Option<id::QuerySetId>,
|
||||
|
||||
// Resource binding dedupe state.
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_bind_groups: BindGroupStateChange,
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
#[cfg_attr(feature = "serial-pass", serde(skip))]
|
||||
current_pipeline: StateChange<id::RenderPipelineId>,
|
||||
}
|
||||
|
||||
@@ -353,7 +360,6 @@ impl VertexBufferState {
|
||||
total_size: 0,
|
||||
step: pipeline::VertexStep {
|
||||
stride: 0,
|
||||
last_stride: 0,
|
||||
mode: VertexStepMode::Vertex,
|
||||
},
|
||||
bound: false,
|
||||
@@ -377,33 +383,16 @@ struct VertexState {
|
||||
|
||||
impl VertexState {
|
||||
fn update_limits(&mut self) {
|
||||
// Implements the validation from https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-draw
|
||||
// Except that the formula is shuffled to extract the number of vertices in order
|
||||
// to carry the bulk of the computation when changing states intead of when producing
|
||||
// draws. Draw calls tend to happen at a higher frequency. Here we determine vertex
|
||||
// limits that can be cheaply checked for each draw call.
|
||||
self.vertex_limit = u32::MAX as u64;
|
||||
self.instance_limit = u32::MAX as u64;
|
||||
// Ensure that the limits are always smaller than u32::MAX so that
|
||||
// interger overlows can be prevented via saturating additions.
|
||||
let max = u32::MAX as u64;
|
||||
self.vertex_limit = max;
|
||||
self.instance_limit = max;
|
||||
for (idx, vbs) in self.inputs.iter().enumerate() {
|
||||
if !vbs.bound {
|
||||
if vbs.step.stride == 0 || !vbs.bound {
|
||||
continue;
|
||||
}
|
||||
|
||||
let limit = if vbs.total_size < vbs.step.last_stride {
|
||||
// The buffer cannot fit the last vertex.
|
||||
0
|
||||
} else {
|
||||
if vbs.step.stride == 0 {
|
||||
// We already checked that the last stride fits, the same
|
||||
// vertex will be repeated so this slot can accomodate any number of
|
||||
// vertices.
|
||||
continue;
|
||||
}
|
||||
|
||||
// The general case.
|
||||
(vbs.total_size - vbs.step.last_stride) / vbs.step.stride + 1
|
||||
};
|
||||
|
||||
let limit = vbs.total_size / vbs.step.stride;
|
||||
match vbs.step.mode {
|
||||
VertexStepMode::Vertex => {
|
||||
if limit < self.vertex_limit {
|
||||
@@ -544,8 +533,6 @@ pub enum RenderPassErrorInner {
|
||||
Encoder(#[from] CommandEncoderError),
|
||||
#[error("Attachment texture view {0:?} is invalid")]
|
||||
InvalidAttachment(id::TextureViewId),
|
||||
#[error("Attachment texture view {0:?} is invalid")]
|
||||
InvalidResolveTarget(id::TextureViewId),
|
||||
#[error("The format of the depth-stencil attachment ({0:?}) is not a depth-stencil format")]
|
||||
InvalidDepthStencilAttachmentFormat(wgt::TextureFormat),
|
||||
#[error("The format of the {location} ({format:?}) is not resolvable")]
|
||||
@@ -727,7 +714,7 @@ struct RenderAttachment<'a, A: HalApi> {
|
||||
impl<A: HalApi> TextureView<A> {
|
||||
fn to_render_attachment(&self, usage: hal::TextureUses) -> RenderAttachment<A> {
|
||||
RenderAttachment {
|
||||
texture: self.parent.clone(),
|
||||
texture: self.parent.read().as_ref().unwrap().clone(),
|
||||
selector: &self.selector,
|
||||
usage,
|
||||
}
|
||||
@@ -762,7 +749,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
if channel.load_op == LoadOp::Load {
|
||||
pending_discard_init_fixups.extend(texture_memory_actions.register_init_action(
|
||||
&TextureInitTrackerAction {
|
||||
texture: view.parent.clone(),
|
||||
texture: view.parent.read().as_ref().unwrap().clone(),
|
||||
range: TextureInitRange::from(view.selector.clone()),
|
||||
// Note that this is needed even if the target is discarded,
|
||||
kind: MemoryInitKind::NeedsInitializedMemory,
|
||||
@@ -771,7 +758,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
} else if channel.store_op == StoreOp::Store {
|
||||
// Clear + Store
|
||||
texture_memory_actions.register_implicit_init(
|
||||
&view.parent,
|
||||
view.parent.read().as_ref().unwrap(),
|
||||
TextureInitRange::from(view.selector.clone()),
|
||||
);
|
||||
}
|
||||
@@ -780,7 +767,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
// discard right away be alright since the texture can't be used
|
||||
// during the pass anyways
|
||||
texture_memory_actions.discard(TextureSurfaceDiscard {
|
||||
texture: view.parent.clone(),
|
||||
texture: view.parent.read().as_ref().unwrap().clone(),
|
||||
mip_level: view.selector.mips.start,
|
||||
layer: view.selector.layers.start,
|
||||
});
|
||||
@@ -798,11 +785,10 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
trackers: &mut Tracker<A>,
|
||||
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
|
||||
pending_query_resets: &mut QueryResetMap<A>,
|
||||
view_guard: &'a Storage<TextureView<A>>,
|
||||
buffer_guard: &'a Storage<Buffer<A>>,
|
||||
texture_guard: &'a Storage<Texture<A>>,
|
||||
query_set_guard: &'a Storage<QuerySet<A>>,
|
||||
snatch_guard: &SnatchGuard<'a>,
|
||||
view_guard: &'a Storage<TextureView<A>, id::TextureViewId>,
|
||||
buffer_guard: &'a Storage<Buffer<A>, id::BufferId>,
|
||||
texture_guard: &'a Storage<Texture<A>, id::TextureId>,
|
||||
query_set_guard: &'a Storage<QuerySet<A>, id::QuerySetId>,
|
||||
) -> Result<Self, RenderPassErrorInner> {
|
||||
profiling::scope!("RenderPassInfo::start");
|
||||
|
||||
@@ -950,7 +936,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
if need_init_beforehand {
|
||||
pending_discard_init_fixups.extend(
|
||||
texture_memory_actions.register_init_action(&TextureInitTrackerAction {
|
||||
texture: view.parent.clone(),
|
||||
texture: view.parent.read().as_ref().unwrap().clone(),
|
||||
range: TextureInitRange::from(view.selector.clone()),
|
||||
kind: MemoryInitKind::NeedsInitializedMemory,
|
||||
}),
|
||||
@@ -968,7 +954,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
if at.depth.store_op != at.stencil.store_op {
|
||||
if !need_init_beforehand {
|
||||
texture_memory_actions.register_implicit_init(
|
||||
&view.parent,
|
||||
view.parent.read().as_ref().unwrap(),
|
||||
TextureInitRange::from(view.selector.clone()),
|
||||
);
|
||||
}
|
||||
@@ -983,7 +969,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
} else if at.depth.store_op == StoreOp::Discard {
|
||||
// Both are discarded using the regular path.
|
||||
discarded_surfaces.push(TextureSurfaceDiscard {
|
||||
texture: view.parent.clone(),
|
||||
texture: view.parent.read().as_ref().unwrap().clone(),
|
||||
mip_level: view.selector.mips.start,
|
||||
layer: view.selector.layers.start,
|
||||
});
|
||||
@@ -1007,9 +993,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
|
||||
depth_stencil = Some(hal::DepthStencilAttachment {
|
||||
target: hal::Attachment {
|
||||
view: view
|
||||
.raw(snatch_guard)
|
||||
.ok_or_else(|| RenderPassErrorInner::InvalidAttachment(view.info.id()))?,
|
||||
view: view.raw(),
|
||||
usage,
|
||||
},
|
||||
depth_ops: at.depth.hal_ops(),
|
||||
@@ -1111,25 +1095,21 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
}
|
||||
|
||||
texture_memory_actions.register_implicit_init(
|
||||
&resolve_view.parent,
|
||||
resolve_view.parent.read().as_ref().unwrap(),
|
||||
TextureInitRange::from(resolve_view.selector.clone()),
|
||||
);
|
||||
render_attachments
|
||||
.push(resolve_view.to_render_attachment(hal::TextureUses::COLOR_TARGET));
|
||||
|
||||
hal_resolve_target = Some(hal::Attachment {
|
||||
view: resolve_view.raw(snatch_guard).ok_or_else(|| {
|
||||
RenderPassErrorInner::InvalidResolveTarget(resolve_view.info.id())
|
||||
})?,
|
||||
view: resolve_view.raw(),
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
});
|
||||
}
|
||||
|
||||
colors.push(Some(hal::ColorAttachment {
|
||||
target: hal::Attachment {
|
||||
view: color_view.raw(snatch_guard).ok_or_else(|| {
|
||||
RenderPassErrorInner::InvalidAttachment(color_view.info.id())
|
||||
})?,
|
||||
view: color_view.raw(),
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
},
|
||||
resolve_target: hal_resolve_target,
|
||||
@@ -1229,7 +1209,6 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
fn finish(
|
||||
mut self,
|
||||
raw: &mut A::CommandEncoder,
|
||||
snatch_guard: &SnatchGuard,
|
||||
) -> Result<(UsageScope<A>, SurfacesInDiscardState<A>), RenderPassErrorInner> {
|
||||
profiling::scope!("RenderPassInfo::finish");
|
||||
unsafe {
|
||||
@@ -1277,9 +1256,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
color_attachments: &[],
|
||||
depth_stencil_attachment: Some(hal::DepthStencilAttachment {
|
||||
target: hal::Attachment {
|
||||
view: view.raw(snatch_guard).ok_or_else(|| {
|
||||
RenderPassErrorInner::InvalidAttachment(view.info.id())
|
||||
})?,
|
||||
view: view.raw(),
|
||||
usage: hal::TextureUses::DEPTH_STENCIL_WRITE,
|
||||
},
|
||||
depth_ops,
|
||||
@@ -1302,7 +1279,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
|
||||
// Common routines between render/compute
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_run_render_pass<A: HalApi>(
|
||||
&self,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
@@ -1409,7 +1386,6 @@ impl Global {
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
&*query_set_guard,
|
||||
&snatch_guard,
|
||||
)
|
||||
.map_pass_err(pass_scope)?;
|
||||
|
||||
@@ -1941,14 +1917,7 @@ impl Global {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
if instance_count > 0 && vertex_count > 0 {
|
||||
raw.draw(
|
||||
first_vertex,
|
||||
vertex_count,
|
||||
first_instance,
|
||||
instance_count,
|
||||
);
|
||||
}
|
||||
raw.draw(first_vertex, vertex_count, first_instance, instance_count);
|
||||
}
|
||||
}
|
||||
RenderCommand::DrawIndexed {
|
||||
@@ -1989,15 +1958,13 @@ impl Global {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
if instance_count > 0 && index_count > 0 {
|
||||
raw.draw_indexed(
|
||||
first_index,
|
||||
index_count,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
instance_count,
|
||||
);
|
||||
}
|
||||
raw.draw_indexed(
|
||||
first_index,
|
||||
index_count,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
instance_count,
|
||||
);
|
||||
}
|
||||
}
|
||||
RenderCommand::MultiDrawIndirect {
|
||||
@@ -2399,13 +2366,13 @@ impl Global {
|
||||
|
||||
log::trace!("Merging renderpass into cmd_buf {:?}", encoder_id);
|
||||
let (trackers, pending_discard_init_fixups) =
|
||||
info.finish(raw, &snatch_guard).map_pass_err(pass_scope)?;
|
||||
info.finish(raw).map_pass_err(pass_scope)?;
|
||||
|
||||
encoder.close().map_pass_err(pass_scope)?;
|
||||
(trackers, pending_discard_init_fixups)
|
||||
};
|
||||
|
||||
let cmd_buf = hub.command_buffers.get(encoder_id.transmute()).unwrap();
|
||||
let cmd_buf = hub.command_buffers.get(encoder_id).unwrap();
|
||||
let mut cmd_buf_data = cmd_buf.data.lock();
|
||||
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{BufferId, CommandEncoderId, DeviceId, TextureId},
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::{
|
||||
has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange,
|
||||
TextureInitTrackerAction,
|
||||
@@ -553,7 +554,7 @@ fn handle_dst_texture_init<A: HalApi>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn command_encoder_copy_buffer_to_buffer<A: HalApi>(
|
||||
&self,
|
||||
command_encoder_id: CommandEncoderId,
|
||||
|
||||
159
third_party/rust/wgpu-core/src/device/global.rs
vendored
159
third_party/rust/wgpu-core/src/device/global.rs
vendored
@@ -9,6 +9,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::TextureInitTracker,
|
||||
instance::{self, Adapter, Surface},
|
||||
pipeline, present,
|
||||
@@ -34,7 +35,7 @@ use std::{
|
||||
|
||||
use super::{ImplicitPipelineIds, InvalidDevice, UserClosures};
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn adapter_is_surface_supported<A: HalApi>(
|
||||
&self,
|
||||
adapter_id: AdapterId,
|
||||
@@ -145,12 +146,12 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Option<id::BufferId>,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||
profiling::scope!("Device::create_buffer");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.buffers.prepare(id_in);
|
||||
let fid = hub.buffers.prepare::<G>(id_in);
|
||||
|
||||
let mut to_destroy: ArrayVec<resource::Buffer<A>, 2> = ArrayVec::new();
|
||||
let error = loop {
|
||||
@@ -308,20 +309,20 @@ impl Global {
|
||||
/// [`device_create_buffer`]: Global::device_create_buffer
|
||||
/// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage
|
||||
/// [`wgpu_types::BufferUsages`]: wgt::BufferUsages
|
||||
pub fn create_buffer_error<A: HalApi>(&self, id_in: Option<id::BufferId>, label: Label) {
|
||||
pub fn create_buffer_error<A: HalApi>(&self, id_in: Input<G, id::BufferId>, label: Label) {
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.buffers.prepare(id_in);
|
||||
let fid = hub.buffers.prepare::<G>(id_in);
|
||||
|
||||
fid.assign_error(label.borrow_or_default());
|
||||
}
|
||||
|
||||
pub fn create_render_bundle_error<A: HalApi>(
|
||||
&self,
|
||||
id_in: Option<id::RenderBundleId>,
|
||||
id_in: Input<G, id::RenderBundleId>,
|
||||
label: Label,
|
||||
) {
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.render_bundles.prepare(id_in);
|
||||
let fid = hub.render_bundles.prepare::<G>(id_in);
|
||||
|
||||
fid.assign_error(label.borrow_or_default());
|
||||
}
|
||||
@@ -329,9 +330,9 @@ impl Global {
|
||||
/// Assign `id_in` an error with the given `label`.
|
||||
///
|
||||
/// See `create_buffer_error` for more context and explaination.
|
||||
pub fn create_texture_error<A: HalApi>(&self, id_in: Option<id::TextureId>, label: Label) {
|
||||
pub fn create_texture_error<A: HalApi>(&self, id_in: Input<G, id::TextureId>, label: Label) {
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.textures.prepare(id_in);
|
||||
let fid = hub.textures.prepare::<G>(id_in);
|
||||
|
||||
fid.assign_error(label.borrow_or_default());
|
||||
}
|
||||
@@ -544,13 +545,13 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::TextureDescriptor,
|
||||
id_in: Option<id::TextureId>,
|
||||
id_in: Input<G, id::TextureId>,
|
||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||
profiling::scope!("Device::create_texture");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.textures.prepare(id_in);
|
||||
let fid = hub.textures.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -598,13 +599,13 @@ impl Global {
|
||||
hal_texture: A::Texture,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::TextureDescriptor,
|
||||
id_in: Option<id::TextureId>,
|
||||
id_in: Input<G, id::TextureId>,
|
||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||
profiling::scope!("Device::create_texture_from_hal");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.textures.prepare(id_in);
|
||||
let fid = hub.textures.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -645,7 +646,7 @@ impl Global {
|
||||
RwLock::new(TextureInitTracker::new(desc.mip_level_count, 0));
|
||||
|
||||
let (id, resource) = fid.assign(texture);
|
||||
api_log!("Device::create_texture({desc:?}) -> {id:?}");
|
||||
api_log!("Device::create_texture -> {id:?}");
|
||||
|
||||
device.trackers.lock().textures.insert_single(
|
||||
id,
|
||||
@@ -672,12 +673,12 @@ impl Global {
|
||||
hal_buffer: A::Buffer,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Option<id::BufferId>,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||
profiling::scope!("Device::create_buffer");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.buffers.prepare(id_in);
|
||||
let fid = hub.buffers.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -782,13 +783,13 @@ impl Global {
|
||||
&self,
|
||||
texture_id: id::TextureId,
|
||||
desc: &resource::TextureViewDescriptor,
|
||||
id_in: Option<id::TextureViewId>,
|
||||
id_in: Input<G, id::TextureViewId>,
|
||||
) -> (id::TextureViewId, Option<resource::CreateTextureViewError>) {
|
||||
profiling::scope!("Texture::create_view");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.texture_views.prepare(id_in);
|
||||
let fid = hub.texture_views.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let texture = match hub.textures.get(texture_id) {
|
||||
@@ -817,12 +818,6 @@ impl Global {
|
||||
};
|
||||
|
||||
let (id, resource) = fid.assign(view);
|
||||
|
||||
{
|
||||
let mut views = texture.views.lock();
|
||||
views.push(Arc::downgrade(&resource));
|
||||
}
|
||||
|
||||
api_log!("Texture::create_view({texture_id:?}) -> {id:?}");
|
||||
device.trackers.lock().views.insert_single(id, resource);
|
||||
return (id, None);
|
||||
@@ -872,12 +867,12 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::SamplerDescriptor,
|
||||
id_in: Option<id::SamplerId>,
|
||||
id_in: Input<G, id::SamplerId>,
|
||||
) -> (id::SamplerId, Option<resource::CreateSamplerError>) {
|
||||
profiling::scope!("Device::create_sampler");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.samplers.prepare(id_in);
|
||||
let fid = hub.samplers.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -933,7 +928,7 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::BindGroupLayoutDescriptor,
|
||||
id_in: Option<id::BindGroupLayoutId>,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
Option<binding_model::CreateBindGroupLayoutError>,
|
||||
@@ -941,7 +936,7 @@ impl Global {
|
||||
profiling::scope!("Device::create_bind_group_layout");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.bind_group_layouts.prepare(id_in);
|
||||
let fid = hub.bind_group_layouts.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1003,7 +998,7 @@ impl Global {
|
||||
return (id.unwrap(), None);
|
||||
};
|
||||
|
||||
let fid = hub.bind_group_layouts.prepare(id_in);
|
||||
let fid = hub.bind_group_layouts.prepare::<G>(id_in);
|
||||
let id = fid.assign_error(desc.label.borrow_or_default());
|
||||
(id, Some(error))
|
||||
}
|
||||
@@ -1032,7 +1027,7 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::PipelineLayoutDescriptor,
|
||||
id_in: Option<id::PipelineLayoutId>,
|
||||
id_in: Input<G, id::PipelineLayoutId>,
|
||||
) -> (
|
||||
id::PipelineLayoutId,
|
||||
Option<binding_model::CreatePipelineLayoutError>,
|
||||
@@ -1040,7 +1035,7 @@ impl Global {
|
||||
profiling::scope!("Device::create_pipeline_layout");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.pipeline_layouts.prepare(id_in);
|
||||
let fid = hub.pipeline_layouts.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1093,12 +1088,12 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::BindGroupDescriptor,
|
||||
id_in: Option<id::BindGroupId>,
|
||||
id_in: Input<G, id::BindGroupId>,
|
||||
) -> (id::BindGroupId, Option<binding_model::CreateBindGroupError>) {
|
||||
profiling::scope!("Device::create_bind_group");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.bind_groups.prepare(id_in);
|
||||
let fid = hub.bind_groups.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1129,15 +1124,6 @@ impl Global {
|
||||
};
|
||||
|
||||
let (id, resource) = fid.assign(bind_group);
|
||||
|
||||
let weak_ref = Arc::downgrade(&resource);
|
||||
for range in &resource.used_texture_ranges {
|
||||
range.texture.bind_groups.lock().push(weak_ref.clone());
|
||||
}
|
||||
for range in &resource.used_buffer_ranges {
|
||||
range.buffer.bind_groups.lock().push(weak_ref.clone());
|
||||
}
|
||||
|
||||
api_log!("Device::create_bind_group -> {id:?}");
|
||||
|
||||
device
|
||||
@@ -1177,7 +1163,7 @@ impl Global {
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ShaderModuleDescriptor,
|
||||
source: pipeline::ShaderModuleSource,
|
||||
id_in: Option<id::ShaderModuleId>,
|
||||
id_in: Input<G, id::ShaderModuleId>,
|
||||
) -> (
|
||||
id::ShaderModuleId,
|
||||
Option<pipeline::CreateShaderModuleError>,
|
||||
@@ -1185,7 +1171,7 @@ impl Global {
|
||||
profiling::scope!("Device::create_shader_module");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.shader_modules.prepare(id_in);
|
||||
let fid = hub.shader_modules.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1203,14 +1189,6 @@ impl Global {
|
||||
pipeline::ShaderModuleSource::Wgsl(ref code) => {
|
||||
trace.make_binary("wgsl", code.as_bytes())
|
||||
}
|
||||
#[cfg(feature = "glsl")]
|
||||
pipeline::ShaderModuleSource::Glsl(ref code, _) => {
|
||||
trace.make_binary("glsl", code.as_bytes())
|
||||
}
|
||||
#[cfg(feature = "spirv")]
|
||||
pipeline::ShaderModuleSource::SpirV(ref code, _) => {
|
||||
trace.make_binary("spirv", bytemuck::cast_slice::<u32, u8>(code))
|
||||
}
|
||||
pipeline::ShaderModuleSource::Naga(ref module) => {
|
||||
let string =
|
||||
ron::ser::to_string_pretty(module, ron::ser::PrettyConfig::default())
|
||||
@@ -1255,7 +1233,7 @@ impl Global {
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ShaderModuleDescriptor,
|
||||
source: Cow<[u32]>,
|
||||
id_in: Option<id::ShaderModuleId>,
|
||||
id_in: Input<G, id::ShaderModuleId>,
|
||||
) -> (
|
||||
id::ShaderModuleId,
|
||||
Option<pipeline::CreateShaderModuleError>,
|
||||
@@ -1263,7 +1241,7 @@ impl Global {
|
||||
profiling::scope!("Device::create_shader_module");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.shader_modules.prepare(id_in);
|
||||
let fid = hub.shader_modules.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1317,12 +1295,12 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &wgt::CommandEncoderDescriptor<Label>,
|
||||
id_in: Option<id::CommandEncoderId>,
|
||||
id_in: Input<G, id::CommandEncoderId>,
|
||||
) -> (id::CommandEncoderId, Option<DeviceError>) {
|
||||
profiling::scope!("Device::create_command_encoder");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.command_buffers.prepare(id_in.map(|id| id.transmute()));
|
||||
let fid = hub.command_buffers.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1358,11 +1336,11 @@ impl Global {
|
||||
|
||||
let (id, _) = fid.assign(command_buffer);
|
||||
api_log!("Device::create_command_encoder -> {id:?}");
|
||||
return (id.transmute(), None);
|
||||
return (id, None);
|
||||
};
|
||||
|
||||
let id = fid.assign_error(desc.label.borrow_or_default());
|
||||
(id.transmute(), Some(error))
|
||||
(id, Some(error))
|
||||
}
|
||||
|
||||
pub fn command_buffer_label<A: HalApi>(&self, id: id::CommandBufferId) -> String {
|
||||
@@ -1375,10 +1353,7 @@ impl Global {
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
if let Some(cmd_buf) = hub
|
||||
.command_buffers
|
||||
.unregister(command_encoder_id.transmute())
|
||||
{
|
||||
if let Some(cmd_buf) = hub.command_buffers.unregister(command_encoder_id) {
|
||||
cmd_buf
|
||||
.device
|
||||
.untrack(&cmd_buf.data.lock().as_ref().unwrap().trackers);
|
||||
@@ -1388,7 +1363,7 @@ impl Global {
|
||||
pub fn command_buffer_drop<A: HalApi>(&self, command_buffer_id: id::CommandBufferId) {
|
||||
profiling::scope!("CommandBuffer::drop");
|
||||
api_log!("CommandBuffer::drop {command_buffer_id:?}");
|
||||
self.command_encoder_drop::<A>(command_buffer_id.transmute())
|
||||
self.command_encoder_drop::<A>(command_buffer_id)
|
||||
}
|
||||
|
||||
pub fn device_create_render_bundle_encoder(
|
||||
@@ -1396,7 +1371,7 @@ impl Global {
|
||||
device_id: DeviceId,
|
||||
desc: &command::RenderBundleEncoderDescriptor,
|
||||
) -> (
|
||||
*mut command::RenderBundleEncoder,
|
||||
id::RenderBundleEncoderId,
|
||||
Option<command::CreateRenderBundleError>,
|
||||
) {
|
||||
profiling::scope!("Device::create_render_bundle_encoder");
|
||||
@@ -1412,13 +1387,13 @@ impl Global {
|
||||
&self,
|
||||
bundle_encoder: command::RenderBundleEncoder,
|
||||
desc: &command::RenderBundleDescriptor,
|
||||
id_in: Option<id::RenderBundleId>,
|
||||
id_in: Input<G, id::RenderBundleId>,
|
||||
) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
|
||||
profiling::scope!("RenderBundleEncoder::finish");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.render_bundles.prepare(id_in);
|
||||
let fid = hub.render_bundles.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(bundle_encoder.parent()) {
|
||||
@@ -1482,12 +1457,12 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::QuerySetDescriptor,
|
||||
id_in: Option<id::QuerySetId>,
|
||||
id_in: Input<G, id::QuerySetId>,
|
||||
) -> (id::QuerySetId, Option<resource::CreateQuerySetError>) {
|
||||
profiling::scope!("Device::create_query_set");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let fid = hub.query_sets.prepare(id_in);
|
||||
let fid = hub.query_sets.prepare::<G>(id_in);
|
||||
|
||||
let error = loop {
|
||||
let device = match hub.devices.get(device_id) {
|
||||
@@ -1556,8 +1531,8 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::RenderPipelineDescriptor,
|
||||
id_in: Option<id::RenderPipelineId>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<'_>>,
|
||||
id_in: Input<G, id::RenderPipelineId>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
) -> (
|
||||
id::RenderPipelineId,
|
||||
Option<pipeline::CreateRenderPipelineError>,
|
||||
@@ -1566,7 +1541,7 @@ impl Global {
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.render_pipelines.prepare(id_in);
|
||||
let fid = hub.render_pipelines.prepare::<G>(id_in);
|
||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
||||
let implicit_error_context = implicit_context.clone();
|
||||
|
||||
@@ -1635,7 +1610,7 @@ impl Global {
|
||||
&self,
|
||||
pipeline_id: id::RenderPipelineId,
|
||||
index: u32,
|
||||
id_in: Option<id::BindGroupLayoutId>,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
Option<binding_model::GetBindGroupLayoutError>,
|
||||
@@ -1648,7 +1623,10 @@ impl Global {
|
||||
Err(_) => break binding_model::GetBindGroupLayoutError::InvalidPipeline,
|
||||
};
|
||||
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
||||
Some(bg) => hub.bind_group_layouts.prepare(id_in).assign_existing(bg),
|
||||
Some(bg) => hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.assign_existing(bg),
|
||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||
};
|
||||
return (id, None);
|
||||
@@ -1656,7 +1634,7 @@ impl Global {
|
||||
|
||||
let id = hub
|
||||
.bind_group_layouts
|
||||
.prepare(id_in)
|
||||
.prepare::<G>(id_in)
|
||||
.assign_error("<derived>");
|
||||
(id, Some(error))
|
||||
}
|
||||
@@ -1691,8 +1669,8 @@ impl Global {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ComputePipelineDescriptor,
|
||||
id_in: Option<id::ComputePipelineId>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<'_>>,
|
||||
id_in: Input<G, id::ComputePipelineId>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
) -> (
|
||||
id::ComputePipelineId,
|
||||
Option<pipeline::CreateComputePipelineError>,
|
||||
@@ -1701,7 +1679,7 @@ impl Global {
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.compute_pipelines.prepare(id_in);
|
||||
let fid = hub.compute_pipelines.prepare::<G>(id_in);
|
||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
||||
let implicit_error_context = implicit_context.clone();
|
||||
|
||||
@@ -1765,7 +1743,7 @@ impl Global {
|
||||
&self,
|
||||
pipeline_id: id::ComputePipelineId,
|
||||
index: u32,
|
||||
id_in: Option<id::BindGroupLayoutId>,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
Option<binding_model::GetBindGroupLayoutError>,
|
||||
@@ -1779,7 +1757,10 @@ impl Global {
|
||||
};
|
||||
|
||||
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
||||
Some(bg) => hub.bind_group_layouts.prepare(id_in).assign_existing(bg),
|
||||
Some(bg) => hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.assign_existing(bg),
|
||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||
};
|
||||
|
||||
@@ -1788,7 +1769,7 @@ impl Global {
|
||||
|
||||
let id = hub
|
||||
.bind_group_layouts
|
||||
.prepare(id_in)
|
||||
.prepare::<G>(id_in)
|
||||
.assign_error("<derived>");
|
||||
(id, Some(error))
|
||||
}
|
||||
@@ -2114,7 +2095,7 @@ impl Global {
|
||||
|
||||
let (closures, queue_empty) = {
|
||||
if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain {
|
||||
if submission_index.queue_id != device_id.transmute() {
|
||||
if submission_index.queue_id != device_id {
|
||||
return Err(WaitIdleError::WrongSubmissionIndex(
|
||||
submission_index.queue_id,
|
||||
device_id,
|
||||
@@ -2248,7 +2229,7 @@ impl Global {
|
||||
if let Some(device) = hub.devices.unregister(device_id) {
|
||||
let device_lost_closure = device.lock_life().device_lost_closure.take();
|
||||
if let Some(closure) = device_lost_closure {
|
||||
closure.call(DeviceLostReason::Dropped, String::from("Device dropped."));
|
||||
closure.call(DeviceLostReason::Unknown, String::from("Device dropped."));
|
||||
}
|
||||
|
||||
// The things `Device::prepare_to_die` takes care are mostly
|
||||
@@ -2266,8 +2247,8 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
// This closure will be called exactly once during "lose the device",
|
||||
// or when it is replaced.
|
||||
// This closure will be called exactly once during "lose the device"
|
||||
// or when the device is dropped, if it was never lost.
|
||||
pub fn device_set_device_lost_closure<A: HalApi>(
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
@@ -2277,12 +2258,6 @@ impl Global {
|
||||
|
||||
if let Ok(device) = hub.devices.get(device_id) {
|
||||
let mut life_tracker = device.lock_life();
|
||||
if let Some(existing_closure) = life_tracker.device_lost_closure.take() {
|
||||
// It's important to not hold the lock while calling the closure.
|
||||
drop(life_tracker);
|
||||
existing_closure.call(DeviceLostReason::ReplacedCallback, "".to_string());
|
||||
life_tracker = device.lock_life();
|
||||
}
|
||||
life_tracker.device_lost_closure = Some(device_lost_closure);
|
||||
}
|
||||
}
|
||||
@@ -2339,7 +2314,7 @@ impl Global {
|
||||
range: Range<BufferAddress>,
|
||||
op: BufferMapOperation,
|
||||
) -> BufferAccessResult {
|
||||
api_log!("Buffer::map_async {buffer_id:?} range {range:?} op: {op:?}");
|
||||
api_log!("Buffer::map_async {buffer_id:?}");
|
||||
|
||||
// User callbacks must not be called while holding buffer_map_async_inner's locks, so we
|
||||
// defer the error callback if it needs to be called immediately (typically when running
|
||||
@@ -2466,7 +2441,7 @@ impl Global {
|
||||
size: Option<BufferAddress>,
|
||||
) -> Result<(*mut u8, u64), BufferAccessError> {
|
||||
profiling::scope!("Buffer::get_mapped_range");
|
||||
api_log!("Buffer::get_mapped_range {buffer_id:?} offset {offset:?} size {size:?}");
|
||||
api_log!("Buffer::get_mapped_range {buffer_id:?}");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
|
||||
66
third_party/rust/wgpu-core/src/device/life.rs
vendored
66
third_party/rust/wgpu-core/src/device/life.rs
vendored
@@ -7,7 +7,7 @@ use crate::{
|
||||
},
|
||||
hal_api::HalApi,
|
||||
id::{
|
||||
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, Id, PipelineLayoutId,
|
||||
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, PipelineLayoutId,
|
||||
QuerySetId, RenderBundleId, RenderPipelineId, SamplerId, StagingBufferId, TextureId,
|
||||
TextureViewId,
|
||||
},
|
||||
@@ -419,14 +419,15 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
}
|
||||
|
||||
impl<A: HalApi> LifetimeTracker<A> {
|
||||
fn triage_resources<R>(
|
||||
resources_map: &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||
fn triage_resources<Id, R>(
|
||||
resources_map: &mut FastHashMap<Id, Arc<R>>,
|
||||
active: &mut [ActiveSubmission<A>],
|
||||
trackers: &mut impl ResourceTracker<R>,
|
||||
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||
trackers: &mut impl ResourceTracker<Id, R>,
|
||||
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id, Arc<R>>,
|
||||
) -> Vec<Arc<R>>
|
||||
where
|
||||
R: Resource,
|
||||
Id: id::TypedId,
|
||||
R: Resource<Id>,
|
||||
{
|
||||
let mut removed_resources = Vec::new();
|
||||
resources_map.retain(|&id, resource| {
|
||||
@@ -524,12 +525,20 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
fn triage_suspected_texture_views(&mut self, trackers: &Mutex<Tracker<A>>) -> &mut Self {
|
||||
let mut trackers = trackers.lock();
|
||||
let resource_map = &mut self.suspected_resources.texture_views;
|
||||
Self::triage_resources(
|
||||
let mut removed_resources = Self::triage_resources(
|
||||
resource_map,
|
||||
self.active.as_mut_slice(),
|
||||
&mut trackers.views,
|
||||
|maps| &mut maps.texture_views,
|
||||
);
|
||||
removed_resources.drain(..).for_each(|texture_view| {
|
||||
let mut lock = texture_view.parent.write();
|
||||
if let Some(parent_texture) = lock.take() {
|
||||
self.suspected_resources
|
||||
.textures
|
||||
.insert(parent_texture.as_info().id(), parent_texture);
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
@@ -828,4 +837,47 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
}
|
||||
pending_callbacks
|
||||
}
|
||||
|
||||
pub(crate) fn release_gpu_resources(&mut self) {
|
||||
// This is called when the device is lost, which makes every associated
|
||||
// resource invalid and unusable. This is an opportunity to release all of
|
||||
// the underlying gpu resources, even though the objects remain visible to
|
||||
// the user agent. We purge this memory naturally when resources have been
|
||||
// moved into the appropriate buckets, so this function just needs to
|
||||
// initiate movement into those buckets, and it can do that by calling
|
||||
// "destroy" on all the resources we know about which aren't already marked
|
||||
// for cleanup.
|
||||
|
||||
// During these iterations, we discard all errors. We don't care!
|
||||
|
||||
// Destroy all the mapped buffers.
|
||||
for buffer in &self.mapped {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy all the unmapped buffers.
|
||||
for buffer in &self.ready_to_map {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy all the future_suspected_buffers.
|
||||
for buffer in &self.future_suspected_buffers {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
|
||||
// Destroy the buffers in all active submissions.
|
||||
for submission in &self.active {
|
||||
for buffer in &submission.mapped {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all the future_suspected_textures.
|
||||
// TODO: texture.destroy is not implemented
|
||||
/*
|
||||
for texture in &self.future_suspected_textures {
|
||||
let _ = texture.destroy();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
29
third_party/rust/wgpu-core/src/device/mod.rs
vendored
29
third_party/rust/wgpu-core/src/device/mod.rs
vendored
@@ -2,7 +2,8 @@ use crate::{
|
||||
binding_model,
|
||||
hal_api::HalApi,
|
||||
hub::Hub,
|
||||
id::{BindGroupLayoutId, PipelineLayoutId},
|
||||
id::{self},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
resource::{Buffer, BufferAccessResult},
|
||||
resource::{BufferAccessError, BufferMapOperation},
|
||||
resource_log, Label, DOWNLEVEL_ERROR_MESSAGE,
|
||||
@@ -41,14 +42,15 @@ pub type DeviceDescriptor<'a> = wgt::DeviceDescriptor<Label<'a>>;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum HostMap {
|
||||
Read,
|
||||
Write,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub(crate) struct AttachmentData<T> {
|
||||
pub colors: ArrayVec<Option<T>, { hal::MAX_COLOR_ATTACHMENTS }>,
|
||||
pub resolves: ArrayVec<T, { hal::MAX_COLOR_ATTACHMENTS }>,
|
||||
@@ -72,7 +74,7 @@ pub enum RenderPassCompatibilityCheckType {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub(crate) struct RenderPassContext {
|
||||
pub attachments: AttachmentData<TextureFormat>,
|
||||
pub sample_count: u32,
|
||||
@@ -455,25 +457,26 @@ pub struct MissingFeatures(pub wgt::Features);
|
||||
pub struct MissingDownlevelFlags(pub wgt::DownlevelFlags);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImplicitPipelineContext {
|
||||
pub root_id: PipelineLayoutId,
|
||||
pub group_ids: ArrayVec<BindGroupLayoutId, { hal::MAX_BIND_GROUPS }>,
|
||||
pub root_id: id::PipelineLayoutId,
|
||||
pub group_ids: ArrayVec<id::BindGroupLayoutId, { hal::MAX_BIND_GROUPS }>,
|
||||
}
|
||||
|
||||
pub struct ImplicitPipelineIds<'a> {
|
||||
pub root_id: Option<PipelineLayoutId>,
|
||||
pub group_ids: &'a [Option<BindGroupLayoutId>],
|
||||
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
|
||||
pub root_id: Input<G, id::PipelineLayoutId>,
|
||||
pub group_ids: &'a [Input<G, id::BindGroupLayoutId>],
|
||||
}
|
||||
|
||||
impl ImplicitPipelineIds<'_> {
|
||||
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
|
||||
fn prepare<A: HalApi>(self, hub: &Hub<A>) -> ImplicitPipelineContext {
|
||||
ImplicitPipelineContext {
|
||||
root_id: hub.pipeline_layouts.prepare(self.root_id).into_id(),
|
||||
root_id: hub.pipeline_layouts.prepare::<G>(self.root_id).into_id(),
|
||||
group_ids: self
|
||||
.group_ids
|
||||
.iter()
|
||||
.map(|id_in| hub.bind_group_layouts.prepare(*id_in).into_id())
|
||||
.map(|id_in| hub.bind_group_layouts.prepare::<G>(*id_in).into_id())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
74
third_party/rust/wgpu-core/src/device/queue.rs
vendored
74
third_party/rust/wgpu-core/src/device/queue.rs
vendored
@@ -13,6 +13,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
id::{self, QueueId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
||||
resource::{
|
||||
Buffer, BufferAccessError, BufferMapState, DestroyedBuffer, DestroyedTexture, Resource,
|
||||
@@ -23,7 +24,6 @@ use crate::{
|
||||
|
||||
use hal::{CommandEncoder as _, Device as _, Queue as _};
|
||||
use parking_lot::Mutex;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::{
|
||||
iter, mem, ptr,
|
||||
@@ -36,19 +36,17 @@ use super::Device;
|
||||
pub struct Queue<A: HalApi> {
|
||||
pub device: Option<Arc<Device<A>>>,
|
||||
pub raw: Option<A::Queue>,
|
||||
pub info: ResourceInfo<Queue<A>>,
|
||||
pub info: ResourceInfo<QueueId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Queue<A> {
|
||||
impl<A: HalApi> Resource<QueueId> for Queue<A> {
|
||||
const TYPE: ResourceType = "Queue";
|
||||
|
||||
type Marker = crate::id::markers::Queue;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<QueueId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QueueId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -229,18 +227,18 @@ impl<A: HalApi> PendingWrites<A> {
|
||||
.push(TempResource::StagingBuffer(buffer));
|
||||
}
|
||||
|
||||
fn pre_submit(&mut self) -> Result<Option<&A::CommandBuffer>, DeviceError> {
|
||||
#[must_use]
|
||||
fn pre_submit(&mut self) -> Option<&A::CommandBuffer> {
|
||||
self.dst_buffers.clear();
|
||||
self.dst_textures.clear();
|
||||
if self.is_active {
|
||||
let cmd_buf = unsafe { self.command_encoder.end_encoding()? };
|
||||
let cmd_buf = unsafe { self.command_encoder.end_encoding().unwrap() };
|
||||
self.is_active = false;
|
||||
self.executing_command_buffers.push(cmd_buf);
|
||||
|
||||
return Ok(self.executing_command_buffers.last());
|
||||
self.executing_command_buffers.last()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -363,7 +361,7 @@ pub enum QueueSubmitError {
|
||||
|
||||
//TODO: move out common parts of write_xxx.
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn queue_write_buffer<A: HalApi>(
|
||||
&self,
|
||||
queue_id: QueueId,
|
||||
@@ -437,7 +435,7 @@ impl Global {
|
||||
&self,
|
||||
queue_id: QueueId,
|
||||
buffer_size: wgt::BufferSize,
|
||||
id_in: Option<id::StagingBufferId>,
|
||||
id_in: Input<G, id::StagingBufferId>,
|
||||
) -> Result<(id::StagingBufferId, *mut u8), QueueWriteError> {
|
||||
profiling::scope!("Queue::create_staging_buffer");
|
||||
let hub = A::hub(self);
|
||||
@@ -452,7 +450,7 @@ impl Global {
|
||||
let (staging_buffer, staging_buffer_ptr) =
|
||||
prepare_staging_buffer(device, buffer_size.get(), device.instance_flags)?;
|
||||
|
||||
let fid = hub.staging_buffers.prepare(id_in);
|
||||
let fid = hub.staging_buffers.prepare::<G>(id_in);
|
||||
let (id, _) = fid.assign(staging_buffer);
|
||||
resource_log!("Queue::create_staging_buffer {id:?}");
|
||||
|
||||
@@ -670,7 +668,7 @@ impl Global {
|
||||
.get(destination.texture)
|
||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||
|
||||
if dst.device.as_info().id() != queue_id.transmute() {
|
||||
if dst.device.as_info().id() != queue_id {
|
||||
return Err(DeviceError::WrongDevice.into());
|
||||
}
|
||||
|
||||
@@ -1117,13 +1115,10 @@ impl Global {
|
||||
.fetch_add(1, Ordering::Relaxed)
|
||||
+ 1;
|
||||
let mut active_executions = Vec::new();
|
||||
|
||||
let mut used_surface_textures = track::TextureUsageScope::new();
|
||||
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
|
||||
let mut submit_surface_textures_owned = SmallVec::<[_; 2]>::new();
|
||||
|
||||
{
|
||||
let mut command_buffer_guard = hub.command_buffers.write();
|
||||
|
||||
@@ -1151,7 +1146,7 @@ impl Global {
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if cmdbuf.device.as_info().id() != queue_id.transmute() {
|
||||
if cmdbuf.device.as_info().id() != queue_id {
|
||||
return Err(DeviceError::WrongDevice.into());
|
||||
}
|
||||
|
||||
@@ -1222,17 +1217,8 @@ impl Global {
|
||||
return Err(QueueSubmitError::DestroyedTexture(id));
|
||||
}
|
||||
Some(TextureInner::Native { .. }) => false,
|
||||
Some(TextureInner::Surface {
|
||||
ref has_work,
|
||||
ref raw,
|
||||
..
|
||||
}) => {
|
||||
Some(TextureInner::Surface { ref has_work, .. }) => {
|
||||
has_work.store(true, Ordering::Relaxed);
|
||||
|
||||
if raw.is_some() {
|
||||
submit_surface_textures_owned.push(texture.clone());
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
};
|
||||
@@ -1423,17 +1409,8 @@ impl Global {
|
||||
return Err(QueueSubmitError::DestroyedTexture(id));
|
||||
}
|
||||
Some(TextureInner::Native { .. }) => {}
|
||||
Some(TextureInner::Surface {
|
||||
ref has_work,
|
||||
ref raw,
|
||||
..
|
||||
}) => {
|
||||
Some(TextureInner::Surface { ref has_work, .. }) => {
|
||||
has_work.store(true, Ordering::Relaxed);
|
||||
|
||||
if raw.is_some() {
|
||||
submit_surface_textures_owned.push(texture.clone());
|
||||
}
|
||||
|
||||
unsafe {
|
||||
used_surface_textures
|
||||
.merge_single(texture, None, hal::TextureUses::PRESENT)
|
||||
@@ -1464,7 +1441,7 @@ impl Global {
|
||||
}
|
||||
|
||||
let refs = pending_writes
|
||||
.pre_submit()?
|
||||
.pre_submit()
|
||||
.into_iter()
|
||||
.chain(
|
||||
active_executions
|
||||
@@ -1472,23 +1449,12 @@ impl Global {
|
||||
.flat_map(|pool_execution| pool_execution.cmd_buffers.iter()),
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut submit_surface_textures =
|
||||
SmallVec::<[_; 2]>::with_capacity(submit_surface_textures_owned.len());
|
||||
|
||||
for texture in &submit_surface_textures_owned {
|
||||
submit_surface_textures.extend(match texture.inner.get(&snatch_guard) {
|
||||
Some(TextureInner::Surface { raw, .. }) => raw.as_ref(),
|
||||
_ => None,
|
||||
});
|
||||
}
|
||||
|
||||
unsafe {
|
||||
queue
|
||||
.raw
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.submit(&refs, &submit_surface_textures, Some((fence, submit_index)))
|
||||
.submit(&refs, Some((fence, submit_index)))
|
||||
.map_err(DeviceError::from)?;
|
||||
}
|
||||
|
||||
|
||||
110
third_party/rust/wgpu-core/src/device/resource.rs
vendored
110
third_party/rust/wgpu-core/src/device/resource.rs
vendored
@@ -12,7 +12,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
hub::Hub,
|
||||
id::QueueId,
|
||||
id::{self, DeviceId, QueueId},
|
||||
init_tracker::{
|
||||
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
|
||||
TextureInitTracker, TextureInitTrackerAction,
|
||||
@@ -90,7 +90,7 @@ pub struct Device<A: HalApi> {
|
||||
pub(crate) queue_id: RwLock<Option<QueueId>>,
|
||||
queue_to_drop: RwLock<Option<A::Queue>>,
|
||||
pub(crate) zero_buffer: Option<A::Buffer>,
|
||||
pub(crate) info: ResourceInfo<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<DeviceId>,
|
||||
|
||||
pub(crate) command_allocator: Mutex<Option<CommandAllocator<A>>>,
|
||||
//Note: The submission index here corresponds to the last submission that is done.
|
||||
@@ -380,7 +380,7 @@ impl<A: HalApi> Device<A> {
|
||||
let mut device_lost_invocations = SmallVec::new();
|
||||
if !self.is_valid() && life_tracker.queue_empty() {
|
||||
// We can release gpu resources associated with this device.
|
||||
self.release_gpu_resources();
|
||||
life_tracker.release_gpu_resources();
|
||||
|
||||
// If we have a DeviceLostClosure, build an invocation with the
|
||||
// reason DeviceLostReason::Destroyed and no message.
|
||||
@@ -566,7 +566,6 @@ impl<A: HalApi> Device<A> {
|
||||
sync_mapped_writes: Mutex::new(None),
|
||||
map_state: Mutex::new(resource::BufferMapState::Idle),
|
||||
info: ResourceInfo::new(desc.label.borrow_or_default()),
|
||||
bind_groups: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -596,8 +595,6 @@ impl<A: HalApi> Device<A> {
|
||||
},
|
||||
info: ResourceInfo::new(desc.label.borrow_or_default()),
|
||||
clear_mode: RwLock::new(clear_mode),
|
||||
views: Mutex::new(Vec::new()),
|
||||
bind_groups: Mutex::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,7 +614,6 @@ impl<A: HalApi> Device<A> {
|
||||
sync_mapped_writes: Mutex::new(None),
|
||||
map_state: Mutex::new(resource::BufferMapState::Idle),
|
||||
info: ResourceInfo::new(desc.label.borrow_or_default()),
|
||||
bind_groups: Mutex::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,8 +1177,8 @@ impl<A: HalApi> Device<A> {
|
||||
};
|
||||
|
||||
Ok(TextureView {
|
||||
raw: Snatchable::new(raw),
|
||||
parent: texture.clone(),
|
||||
raw: Some(raw),
|
||||
parent: RwLock::new(Some(texture.clone())),
|
||||
device: self.clone(),
|
||||
desc: resource::HalTextureViewDescriptor {
|
||||
texture_format: texture.desc.format,
|
||||
@@ -1313,7 +1309,7 @@ impl<A: HalApi> Device<A> {
|
||||
let (module, source) = match source {
|
||||
#[cfg(feature = "wgsl")]
|
||||
pipeline::ShaderModuleSource::Wgsl(code) => {
|
||||
profiling::scope!("naga::front::wgsl::parse_str");
|
||||
profiling::scope!("naga::wgsl::parse_str");
|
||||
let module = naga::front::wgsl::parse_str(&code).map_err(|inner| {
|
||||
pipeline::CreateShaderModuleError::Parsing(pipeline::ShaderError {
|
||||
source: code.to_string(),
|
||||
@@ -1323,32 +1319,6 @@ impl<A: HalApi> Device<A> {
|
||||
})?;
|
||||
(Cow::Owned(module), code.into_owned())
|
||||
}
|
||||
#[cfg(feature = "spirv")]
|
||||
pipeline::ShaderModuleSource::SpirV(spv, options) => {
|
||||
let parser = naga::front::spv::Frontend::new(spv.iter().cloned(), &options);
|
||||
profiling::scope!("naga::front::spv::Frontend");
|
||||
let module = parser.parse().map_err(|inner| {
|
||||
pipeline::CreateShaderModuleError::ParsingSpirV(pipeline::ShaderError {
|
||||
source: String::new(),
|
||||
label: desc.label.as_ref().map(|l| l.to_string()),
|
||||
inner: Box::new(inner),
|
||||
})
|
||||
})?;
|
||||
(Cow::Owned(module), String::new())
|
||||
}
|
||||
#[cfg(feature = "glsl")]
|
||||
pipeline::ShaderModuleSource::Glsl(code, options) => {
|
||||
let mut parser = naga::front::glsl::Frontend::default();
|
||||
profiling::scope!("naga::front::glsl::Frontend.parse");
|
||||
let module = parser.parse(&options, &code).map_err(|inner| {
|
||||
pipeline::CreateShaderModuleError::ParsingGlsl(pipeline::ShaderError {
|
||||
source: code.to_string(),
|
||||
label: desc.label.as_ref().map(|l| l.to_string()),
|
||||
inner: Box::new(inner),
|
||||
})
|
||||
})?;
|
||||
(Cow::Owned(module), code.into_owned())
|
||||
}
|
||||
pipeline::ShaderModuleSource::Naga(module) => (module, String::new()),
|
||||
pipeline::ShaderModuleSource::Dummy(_) => panic!("found `ShaderModuleSource::Dummy`"),
|
||||
};
|
||||
@@ -1785,7 +1755,7 @@ impl<A: HalApi> Device<A> {
|
||||
dynamic_binding_info: &mut Vec<binding_model::BindGroupDynamicBindingData>,
|
||||
late_buffer_binding_sizes: &mut FastHashMap<u32, wgt::BufferSize>,
|
||||
used: &mut BindGroupStates<A>,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
storage: &'a Storage<Buffer<A>, id::BufferId>,
|
||||
limits: &wgt::Limits,
|
||||
snatch_guard: &'a SnatchGuard<'a>,
|
||||
) -> Result<hal::BufferBinding<'a, A>, binding_model::CreateBindGroupError> {
|
||||
@@ -1922,13 +1892,17 @@ impl<A: HalApi> Device<A> {
|
||||
used: &mut BindGroupStates<A>,
|
||||
used_texture_ranges: &mut Vec<TextureInitTrackerAction<A>>,
|
||||
) -> Result<(), binding_model::CreateBindGroupError> {
|
||||
let texture = &view.parent;
|
||||
let texture_id = texture.as_info().id();
|
||||
let texture = view.parent.read();
|
||||
let texture_id = texture.as_ref().unwrap().as_info().id();
|
||||
// Careful here: the texture may no longer have its own ref count,
|
||||
// if it was deleted by the user.
|
||||
let texture = used
|
||||
.textures
|
||||
.add_single(texture, Some(view.selector.clone()), internal_use)
|
||||
.add_single(
|
||||
texture.as_ref().unwrap(),
|
||||
Some(view.selector.clone()),
|
||||
internal_use,
|
||||
)
|
||||
.ok_or(binding_model::CreateBindGroupError::InvalidTexture(
|
||||
texture_id,
|
||||
))?;
|
||||
@@ -2130,9 +2104,7 @@ impl<A: HalApi> Device<A> {
|
||||
)?;
|
||||
let res_index = hal_textures.len();
|
||||
hal_textures.push(hal::TextureBinding {
|
||||
view: view
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(Error::InvalidTextureView(id))?,
|
||||
view: view.raw(),
|
||||
usage: internal_use,
|
||||
});
|
||||
(res_index, 1)
|
||||
@@ -2158,9 +2130,7 @@ impl<A: HalApi> Device<A> {
|
||||
&mut used_texture_ranges,
|
||||
)?;
|
||||
hal_textures.push(hal::TextureBinding {
|
||||
view: view
|
||||
.raw(&snatch_guard)
|
||||
.ok_or(Error::InvalidTextureView(id))?,
|
||||
view: view.raw(),
|
||||
usage: internal_use,
|
||||
});
|
||||
}
|
||||
@@ -2202,7 +2172,7 @@ impl<A: HalApi> Device<A> {
|
||||
};
|
||||
|
||||
Ok(binding_model::BindGroup {
|
||||
raw: Snatchable::new(raw),
|
||||
raw: Some(raw),
|
||||
device: self.clone(),
|
||||
layout: layout.clone(),
|
||||
info: ResourceInfo::new(desc.label.borrow_or_default()),
|
||||
@@ -2386,7 +2356,7 @@ impl<A: HalApi> Device<A> {
|
||||
pub(crate) fn create_pipeline_layout(
|
||||
self: &Arc<Self>,
|
||||
desc: &binding_model::PipelineLayoutDescriptor,
|
||||
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
) -> Result<binding_model::PipelineLayout<A>, binding_model::CreatePipelineLayoutError> {
|
||||
use crate::binding_model::CreatePipelineLayoutError as Error;
|
||||
|
||||
@@ -2499,8 +2469,8 @@ impl<A: HalApi> Device<A> {
|
||||
self: &Arc<Self>,
|
||||
implicit_context: Option<ImplicitPipelineContext>,
|
||||
mut derived_group_layouts: ArrayVec<bgl::EntryMap, { hal::MAX_BIND_GROUPS }>,
|
||||
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||
pipeline_layout_registry: &Registry<binding_model::PipelineLayout<A>>,
|
||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
pipeline_layout_registry: &Registry<id::PipelineLayoutId, binding_model::PipelineLayout<A>>,
|
||||
) -> Result<Arc<binding_model::PipelineLayout<A>>, pipeline::ImplicitLayoutError> {
|
||||
while derived_group_layouts
|
||||
.last()
|
||||
@@ -2717,13 +2687,8 @@ impl<A: HalApi> Device<A> {
|
||||
let mut shader_expects_dual_source_blending = false;
|
||||
let mut pipeline_expects_dual_source_blending = false;
|
||||
for (i, vb_state) in desc.vertex.buffers.iter().enumerate() {
|
||||
let mut last_stride = 0;
|
||||
for attribute in vb_state.attributes.iter() {
|
||||
last_stride = last_stride.max(attribute.offset + attribute.format.size());
|
||||
}
|
||||
vertex_steps.push(pipeline::VertexStep {
|
||||
stride: vb_state.array_stride,
|
||||
last_stride,
|
||||
mode: vb_state.step_mode,
|
||||
});
|
||||
if vb_state.attributes.is_empty() {
|
||||
@@ -3366,6 +3331,7 @@ impl<A: HalApi> Device<A> {
|
||||
// It's important to not hold the lock while calling the closure.
|
||||
drop(life_lock);
|
||||
device_lost_closure.call(DeviceLostReason::Unknown, message.to_string());
|
||||
life_lock = self.lock_life();
|
||||
}
|
||||
|
||||
// 2) Complete any outstanding mapAsync() steps.
|
||||
@@ -3377,26 +3343,7 @@ impl<A: HalApi> Device<A> {
|
||||
// until they are cleared, and then drop the device.
|
||||
|
||||
// Eagerly release GPU resources.
|
||||
self.release_gpu_resources();
|
||||
}
|
||||
|
||||
pub(crate) fn release_gpu_resources(&self) {
|
||||
// This is called when the device is lost, which makes every associated
|
||||
// resource invalid and unusable. This is an opportunity to release all of
|
||||
// the underlying gpu resources, even though the objects remain visible to
|
||||
// the user agent. We purge this memory naturally when resources have been
|
||||
// moved into the appropriate buckets, so this function just needs to
|
||||
// initiate movement into those buckets, and it can do that by calling
|
||||
// "destroy" on all the resources we know about.
|
||||
|
||||
// During these iterations, we discard all errors. We don't care!
|
||||
let trackers = self.trackers.lock();
|
||||
for buffer in trackers.buffers.used_resources() {
|
||||
let _ = buffer.destroy();
|
||||
}
|
||||
for texture in trackers.textures.used_resources() {
|
||||
let _ = texture.destroy();
|
||||
}
|
||||
life_lock.release_gpu_resources();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3433,11 +3380,6 @@ impl<A: HalApi> Device<A> {
|
||||
current_index,
|
||||
self.command_allocator.lock().as_mut().unwrap(),
|
||||
);
|
||||
if let Some(device_lost_closure) = life_tracker.device_lost_closure.take() {
|
||||
// It's important to not hold the lock while calling the closure.
|
||||
drop(life_tracker);
|
||||
device_lost_closure.call(DeviceLostReason::Dropped, "Device is dying.".to_string());
|
||||
}
|
||||
#[cfg(feature = "trace")]
|
||||
{
|
||||
*self.trace.lock() = None;
|
||||
@@ -3445,16 +3387,14 @@ impl<A: HalApi> Device<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Device<A> {
|
||||
impl<A: HalApi> Resource<DeviceId> for Device<A> {
|
||||
const TYPE: ResourceType = "Device";
|
||||
|
||||
type Marker = crate::id::markers::Device;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<DeviceId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<DeviceId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ pub(crate) fn new_render_bundle_encoder_descriptor<'a>(
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum Action<'a> {
|
||||
Init {
|
||||
desc: crate::device::DeviceDescriptor<'a>,
|
||||
@@ -125,7 +126,8 @@ pub enum Action<'a> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum Command {
|
||||
CopyBufferToBuffer {
|
||||
src: id::BufferId,
|
||||
|
||||
6
third_party/rust/wgpu-core/src/error.rs
vendored
6
third_party/rust/wgpu-core/src/error.rs
vendored
@@ -1,11 +1,11 @@
|
||||
use core::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
use crate::{gfx_select, global::Global};
|
||||
use crate::{gfx_select, global::Global, identity::IdentityManagerFactory};
|
||||
|
||||
pub struct ErrorFormatter<'a> {
|
||||
writer: &'a mut dyn fmt::Write,
|
||||
global: &'a Global,
|
||||
global: &'a Global<IdentityManagerFactory>,
|
||||
}
|
||||
|
||||
impl<'a> ErrorFormatter<'a> {
|
||||
@@ -94,7 +94,7 @@ pub trait PrettyError: Error + Sized {
|
||||
|
||||
pub fn format_pretty_any(
|
||||
writer: &mut dyn fmt::Write,
|
||||
global: &Global,
|
||||
global: &Global<IdentityManagerFactory>,
|
||||
error: &(dyn Error + 'static),
|
||||
) {
|
||||
let mut fmt = ErrorFormatter { writer, global };
|
||||
|
||||
40
third_party/rust/wgpu-core/src/global.rs
vendored
40
third_party/rust/wgpu-core/src/global.rs
vendored
@@ -1,10 +1,12 @@
|
||||
use std::sync::Arc;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
hub::{HubReport, Hubs},
|
||||
id::SurfaceId,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
instance::{Instance, Surface},
|
||||
registry::{Registry, RegistryReport},
|
||||
resource_log,
|
||||
@@ -43,31 +45,38 @@ impl GlobalReport {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Global {
|
||||
pub struct Global<G: GlobalIdentityHandlerFactory> {
|
||||
pub instance: Instance,
|
||||
pub surfaces: Registry<Surface>,
|
||||
pub surfaces: Registry<SurfaceId, Surface>,
|
||||
pub(crate) hubs: Hubs,
|
||||
_phantom: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn new(name: &str, factory: G, instance_desc: wgt::InstanceDescriptor) -> Self {
|
||||
profiling::scope!("Global::new");
|
||||
Self {
|
||||
instance: Instance::new(name, instance_desc),
|
||||
surfaces: Registry::without_backend(),
|
||||
hubs: Hubs::new(),
|
||||
surfaces: Registry::without_backend(&factory),
|
||||
hubs: Hubs::new(&factory),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Refer to the creation of wgpu-hal Instance for every backend.
|
||||
pub unsafe fn from_hal_instance<A: HalApi>(name: &str, hal_instance: A::Instance) -> Self {
|
||||
pub unsafe fn from_hal_instance<A: HalApi>(
|
||||
name: &str,
|
||||
factory: G,
|
||||
hal_instance: A::Instance,
|
||||
) -> Self {
|
||||
profiling::scope!("Global::new");
|
||||
Self {
|
||||
instance: A::create_instance_from_hal(name, hal_instance),
|
||||
surfaces: Registry::without_backend(),
|
||||
hubs: Hubs::new(),
|
||||
surfaces: Registry::without_backend(&factory),
|
||||
hubs: Hubs::new(&factory),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +90,13 @@ impl Global {
|
||||
/// # Safety
|
||||
///
|
||||
/// - The raw handles obtained from the Instance must not be manually destroyed
|
||||
pub unsafe fn from_instance(instance: Instance) -> Self {
|
||||
pub unsafe fn from_instance(factory: G, instance: Instance) -> Self {
|
||||
profiling::scope!("Global::new");
|
||||
Self {
|
||||
instance,
|
||||
surfaces: Registry::without_backend(),
|
||||
hubs: Hubs::new(),
|
||||
surfaces: Registry::without_backend(&factory),
|
||||
hubs: Hubs::new(&factory),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +138,7 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Drop for Global<G> {
|
||||
fn drop(&mut self) {
|
||||
profiling::scope!("Global::drop");
|
||||
resource_log!("Global::drop");
|
||||
@@ -166,7 +176,7 @@ impl Drop for Global {
|
||||
}
|
||||
|
||||
#[cfg(send_sync)]
|
||||
fn _test_send_sync(global: &Global) {
|
||||
fn _test_send_sync(global: &Global<crate::identity::IdentityManagerFactory>) {
|
||||
fn test_internal<T: Send + Sync>(_: T) {}
|
||||
test_internal(global)
|
||||
}
|
||||
|
||||
13
third_party/rust/wgpu-core/src/hal_api.rs
vendored
13
third_party/rust/wgpu-core/src/hal_api.rs
vendored
@@ -3,6 +3,7 @@ use wgt::{Backend, WasmNotSendSync};
|
||||
use crate::{
|
||||
global::Global,
|
||||
hub::Hub,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
instance::{HalSurface, Instance, Surface},
|
||||
};
|
||||
|
||||
@@ -10,7 +11,7 @@ pub trait HalApi: hal::Api + 'static + WasmNotSendSync {
|
||||
const VARIANT: Backend;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance;
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance>;
|
||||
fn hub(global: &Global) -> &Hub<Self>;
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self>;
|
||||
fn get_surface(surface: &Surface) -> Option<&HalSurface<Self>>;
|
||||
}
|
||||
|
||||
@@ -22,7 +23,7 @@ impl HalApi for hal::api::Empty {
|
||||
fn instance_as_hal(_: &Instance) -> Option<&Self::Instance> {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
fn hub(_: &Global) -> &Hub<Self> {
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(_: &Global<G>) -> &Hub<Self> {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
fn get_surface(_: &Surface) -> Option<&HalSurface<Self>> {
|
||||
@@ -43,7 +44,7 @@ impl HalApi for hal::api::Vulkan {
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.vulkan.as_ref()
|
||||
}
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self> {
|
||||
&global.hubs.vulkan
|
||||
}
|
||||
fn get_surface(surface: &Surface) -> Option<&HalSurface<Self>> {
|
||||
@@ -64,7 +65,7 @@ impl HalApi for hal::api::Metal {
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.metal.as_ref()
|
||||
}
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self> {
|
||||
&global.hubs.metal
|
||||
}
|
||||
fn get_surface(surface: &Surface) -> Option<&HalSurface<Self>> {
|
||||
@@ -85,7 +86,7 @@ impl HalApi for hal::api::Dx12 {
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.dx12.as_ref()
|
||||
}
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self> {
|
||||
&global.hubs.dx12
|
||||
}
|
||||
fn get_surface(surface: &Surface) -> Option<&HalSurface<Self>> {
|
||||
@@ -107,7 +108,7 @@ impl HalApi for hal::api::Gles {
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.gl.as_ref()
|
||||
}
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self> {
|
||||
&global.hubs.gl
|
||||
}
|
||||
fn get_surface(surface: &Surface) -> Option<&HalSurface<Self>> {
|
||||
|
||||
112
third_party/rust/wgpu-core/src/hub.rs
vendored
112
third_party/rust/wgpu-core/src/hub.rs
vendored
@@ -2,13 +2,10 @@
|
||||
|
||||
The `wgpu_core` API uses identifiers of type [`Id<R>`] to refer to
|
||||
resources of type `R`. For example, [`id::DeviceId`] is an alias for
|
||||
`Id<markers::Device>`, and [`id::BufferId`] is an alias for
|
||||
`Id<markers::Buffer>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
||||
`Id<Device<Empty>>`, and [`id::BufferId`] is an alias for
|
||||
`Id<Buffer<Empty>>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
||||
of course `Debug`.
|
||||
|
||||
[`id::DeviceId`]: crate::id::DeviceId
|
||||
[`id::BufferId`]: crate::id::BufferId
|
||||
|
||||
Each `Id` contains not only an index for the resource it denotes but
|
||||
also a Backend indicating which `wgpu` backend it belongs to. You
|
||||
can use the [`gfx_select`] macro to dynamically dispatch on an id's
|
||||
@@ -40,13 +37,13 @@ specify the id, and they all return the id used. For example, the
|
||||
declaration of `Global::device_create_buffer` looks like this:
|
||||
|
||||
```ignore
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
/* ... */
|
||||
pub fn device_create_buffer<A: HalApi>(
|
||||
&self,
|
||||
device_id: id::DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Input<G>,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
) -> (id::BufferId, Option<resource::CreateBufferError>) {
|
||||
/* ... */
|
||||
}
|
||||
@@ -60,7 +57,15 @@ itself to choose ids always pass `()`. In either case, the id
|
||||
ultimately assigned is returned as the first element of the tuple.
|
||||
|
||||
Producing true identifiers from `id_in` values is the job of an
|
||||
[`crate::identity::IdentityManager`] or ids will be received from outside through `Option<Id>` arguments.
|
||||
[`crate::identity::IdentityManager`], but only if the `IdentityHandlerFactory`
|
||||
create it and then generated by it, otherwise ids will be received from outside.
|
||||
|
||||
`Global::new` expects a `factory` argument that
|
||||
implements the [`GlobalIdentityHandlerFactory`] trait, which extends
|
||||
[`crate::identity::IdentityHandlerFactory<I>`] for each resource id type `I`. This
|
||||
trait, in turn, has a `spawn` method that constructs an
|
||||
`crate::identity::IdentityManager` for the `Global` to use,
|
||||
if ids should be generated by wgpu or will return None otherwise.
|
||||
|
||||
## Id allocation and streaming
|
||||
|
||||
@@ -97,6 +102,7 @@ as much, allowing subsequent operations using that id to be properly
|
||||
flagged as errors as well.
|
||||
|
||||
[`gfx_select`]: crate::gfx_select
|
||||
[`Input`]: crate::identity::IdentityHandlerFactory::Input
|
||||
[`process`]: crate::identity::IdentityManager::process
|
||||
[`Id<R>`]: crate::id::Id
|
||||
[wrapped in a mutex]: trait.IdentityHandler.html#impl-IdentityHandler%3CI%3E-for-Mutex%3CIdentityManager%3E
|
||||
@@ -109,6 +115,8 @@ use crate::{
|
||||
command::{CommandBuffer, RenderBundle},
|
||||
device::{queue::Queue, Device},
|
||||
hal_api::HalApi,
|
||||
id,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
instance::{Adapter, HalSurface, Surface},
|
||||
pipeline::{ComputePipeline, RenderPipeline, ShaderModule},
|
||||
registry::{Registry, RegistryReport},
|
||||
@@ -169,52 +177,56 @@ impl HubReport {
|
||||
///
|
||||
/// [`A::hub(global)`]: HalApi::hub
|
||||
pub struct Hub<A: HalApi> {
|
||||
pub adapters: Registry<Adapter<A>>,
|
||||
pub devices: Registry<Device<A>>,
|
||||
pub queues: Registry<Queue<A>>,
|
||||
pub pipeline_layouts: Registry<PipelineLayout<A>>,
|
||||
pub shader_modules: Registry<ShaderModule<A>>,
|
||||
pub bind_group_layouts: Registry<BindGroupLayout<A>>,
|
||||
pub bind_groups: Registry<BindGroup<A>>,
|
||||
pub command_buffers: Registry<CommandBuffer<A>>,
|
||||
pub render_bundles: Registry<RenderBundle<A>>,
|
||||
pub render_pipelines: Registry<RenderPipeline<A>>,
|
||||
pub compute_pipelines: Registry<ComputePipeline<A>>,
|
||||
pub query_sets: Registry<QuerySet<A>>,
|
||||
pub buffers: Registry<Buffer<A>>,
|
||||
pub staging_buffers: Registry<StagingBuffer<A>>,
|
||||
pub textures: Registry<Texture<A>>,
|
||||
pub texture_views: Registry<TextureView<A>>,
|
||||
pub samplers: Registry<Sampler<A>>,
|
||||
pub adapters: Registry<id::AdapterId, Adapter<A>>,
|
||||
pub devices: Registry<id::DeviceId, Device<A>>,
|
||||
pub queues: Registry<id::QueueId, Queue<A>>,
|
||||
pub pipeline_layouts: Registry<id::PipelineLayoutId, PipelineLayout<A>>,
|
||||
pub shader_modules: Registry<id::ShaderModuleId, ShaderModule<A>>,
|
||||
pub bind_group_layouts: Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
pub bind_groups: Registry<id::BindGroupId, BindGroup<A>>,
|
||||
pub command_buffers: Registry<id::CommandBufferId, CommandBuffer<A>>,
|
||||
pub render_bundles: Registry<id::RenderBundleId, RenderBundle<A>>,
|
||||
pub render_pipelines: Registry<id::RenderPipelineId, RenderPipeline<A>>,
|
||||
pub compute_pipelines: Registry<id::ComputePipelineId, ComputePipeline<A>>,
|
||||
pub query_sets: Registry<id::QuerySetId, QuerySet<A>>,
|
||||
pub buffers: Registry<id::BufferId, Buffer<A>>,
|
||||
pub staging_buffers: Registry<id::StagingBufferId, StagingBuffer<A>>,
|
||||
pub textures: Registry<id::TextureId, Texture<A>>,
|
||||
pub texture_views: Registry<id::TextureViewId, TextureView<A>>,
|
||||
pub samplers: Registry<id::SamplerId, Sampler<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Hub<A> {
|
||||
fn new() -> Self {
|
||||
fn new<F: GlobalIdentityHandlerFactory>(factory: &F) -> Self {
|
||||
Self {
|
||||
adapters: Registry::new(A::VARIANT),
|
||||
devices: Registry::new(A::VARIANT),
|
||||
queues: Registry::new(A::VARIANT),
|
||||
pipeline_layouts: Registry::new(A::VARIANT),
|
||||
shader_modules: Registry::new(A::VARIANT),
|
||||
bind_group_layouts: Registry::new(A::VARIANT),
|
||||
bind_groups: Registry::new(A::VARIANT),
|
||||
command_buffers: Registry::new(A::VARIANT),
|
||||
render_bundles: Registry::new(A::VARIANT),
|
||||
render_pipelines: Registry::new(A::VARIANT),
|
||||
compute_pipelines: Registry::new(A::VARIANT),
|
||||
query_sets: Registry::new(A::VARIANT),
|
||||
buffers: Registry::new(A::VARIANT),
|
||||
staging_buffers: Registry::new(A::VARIANT),
|
||||
textures: Registry::new(A::VARIANT),
|
||||
texture_views: Registry::new(A::VARIANT),
|
||||
samplers: Registry::new(A::VARIANT),
|
||||
adapters: Registry::new(A::VARIANT, factory),
|
||||
devices: Registry::new(A::VARIANT, factory),
|
||||
queues: Registry::new(A::VARIANT, factory),
|
||||
pipeline_layouts: Registry::new(A::VARIANT, factory),
|
||||
shader_modules: Registry::new(A::VARIANT, factory),
|
||||
bind_group_layouts: Registry::new(A::VARIANT, factory),
|
||||
bind_groups: Registry::new(A::VARIANT, factory),
|
||||
command_buffers: Registry::new(A::VARIANT, factory),
|
||||
render_bundles: Registry::new(A::VARIANT, factory),
|
||||
render_pipelines: Registry::new(A::VARIANT, factory),
|
||||
compute_pipelines: Registry::new(A::VARIANT, factory),
|
||||
query_sets: Registry::new(A::VARIANT, factory),
|
||||
buffers: Registry::new(A::VARIANT, factory),
|
||||
staging_buffers: Registry::new(A::VARIANT, factory),
|
||||
textures: Registry::new(A::VARIANT, factory),
|
||||
texture_views: Registry::new(A::VARIANT, factory),
|
||||
samplers: Registry::new(A::VARIANT, factory),
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: instead of having a hacky `with_adapters` parameter,
|
||||
// we should have `clear_device(device_id)` that specifically destroys
|
||||
// everything related to a logical device.
|
||||
pub(crate) fn clear(&self, surface_guard: &Storage<Surface>, with_adapters: bool) {
|
||||
pub(crate) fn clear(
|
||||
&self,
|
||||
surface_guard: &Storage<Surface, id::SurfaceId>,
|
||||
with_adapters: bool,
|
||||
) {
|
||||
use hal::Surface;
|
||||
|
||||
let mut devices = self.devices.write();
|
||||
@@ -303,18 +315,18 @@ pub struct Hubs {
|
||||
}
|
||||
|
||||
impl Hubs {
|
||||
pub(crate) fn new() -> Self {
|
||||
pub(crate) fn new<F: GlobalIdentityHandlerFactory>(factory: &F) -> Self {
|
||||
Self {
|
||||
#[cfg(vulkan)]
|
||||
vulkan: Hub::new(),
|
||||
vulkan: Hub::new(factory),
|
||||
#[cfg(metal)]
|
||||
metal: Hub::new(),
|
||||
metal: Hub::new(factory),
|
||||
#[cfg(dx12)]
|
||||
dx12: Hub::new(),
|
||||
dx12: Hub::new(factory),
|
||||
#[cfg(gles)]
|
||||
gl: Hub::new(),
|
||||
gl: Hub::new(factory),
|
||||
#[cfg(all(not(vulkan), not(metal), not(dx12), not(gles)))]
|
||||
empty: Hub::new(),
|
||||
empty: Hub::new(factory),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
295
third_party/rust/wgpu-core/src/id.rs
vendored
295
third_party/rust/wgpu-core/src/id.rs
vendored
@@ -1,5 +1,6 @@
|
||||
use crate::{Epoch, Index};
|
||||
use std::{
|
||||
any::Any,
|
||||
cmp::Ordering,
|
||||
fmt::{self, Debug},
|
||||
hash::Hash,
|
||||
@@ -8,80 +9,15 @@ use std::{
|
||||
use wgt::{Backend, WasmNotSendSync};
|
||||
|
||||
type IdType = u64;
|
||||
type ZippedIndex = Index;
|
||||
type NonZeroId = std::num::NonZeroU64;
|
||||
type ZippedIndex = Index;
|
||||
|
||||
const INDEX_BITS: usize = std::mem::size_of::<ZippedIndex>() * 8;
|
||||
const EPOCH_BITS: usize = INDEX_BITS - BACKEND_BITS;
|
||||
const BACKEND_BITS: usize = 3;
|
||||
const BACKEND_SHIFT: usize = INDEX_BITS * 2 - BACKEND_BITS;
|
||||
pub const EPOCH_MASK: u32 = (1 << (EPOCH_BITS)) - 1;
|
||||
|
||||
/// The raw underlying representation of an identifier.
|
||||
#[repr(transparent)]
|
||||
#[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))]
|
||||
#[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", serde(into = "SerialId"))]
|
||||
#[cfg_attr(feature = "replay", serde(from = "SerialId"))]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct RawId(NonZeroId);
|
||||
|
||||
impl RawId {
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn from_non_zero(non_zero: NonZeroId) -> Self {
|
||||
Self(non_zero)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn into_non_zero(self) -> NonZeroId {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Zip together an identifier and return its raw underlying representation.
|
||||
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> RawId {
|
||||
assert_eq!(0, epoch >> EPOCH_BITS);
|
||||
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
||||
let v = index as IdType
|
||||
| ((epoch as IdType) << INDEX_BITS)
|
||||
| ((backend as IdType) << BACKEND_SHIFT);
|
||||
Self(NonZeroId::new(v).unwrap())
|
||||
}
|
||||
|
||||
/// Unzip a raw identifier into its components.
|
||||
#[allow(trivial_numeric_casts)]
|
||||
pub fn unzip(self) -> (Index, Epoch, Backend) {
|
||||
(
|
||||
(self.0.get() as ZippedIndex) as Index,
|
||||
(((self.0.get() >> INDEX_BITS) as ZippedIndex) & (EPOCH_MASK as ZippedIndex)) as Index,
|
||||
self.backend(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn backend(self) -> Backend {
|
||||
match self.0.get() >> (BACKEND_SHIFT) as u8 {
|
||||
0 => Backend::Empty,
|
||||
1 => Backend::Vulkan,
|
||||
2 => Backend::Metal,
|
||||
3 => Backend::Dx12,
|
||||
4 => Backend::Gl,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Coerce a slice of identifiers into a slice of optional raw identifiers.
|
||||
///
|
||||
/// There's two reasons why we know this is correct:
|
||||
/// * `Option<T>` is guarnateed to be niche-filled to 0's.
|
||||
/// * The `T` in `Option<T>` can inhabit any representation except 0's, since
|
||||
/// its underlying representation is `NonZero*`.
|
||||
pub fn as_option_slice<T: Marker>(ids: &[Id<T>]) -> &[Option<Id<T>>] {
|
||||
// SAFETY: Any Id<T> is repr(transparent) over `Option<RawId>`, since both
|
||||
// are backed by non-zero types.
|
||||
unsafe { std::slice::from_raw_parts(ids.as_ptr().cast(), ids.len()) }
|
||||
}
|
||||
type Dummy = hal::api::Empty;
|
||||
|
||||
/// An identifier for a wgpu object.
|
||||
///
|
||||
@@ -113,55 +49,63 @@ pub fn as_option_slice<T: Marker>(ids: &[Id<T>]) -> &[Option<Id<T>>] {
|
||||
/// [`Registry`]: crate::hub::Registry
|
||||
/// [`Empty`]: hal::api::Empty
|
||||
#[repr(transparent)]
|
||||
#[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))]
|
||||
#[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize), serde(into = "SerialId"))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serde", feature = "trace", feature = "replay"),
|
||||
serde(transparent)
|
||||
feature = "replay",
|
||||
derive(serde::Deserialize),
|
||||
serde(from = "SerialId")
|
||||
)]
|
||||
pub struct Id<T: Marker>(RawId, PhantomData<T>);
|
||||
#[cfg_attr(
|
||||
all(feature = "serde", not(feature = "trace")),
|
||||
derive(serde::Serialize)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
all(feature = "serde", not(feature = "replay")),
|
||||
derive(serde::Deserialize)
|
||||
)]
|
||||
pub struct Id<T: 'static + WasmNotSendSync>(NonZeroId, PhantomData<T>);
|
||||
|
||||
// This type represents Id in a more readable (and editable) way.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
enum SerialId {
|
||||
// The only variant forces RON to not ignore "Id"
|
||||
Id(Index, Epoch, Backend),
|
||||
}
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
impl From<RawId> for SerialId {
|
||||
fn from(id: RawId) -> Self {
|
||||
impl<T> From<Id<T>> for SerialId
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn from(id: Id<T>) -> Self {
|
||||
let (index, epoch, backend) = id.unzip();
|
||||
Self::Id(index, epoch, backend)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
impl From<SerialId> for RawId {
|
||||
impl<T> From<SerialId> for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn from(id: SerialId) -> Self {
|
||||
match id {
|
||||
SerialId::Id(index, epoch, backend) => RawId::zip(index, epoch, backend),
|
||||
SerialId::Id(index, epoch, backend) => TypedId::zip(index, epoch, backend),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
/// # Safety
|
||||
///
|
||||
/// The raw id must be valid for the type.
|
||||
pub unsafe fn from_raw(raw: RawId) -> Self {
|
||||
pub unsafe fn from_raw(raw: NonZeroId) -> Self {
|
||||
Self(raw, PhantomData)
|
||||
}
|
||||
|
||||
/// Coerce the identifiers into its raw underlying representation.
|
||||
pub fn into_raw(self) -> RawId {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn dummy(index: u32) -> Self {
|
||||
Id::zip(index, 1, Backend::Empty)
|
||||
@@ -172,53 +116,24 @@ where
|
||||
self.backend() != Backend::Empty
|
||||
}
|
||||
|
||||
/// Get the backend this identifier corresponds to.
|
||||
#[inline]
|
||||
pub fn backend(self) -> Backend {
|
||||
self.0.backend()
|
||||
}
|
||||
|
||||
/// Transmute this identifier to one with a different marker trait.
|
||||
///
|
||||
/// Legal use is governed through a sealed trait, however it's correctness
|
||||
/// depends on the current implementation of `wgpu-core`.
|
||||
#[inline]
|
||||
pub const fn transmute<U: self::transmute::Transmute<T>>(self) -> Id<U> {
|
||||
Id(self.0, PhantomData)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
||||
Id(RawId::zip(index, epoch, backend), PhantomData)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn unzip(self) -> (Index, Epoch, Backend) {
|
||||
self.0.unzip()
|
||||
match self.0.get() >> (BACKEND_SHIFT) as u8 {
|
||||
0 => Backend::Empty,
|
||||
1 => Backend::Vulkan,
|
||||
2 => Backend::Metal,
|
||||
3 => Backend::Dx12,
|
||||
4 => Backend::Gl,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod transmute {
|
||||
// This trait is effectively sealed to prevent illegal transmutes.
|
||||
pub trait Transmute<U>: super::Marker {}
|
||||
|
||||
// Self-transmute is always legal.
|
||||
impl<T> Transmute<T> for T where T: super::Marker {}
|
||||
|
||||
// TODO: Remove these once queues have their own identifiers.
|
||||
impl Transmute<super::markers::Queue> for super::markers::Device {}
|
||||
impl Transmute<super::markers::Device> for super::markers::Queue {}
|
||||
impl Transmute<super::markers::CommandBuffer> for super::markers::CommandEncoder {}
|
||||
impl Transmute<super::markers::CommandEncoder> for super::markers::CommandBuffer {}
|
||||
}
|
||||
|
||||
impl<T> Copy for Id<T> where T: Marker {}
|
||||
impl<T> Copy for Id<T> where T: 'static + WasmNotSendSync {}
|
||||
|
||||
impl<T> Clone for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
@@ -226,7 +141,7 @@ where
|
||||
|
||||
impl<T> Debug for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let (index, epoch, backend) = self.unzip();
|
||||
@@ -245,9 +160,8 @@ where
|
||||
|
||||
impl<T> Hash for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
@@ -255,21 +169,19 @@ where
|
||||
|
||||
impl<T> PartialEq for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for Id<T> where T: Marker {}
|
||||
impl<T> Eq for Id<T> where T: 'static + WasmNotSendSync {}
|
||||
|
||||
impl<T> PartialOrd for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.0.partial_cmp(&other.0)
|
||||
}
|
||||
@@ -277,73 +189,78 @@ where
|
||||
|
||||
impl<T> Ord for Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0.cmp(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker trait used to determine which types uniquely identify a resource.
|
||||
/// Trait carrying methods for direct `Id` access.
|
||||
///
|
||||
/// For example, `Device<A>` will have the same type of identifier as
|
||||
/// `Device<B>` because `Device<T>` for any `T` defines the same maker type.
|
||||
pub trait Marker: 'static + WasmNotSendSync {}
|
||||
/// Most `wgpu-core` clients should not use this trait. Unusual clients that
|
||||
/// 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 + Debug + Any + 'static + WasmNotSendSync + Eq + Hash {
|
||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self;
|
||||
fn unzip(self) -> (Index, Epoch, Backend);
|
||||
fn into_raw(self) -> NonZeroId;
|
||||
}
|
||||
|
||||
// This allows `()` to be used as a marker type for tests.
|
||||
//
|
||||
// We don't want these in production code, since they essentially remove type
|
||||
// safety, like how identifiers across different types can be compared.
|
||||
#[cfg(test)]
|
||||
impl Marker for () {}
|
||||
#[allow(trivial_numeric_casts)]
|
||||
impl<T> TypedId for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
||||
assert_eq!(0, epoch >> EPOCH_BITS);
|
||||
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
||||
let v = index as IdType
|
||||
| ((epoch as IdType) << INDEX_BITS)
|
||||
| ((backend as IdType) << BACKEND_SHIFT);
|
||||
Id(NonZeroId::new(v).unwrap(), PhantomData)
|
||||
}
|
||||
|
||||
/// Define identifiers for each resource.
|
||||
macro_rules! ids {
|
||||
($(
|
||||
$(#[$($meta:meta)*])*
|
||||
pub type $name:ident $marker:ident;
|
||||
)*) => {
|
||||
/// Marker types for each resource.
|
||||
pub mod markers {
|
||||
$(
|
||||
#[derive(Debug)]
|
||||
pub enum $marker {}
|
||||
impl super::Marker for $marker {}
|
||||
)*
|
||||
}
|
||||
fn unzip(self) -> (Index, Epoch, Backend) {
|
||||
(
|
||||
(self.0.get() as ZippedIndex) as Index,
|
||||
(((self.0.get() >> INDEX_BITS) as ZippedIndex) & (EPOCH_MASK as ZippedIndex)) as Index,
|
||||
self.backend(),
|
||||
)
|
||||
}
|
||||
|
||||
$(
|
||||
$(#[$($meta)*])*
|
||||
pub type $name = Id<self::markers::$marker>;
|
||||
)*
|
||||
fn into_raw(self) -> NonZeroId {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
ids! {
|
||||
pub type AdapterId Adapter;
|
||||
pub type SurfaceId Surface;
|
||||
pub type DeviceId Device;
|
||||
pub type QueueId Queue;
|
||||
pub type BufferId Buffer;
|
||||
pub type StagingBufferId StagingBuffer;
|
||||
pub type TextureViewId TextureView;
|
||||
pub type TextureId Texture;
|
||||
pub type SamplerId Sampler;
|
||||
pub type BindGroupLayoutId BindGroupLayout;
|
||||
pub type PipelineLayoutId PipelineLayout;
|
||||
pub type BindGroupId BindGroup;
|
||||
pub type ShaderModuleId ShaderModule;
|
||||
pub type RenderPipelineId RenderPipeline;
|
||||
pub type ComputePipelineId ComputePipeline;
|
||||
pub type CommandEncoderId CommandEncoder;
|
||||
pub type CommandBufferId CommandBuffer;
|
||||
pub type RenderPassEncoderId RenderPassEncoder;
|
||||
pub type ComputePassEncoderId ComputePassEncoder;
|
||||
pub type RenderBundleEncoderId RenderBundleEncoder;
|
||||
pub type RenderBundleId RenderBundle;
|
||||
pub type QuerySetId QuerySet;
|
||||
}
|
||||
pub type AdapterId = Id<crate::instance::Adapter<Dummy>>;
|
||||
pub type SurfaceId = Id<crate::instance::Surface>;
|
||||
// Device
|
||||
pub type DeviceId = Id<crate::device::Device<Dummy>>;
|
||||
pub type QueueId = DeviceId;
|
||||
// Resource
|
||||
pub type BufferId = Id<crate::resource::Buffer<Dummy>>;
|
||||
pub type StagingBufferId = Id<crate::resource::StagingBuffer<Dummy>>;
|
||||
pub type TextureViewId = Id<crate::resource::TextureView<Dummy>>;
|
||||
pub type TextureId = Id<crate::resource::Texture<Dummy>>;
|
||||
pub type SamplerId = Id<crate::resource::Sampler<Dummy>>;
|
||||
// Binding model
|
||||
pub type BindGroupLayoutId = Id<crate::binding_model::BindGroupLayout<Dummy>>;
|
||||
pub type PipelineLayoutId = Id<crate::binding_model::PipelineLayout<Dummy>>;
|
||||
pub type BindGroupId = Id<crate::binding_model::BindGroup<Dummy>>;
|
||||
// Pipeline
|
||||
pub type ShaderModuleId = Id<crate::pipeline::ShaderModule<Dummy>>;
|
||||
pub type RenderPipelineId = Id<crate::pipeline::RenderPipeline<Dummy>>;
|
||||
pub type ComputePipelineId = Id<crate::pipeline::ComputePipeline<Dummy>>;
|
||||
// Command
|
||||
pub type CommandEncoderId = CommandBufferId;
|
||||
pub type CommandBufferId = Id<crate::command::CommandBuffer<Dummy>>;
|
||||
pub type RenderPassEncoderId = *mut crate::command::RenderPass;
|
||||
pub type ComputePassEncoderId = *mut crate::command::ComputePass;
|
||||
pub type RenderBundleEncoderId = *mut crate::command::RenderBundleEncoder;
|
||||
pub type RenderBundleId = Id<crate::command::RenderBundle<Dummy>>;
|
||||
pub type QuerySetId = Id<crate::resource::QuerySet<Dummy>>;
|
||||
|
||||
#[test]
|
||||
fn test_id_backend() {
|
||||
@@ -354,7 +271,7 @@ fn test_id_backend() {
|
||||
Backend::Dx12,
|
||||
Backend::Gl,
|
||||
] {
|
||||
let id = crate::id::Id::<()>::zip(1, 0, b);
|
||||
let id: Id<()> = Id::zip(1, 0, b);
|
||||
let (_id, _epoch, backend) = id.unzip();
|
||||
assert_eq!(id.backend(), b);
|
||||
assert_eq!(backend, b);
|
||||
@@ -376,7 +293,7 @@ fn test_id() {
|
||||
for &i in &indexes {
|
||||
for &e in &epochs {
|
||||
for &b in &backends {
|
||||
let id = crate::id::Id::<()>::zip(i, e, b);
|
||||
let id: Id<()> = Id::zip(i, e, b);
|
||||
let (index, epoch, backend) = id.unzip();
|
||||
assert_eq!(index, i);
|
||||
assert_eq!(epoch, e);
|
||||
|
||||
97
third_party/rust/wgpu-core/src/identity.rs
vendored
97
third_party/rust/wgpu-core/src/identity.rs
vendored
@@ -2,10 +2,10 @@ use parking_lot::Mutex;
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
id::{Id, Marker},
|
||||
id::{self},
|
||||
Epoch, FastHashMap, Index,
|
||||
};
|
||||
use std::{fmt::Debug, marker::PhantomData};
|
||||
use std::{fmt::Debug, marker::PhantomData, sync::Arc};
|
||||
|
||||
/// A simple structure to allocate [`Id`] identifiers.
|
||||
///
|
||||
@@ -47,10 +47,10 @@ impl IdentityValues {
|
||||
///
|
||||
/// The backend is incorporated into the id, so that ids allocated with
|
||||
/// different `backend` values are always distinct.
|
||||
pub fn alloc<T: Marker>(&mut self, backend: Backend) -> Id<T> {
|
||||
pub fn alloc<I: id::TypedId>(&mut self, backend: Backend) -> I {
|
||||
self.count += 1;
|
||||
match self.free.pop() {
|
||||
Some((index, epoch)) => Id::zip(index, epoch + 1, backend),
|
||||
Some((index, epoch)) => I::zip(index, epoch + 1, backend),
|
||||
None => {
|
||||
let epoch = 1;
|
||||
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
||||
@@ -60,12 +60,12 @@ impl IdentityValues {
|
||||
0
|
||||
};
|
||||
used.push(index);
|
||||
Id::zip(index, epoch, backend)
|
||||
I::zip(index, epoch, backend)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mark_as_used<T: Marker>(&mut self, id: Id<T>) -> Id<T> {
|
||||
pub fn mark_as_used<I: id::TypedId>(&mut self, id: I) -> I {
|
||||
self.count += 1;
|
||||
let (index, epoch, _backend) = id.unzip();
|
||||
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
||||
@@ -74,7 +74,7 @@ impl IdentityValues {
|
||||
}
|
||||
|
||||
/// Free `id`. It will never be returned from `alloc` again.
|
||||
pub fn release<T: Marker>(&mut self, id: Id<T>) {
|
||||
pub fn release<I: id::TypedId>(&mut self, id: I) {
|
||||
let (index, epoch, _backend) = id.unzip();
|
||||
self.free.push((index, epoch));
|
||||
self.count -= 1;
|
||||
@@ -86,24 +86,24 @@ impl IdentityValues {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IdentityManager<T: Marker> {
|
||||
pub struct IdentityManager<I: id::TypedId> {
|
||||
pub(super) values: Mutex<IdentityValues>,
|
||||
_phantom: PhantomData<T>,
|
||||
_phantom: PhantomData<I>,
|
||||
}
|
||||
|
||||
impl<T: Marker> IdentityManager<T> {
|
||||
pub fn process(&self, backend: Backend) -> Id<T> {
|
||||
impl<I: id::TypedId> IdentityManager<I> {
|
||||
pub fn process(&self, backend: Backend) -> I {
|
||||
self.values.lock().alloc(backend)
|
||||
}
|
||||
pub fn mark_as_used(&self, id: Id<T>) -> Id<T> {
|
||||
pub fn mark_as_used(&self, id: I) -> I {
|
||||
self.values.lock().mark_as_used(id)
|
||||
}
|
||||
pub fn free(&self, id: Id<T>) {
|
||||
pub fn free(&self, id: I) {
|
||||
self.values.lock().release(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Marker> IdentityManager<T> {
|
||||
impl<I: id::TypedId> IdentityManager<I> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
values: Mutex::new(IdentityValues::default()),
|
||||
@@ -112,11 +112,74 @@ impl<T: Marker> IdentityManager<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type that can produce [`IdentityManager`] filters for ids of type `I`.
|
||||
///
|
||||
/// See the module-level documentation for details.
|
||||
pub trait IdentityHandlerFactory<I: id::TypedId> {
|
||||
type Input: Copy;
|
||||
/// Create an [`IdentityManager<I>`] implementation that can
|
||||
/// transform proto-ids into ids of type `I`.
|
||||
/// It can return None if ids are passed from outside
|
||||
/// and are not generated by wgpu
|
||||
///
|
||||
/// [`IdentityManager<I>`]: IdentityManager
|
||||
fn spawn(&self) -> Arc<IdentityManager<I>> {
|
||||
Arc::new(IdentityManager::new())
|
||||
}
|
||||
fn autogenerate_ids() -> bool;
|
||||
fn input_to_id(id_in: Self::Input) -> I;
|
||||
}
|
||||
|
||||
/// A global identity handler factory based on [`IdentityManager`].
|
||||
///
|
||||
/// Each of this type's `IdentityHandlerFactory<I>::spawn` methods
|
||||
/// returns a `Mutex<IdentityManager<I>>`, which allocates fresh `I`
|
||||
/// ids itself, and takes `()` as its proto-id type.
|
||||
#[derive(Debug)]
|
||||
pub struct IdentityManagerFactory;
|
||||
|
||||
impl<I: id::TypedId> IdentityHandlerFactory<I> for IdentityManagerFactory {
|
||||
type Input = ();
|
||||
fn autogenerate_ids() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn input_to_id(_id_in: Self::Input) -> I {
|
||||
unreachable!("It should not be called")
|
||||
}
|
||||
}
|
||||
|
||||
/// A factory that can build [`IdentityManager`]s for all resource
|
||||
/// types.
|
||||
pub trait GlobalIdentityHandlerFactory:
|
||||
IdentityHandlerFactory<id::AdapterId>
|
||||
+ IdentityHandlerFactory<id::DeviceId>
|
||||
+ IdentityHandlerFactory<id::PipelineLayoutId>
|
||||
+ IdentityHandlerFactory<id::ShaderModuleId>
|
||||
+ IdentityHandlerFactory<id::BindGroupLayoutId>
|
||||
+ IdentityHandlerFactory<id::BindGroupId>
|
||||
+ IdentityHandlerFactory<id::CommandBufferId>
|
||||
+ IdentityHandlerFactory<id::RenderBundleId>
|
||||
+ IdentityHandlerFactory<id::RenderPipelineId>
|
||||
+ IdentityHandlerFactory<id::ComputePipelineId>
|
||||
+ IdentityHandlerFactory<id::QuerySetId>
|
||||
+ IdentityHandlerFactory<id::BufferId>
|
||||
+ IdentityHandlerFactory<id::StagingBufferId>
|
||||
+ IdentityHandlerFactory<id::TextureId>
|
||||
+ IdentityHandlerFactory<id::TextureViewId>
|
||||
+ IdentityHandlerFactory<id::SamplerId>
|
||||
+ IdentityHandlerFactory<id::SurfaceId>
|
||||
{
|
||||
}
|
||||
|
||||
impl GlobalIdentityHandlerFactory for IdentityManagerFactory {}
|
||||
|
||||
pub type Input<G, I> = <G as IdentityHandlerFactory<I>>::Input;
|
||||
|
||||
#[test]
|
||||
fn test_epoch_end_of_life() {
|
||||
use crate::id;
|
||||
|
||||
let man = IdentityManager::<id::markers::Buffer>::new();
|
||||
use id::TypedId as _;
|
||||
let man = IdentityManager::<id::BufferId>::new();
|
||||
let forced_id = man.mark_as_used(id::BufferId::zip(0, 1, Backend::Empty));
|
||||
assert_eq!(forced_id.unzip().0, 0);
|
||||
let id1 = man.process(Backend::Empty);
|
||||
|
||||
158
third_party/rust/wgpu-core/src/instance.rs
vendored
158
third_party/rust/wgpu-core/src/instance.rs
vendored
@@ -6,8 +6,8 @@ use crate::{
|
||||
device::{queue::Queue, resource::Device, DeviceDescriptor},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::markers,
|
||||
id::{AdapterId, DeviceId, Id, Marker, QueueId, SurfaceId},
|
||||
id::{AdapterId, DeviceId, QueueId, SurfaceId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
present::Presentation,
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log, LabelHelpers, DOWNLEVEL_WARNING_MESSAGE,
|
||||
@@ -149,20 +149,18 @@ impl Instance {
|
||||
|
||||
pub struct Surface {
|
||||
pub(crate) presentation: Mutex<Option<Presentation>>,
|
||||
pub(crate) info: ResourceInfo<Surface>,
|
||||
pub(crate) info: ResourceInfo<SurfaceId>,
|
||||
pub(crate) raw: AnySurface,
|
||||
}
|
||||
|
||||
impl Resource for Surface {
|
||||
impl Resource<SurfaceId> for Surface {
|
||||
const TYPE: ResourceType = "Surface";
|
||||
|
||||
type Marker = markers::Surface;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<SurfaceId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SurfaceId> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@@ -192,7 +190,7 @@ impl Surface {
|
||||
|
||||
pub struct Adapter<A: HalApi> {
|
||||
pub(crate) raw: hal::ExposedAdapter<A>,
|
||||
pub(crate) info: ResourceInfo<Adapter<A>>,
|
||||
pub(crate) info: ResourceInfo<AdapterId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Adapter<A> {
|
||||
@@ -384,16 +382,14 @@ impl<A: HalApi> Adapter<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Adapter<A> {
|
||||
impl<A: HalApi> Resource<AdapterId> for Adapter<A> {
|
||||
const TYPE: ResourceType = "Adapter";
|
||||
|
||||
type Marker = markers::Adapter;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<AdapterId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<AdapterId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -438,15 +434,15 @@ pub enum RequestDeviceError {
|
||||
UnsupportedFeature(wgt::Features),
|
||||
}
|
||||
|
||||
pub enum AdapterInputs<'a, M: Marker> {
|
||||
IdSet(&'a [Id<M>]),
|
||||
Mask(Backends, fn(Backend) -> Option<Id<M>>),
|
||||
pub enum AdapterInputs<'a, I> {
|
||||
IdSet(&'a [I], fn(&I) -> Backend),
|
||||
Mask(Backends, fn(Backend) -> I),
|
||||
}
|
||||
|
||||
impl<M: Marker> AdapterInputs<'_, M> {
|
||||
fn find(&self, b: Backend) -> Option<Option<Id<M>>> {
|
||||
impl<I: Copy> AdapterInputs<'_, I> {
|
||||
fn find(&self, b: Backend) -> Option<I> {
|
||||
match *self {
|
||||
Self::IdSet(ids) => Some(Some(ids.iter().find(|id| id.backend() == b).copied()?)),
|
||||
Self::IdSet(ids, ref fun) => ids.iter().find(|id| fun(id) == b).copied(),
|
||||
Self::Mask(bits, ref fun) => {
|
||||
if bits.contains(b.into()) {
|
||||
Some(fun(b))
|
||||
@@ -471,16 +467,7 @@ pub enum RequestAdapterError {
|
||||
InvalidSurface(SurfaceId),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum CreateSurfaceError {
|
||||
#[error("No backend is available")]
|
||||
NoSupportedBackend,
|
||||
#[error(transparent)]
|
||||
InstanceError(#[from] hal::InstanceError),
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
/// # Safety
|
||||
///
|
||||
/// - `display_handle` must be a valid object to create a surface upon.
|
||||
@@ -491,8 +478,8 @@ impl Global {
|
||||
&self,
|
||||
display_handle: raw_window_handle::RawDisplayHandle,
|
||||
window_handle: raw_window_handle::RawWindowHandle,
|
||||
id_in: Option<SurfaceId>,
|
||||
) -> Result<SurfaceId, CreateSurfaceError> {
|
||||
id_in: Input<G, SurfaceId>,
|
||||
) -> Result<SurfaceId, hal::InstanceError> {
|
||||
profiling::scope!("Instance::create_surface");
|
||||
|
||||
fn init<A: HalApi>(
|
||||
@@ -530,7 +517,8 @@ impl Global {
|
||||
hal_surface = init::<hal::api::Gles>(&self.instance.gl, display_handle, window_handle);
|
||||
}
|
||||
|
||||
let hal_surface = hal_surface.ok_or(CreateSurfaceError::NoSupportedBackend)??;
|
||||
// This is only None if there's no instance at all.
|
||||
let hal_surface = hal_surface.unwrap()?;
|
||||
|
||||
let surface = Surface {
|
||||
presentation: Mutex::new(None),
|
||||
@@ -538,7 +526,7 @@ impl Global {
|
||||
raw: hal_surface,
|
||||
};
|
||||
|
||||
let (id, _) = self.surfaces.prepare(id_in).assign(surface);
|
||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@@ -549,7 +537,7 @@ impl Global {
|
||||
pub unsafe fn instance_create_surface_metal(
|
||||
&self,
|
||||
layer: *mut std::ffi::c_void,
|
||||
id_in: Option<SurfaceId>,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
) -> SurfaceId {
|
||||
profiling::scope!("Instance::create_surface_metal");
|
||||
|
||||
@@ -573,7 +561,7 @@ impl Global {
|
||||
},
|
||||
};
|
||||
|
||||
let (id, _) = self.surfaces.prepare(id_in).assign(surface);
|
||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
||||
id
|
||||
}
|
||||
|
||||
@@ -584,7 +572,7 @@ impl Global {
|
||||
pub unsafe fn instance_create_surface_from_visual(
|
||||
&self,
|
||||
visual: *mut std::ffi::c_void,
|
||||
id_in: Option<SurfaceId>,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
) -> SurfaceId {
|
||||
profiling::scope!("Instance::instance_create_surface_from_visual");
|
||||
|
||||
@@ -604,7 +592,7 @@ impl Global {
|
||||
},
|
||||
};
|
||||
|
||||
let (id, _) = self.surfaces.prepare(id_in).assign(surface);
|
||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
||||
id
|
||||
}
|
||||
|
||||
@@ -615,7 +603,7 @@ impl Global {
|
||||
pub unsafe fn instance_create_surface_from_surface_handle(
|
||||
&self,
|
||||
surface_handle: *mut std::ffi::c_void,
|
||||
id_in: Option<SurfaceId>,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
) -> SurfaceId {
|
||||
profiling::scope!("Instance::instance_create_surface_from_surface_handle");
|
||||
|
||||
@@ -637,7 +625,7 @@ impl Global {
|
||||
},
|
||||
};
|
||||
|
||||
let (id, _) = self.surfaces.prepare(id_in).assign(surface);
|
||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
||||
id
|
||||
}
|
||||
|
||||
@@ -648,7 +636,7 @@ impl Global {
|
||||
pub unsafe fn instance_create_surface_from_swap_chain_panel(
|
||||
&self,
|
||||
swap_chain_panel: *mut std::ffi::c_void,
|
||||
id_in: Option<SurfaceId>,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
) -> SurfaceId {
|
||||
profiling::scope!("Instance::instance_create_surface_from_swap_chain_panel");
|
||||
|
||||
@@ -670,7 +658,7 @@ impl Global {
|
||||
},
|
||||
};
|
||||
|
||||
let (id, _) = self.surfaces.prepare(id_in).assign(surface);
|
||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
||||
id
|
||||
}
|
||||
|
||||
@@ -679,7 +667,11 @@ impl Global {
|
||||
|
||||
api_log!("Surface::drop {id:?}");
|
||||
|
||||
fn unconfigure<A: HalApi>(global: &Global, surface: &AnySurface, present: &Presentation) {
|
||||
fn unconfigure<G: GlobalIdentityHandlerFactory, A: HalApi>(
|
||||
global: &Global<G>,
|
||||
surface: &AnySurface,
|
||||
present: &Presentation,
|
||||
) {
|
||||
let hub = HalApi::hub(global);
|
||||
if let Some(hal_surface) = surface.downcast_ref::<A>() {
|
||||
if let Some(device) = present.device.downcast_ref::<A>() {
|
||||
@@ -692,13 +684,13 @@ impl Global {
|
||||
if let Some(surface) = Arc::into_inner(surface.unwrap()) {
|
||||
if let Some(present) = surface.presentation.lock().take() {
|
||||
#[cfg(vulkan)]
|
||||
unconfigure::<hal::api::Vulkan>(self, &surface.raw, &present);
|
||||
unconfigure::<_, hal::api::Vulkan>(self, &surface.raw, &present);
|
||||
#[cfg(metal)]
|
||||
unconfigure::<hal::api::Metal>(self, &surface.raw, &present);
|
||||
unconfigure::<_, hal::api::Metal>(self, &surface.raw, &present);
|
||||
#[cfg(dx12)]
|
||||
unconfigure::<hal::api::Dx12>(self, &surface.raw, &present);
|
||||
unconfigure::<_, hal::api::Dx12>(self, &surface.raw, &present);
|
||||
#[cfg(gles)]
|
||||
unconfigure::<hal::api::Gles>(self, &surface.raw, &present);
|
||||
unconfigure::<_, hal::api::Gles>(self, &surface.raw, &present);
|
||||
}
|
||||
|
||||
self.instance.destroy_surface(surface);
|
||||
@@ -711,7 +703,7 @@ impl Global {
|
||||
&self,
|
||||
_: A,
|
||||
instance: &Option<A::Instance>,
|
||||
inputs: &AdapterInputs<markers::Adapter>,
|
||||
inputs: &AdapterInputs<Input<G, AdapterId>>,
|
||||
list: &mut Vec<AdapterId>,
|
||||
) {
|
||||
let inst = match *instance {
|
||||
@@ -730,12 +722,12 @@ impl Global {
|
||||
for raw in hal_adapters {
|
||||
let adapter = Adapter::new(raw);
|
||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||
let (id, _) = hub.adapters.prepare(id_backend).assign(adapter);
|
||||
let (id, _) = hub.adapters.prepare::<G>(id_backend).assign(adapter);
|
||||
list.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enumerate_adapters(&self, inputs: AdapterInputs<markers::Adapter>) -> Vec<AdapterId> {
|
||||
pub fn enumerate_adapters(&self, inputs: AdapterInputs<Input<G, AdapterId>>) -> Vec<AdapterId> {
|
||||
profiling::scope!("Instance::enumerate_adapters");
|
||||
api_log!("Instance::enumerate_adapters");
|
||||
|
||||
@@ -766,7 +758,7 @@ impl Global {
|
||||
fn select<A: HalApi>(
|
||||
&self,
|
||||
selected: &mut usize,
|
||||
new_id: Option<AdapterId>,
|
||||
new_id: Option<Input<G, AdapterId>>,
|
||||
mut list: Vec<hal::ExposedAdapter<A>>,
|
||||
) -> Option<AdapterId> {
|
||||
match selected.checked_sub(list.len()) {
|
||||
@@ -777,7 +769,10 @@ impl Global {
|
||||
None => {
|
||||
let adapter = Adapter::new(list.swap_remove(*selected));
|
||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||
let (id, _) = HalApi::hub(self).adapters.prepare(new_id).assign(adapter);
|
||||
let (id, _) = HalApi::hub(self)
|
||||
.adapters
|
||||
.prepare::<G>(new_id.unwrap())
|
||||
.assign(adapter);
|
||||
Some(id)
|
||||
}
|
||||
}
|
||||
@@ -786,22 +781,22 @@ impl Global {
|
||||
pub fn request_adapter(
|
||||
&self,
|
||||
desc: &RequestAdapterOptions,
|
||||
inputs: AdapterInputs<markers::Adapter>,
|
||||
inputs: AdapterInputs<Input<G, AdapterId>>,
|
||||
) -> Result<AdapterId, RequestAdapterError> {
|
||||
profiling::scope!("Instance::request_adapter");
|
||||
api_log!("Instance::request_adapter");
|
||||
|
||||
fn gather<A: HalApi>(
|
||||
fn gather<A: HalApi, I: Copy>(
|
||||
_: A,
|
||||
instance: Option<&A::Instance>,
|
||||
inputs: &AdapterInputs<markers::Adapter>,
|
||||
inputs: &AdapterInputs<I>,
|
||||
compatible_surface: Option<&Surface>,
|
||||
force_software: bool,
|
||||
device_types: &mut Vec<wgt::DeviceType>,
|
||||
) -> (Option<Id<markers::Adapter>>, Vec<hal::ExposedAdapter<A>>) {
|
||||
) -> (Option<I>, Vec<hal::ExposedAdapter<A>>) {
|
||||
let id = inputs.find(A::VARIANT);
|
||||
match (id, instance) {
|
||||
(Some(id), Some(inst)) => {
|
||||
match instance {
|
||||
Some(inst) if id.is_some() => {
|
||||
let mut adapters = unsafe { inst.enumerate_adapters() };
|
||||
if force_software {
|
||||
adapters.retain(|exposed| exposed.info.device_type == wgt::DeviceType::Cpu);
|
||||
@@ -821,7 +816,7 @@ impl Global {
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type));
|
||||
(id, adapters)
|
||||
}
|
||||
_ => (None, Vec::new()),
|
||||
_ => (id, Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,23 +947,24 @@ impl Global {
|
||||
pub unsafe fn create_adapter_from_hal<A: HalApi>(
|
||||
&self,
|
||||
hal_adapter: hal::ExposedAdapter<A>,
|
||||
input: Option<AdapterId>,
|
||||
input: Input<G, AdapterId>,
|
||||
) -> AdapterId {
|
||||
profiling::scope!("Instance::create_adapter_from_hal");
|
||||
|
||||
let fid = A::hub(self).adapters.prepare(input);
|
||||
let fid = A::hub(self).adapters.prepare::<G>(input);
|
||||
|
||||
let (id, _adapter): (_, Arc<Adapter<A>>) = match A::VARIANT {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (id, _adapter): (crate::id::Id<Adapter<hal::empty::Api>>, Arc<Adapter<A>>) =
|
||||
match A::VARIANT {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
resource_log!("Created Adapter {:?}", id);
|
||||
id
|
||||
}
|
||||
@@ -1063,21 +1059,21 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn adapter_request_device<A: HalApi>(
|
||||
&self,
|
||||
adapter_id: AdapterId,
|
||||
desc: &DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
device_id_in: Option<DeviceId>,
|
||||
queue_id_in: Option<QueueId>,
|
||||
device_id_in: Input<G, DeviceId>,
|
||||
queue_id_in: Input<G, QueueId>,
|
||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||
profiling::scope!("Adapter::request_device");
|
||||
api_log!("Adapter::request_device");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let device_fid = hub.devices.prepare(device_id_in);
|
||||
let queue_fid = hub.queues.prepare(queue_id_in);
|
||||
let device_fid = hub.devices.prepare::<G>(device_id_in);
|
||||
let queue_fid = hub.queues.prepare::<G>(queue_id_in);
|
||||
|
||||
let error = loop {
|
||||
let adapter = match hub.adapters.get(adapter_id) {
|
||||
@@ -1118,14 +1114,14 @@ impl Global {
|
||||
hal_device: OpenDevice<A>,
|
||||
desc: &DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
device_id_in: Option<DeviceId>,
|
||||
queue_id_in: Option<QueueId>,
|
||||
device_id_in: Input<G, DeviceId>,
|
||||
queue_id_in: Input<G, QueueId>,
|
||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||
profiling::scope!("Global::create_device_from_hal");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let devices_fid = hub.devices.prepare(device_id_in);
|
||||
let queues_fid = hub.queues.prepare(queue_id_in);
|
||||
let devices_fid = hub.devices.prepare::<G>(device_id_in);
|
||||
let queues_fid = hub.queues.prepare::<G>(queue_id_in);
|
||||
|
||||
let error = loop {
|
||||
let adapter = match hub.adapters.get(adapter_id) {
|
||||
|
||||
4
third_party/rust/wgpu-core/src/lib.rs
vendored
4
third_party/rust/wgpu-core/src/lib.rs
vendored
@@ -13,9 +13,9 @@
|
||||
//! [https://renderdoc.org/](https://renderdoc.org/)
|
||||
//! - **`strict_asserts`** --- Apply run-time checks, even in release builds. These are in addition
|
||||
//! to the validation carried out at public APIs in all builds.
|
||||
//! - **`serde`** --- Enables serialization via `serde` on common wgpu types.
|
||||
//! - **`trace`** --- Enable API tracing.
|
||||
//! - **`replay`** --- Enable API replaying
|
||||
//! - **`serial-pass`** --- Enable serializable compute/render passes, and bundle encoders.
|
||||
//! - **`wgsl`** --- Enable `ShaderModuleSource::Wgsl`
|
||||
//! - **`fragile-send-sync-non-atomic-wasm`** --- Implement `Send` and `Sync` on Wasm, but only if
|
||||
//! atomics are not enabled.
|
||||
@@ -289,7 +289,7 @@ define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all(
|
||||
/// where the `device_create_buffer` method is defined like this:
|
||||
///
|
||||
/// ```ignore
|
||||
/// impl Global {
|
||||
/// impl<...> Global<...> {
|
||||
/// pub fn device_create_buffer<A: HalApi>(&self, ...) -> ...
|
||||
/// { ... }
|
||||
/// }
|
||||
|
||||
89
third_party/rust/wgpu-core/src/pipeline.rs
vendored
89
third_party/rust/wgpu-core/src/pipeline.rs
vendored
@@ -5,7 +5,7 @@ use crate::{
|
||||
command::ColorAttachmentError,
|
||||
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
|
||||
hal_api::HalApi,
|
||||
id::{PipelineLayoutId, ShaderModuleId},
|
||||
id::{ComputePipelineId, PipelineLayoutId, RenderPipelineId, ShaderModuleId},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log, validation, Label,
|
||||
};
|
||||
@@ -26,10 +26,6 @@ pub(crate) struct LateSizedBufferGroup {
|
||||
pub enum ShaderModuleSource<'a> {
|
||||
#[cfg(feature = "wgsl")]
|
||||
Wgsl(Cow<'a, str>),
|
||||
#[cfg(feature = "glsl")]
|
||||
Glsl(Cow<'a, str>, naga::front::glsl::Options),
|
||||
#[cfg(feature = "spirv")]
|
||||
SpirV(Cow<'a, [u32]>, naga::front::spv::Options),
|
||||
Naga(Cow<'static, naga::Module>),
|
||||
/// Dummy variant because `Naga` doesn't have a lifetime and without enough active features it
|
||||
/// could be the last one active.
|
||||
@@ -38,7 +34,8 @@ pub enum ShaderModuleSource<'a> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ShaderModuleDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
@@ -50,7 +47,7 @@ pub struct ShaderModule<A: HalApi> {
|
||||
pub(crate) raw: Option<A::ShaderModule>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) interface: Option<validation::Interface>,
|
||||
pub(crate) info: ResourceInfo<ShaderModule<A>>,
|
||||
pub(crate) info: ResourceInfo<ShaderModuleId>,
|
||||
pub(crate) label: String,
|
||||
}
|
||||
|
||||
@@ -70,16 +67,14 @@ impl<A: HalApi> Drop for ShaderModule<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for ShaderModule<A> {
|
||||
impl<A: HalApi> Resource<ShaderModuleId> for ShaderModule<A> {
|
||||
const TYPE: ResourceType = "ShaderModule";
|
||||
|
||||
type Marker = crate::id::markers::ShaderModule;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<ShaderModuleId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ShaderModuleId> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@@ -108,22 +103,6 @@ impl fmt::Display for ShaderError<naga::front::wgsl::ParseError> {
|
||||
write!(f, "\nShader '{label}' parsing {string}")
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "glsl")]
|
||||
impl fmt::Display for ShaderError<naga::front::glsl::ParseError> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let label = self.label.as_deref().unwrap_or_default();
|
||||
let string = self.inner.emit_to_string(&self.source);
|
||||
write!(f, "\nShader '{label}' parsing {string}")
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "spirv")]
|
||||
impl fmt::Display for ShaderError<naga::front::spv::Error> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let label = self.label.as_deref().unwrap_or_default();
|
||||
let string = self.inner.emit_to_string(&self.source);
|
||||
write!(f, "\nShader '{label}' parsing {string}")
|
||||
}
|
||||
}
|
||||
impl fmt::Display for ShaderError<naga::WithSpan<naga::valid::ValidationError>> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use codespan_reporting::{
|
||||
@@ -172,12 +151,6 @@ pub enum CreateShaderModuleError {
|
||||
#[cfg(feature = "wgsl")]
|
||||
#[error(transparent)]
|
||||
Parsing(#[from] ShaderError<naga::front::wgsl::ParseError>),
|
||||
#[cfg(feature = "glsl")]
|
||||
#[error(transparent)]
|
||||
ParsingGlsl(#[from] ShaderError<naga::front::glsl::ParseError>),
|
||||
#[cfg(feature = "spirv")]
|
||||
#[error(transparent)]
|
||||
ParsingSpirV(#[from] ShaderError<naga::front::spv::Error>),
|
||||
#[error("Failed to generate the backend-specific code")]
|
||||
Generation,
|
||||
#[error(transparent)]
|
||||
@@ -209,7 +182,8 @@ impl CreateShaderModuleError {
|
||||
|
||||
/// Describes a programmable pipeline stage.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ProgrammableStageDescriptor<'a> {
|
||||
/// The compiled shader module for this stage.
|
||||
pub module: ShaderModuleId,
|
||||
@@ -236,7 +210,8 @@ pub enum ImplicitLayoutError {
|
||||
|
||||
/// Describes a compute pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ComputePipelineDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
/// The layout of bind groups for this pipeline.
|
||||
@@ -269,7 +244,7 @@ pub struct ComputePipeline<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) _shader_module: Arc<ShaderModule<A>>,
|
||||
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
||||
pub(crate) info: ResourceInfo<ComputePipeline<A>>,
|
||||
pub(crate) info: ResourceInfo<ComputePipelineId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for ComputePipeline<A> {
|
||||
@@ -290,16 +265,14 @@ impl<A: HalApi> Drop for ComputePipeline<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for ComputePipeline<A> {
|
||||
impl<A: HalApi> Resource<ComputePipelineId> for ComputePipeline<A> {
|
||||
const TYPE: ResourceType = "ComputePipeline";
|
||||
|
||||
type Marker = crate::id::markers::ComputePipeline;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<ComputePipelineId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ComputePipelineId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -312,7 +285,8 @@ impl<A: HalApi> ComputePipeline<A> {
|
||||
|
||||
/// Describes how the vertex buffer is interpreted.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct VertexBufferLayout<'a> {
|
||||
/// The stride, in bytes, between elements of this buffer.
|
||||
@@ -325,7 +299,8 @@ pub struct VertexBufferLayout<'a> {
|
||||
|
||||
/// Describes the vertex process in a render pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct VertexState<'a> {
|
||||
/// The compiled vertex stage and its entry point.
|
||||
pub stage: ProgrammableStageDescriptor<'a>,
|
||||
@@ -335,7 +310,8 @@ pub struct VertexState<'a> {
|
||||
|
||||
/// Describes fragment processing in a render pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct FragmentState<'a> {
|
||||
/// The compiled fragment stage and its entry point.
|
||||
pub stage: ProgrammableStageDescriptor<'a>,
|
||||
@@ -345,7 +321,8 @@ pub struct FragmentState<'a> {
|
||||
|
||||
/// Describes a render (graphics) pipeline.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct RenderPipelineDescriptor<'a> {
|
||||
pub label: Label<'a>,
|
||||
/// The layout of bind groups for this pipeline.
|
||||
@@ -353,13 +330,13 @@ pub struct RenderPipelineDescriptor<'a> {
|
||||
/// The vertex processing state for this pipeline.
|
||||
pub vertex: VertexState<'a>,
|
||||
/// The properties of the pipeline at the primitive assembly and rasterization level.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "replay", feature = "trace"), serde(default))]
|
||||
pub primitive: wgt::PrimitiveState,
|
||||
/// The effect of draw calls on the depth and stencil aspects of the output target, if any.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "replay", feature = "trace"), serde(default))]
|
||||
pub depth_stencil: Option<wgt::DepthStencilState>,
|
||||
/// The multi-sampling properties of the pipeline.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "replay", feature = "trace"), serde(default))]
|
||||
pub multisample: wgt::MultisampleState,
|
||||
/// The fragment processing state for this pipeline.
|
||||
pub fragment: Option<FragmentState<'a>>,
|
||||
@@ -490,9 +467,6 @@ pub struct VertexStep {
|
||||
/// The byte stride in the buffer between one attribute value and the next.
|
||||
pub stride: wgt::BufferAddress,
|
||||
|
||||
/// The byte size required to fit the last vertex in the stream.
|
||||
pub last_stride: wgt::BufferAddress,
|
||||
|
||||
/// Whether the buffer is indexed by vertex number or instance number.
|
||||
pub mode: wgt::VertexStepMode,
|
||||
}
|
||||
@@ -501,7 +475,6 @@ impl Default for VertexStep {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
stride: 0,
|
||||
last_stride: 0,
|
||||
mode: wgt::VertexStepMode::Vertex,
|
||||
}
|
||||
}
|
||||
@@ -519,7 +492,7 @@ pub struct RenderPipeline<A: HalApi> {
|
||||
pub(crate) strip_index_format: Option<wgt::IndexFormat>,
|
||||
pub(crate) vertex_steps: Vec<VertexStep>,
|
||||
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
||||
pub(crate) info: ResourceInfo<RenderPipeline<A>>,
|
||||
pub(crate) info: ResourceInfo<RenderPipelineId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for RenderPipeline<A> {
|
||||
@@ -540,16 +513,14 @@ impl<A: HalApi> Drop for RenderPipeline<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for RenderPipeline<A> {
|
||||
impl<A: HalApi> Resource<RenderPipelineId> for RenderPipeline<A> {
|
||||
const TYPE: ResourceType = "RenderPipeline";
|
||||
|
||||
type Marker = crate::id::markers::RenderPipeline;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<RenderPipelineId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderPipelineId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
24
third_party/rust/wgpu-core/src/present.rs
vendored
24
third_party/rust/wgpu-core/src/present.rs
vendored
@@ -22,7 +22,9 @@ use crate::{
|
||||
device::{DeviceError, MissingDownlevelFlags, WaitIdleError},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
hal_label, id,
|
||||
hal_label,
|
||||
id::{SurfaceId, TextureId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::TextureInitTracker,
|
||||
resource::{self, ResourceInfo},
|
||||
snatch::Snatchable,
|
||||
@@ -30,7 +32,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use hal::{Queue as _, Surface as _};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use parking_lot::RwLock;
|
||||
use thiserror::Error;
|
||||
use wgt::SurfaceStatus as Status;
|
||||
|
||||
@@ -40,7 +42,7 @@ const FRAME_TIMEOUT_MS: u32 = 1000;
|
||||
pub(crate) struct Presentation {
|
||||
pub(crate) device: AnyDevice,
|
||||
pub(crate) config: wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
|
||||
pub(crate) acquired_texture: Option<id::TextureId>,
|
||||
pub(crate) acquired_texture: Option<TextureId>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@@ -116,20 +118,20 @@ impl From<WaitIdleError> for ConfigureSurfaceError {
|
||||
#[derive(Debug)]
|
||||
pub struct SurfaceOutput {
|
||||
pub status: Status,
|
||||
pub texture_id: Option<id::TextureId>,
|
||||
pub texture_id: Option<TextureId>,
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn surface_get_current_texture<A: HalApi>(
|
||||
&self,
|
||||
surface_id: id::SurfaceId,
|
||||
texture_id_in: Option<id::TextureId>,
|
||||
surface_id: SurfaceId,
|
||||
texture_id_in: Input<G, TextureId>,
|
||||
) -> Result<SurfaceOutput, SurfaceError> {
|
||||
profiling::scope!("SwapChain::get_next_texture");
|
||||
|
||||
let hub = A::hub(self);
|
||||
|
||||
let fid = hub.textures.prepare(texture_id_in);
|
||||
let fid = hub.textures.prepare::<G>(texture_id_in);
|
||||
|
||||
let surface = self
|
||||
.surfaces
|
||||
@@ -229,8 +231,6 @@ impl Global {
|
||||
clear_mode: RwLock::new(resource::TextureClearMode::Surface {
|
||||
clear_view: Some(clear_view),
|
||||
}),
|
||||
views: Mutex::new(Vec::new()),
|
||||
bind_groups: Mutex::new(Vec::new()),
|
||||
};
|
||||
|
||||
let (id, resource) = fid.assign(texture);
|
||||
@@ -278,7 +278,7 @@ impl Global {
|
||||
|
||||
pub fn surface_present<A: HalApi>(
|
||||
&self,
|
||||
surface_id: id::SurfaceId,
|
||||
surface_id: SurfaceId,
|
||||
) -> Result<Status, SurfaceError> {
|
||||
profiling::scope!("SwapChain::present");
|
||||
|
||||
@@ -376,7 +376,7 @@ impl Global {
|
||||
|
||||
pub fn surface_texture_discard<A: HalApi>(
|
||||
&self,
|
||||
surface_id: id::SurfaceId,
|
||||
surface_id: SurfaceId,
|
||||
) -> Result<(), SurfaceError> {
|
||||
profiling::scope!("SwapChain::discard");
|
||||
|
||||
|
||||
78
third_party/rust/wgpu-core/src/registry.rs
vendored
78
third_party/rust/wgpu-core/src/registry.rs
vendored
@@ -4,8 +4,8 @@ use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
id::Id,
|
||||
identity::IdentityManager,
|
||||
id,
|
||||
identity::{IdentityHandlerFactory, IdentityManager},
|
||||
resource::Resource,
|
||||
storage::{Element, InvalidId, Storage},
|
||||
};
|
||||
@@ -37,40 +37,40 @@ impl RegistryReport {
|
||||
/// any other dependent resource
|
||||
///
|
||||
#[derive(Debug)]
|
||||
pub struct Registry<T: Resource> {
|
||||
identity: Arc<IdentityManager<T::Marker>>,
|
||||
storage: RwLock<Storage<T>>,
|
||||
pub struct Registry<I: id::TypedId, T: Resource<I>> {
|
||||
identity: Arc<IdentityManager<I>>,
|
||||
storage: RwLock<Storage<T, I>>,
|
||||
backend: Backend,
|
||||
}
|
||||
|
||||
impl<T: Resource> Registry<T> {
|
||||
pub(crate) fn new(backend: Backend) -> Self {
|
||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
||||
pub(crate) fn new<F: IdentityHandlerFactory<I>>(backend: Backend, factory: &F) -> Self {
|
||||
Self {
|
||||
identity: Arc::new(IdentityManager::new()),
|
||||
identity: factory.spawn(),
|
||||
storage: RwLock::new(Storage::new()),
|
||||
backend,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn without_backend() -> Self {
|
||||
Self::new(Backend::Empty)
|
||||
pub(crate) fn without_backend<F: IdentityHandlerFactory<I>>(factory: &F) -> Self {
|
||||
Self::new(Backend::Empty, factory)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) struct FutureId<'a, T: Resource> {
|
||||
id: Id<T::Marker>,
|
||||
identity: Arc<IdentityManager<T::Marker>>,
|
||||
data: &'a RwLock<Storage<T>>,
|
||||
pub(crate) struct FutureId<'a, I: id::TypedId, T: Resource<I>> {
|
||||
id: I,
|
||||
identity: Arc<IdentityManager<I>>,
|
||||
data: &'a RwLock<Storage<T, I>>,
|
||||
}
|
||||
|
||||
impl<T: Resource> FutureId<'_, T> {
|
||||
impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
||||
#[allow(dead_code)]
|
||||
pub fn id(&self) -> Id<T::Marker> {
|
||||
pub fn id(&self) -> I {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn into_id(self) -> Id<T::Marker> {
|
||||
pub fn into_id(self) -> I {
|
||||
self.id
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ impl<T: Resource> FutureId<'_, T> {
|
||||
/// Assign a new resource to this ID.
|
||||
///
|
||||
/// Registers it with the registry, and fills out the resource info.
|
||||
pub fn assign(self, value: T) -> (Id<T::Marker>, Arc<T>) {
|
||||
pub fn assign(self, value: T) -> (I, Arc<T>) {
|
||||
let mut data = self.data.write();
|
||||
data.insert(self.id, self.init(value));
|
||||
(self.id, data.get(self.id).unwrap().clone())
|
||||
@@ -94,73 +94,73 @@ impl<T: Resource> FutureId<'_, T> {
|
||||
///
|
||||
/// This _will_ leak the ID, and it will not be recycled again.
|
||||
/// See https://github.com/gfx-rs/wgpu/issues/4912.
|
||||
pub fn assign_existing(self, value: &Arc<T>) -> Id<T::Marker> {
|
||||
pub fn assign_existing(self, value: &Arc<T>) -> I {
|
||||
let mut data = self.data.write();
|
||||
debug_assert!(!data.contains(self.id));
|
||||
data.insert(self.id, value.clone());
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn assign_error(self, label: &str) -> Id<T::Marker> {
|
||||
pub fn assign_error(self, label: &str) -> I {
|
||||
self.data.write().insert_error(self.id, label);
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Resource> Registry<T> {
|
||||
pub(crate) fn prepare(&self, id_in: Option<Id<T::Marker>>) -> FutureId<T> {
|
||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
||||
pub(crate) fn prepare<F>(&self, id_in: F::Input) -> FutureId<I, T>
|
||||
where
|
||||
F: IdentityHandlerFactory<I>,
|
||||
{
|
||||
FutureId {
|
||||
id: match id_in {
|
||||
Some(id_in) => {
|
||||
self.identity.mark_as_used(id_in);
|
||||
id_in
|
||||
}
|
||||
None => self.identity.process(self.backend),
|
||||
id: if F::autogenerate_ids() {
|
||||
self.identity.process(self.backend)
|
||||
} else {
|
||||
self.identity.mark_as_used(F::input_to_id(id_in))
|
||||
},
|
||||
identity: self.identity.clone(),
|
||||
data: &self.storage,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn request(&self) -> FutureId<T> {
|
||||
pub(crate) fn request(&self) -> FutureId<I, T> {
|
||||
FutureId {
|
||||
id: self.identity.process(self.backend),
|
||||
identity: self.identity.clone(),
|
||||
data: &self.storage,
|
||||
}
|
||||
}
|
||||
pub(crate) fn try_get(&self, id: Id<T::Marker>) -> Result<Option<Arc<T>>, InvalidId> {
|
||||
pub(crate) fn try_get(&self, id: I) -> Result<Option<Arc<T>>, InvalidId> {
|
||||
self.read().try_get(id).map(|o| o.cloned())
|
||||
}
|
||||
pub(crate) fn get(&self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||
pub(crate) fn get(&self, id: I) -> Result<Arc<T>, InvalidId> {
|
||||
self.read().get_owned(id)
|
||||
}
|
||||
pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage<T>> {
|
||||
pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage<T, I>> {
|
||||
self.storage.read()
|
||||
}
|
||||
pub(crate) fn write<'a>(&'a self) -> RwLockWriteGuard<'a, Storage<T>> {
|
||||
pub(crate) fn write<'a>(&'a self) -> RwLockWriteGuard<'a, Storage<T, I>> {
|
||||
self.storage.write()
|
||||
}
|
||||
pub fn unregister_locked(&self, id: Id<T::Marker>, storage: &mut Storage<T>) -> Option<Arc<T>> {
|
||||
pub fn unregister_locked(&self, id: I, storage: &mut Storage<T, I>) -> Option<Arc<T>> {
|
||||
storage.remove(id)
|
||||
}
|
||||
pub fn force_replace(&self, id: Id<T::Marker>, mut value: T) {
|
||||
pub fn force_replace(&self, id: I, mut value: T) {
|
||||
let mut storage = self.storage.write();
|
||||
value.as_info_mut().set_id(id, &self.identity);
|
||||
storage.force_replace(id, value)
|
||||
}
|
||||
pub fn force_replace_with_error(&self, id: Id<T::Marker>, label: &str) {
|
||||
pub fn force_replace_with_error(&self, id: I, label: &str) {
|
||||
let mut storage = self.storage.write();
|
||||
storage.remove(id);
|
||||
storage.insert_error(id, label);
|
||||
}
|
||||
pub(crate) fn unregister(&self, id: Id<T::Marker>) -> Option<Arc<T>> {
|
||||
pub(crate) fn unregister(&self, id: I) -> Option<Arc<T>> {
|
||||
let value = self.storage.write().remove(id);
|
||||
//Returning None is legal if it's an error ID
|
||||
value
|
||||
}
|
||||
|
||||
pub fn label_for_resource(&self, id: Id<T::Marker>) -> String {
|
||||
pub fn label_for_resource(&self, id: I) -> String {
|
||||
let guard = self.storage.read();
|
||||
|
||||
let type_name = guard.kind();
|
||||
|
||||
179
third_party/rust/wgpu-core/src/resource.rs
vendored
179
third_party/rust/wgpu-core/src/resource.rs
vendored
@@ -1,15 +1,17 @@
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace;
|
||||
use crate::{
|
||||
binding_model::BindGroup,
|
||||
device::{
|
||||
queue, BufferMapPendingClosure, Device, DeviceError, HostMap, MissingDownlevelFlags,
|
||||
MissingFeatures,
|
||||
},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{AdapterId, BufferId, DeviceId, Id, Marker, SurfaceId, TextureId},
|
||||
identity::IdentityManager,
|
||||
id::{
|
||||
AdapterId, BufferId, DeviceId, QuerySetId, SamplerId, StagingBufferId, SurfaceId,
|
||||
TextureId, TextureViewId, TypedId,
|
||||
},
|
||||
identity::{GlobalIdentityHandlerFactory, IdentityManager},
|
||||
init_tracker::{BufferInitTracker, TextureInitTracker},
|
||||
resource, resource_log,
|
||||
snatch::{ExclusiveSnatchGuard, SnatchGuard, Snatchable},
|
||||
@@ -32,7 +34,7 @@ use std::{
|
||||
ptr::NonNull,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
Arc, Weak,
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -56,9 +58,9 @@ use std::{
|
||||
/// [`Device`]: crate::device::resource::Device
|
||||
/// [`Buffer`]: crate::resource::Buffer
|
||||
#[derive(Debug)]
|
||||
pub struct ResourceInfo<T: Resource> {
|
||||
id: Option<Id<T::Marker>>,
|
||||
identity: Option<Arc<IdentityManager<T::Marker>>>,
|
||||
pub struct ResourceInfo<Id: TypedId> {
|
||||
id: Option<Id>,
|
||||
identity: Option<Arc<IdentityManager<Id>>>,
|
||||
/// The index of the last queue submission in which the resource
|
||||
/// was used.
|
||||
///
|
||||
@@ -72,7 +74,7 @@ pub struct ResourceInfo<T: Resource> {
|
||||
pub(crate) label: String,
|
||||
}
|
||||
|
||||
impl<T: Resource> Drop for ResourceInfo<T> {
|
||||
impl<Id: TypedId> Drop for ResourceInfo<Id> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(identity) = self.identity.as_ref() {
|
||||
let id = self.id.as_ref().unwrap();
|
||||
@@ -81,7 +83,7 @@ impl<T: Resource> Drop for ResourceInfo<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Resource> ResourceInfo<T> {
|
||||
impl<Id: TypedId> ResourceInfo<Id> {
|
||||
#[allow(unused_variables)]
|
||||
pub(crate) fn new(label: &str) -> Self {
|
||||
Self {
|
||||
@@ -94,7 +96,7 @@ impl<T: Resource> ResourceInfo<T> {
|
||||
|
||||
pub(crate) fn label(&self) -> &dyn Debug
|
||||
where
|
||||
Id<T::Marker>: Debug,
|
||||
Id: Debug,
|
||||
{
|
||||
if !self.label.is_empty() {
|
||||
return &self.label;
|
||||
@@ -107,11 +109,11 @@ impl<T: Resource> ResourceInfo<T> {
|
||||
&""
|
||||
}
|
||||
|
||||
pub(crate) fn id(&self) -> Id<T::Marker> {
|
||||
pub(crate) fn id(&self) -> Id {
|
||||
self.id.unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn set_id(&mut self, id: Id<T::Marker>, identity: &Arc<IdentityManager<T::Marker>>) {
|
||||
pub(crate) fn set_id(&mut self, id: Id, identity: &Arc<IdentityManager<Id>>) {
|
||||
self.id = Some(id);
|
||||
self.identity = Some(identity.clone());
|
||||
}
|
||||
@@ -130,11 +132,10 @@ impl<T: Resource> ResourceInfo<T> {
|
||||
|
||||
pub(crate) type ResourceType = &'static str;
|
||||
|
||||
pub trait Resource: 'static + Sized + WasmNotSendSync {
|
||||
type Marker: Marker;
|
||||
pub trait Resource<Id: TypedId>: 'static + WasmNotSendSync {
|
||||
const TYPE: ResourceType;
|
||||
fn as_info(&self) -> &ResourceInfo<Self>;
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self>;
|
||||
fn as_info(&self) -> &ResourceInfo<Id>;
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Id>;
|
||||
fn label(&self) -> String {
|
||||
self.as_info().label.clone()
|
||||
}
|
||||
@@ -375,9 +376,8 @@ pub struct Buffer<A: HalApi> {
|
||||
pub(crate) size: wgt::BufferAddress,
|
||||
pub(crate) initialization_status: RwLock<BufferInitTracker>,
|
||||
pub(crate) sync_mapped_writes: Mutex<Option<hal::MemoryRange>>,
|
||||
pub(crate) info: ResourceInfo<Buffer<A>>,
|
||||
pub(crate) info: ResourceInfo<BufferId>,
|
||||
pub(crate) map_state: Mutex<BufferMapState<A>>,
|
||||
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for Buffer<A> {
|
||||
@@ -541,18 +541,12 @@ impl<A: HalApi> Buffer<A> {
|
||||
}
|
||||
};
|
||||
|
||||
let bind_groups = {
|
||||
let mut guard = self.bind_groups.lock();
|
||||
std::mem::take(&mut *guard)
|
||||
};
|
||||
|
||||
queue::TempResource::DestroyedBuffer(Arc::new(DestroyedBuffer {
|
||||
raw: Some(raw),
|
||||
device: Arc::clone(&self.device),
|
||||
submission_index: self.info.submission_index(),
|
||||
id: self.info.id.unwrap(),
|
||||
label: self.info.label.clone(),
|
||||
bind_groups,
|
||||
}))
|
||||
};
|
||||
|
||||
@@ -590,43 +584,18 @@ pub enum CreateBufferError {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Buffer<A> {
|
||||
impl<A: HalApi> Resource<BufferId> for Buffer<A> {
|
||||
const TYPE: ResourceType = "Buffer";
|
||||
|
||||
type Marker = crate::id::markers::Buffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<BufferId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BufferId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
fn snatch_and_destroy_bind_groups<A: HalApi>(
|
||||
device: &Device<A>,
|
||||
bind_groups: &[Weak<BindGroup<A>>],
|
||||
) {
|
||||
for bind_group in bind_groups {
|
||||
if let Some(bind_group) = bind_group.upgrade() {
|
||||
if let Some(raw_bind_group) = bind_group.raw.snatch(device.snatchable_lock.write()) {
|
||||
resource_log!("Destroy raw BindGroup (destroyed) {:?}", bind_group.label());
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(t) = device.trace.lock().as_mut() {
|
||||
t.add(trace::Action::DestroyBindGroup(bind_group.info.id()));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
use hal::Device;
|
||||
device.raw().destroy_bind_group(raw_bind_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A buffer that has been marked as destroyed and is staged for actual deletion soon.
|
||||
#[derive(Debug)]
|
||||
pub struct DestroyedBuffer<A: HalApi> {
|
||||
@@ -635,7 +604,6 @@ pub struct DestroyedBuffer<A: HalApi> {
|
||||
label: String,
|
||||
pub(crate) id: BufferId,
|
||||
pub(crate) submission_index: u64,
|
||||
bind_groups: Vec<Weak<BindGroup<A>>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> DestroyedBuffer<A> {
|
||||
@@ -650,8 +618,6 @@ impl<A: HalApi> DestroyedBuffer<A> {
|
||||
|
||||
impl<A: HalApi> Drop for DestroyedBuffer<A> {
|
||||
fn drop(&mut self) {
|
||||
snatch_and_destroy_bind_groups(&self.device, &self.bind_groups);
|
||||
|
||||
if let Some(raw) = self.raw.take() {
|
||||
resource_log!("Destroy raw Buffer (destroyed) {:?}", self.label());
|
||||
|
||||
@@ -693,7 +659,7 @@ pub struct StagingBuffer<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) size: wgt::BufferAddress,
|
||||
pub(crate) is_coherent: bool,
|
||||
pub(crate) info: ResourceInfo<StagingBuffer<A>>,
|
||||
pub(crate) info: ResourceInfo<StagingBufferId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for StagingBuffer<A> {
|
||||
@@ -708,16 +674,14 @@ impl<A: HalApi> Drop for StagingBuffer<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for StagingBuffer<A> {
|
||||
impl<A: HalApi> Resource<StagingBufferId> for StagingBuffer<A> {
|
||||
const TYPE: ResourceType = "StagingBuffer";
|
||||
|
||||
type Marker = crate::id::markers::StagingBuffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<StagingBufferId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<StagingBufferId> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@@ -775,10 +739,8 @@ pub struct Texture<A: HalApi> {
|
||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||
pub(crate) initialization_status: RwLock<TextureInitTracker>,
|
||||
pub(crate) full_range: TextureSelector,
|
||||
pub(crate) info: ResourceInfo<Texture<A>>,
|
||||
pub(crate) info: ResourceInfo<TextureId>,
|
||||
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
|
||||
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
|
||||
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for Texture<A> {
|
||||
@@ -890,20 +852,8 @@ impl<A: HalApi> Texture<A> {
|
||||
}
|
||||
};
|
||||
|
||||
let views = {
|
||||
let mut guard = self.views.lock();
|
||||
std::mem::take(&mut *guard)
|
||||
};
|
||||
|
||||
let bind_groups = {
|
||||
let mut guard = self.bind_groups.lock();
|
||||
std::mem::take(&mut *guard)
|
||||
};
|
||||
|
||||
queue::TempResource::DestroyedTexture(Arc::new(DestroyedTexture {
|
||||
raw: Some(raw),
|
||||
views,
|
||||
bind_groups,
|
||||
device: Arc::clone(&self.device),
|
||||
submission_index: self.info.submission_index(),
|
||||
id: self.info.id.unwrap(),
|
||||
@@ -926,7 +876,7 @@ impl<A: HalApi> Texture<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Global {
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
/// # Safety
|
||||
///
|
||||
/// - The raw texture handle must not be manually destroyed
|
||||
@@ -1020,8 +970,6 @@ impl Global {
|
||||
#[derive(Debug)]
|
||||
pub struct DestroyedTexture<A: HalApi> {
|
||||
raw: Option<A::Texture>,
|
||||
views: Vec<Weak<TextureView<A>>>,
|
||||
bind_groups: Vec<Weak<BindGroup<A>>>,
|
||||
device: Arc<Device<A>>,
|
||||
label: String,
|
||||
pub(crate) id: TextureId,
|
||||
@@ -1040,26 +988,6 @@ impl<A: HalApi> DestroyedTexture<A> {
|
||||
|
||||
impl<A: HalApi> Drop for DestroyedTexture<A> {
|
||||
fn drop(&mut self) {
|
||||
let device = &self.device;
|
||||
snatch_and_destroy_bind_groups(device, &self.bind_groups);
|
||||
|
||||
for view in self.views.drain(..) {
|
||||
if let Some(view) = view.upgrade() {
|
||||
if let Some(raw_view) = view.raw.snatch(device.snatchable_lock.write()) {
|
||||
resource_log!("Destroy raw TextureView (destroyed) {:?}", view.label());
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(t) = self.device.trace.lock().as_mut() {
|
||||
t.add(trace::Action::DestroyTextureView(view.info.id()));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
use hal::Device;
|
||||
self.device.raw().destroy_texture_view(raw_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(raw) = self.raw.take() {
|
||||
resource_log!("Destroy raw Texture (destroyed) {:?}", self.label());
|
||||
|
||||
@@ -1168,16 +1096,14 @@ pub enum CreateTextureError {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Texture<A> {
|
||||
impl<A: HalApi> Resource<TextureId> for Texture<A> {
|
||||
const TYPE: ResourceType = "Texture";
|
||||
|
||||
type Marker = crate::id::markers::Texture;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<TextureId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -1190,8 +1116,8 @@ impl<A: HalApi> Borrow<TextureSelector> for Texture<A> {
|
||||
|
||||
/// Describes a [`TextureView`].
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize), serde(default))]
|
||||
pub struct TextureViewDescriptor<'a> {
|
||||
/// Debug label of the texture view.
|
||||
///
|
||||
@@ -1244,9 +1170,9 @@ pub enum TextureViewNotRenderableReason {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TextureView<A: HalApi> {
|
||||
pub(crate) raw: Snatchable<A::TextureView>,
|
||||
pub(crate) raw: Option<A::TextureView>,
|
||||
// if it's a surface texture - it's none
|
||||
pub(crate) parent: Arc<Texture<A>>,
|
||||
pub(crate) parent: RwLock<Option<Arc<Texture<A>>>>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
//TODO: store device_id for quick access?
|
||||
pub(crate) desc: HalTextureViewDescriptor,
|
||||
@@ -1255,7 +1181,7 @@ pub struct TextureView<A: HalApi> {
|
||||
pub(crate) render_extent: Result<wgt::Extent3d, TextureViewNotRenderableReason>,
|
||||
pub(crate) samples: u32,
|
||||
pub(crate) selector: TextureSelector,
|
||||
pub(crate) info: ResourceInfo<TextureView<A>>,
|
||||
pub(crate) info: ResourceInfo<TextureViewId>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for TextureView<A> {
|
||||
@@ -1277,8 +1203,8 @@ impl<A: HalApi> Drop for TextureView<A> {
|
||||
}
|
||||
|
||||
impl<A: HalApi> TextureView<A> {
|
||||
pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::TextureView> {
|
||||
self.raw.get(snatch_guard)
|
||||
pub(crate) fn raw(&self) -> &A::TextureView {
|
||||
self.raw.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,23 +1259,22 @@ pub enum CreateTextureViewError {
|
||||
#[non_exhaustive]
|
||||
pub enum TextureViewDestroyError {}
|
||||
|
||||
impl<A: HalApi> Resource for TextureView<A> {
|
||||
impl<A: HalApi> Resource<TextureViewId> for TextureView<A> {
|
||||
const TYPE: ResourceType = "TextureView";
|
||||
|
||||
type Marker = crate::id::markers::TextureView;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<TextureViewId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureViewId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes a [`Sampler`]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct SamplerDescriptor<'a> {
|
||||
/// Debug label of the sampler.
|
||||
///
|
||||
@@ -1380,7 +1305,7 @@ pub struct SamplerDescriptor<'a> {
|
||||
pub struct Sampler<A: HalApi> {
|
||||
pub(crate) raw: Option<A::Sampler>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<Self>,
|
||||
pub(crate) info: ResourceInfo<SamplerId>,
|
||||
/// `true` if this is a comparison sampler
|
||||
pub(crate) comparison: bool,
|
||||
/// `true` if this is a filtering sampler
|
||||
@@ -1454,16 +1379,14 @@ pub enum CreateSamplerError {
|
||||
MissingFeatures(#[from] MissingFeatures),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for Sampler<A> {
|
||||
impl<A: HalApi> Resource<SamplerId> for Sampler<A> {
|
||||
const TYPE: ResourceType = "Sampler";
|
||||
|
||||
type Marker = crate::id::markers::Sampler;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<SamplerId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SamplerId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@@ -1487,7 +1410,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
|
||||
pub struct QuerySet<A: HalApi> {
|
||||
pub(crate) raw: Option<A::QuerySet>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<Self>,
|
||||
pub(crate) info: ResourceInfo<QuerySetId>,
|
||||
pub(crate) desc: wgt::QuerySetDescriptor<()>,
|
||||
}
|
||||
|
||||
@@ -1508,16 +1431,14 @@ impl<A: HalApi> Drop for QuerySet<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource for QuerySet<A> {
|
||||
impl<A: HalApi> Resource<QuerySetId> for QuerySet<A> {
|
||||
const TYPE: ResourceType = "QuerySet";
|
||||
|
||||
type Marker = crate::id::markers::QuerySet;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
fn as_info(&self) -> &ResourceInfo<QuerySetId> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QuerySetId> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
||||
55
third_party/rust/wgpu-core/src/storage.rs
vendored
55
third_party/rust/wgpu-core/src/storage.rs
vendored
@@ -1,11 +1,8 @@
|
||||
use std::ops;
|
||||
use std::sync::Arc;
|
||||
use std::{marker::PhantomData, ops, sync::Arc};
|
||||
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::id::Id;
|
||||
use crate::resource::Resource;
|
||||
use crate::{Epoch, Index};
|
||||
use crate::{id, resource::Resource, Epoch, Index};
|
||||
|
||||
/// An entry in a `Storage::map` table.
|
||||
#[derive(Debug)]
|
||||
@@ -33,41 +30,47 @@ pub(crate) struct InvalidId;
|
||||
/// values, so you should use an id allocator like `IdentityManager`
|
||||
/// that keeps the index values dense and close to zero.
|
||||
#[derive(Debug)]
|
||||
pub struct Storage<T>
|
||||
pub struct Storage<T, I>
|
||||
where
|
||||
T: Resource,
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
{
|
||||
pub(crate) map: Vec<Element<T>>,
|
||||
kind: &'static str,
|
||||
_phantom: PhantomData<I>,
|
||||
}
|
||||
|
||||
impl<T> ops::Index<Id<T::Marker>> for Storage<T>
|
||||
impl<T, I> ops::Index<I> for Storage<T, I>
|
||||
where
|
||||
T: Resource,
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
{
|
||||
type Output = Arc<T>;
|
||||
fn index(&self, id: Id<T::Marker>) -> &Arc<T> {
|
||||
fn index(&self, id: I) -> &Arc<T> {
|
||||
self.get(id).unwrap()
|
||||
}
|
||||
}
|
||||
impl<T> Storage<T>
|
||||
impl<T, I> Storage<T, I>
|
||||
where
|
||||
T: Resource,
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
{
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
map: Vec::new(),
|
||||
kind: T::TYPE,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Storage<T>
|
||||
impl<T, I> Storage<T, I>
|
||||
where
|
||||
T: Resource,
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
{
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn contains(&self, id: Id<T::Marker>) -> bool {
|
||||
pub(crate) fn contains(&self, id: I) -> bool {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match self.map.get(index as usize) {
|
||||
Some(&Element::Vacant) => false,
|
||||
@@ -85,7 +88,7 @@ where
|
||||
/// This function is primarily intended for the `as_hal` family of functions
|
||||
/// where you may need to fallibly get a object backed by an id that could
|
||||
/// be in a different hub.
|
||||
pub(crate) fn try_get(&self, id: Id<T::Marker>) -> Result<Option<&Arc<T>>, InvalidId> {
|
||||
pub(crate) fn try_get(&self, id: I) -> Result<Option<&Arc<T>>, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(Some(v)), epoch),
|
||||
@@ -103,7 +106,7 @@ where
|
||||
|
||||
/// Get a reference to an item behind a potentially invalid ID.
|
||||
/// Panics if there is an epoch mismatch, or the entry is empty.
|
||||
pub(crate) fn get(&self, id: Id<T::Marker>) -> Result<&Arc<T>, InvalidId> {
|
||||
pub(crate) fn get(&self, id: I) -> Result<&Arc<T>, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch),
|
||||
@@ -121,11 +124,11 @@ where
|
||||
|
||||
/// Get an owned reference to an item behind a potentially invalid ID.
|
||||
/// Panics if there is an epoch mismatch, or the entry is empty.
|
||||
pub(crate) fn get_owned(&self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||
pub(crate) fn get_owned(&self, id: I) -> Result<Arc<T>, InvalidId> {
|
||||
Ok(Arc::clone(self.get(id)?))
|
||||
}
|
||||
|
||||
pub(crate) fn label_for_invalid_id(&self, id: Id<T::Marker>) -> &str {
|
||||
pub(crate) fn label_for_invalid_id(&self, id: I) -> &str {
|
||||
let (index, _, _) = id.unzip();
|
||||
match self.map.get(index as usize) {
|
||||
Some(Element::Error(_, label)) => label,
|
||||
@@ -158,13 +161,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn insert(&mut self, id: Id<T::Marker>, value: Arc<T>) {
|
||||
pub(crate) fn insert(&mut self, id: I, value: Arc<T>) {
|
||||
log::trace!("User is inserting {}{:?}", T::TYPE, id);
|
||||
let (index, epoch, _backend) = id.unzip();
|
||||
self.insert_impl(index as usize, epoch, Element::Occupied(value, epoch))
|
||||
}
|
||||
|
||||
pub(crate) fn insert_error(&mut self, id: Id<T::Marker>, label: &str) {
|
||||
pub(crate) fn insert_error(&mut self, id: I, label: &str) {
|
||||
log::trace!("User is insering as error {}{:?}", T::TYPE, id);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
self.insert_impl(
|
||||
@@ -174,7 +177,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn replace_with_error(&mut self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||
pub(crate) fn replace_with_error(&mut self, id: I) -> Result<Arc<T>, InvalidId> {
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match std::mem::replace(
|
||||
&mut self.map[index as usize],
|
||||
@@ -189,13 +192,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn force_replace(&mut self, id: Id<T::Marker>, value: T) {
|
||||
pub(crate) fn force_replace(&mut self, id: I, value: T) {
|
||||
log::trace!("User is replacing {}{:?}", T::TYPE, id);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
self.map[index as usize] = Element::Occupied(Arc::new(value), epoch);
|
||||
}
|
||||
|
||||
pub(crate) fn remove(&mut self, id: Id<T::Marker>) -> Option<Arc<T>> {
|
||||
pub(crate) fn remove(&mut self, id: I) -> Option<Arc<T>> {
|
||||
log::trace!("User is removing {}{:?}", T::TYPE, id);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
match std::mem::replace(&mut self.map[index as usize], Element::Vacant) {
|
||||
@@ -208,13 +211,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn iter(&self, backend: Backend) -> impl Iterator<Item = (Id<T::Marker>, &Arc<T>)> {
|
||||
pub(crate) fn iter(&self, backend: Backend) -> impl Iterator<Item = (I, &Arc<T>)> {
|
||||
self.map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(move |(index, x)| match *x {
|
||||
Element::Occupied(ref value, storage_epoch) => {
|
||||
Some((Id::zip(index as Index, storage_epoch, backend), value))
|
||||
Some((I::zip(index as Index, storage_epoch, backend), value))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
||||
27
third_party/rust/wgpu-core/src/track/buffer.rs
vendored
27
third_party/rust/wgpu-core/src/track/buffer.rs
vendored
@@ -10,7 +10,7 @@ use std::{borrow::Cow, marker::PhantomData, sync::Arc};
|
||||
use super::{PendingTransition, ResourceTracker};
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
id::BufferId,
|
||||
id::{BufferId, TypedId},
|
||||
resource::{Buffer, Resource},
|
||||
snatch::SnatchGuard,
|
||||
storage::Storage,
|
||||
@@ -26,6 +26,7 @@ use wgt::{strict_assert, strict_assert_eq};
|
||||
impl ResourceUses for BufferUses {
|
||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||
|
||||
type Id = BufferId;
|
||||
type Selector = ();
|
||||
|
||||
fn bits(self) -> u16 {
|
||||
@@ -91,7 +92,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
||||
/// Adds the given resource with the given state.
|
||||
pub fn add_single<'a>(
|
||||
&self,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
||||
id: BufferId,
|
||||
state: BufferUses,
|
||||
) -> Option<&'a Arc<Buffer<A>>> {
|
||||
@@ -109,7 +110,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
||||
pub(crate) struct BufferUsageScope<A: HalApi> {
|
||||
state: Vec<BufferUses>,
|
||||
|
||||
metadata: ResourceMetadata<A, Buffer<A>>,
|
||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> BufferUsageScope<A> {
|
||||
@@ -247,7 +248,7 @@ impl<A: HalApi> BufferUsageScope<A> {
|
||||
/// the vectors will be extended. A call to set_size is not needed.
|
||||
pub fn merge_single<'a>(
|
||||
&mut self,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
||||
id: BufferId,
|
||||
new_state: BufferUses,
|
||||
) -> Result<&'a Arc<Buffer<A>>, UsageConflict> {
|
||||
@@ -287,12 +288,12 @@ pub(crate) struct BufferTracker<A: HalApi> {
|
||||
start: Vec<BufferUses>,
|
||||
end: Vec<BufferUses>,
|
||||
|
||||
metadata: ResourceMetadata<A, Buffer<A>>,
|
||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
|
||||
temp: Vec<PendingTransition<BufferUses>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> ResourceTracker<Buffer<A>> for BufferTracker<A> {
|
||||
impl<A: HalApi> ResourceTracker<BufferId, Buffer<A>> for BufferTracker<A> {
|
||||
/// Try to remove the buffer `id` from this tracker if it is otherwise unused.
|
||||
///
|
||||
/// A buffer is 'otherwise unused' when the only references to it are:
|
||||
@@ -653,11 +654,11 @@ impl BufferStateProvider<'_> {
|
||||
unsafe fn insert_or_merge<A: HalApi>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
index32: u32,
|
||||
index: usize,
|
||||
state_provider: BufferStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
|
||||
@@ -708,11 +709,11 @@ unsafe fn insert_or_merge<A: HalApi>(
|
||||
unsafe fn insert_or_barrier_update<A: HalApi>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
index: usize,
|
||||
start_state_provider: BufferStateProvider<'_>,
|
||||
end_state_provider: Option<BufferStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
barriers: &mut Vec<PendingTransition<BufferUses>>,
|
||||
) {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
@@ -742,11 +743,11 @@ unsafe fn insert_or_barrier_update<A: HalApi>(
|
||||
unsafe fn insert<A: HalApi>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
index: usize,
|
||||
start_state_provider: BufferStateProvider<'_>,
|
||||
end_state_provider: Option<BufferStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
) {
|
||||
let new_start_state = unsafe { start_state_provider.get_state(index) };
|
||||
let new_end_state =
|
||||
@@ -776,7 +777,7 @@ unsafe fn merge<A: HalApi>(
|
||||
index32: u32,
|
||||
index: usize,
|
||||
state_provider: BufferStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let current_state = unsafe { current_states.get_unchecked_mut(index) };
|
||||
let new_state = unsafe { state_provider.get_state(index) };
|
||||
|
||||
14
third_party/rust/wgpu-core/src/track/metadata.rs
vendored
14
third_party/rust/wgpu-core/src/track/metadata.rs
vendored
@@ -1,6 +1,6 @@
|
||||
//! The `ResourceMetadata` type.
|
||||
|
||||
use crate::{hal_api::HalApi, resource::Resource, Epoch};
|
||||
use crate::{hal_api::HalApi, id::TypedId, resource::Resource, Epoch};
|
||||
use bit_vec::BitVec;
|
||||
use std::{borrow::Cow, marker::PhantomData, mem, sync::Arc};
|
||||
use wgt::strict_assert;
|
||||
@@ -13,7 +13,7 @@ use wgt::strict_assert;
|
||||
/// members, but a bit vector tracks occupancy, so iteration touches
|
||||
/// only occupied elements.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct ResourceMetadata<A: HalApi, T: Resource> {
|
||||
pub(super) struct ResourceMetadata<A: HalApi, I: TypedId, T: Resource<I>> {
|
||||
/// If the resource with index `i` is a member, `owned[i]` is `true`.
|
||||
owned: BitVec<usize>,
|
||||
|
||||
@@ -21,10 +21,10 @@ pub(super) struct ResourceMetadata<A: HalApi, T: Resource> {
|
||||
resources: Vec<Option<Arc<T>>>,
|
||||
|
||||
/// This tells Rust that this type should be covariant with `A`.
|
||||
_phantom: PhantomData<A>,
|
||||
_phantom: PhantomData<(A, I)>,
|
||||
}
|
||||
|
||||
impl<A: HalApi, T: Resource> ResourceMetadata<A, T> {
|
||||
impl<A: HalApi, I: TypedId, T: Resource<I>> ResourceMetadata<A, I, T> {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
owned: BitVec::default(),
|
||||
@@ -172,15 +172,15 @@ impl<A: HalApi, T: Resource> ResourceMetadata<A, T> {
|
||||
///
|
||||
/// This is used to abstract over the various places
|
||||
/// trackers can get new resource metadata from.
|
||||
pub(super) enum ResourceMetadataProvider<'a, A: HalApi, T: Resource> {
|
||||
pub(super) enum ResourceMetadataProvider<'a, A: HalApi, I: TypedId, T: Resource<I>> {
|
||||
/// Comes directly from explicit values.
|
||||
Direct { resource: Cow<'a, Arc<T>> },
|
||||
/// Comes from another metadata tracker.
|
||||
Indirect {
|
||||
metadata: &'a ResourceMetadata<A, T>,
|
||||
metadata: &'a ResourceMetadata<A, I, T>,
|
||||
},
|
||||
}
|
||||
impl<A: HalApi, T: Resource> ResourceMetadataProvider<'_, A, T> {
|
||||
impl<A: HalApi, I: TypedId, T: Resource<I>> ResourceMetadataProvider<'_, A, I, T> {
|
||||
/// Get the epoch and an owned refcount from this.
|
||||
///
|
||||
/// # Safety
|
||||
|
||||
68
third_party/rust/wgpu-core/src/track/mod.rs
vendored
68
third_party/rust/wgpu-core/src/track/mod.rs
vendored
@@ -104,7 +104,7 @@ mod texture;
|
||||
use crate::{
|
||||
binding_model, command, conv,
|
||||
hal_api::HalApi,
|
||||
id::{self, Id},
|
||||
id::{self, TypedId},
|
||||
pipeline, resource,
|
||||
snatch::SnatchGuard,
|
||||
storage::Storage,
|
||||
@@ -182,6 +182,8 @@ pub(crate) trait ResourceUses:
|
||||
/// All flags that are exclusive.
|
||||
const EXCLUSIVE: Self;
|
||||
|
||||
/// The relevant resource ID type.
|
||||
type Id: Copy + fmt::Debug + TypedId;
|
||||
/// The selector used by this resource.
|
||||
type Selector: fmt::Debug;
|
||||
|
||||
@@ -318,8 +320,8 @@ impl<T: ResourceUses> fmt::Display for InvalidUse<T> {
|
||||
pub(crate) struct BindGroupStates<A: HalApi> {
|
||||
pub buffers: BufferBindGroupState<A>,
|
||||
pub textures: TextureBindGroupState<A>,
|
||||
pub views: StatelessBindGroupSate<resource::TextureView<A>>,
|
||||
pub samplers: StatelessBindGroupSate<resource::Sampler<A>>,
|
||||
pub views: StatelessBindGroupSate<id::TextureViewId, resource::TextureView<A>>,
|
||||
pub samplers: StatelessBindGroupSate<id::SamplerId, resource::Sampler<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> BindGroupStates<A> {
|
||||
@@ -352,19 +354,20 @@ pub(crate) struct RenderBundleScope<A: HalApi> {
|
||||
pub buffers: RwLock<BufferUsageScope<A>>,
|
||||
pub textures: RwLock<TextureUsageScope<A>>,
|
||||
// Don't need to track views and samplers, they are never used directly, only by bind groups.
|
||||
pub bind_groups: RwLock<StatelessTracker<A, binding_model::BindGroup<A>>>,
|
||||
pub render_pipelines: RwLock<StatelessTracker<A, pipeline::RenderPipeline<A>>>,
|
||||
pub query_sets: RwLock<StatelessTracker<A, resource::QuerySet<A>>>,
|
||||
pub bind_groups: RwLock<StatelessTracker<A, id::BindGroupId, binding_model::BindGroup<A>>>,
|
||||
pub render_pipelines:
|
||||
RwLock<StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>>,
|
||||
pub query_sets: RwLock<StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> RenderBundleScope<A> {
|
||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||
pub fn new(
|
||||
buffers: &Storage<resource::Buffer<A>>,
|
||||
textures: &Storage<resource::Texture<A>>,
|
||||
bind_groups: &Storage<binding_model::BindGroup<A>>,
|
||||
render_pipelines: &Storage<pipeline::RenderPipeline<A>>,
|
||||
query_sets: &Storage<resource::QuerySet<A>>,
|
||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
||||
bind_groups: &Storage<binding_model::BindGroup<A>, id::BindGroupId>,
|
||||
render_pipelines: &Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>,
|
||||
query_sets: &Storage<resource::QuerySet<A>, id::QuerySetId>,
|
||||
) -> Self {
|
||||
let value = Self {
|
||||
buffers: RwLock::new(BufferUsageScope::new()),
|
||||
@@ -421,8 +424,8 @@ pub(crate) struct UsageScope<A: HalApi> {
|
||||
impl<A: HalApi> UsageScope<A> {
|
||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||
pub fn new(
|
||||
buffers: &Storage<resource::Buffer<A>>,
|
||||
textures: &Storage<resource::Texture<A>>,
|
||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
||||
) -> Self {
|
||||
let mut value = Self {
|
||||
buffers: BufferUsageScope::new(),
|
||||
@@ -478,24 +481,25 @@ impl<A: HalApi> UsageScope<A> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ResourceTracker<R>
|
||||
pub(crate) trait ResourceTracker<Id, R>
|
||||
where
|
||||
R: resource::Resource,
|
||||
Id: TypedId,
|
||||
R: resource::Resource<Id>,
|
||||
{
|
||||
fn remove_abandoned(&mut self, id: Id<R::Marker>) -> bool;
|
||||
fn remove_abandoned(&mut self, id: Id) -> bool;
|
||||
}
|
||||
|
||||
/// A full double sided tracker used by CommandBuffers and the Device.
|
||||
pub(crate) struct Tracker<A: HalApi> {
|
||||
pub buffers: BufferTracker<A>,
|
||||
pub textures: TextureTracker<A>,
|
||||
pub views: StatelessTracker<A, resource::TextureView<A>>,
|
||||
pub samplers: StatelessTracker<A, resource::Sampler<A>>,
|
||||
pub bind_groups: StatelessTracker<A, binding_model::BindGroup<A>>,
|
||||
pub compute_pipelines: StatelessTracker<A, pipeline::ComputePipeline<A>>,
|
||||
pub render_pipelines: StatelessTracker<A, pipeline::RenderPipeline<A>>,
|
||||
pub bundles: StatelessTracker<A, command::RenderBundle<A>>,
|
||||
pub query_sets: StatelessTracker<A, resource::QuerySet<A>>,
|
||||
pub views: StatelessTracker<A, id::TextureViewId, resource::TextureView<A>>,
|
||||
pub samplers: StatelessTracker<A, id::SamplerId, resource::Sampler<A>>,
|
||||
pub bind_groups: StatelessTracker<A, id::BindGroupId, binding_model::BindGroup<A>>,
|
||||
pub compute_pipelines: StatelessTracker<A, id::ComputePipelineId, pipeline::ComputePipeline<A>>,
|
||||
pub render_pipelines: StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>,
|
||||
pub bundles: StatelessTracker<A, id::RenderBundleId, command::RenderBundle<A>>,
|
||||
pub query_sets: StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Tracker<A> {
|
||||
@@ -516,15 +520,15 @@ impl<A: HalApi> Tracker<A> {
|
||||
/// Pull the maximum IDs from the hubs.
|
||||
pub fn set_size(
|
||||
&mut self,
|
||||
buffers: Option<&Storage<resource::Buffer<A>>>,
|
||||
textures: Option<&Storage<resource::Texture<A>>>,
|
||||
views: Option<&Storage<resource::TextureView<A>>>,
|
||||
samplers: Option<&Storage<resource::Sampler<A>>>,
|
||||
bind_groups: Option<&Storage<binding_model::BindGroup<A>>>,
|
||||
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>>>,
|
||||
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>>>,
|
||||
bundles: Option<&Storage<command::RenderBundle<A>>>,
|
||||
query_sets: Option<&Storage<resource::QuerySet<A>>>,
|
||||
buffers: Option<&Storage<resource::Buffer<A>, id::BufferId>>,
|
||||
textures: Option<&Storage<resource::Texture<A>, id::TextureId>>,
|
||||
views: Option<&Storage<resource::TextureView<A>, id::TextureViewId>>,
|
||||
samplers: Option<&Storage<resource::Sampler<A>, id::SamplerId>>,
|
||||
bind_groups: Option<&Storage<binding_model::BindGroup<A>, id::BindGroupId>>,
|
||||
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>, id::ComputePipelineId>>,
|
||||
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>>,
|
||||
bundles: Option<&Storage<command::RenderBundle<A>, id::RenderBundleId>>,
|
||||
query_sets: Option<&Storage<resource::QuerySet<A>, id::QuerySetId>>,
|
||||
) {
|
||||
if let Some(buffers) = buffers {
|
||||
self.buffers.set_size(buffers.len());
|
||||
|
||||
@@ -4,27 +4,24 @@
|
||||
* distinction between a usage scope and a full tracker.
|
||||
!*/
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::{
|
||||
hal_api::HalApi, id::Id, resource::Resource, resource_log, storage::Storage,
|
||||
hal_api::HalApi, id::TypedId, resource::Resource, resource_log, storage::Storage,
|
||||
track::ResourceMetadata,
|
||||
};
|
||||
|
||||
use super::ResourceTracker;
|
||||
|
||||
/// Satisfy clippy.
|
||||
type Pair<T> = (Id<<T as Resource>::Marker>, Arc<T>);
|
||||
|
||||
/// Stores all the resources that a bind group stores.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StatelessBindGroupSate<T: Resource> {
|
||||
resources: Mutex<Vec<Pair<T>>>,
|
||||
pub(crate) struct StatelessBindGroupSate<Id: TypedId, T: Resource<Id>> {
|
||||
resources: Mutex<Vec<(Id, Arc<T>)>>,
|
||||
}
|
||||
|
||||
impl<T: Resource> StatelessBindGroupSate<T> {
|
||||
impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
resources: Mutex::new(Vec::new()),
|
||||
@@ -61,7 +58,7 @@ impl<T: Resource> StatelessBindGroupSate<T> {
|
||||
}
|
||||
|
||||
/// Adds the given resource.
|
||||
pub fn add_single<'a>(&self, storage: &'a Storage<T>, id: Id<T::Marker>) -> Option<&'a T> {
|
||||
pub fn add_single<'a>(&self, storage: &'a Storage<T, Id>, id: Id) -> Option<&'a T> {
|
||||
let resource = storage.get(id).ok()?;
|
||||
|
||||
let mut resources = self.resources.lock();
|
||||
@@ -73,11 +70,14 @@ impl<T: Resource> StatelessBindGroupSate<T> {
|
||||
|
||||
/// Stores all resource state within a command buffer or device.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StatelessTracker<A: HalApi, T: Resource> {
|
||||
metadata: ResourceMetadata<A, T>,
|
||||
pub(crate) struct StatelessTracker<A: HalApi, Id: TypedId, T: Resource<Id>> {
|
||||
metadata: ResourceMetadata<A, Id, T>,
|
||||
_phantom: PhantomData<Id>,
|
||||
}
|
||||
|
||||
impl<A: HalApi, T: Resource> ResourceTracker<T> for StatelessTracker<A, T> {
|
||||
impl<A: HalApi, Id: TypedId, T: Resource<Id>> ResourceTracker<Id, T>
|
||||
for StatelessTracker<A, Id, T>
|
||||
{
|
||||
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
||||
/// resource and the epoch matches.
|
||||
///
|
||||
@@ -85,7 +85,7 @@ impl<A: HalApi, T: Resource> ResourceTracker<T> for StatelessTracker<A, T> {
|
||||
///
|
||||
/// If the ID is higher than the length of internal vectors,
|
||||
/// false will be returned.
|
||||
fn remove_abandoned(&mut self, id: Id<T::Marker>) -> bool {
|
||||
fn remove_abandoned(&mut self, id: Id) -> bool {
|
||||
let index = id.unzip().0 as usize;
|
||||
|
||||
if index >= self.metadata.size() {
|
||||
@@ -120,10 +120,11 @@ impl<A: HalApi, T: Resource> ResourceTracker<T> for StatelessTracker<A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: HalApi, T: Resource> StatelessTracker<A, T> {
|
||||
impl<A: HalApi, Id: TypedId, T: Resource<Id>> StatelessTracker<A, Id, T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
metadata: ResourceMetadata::new(),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +164,7 @@ impl<A: HalApi, T: Resource> StatelessTracker<A, T> {
|
||||
///
|
||||
/// If the ID is higher than the length of internal vectors,
|
||||
/// the vectors will be extended. A call to set_size is not needed.
|
||||
pub fn insert_single(&mut self, id: Id<T::Marker>, resource: Arc<T>) {
|
||||
pub fn insert_single(&mut self, id: Id, resource: Arc<T>) {
|
||||
let (index32, _epoch, _) = id.unzip();
|
||||
let index = index32 as usize;
|
||||
|
||||
@@ -180,11 +181,7 @@ impl<A: HalApi, T: Resource> StatelessTracker<A, T> {
|
||||
///
|
||||
/// If the ID is higher than the length of internal vectors,
|
||||
/// the vectors will be extended. A call to set_size is not needed.
|
||||
pub fn add_single<'a>(
|
||||
&mut self,
|
||||
storage: &'a Storage<T>,
|
||||
id: Id<T::Marker>,
|
||||
) -> Option<&'a Arc<T>> {
|
||||
pub fn add_single<'a>(&mut self, storage: &'a Storage<T, Id>, id: Id) -> Option<&'a Arc<T>> {
|
||||
let resource = storage.get(id).ok()?;
|
||||
|
||||
let (index32, _epoch, _) = id.unzip();
|
||||
@@ -225,7 +222,7 @@ impl<A: HalApi, T: Resource> StatelessTracker<A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, id: Id<T::Marker>) -> Option<&Arc<T>> {
|
||||
pub fn get(&self, id: Id) -> Option<&Arc<T>> {
|
||||
let index = id.unzip().0 as usize;
|
||||
if index > self.metadata.size() {
|
||||
return None;
|
||||
|
||||
23
third_party/rust/wgpu-core/src/track/texture.rs
vendored
23
third_party/rust/wgpu-core/src/track/texture.rs
vendored
@@ -22,7 +22,7 @@
|
||||
use super::{range::RangedStates, PendingTransition, PendingTransitionList, ResourceTracker};
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
id::TextureId,
|
||||
id::{TextureId, TypedId},
|
||||
resource::{Resource, Texture, TextureInner},
|
||||
snatch::SnatchGuard,
|
||||
track::{
|
||||
@@ -50,6 +50,7 @@ pub struct TextureSelector {
|
||||
impl ResourceUses for TextureUses {
|
||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||
|
||||
type Id = TextureId;
|
||||
type Selector = TextureSelector;
|
||||
|
||||
fn bits(self) -> u16 {
|
||||
@@ -231,7 +232,7 @@ impl TextureStateSet {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TextureUsageScope<A: HalApi> {
|
||||
set: TextureStateSet,
|
||||
metadata: ResourceMetadata<A, Texture<A>>,
|
||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> TextureUsageScope<A> {
|
||||
@@ -386,14 +387,14 @@ pub(crate) struct TextureTracker<A: HalApi> {
|
||||
start_set: TextureStateSet,
|
||||
end_set: TextureStateSet,
|
||||
|
||||
metadata: ResourceMetadata<A, Texture<A>>,
|
||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
|
||||
temp: Vec<PendingTransition<TextureUses>>,
|
||||
|
||||
_phantom: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> ResourceTracker<Texture<A>> for TextureTracker<A> {
|
||||
impl<A: HalApi> ResourceTracker<TextureId, Texture<A>> for TextureTracker<A> {
|
||||
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
||||
/// resource and the epoch matches.
|
||||
///
|
||||
@@ -863,10 +864,10 @@ impl<'a> TextureStateProvider<'a> {
|
||||
unsafe fn insert_or_merge<A: HalApi>(
|
||||
texture_selector: &TextureSelector,
|
||||
current_state_set: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
index: usize,
|
||||
state_provider: TextureStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
|
||||
@@ -919,11 +920,11 @@ unsafe fn insert_or_barrier_update<A: HalApi>(
|
||||
texture_selector: &TextureSelector,
|
||||
start_state: Option<&mut TextureStateSet>,
|
||||
current_state_set: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
index: usize,
|
||||
start_state_provider: TextureStateProvider<'_>,
|
||||
end_state_provider: Option<TextureStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
barriers: &mut Vec<PendingTransition<TextureUses>>,
|
||||
) {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
@@ -972,11 +973,11 @@ unsafe fn insert<A: HalApi>(
|
||||
texture_selector: Option<&TextureSelector>,
|
||||
start_state: Option<&mut TextureStateSet>,
|
||||
end_state: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
index: usize,
|
||||
start_state_provider: TextureStateProvider<'_>,
|
||||
end_state_provider: Option<TextureStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
) {
|
||||
let start_layers = unsafe { start_state_provider.get_state(texture_selector, index) };
|
||||
match start_layers {
|
||||
@@ -1059,7 +1060,7 @@ unsafe fn merge<A: HalApi>(
|
||||
current_state_set: &mut TextureStateSet,
|
||||
index: usize,
|
||||
state_provider: TextureStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) };
|
||||
let current_state = if *current_simple == TextureUses::COMPLEX {
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
third_party/rust/wgpu-hal/Cargo.toml
vendored
2
third_party/rust/wgpu-hal/Cargo.toml
vendored
@@ -87,7 +87,7 @@ path = "../naga"
|
||||
features = ["wgsl-in"]
|
||||
|
||||
[dev-dependencies.winit]
|
||||
version = "0.29.10"
|
||||
version = "0.29.9"
|
||||
features = ["android-native-activity"]
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -490,7 +490,7 @@ impl<A: hal::Api> Example<A> {
|
||||
let mut fence = device.create_fence().unwrap();
|
||||
let init_cmd = cmd_encoder.end_encoding().unwrap();
|
||||
queue
|
||||
.submit(&[&init_cmd], &[], Some((&mut fence, init_fence_value)))
|
||||
.submit(&[&init_cmd], Some((&mut fence, init_fence_value)))
|
||||
.unwrap();
|
||||
device.wait(&fence, init_fence_value, !0).unwrap();
|
||||
device.destroy_buffer(staging_buffer);
|
||||
@@ -542,7 +542,7 @@ impl<A: hal::Api> Example<A> {
|
||||
{
|
||||
let ctx = &mut self.contexts[self.context_index];
|
||||
self.queue
|
||||
.submit(&[], &[], Some((&mut ctx.fence, ctx.fence_value)))
|
||||
.submit(&[], Some((&mut ctx.fence, ctx.fence_value)))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -729,9 +729,7 @@ impl<A: hal::Api> Example<A> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.queue
|
||||
.submit(&[&cmd_buf], &[&surface_tex], fence_param)
|
||||
.unwrap();
|
||||
self.queue.submit(&[&cmd_buf], fence_param).unwrap();
|
||||
self.queue.present(&self.surface, surface_tex).unwrap();
|
||||
ctx.used_cmd_bufs.push(cmd_buf);
|
||||
ctx.used_views.push(surface_tex_view);
|
||||
|
||||
@@ -183,6 +183,6 @@ fn fill_screen(exposed: &hal::ExposedAdapter<hal::api::Gles>, width: u32, height
|
||||
encoder.begin_render_pass(&rp_desc);
|
||||
encoder.end_render_pass();
|
||||
let cmd_buf = encoder.end_encoding().unwrap();
|
||||
od.queue.submit(&[&cmd_buf], &[], None).unwrap();
|
||||
od.queue.submit(&[&cmd_buf], None).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,7 +755,7 @@ impl<A: hal::Api> Example<A> {
|
||||
let mut fence = device.create_fence().unwrap();
|
||||
let init_cmd = cmd_encoder.end_encoding().unwrap();
|
||||
queue
|
||||
.submit(&[&init_cmd], &[], Some((&mut fence, init_fence_value)))
|
||||
.submit(&[&init_cmd], Some((&mut fence, init_fence_value)))
|
||||
.unwrap();
|
||||
device.wait(&fence, init_fence_value, !0).unwrap();
|
||||
cmd_encoder.reset_all(iter::once(init_cmd));
|
||||
@@ -960,9 +960,7 @@ impl<A: hal::Api> Example<A> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.queue
|
||||
.submit(&[&cmd_buf], &[&surface_tex], fence_param)
|
||||
.unwrap();
|
||||
self.queue.submit(&[&cmd_buf], fence_param).unwrap();
|
||||
self.queue.present(&self.surface, surface_tex).unwrap();
|
||||
ctx.used_cmd_bufs.push(cmd_buf);
|
||||
ctx.used_views.push(surface_tex_view);
|
||||
@@ -1001,7 +999,7 @@ impl<A: hal::Api> Example<A> {
|
||||
{
|
||||
let ctx = &mut self.contexts[self.context_index];
|
||||
self.queue
|
||||
.submit(&[], &[], Some((&mut ctx.fence, ctx.fence_value)))
|
||||
.submit(&[], Some((&mut ctx.fence, ctx.fence_value)))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
||||
@@ -289,13 +289,14 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
|
||||
}
|
||||
unsafe fn end_encoding(&mut self) -> Result<super::CommandBuffer, crate::DeviceError> {
|
||||
let raw = self.list.take().unwrap();
|
||||
raw.close()
|
||||
.into_device_result("GraphicsCommandList::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);
|
||||
}
|
||||
}
|
||||
self.allocator.reset();
|
||||
}
|
||||
|
||||
22
third_party/rust/wgpu-hal/src/dx12/instance.rs
vendored
22
third_party/rust/wgpu-hal/src/dx12/instance.rs
vendored
@@ -7,9 +7,7 @@ use std::{mem, sync::Arc};
|
||||
|
||||
impl Drop for super::Instance {
|
||||
fn drop(&mut self) {
|
||||
if self.flags.contains(wgt::InstanceFlags::VALIDATION) {
|
||||
crate::auxil::dxgi::exception::unregister_exception_handler();
|
||||
}
|
||||
crate::auxil::dxgi::exception::unregister_exception_handler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,26 +18,12 @@ impl crate::Instance<super::Api> for super::Instance {
|
||||
crate::InstanceError::with_source(String::from("failed to load d3d12.dll"), e)
|
||||
})?;
|
||||
|
||||
if desc
|
||||
.flags
|
||||
.intersects(wgt::InstanceFlags::VALIDATION | wgt::InstanceFlags::GPU_BASED_VALIDATION)
|
||||
{
|
||||
if desc.flags.contains(wgt::InstanceFlags::VALIDATION) {
|
||||
// Enable debug layer
|
||||
match lib_main.get_debug_interface() {
|
||||
Ok(pair) => match pair.into_result() {
|
||||
Ok(debug_controller) => {
|
||||
if desc.flags.intersects(wgt::InstanceFlags::VALIDATION) {
|
||||
debug_controller.enable_layer();
|
||||
}
|
||||
if desc
|
||||
.flags
|
||||
.intersects(wgt::InstanceFlags::GPU_BASED_VALIDATION)
|
||||
{
|
||||
#[allow(clippy::collapsible_if)]
|
||||
if !debug_controller.enable_gpu_based_validation() {
|
||||
log::warn!("Failed to enable GPU-based validation");
|
||||
}
|
||||
}
|
||||
debug_controller.enable_layer();
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Unable to enable D3D12 debug interface: {}", err);
|
||||
|
||||
2
third_party/rust/wgpu-hal/src/dx12/mod.rs
vendored
2
third_party/rust/wgpu-hal/src/dx12/mod.rs
vendored
@@ -386,6 +386,7 @@ impl fmt::Debug for CommandEncoder {
|
||||
#[derive(Debug)]
|
||||
pub struct CommandBuffer {
|
||||
raw: d3d12::GraphicsCommandList,
|
||||
closed: bool,
|
||||
}
|
||||
|
||||
unsafe impl Send for CommandBuffer {}
|
||||
@@ -885,7 +886,6 @@ impl crate::Queue<Api> for Queue {
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&CommandBuffer],
|
||||
_surface_textures: &[&Texture],
|
||||
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
let mut temp_lists = self.temp_lists.lock();
|
||||
|
||||
1
third_party/rust/wgpu-hal/src/empty.rs
vendored
1
third_party/rust/wgpu-hal/src/empty.rs
vendored
@@ -104,7 +104,6 @@ impl crate::Queue<Api> for Context {
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&Resource],
|
||||
surface_textures: &[&Resource],
|
||||
signal_fence: Option<(&mut Resource, crate::FenceValue)>,
|
||||
) -> DeviceResult<()> {
|
||||
Ok(())
|
||||
|
||||
1
third_party/rust/wgpu-hal/src/gles/egl.rs
vendored
1
third_party/rust/wgpu-hal/src/gles/egl.rs
vendored
@@ -1092,7 +1092,6 @@ impl Surface {
|
||||
.map_err(|e| {
|
||||
log::error!("swap_buffers failed: {}", e);
|
||||
crate::SurfaceError::Lost
|
||||
// TODO: should we unset the current context here?
|
||||
})?;
|
||||
self.egl
|
||||
.instance
|
||||
|
||||
1
third_party/rust/wgpu-hal/src/gles/queue.rs
vendored
1
third_party/rust/wgpu-hal/src/gles/queue.rs
vendored
@@ -1748,7 +1748,6 @@ impl crate::Queue<super::Api> for super::Queue {
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&super::CommandBuffer],
|
||||
_surface_textures: &[&super::Texture],
|
||||
signal_fence: Option<(&mut super::Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
let shared = Arc::clone(&self.shared);
|
||||
|
||||
43
third_party/rust/wgpu-hal/src/gles/wgl.rs
vendored
43
third_party/rust/wgpu-hal/src/gles/wgl.rs
vendored
@@ -77,24 +77,6 @@ impl AdapterContext {
|
||||
|
||||
AdapterContextLock { inner }
|
||||
}
|
||||
|
||||
/// Obtain a lock to the WGL context and get handle to the [`glow::Context`] that can be used to
|
||||
/// do rendering.
|
||||
///
|
||||
/// Unlike [`lock`](Self::lock), this accepts a device to pass to `make_current` and exposes the error
|
||||
/// when `make_current` fails.
|
||||
#[track_caller]
|
||||
fn lock_with_dc(&self, device: HDC) -> Result<AdapterContextLock<'_>, Error> {
|
||||
let inner = self
|
||||
.inner
|
||||
.try_lock_for(Duration::from_secs(CONTEXT_LOCK_TIMEOUT_SECS))
|
||||
.expect("Could not lock adapter context. This is most-likely a deadlock.");
|
||||
|
||||
inner
|
||||
.context
|
||||
.make_current(device)
|
||||
.map(|()| AdapterContextLock { inner })
|
||||
}
|
||||
}
|
||||
|
||||
/// A guard containing a lock to an [`AdapterContext`]
|
||||
@@ -621,10 +603,16 @@ impl Surface {
|
||||
window: self.window,
|
||||
};
|
||||
|
||||
let gl = context.lock_with_dc(dc.device).map_err(|e| {
|
||||
let inner = context.inner.lock();
|
||||
|
||||
if let Err(e) = inner.context.make_current(dc.device) {
|
||||
log::error!("unable to make the OpenGL context current for surface: {e}",);
|
||||
crate::SurfaceError::Other("unable to make the OpenGL context current for surface")
|
||||
})?;
|
||||
return Err(crate::SurfaceError::Other(
|
||||
"unable to make the OpenGL context current for surface",
|
||||
));
|
||||
}
|
||||
|
||||
let gl = &inner.gl;
|
||||
|
||||
unsafe { gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None) };
|
||||
unsafe { gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer)) };
|
||||
@@ -705,11 +693,16 @@ impl crate::Surface<super::Api> for Surface {
|
||||
}
|
||||
|
||||
let format_desc = device.shared.describe_texture_format(config.format);
|
||||
let gl = &device.shared.context.lock_with_dc(dc.device).map_err(|e| {
|
||||
log::error!("unable to make the OpenGL context current for surface: {e}",);
|
||||
crate::SurfaceError::Other("unable to make the OpenGL context current for surface")
|
||||
})?;
|
||||
let inner = &device.shared.context.inner.lock();
|
||||
|
||||
if let Err(e) = inner.context.make_current(dc.device) {
|
||||
log::error!("unable to make the OpenGL context current for surface: {e}",);
|
||||
return Err(crate::SurfaceError::Other(
|
||||
"unable to make the OpenGL context current for surface",
|
||||
));
|
||||
}
|
||||
|
||||
let gl = &inner.gl;
|
||||
let renderbuffer = unsafe { gl.create_renderbuffer() }.map_err(|error| {
|
||||
log::error!("Internal swapchain renderbuffer creation failed: {error}");
|
||||
crate::DeviceError::OutOfMemory
|
||||
|
||||
3
third_party/rust/wgpu-hal/src/lib.rs
vendored
3
third_party/rust/wgpu-hal/src/lib.rs
vendored
@@ -413,12 +413,9 @@ pub trait Queue<A: Api>: WasmNotSendSync {
|
||||
/// - all of the command buffers were created from command pools
|
||||
/// that are associated with this queue.
|
||||
/// - all of the command buffers had `CommadBuffer::finish()` called.
|
||||
/// - all surface textures that the command buffers write to must be
|
||||
/// passed to the surface_textures argument.
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&A::CommandBuffer],
|
||||
surface_textures: &[&A::SurfaceTexture],
|
||||
signal_fence: Option<(&mut A::Fence, FenceValue)>,
|
||||
) -> Result<(), DeviceError>;
|
||||
unsafe fn present(
|
||||
|
||||
1
third_party/rust/wgpu-hal/src/metal/mod.rs
vendored
1
third_party/rust/wgpu-hal/src/metal/mod.rs
vendored
@@ -368,7 +368,6 @@ impl crate::Queue<Api> for Queue {
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&CommandBuffer],
|
||||
_surface_textures: &[&SurfaceTexture],
|
||||
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
objc::rc::autoreleasepool(|| {
|
||||
|
||||
15
third_party/rust/wgpu-hal/src/vulkan/device.rs
vendored
15
third_party/rust/wgpu-hal/src/vulkan/device.rs
vendored
@@ -627,16 +627,8 @@ impl super::Device {
|
||||
let images =
|
||||
unsafe { functor.get_swapchain_images(raw) }.map_err(crate::DeviceError::from)?;
|
||||
|
||||
// NOTE: It's important that we define at least images.len() + 1 wait
|
||||
// semaphores, since we prospectively need to provide the call to
|
||||
// acquire the next image with an unsignaled semaphore.
|
||||
let surface_semaphores = (0..images.len() + 1)
|
||||
.map(|_| unsafe {
|
||||
self.shared
|
||||
.raw
|
||||
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
let vk_info = vk::FenceCreateInfo::builder().build();
|
||||
let fence = unsafe { self.shared.raw.create_fence(&vk_info, None) }
|
||||
.map_err(crate::DeviceError::from)?;
|
||||
|
||||
Ok(super::Swapchain {
|
||||
@@ -644,11 +636,10 @@ impl super::Device {
|
||||
raw_flags,
|
||||
functor,
|
||||
device: Arc::clone(&self.shared),
|
||||
fence,
|
||||
images,
|
||||
config: config.clone(),
|
||||
view_formats: wgt_view_formats,
|
||||
surface_semaphores,
|
||||
next_surface_index: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
24
third_party/rust/wgpu-hal/src/vulkan/instance.rs
vendored
24
third_party/rust/wgpu-hal/src/vulkan/instance.rs
vendored
@@ -169,7 +169,7 @@ impl super::Swapchain {
|
||||
/// # Safety
|
||||
///
|
||||
/// - The device must have been made idle before calling this function.
|
||||
unsafe fn release_resources(mut self, device: &ash::Device) -> Self {
|
||||
unsafe fn release_resources(self, device: &ash::Device) -> Self {
|
||||
profiling::scope!("Swapchain::release_resources");
|
||||
{
|
||||
profiling::scope!("vkDeviceWaitIdle");
|
||||
@@ -177,13 +177,7 @@ impl super::Swapchain {
|
||||
// the presentation work is done, we are forced to wait until the device is idle.
|
||||
let _ = unsafe { device.device_wait_idle() };
|
||||
};
|
||||
|
||||
for semaphore in self.surface_semaphores.drain(..) {
|
||||
unsafe {
|
||||
device.destroy_semaphore(semaphore, None);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { device.destroy_fence(self.fence, None) };
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -940,12 +934,10 @@ impl crate::Surface<super::Api> for super::Surface {
|
||||
timeout_ns = u64::MAX;
|
||||
}
|
||||
|
||||
let wait_semaphore = sc.surface_semaphores[sc.next_surface_index];
|
||||
|
||||
// will block if no image is available
|
||||
let (index, suboptimal) = match unsafe {
|
||||
sc.functor
|
||||
.acquire_next_image(sc.raw, timeout_ns, wait_semaphore, vk::Fence::null())
|
||||
.acquire_next_image(sc.raw, timeout_ns, vk::Semaphore::null(), sc.fence)
|
||||
} {
|
||||
// We treat `VK_SUBOPTIMAL_KHR` as `VK_SUCCESS` on Android.
|
||||
// See the comment in `Queue::present`.
|
||||
@@ -965,14 +957,17 @@ impl crate::Surface<super::Api> for super::Surface {
|
||||
}
|
||||
};
|
||||
|
||||
sc.next_surface_index += 1;
|
||||
sc.next_surface_index %= sc.surface_semaphores.len();
|
||||
|
||||
// special case for Intel Vulkan returning bizzare values (ugh)
|
||||
if sc.device.vendor_id == crate::auxil::db::intel::VENDOR && index > 0x100 {
|
||||
return Err(crate::SurfaceError::Outdated);
|
||||
}
|
||||
|
||||
let fences = &[sc.fence];
|
||||
|
||||
unsafe { sc.device.raw.wait_for_fences(fences, true, !0) }
|
||||
.map_err(crate::DeviceError::from)?;
|
||||
unsafe { sc.device.raw.reset_fences(fences) }.map_err(crate::DeviceError::from)?;
|
||||
|
||||
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkRenderPassBeginInfo.html#VUID-VkRenderPassBeginInfo-framebuffer-03209
|
||||
let raw_flags = if sc
|
||||
.raw_flags
|
||||
@@ -999,7 +994,6 @@ impl crate::Surface<super::Api> for super::Surface {
|
||||
},
|
||||
view_formats: sc.view_formats.clone(),
|
||||
},
|
||||
wait_semaphore,
|
||||
};
|
||||
Ok(Some(crate::AcquiredSurfaceTexture {
|
||||
texture,
|
||||
|
||||
88
third_party/rust/wgpu-hal/src/vulkan/mod.rs
vendored
88
third_party/rust/wgpu-hal/src/vulkan/mod.rs
vendored
@@ -146,14 +146,10 @@ struct Swapchain {
|
||||
raw_flags: vk::SwapchainCreateFlagsKHR,
|
||||
functor: khr::Swapchain,
|
||||
device: Arc<DeviceShared>,
|
||||
fence: vk::Fence,
|
||||
images: Vec<vk::Image>,
|
||||
config: crate::SurfaceConfiguration,
|
||||
view_formats: Vec<wgt::TextureFormat>,
|
||||
/// One wait semaphore per swapchain image. This will be associated with the
|
||||
/// surface texture, and later collected during submission.
|
||||
surface_semaphores: Vec<vk::Semaphore>,
|
||||
/// Current semaphore index to use when acquiring a surface.
|
||||
next_surface_index: usize,
|
||||
}
|
||||
|
||||
pub struct Surface {
|
||||
@@ -167,7 +163,6 @@ pub struct Surface {
|
||||
pub struct SurfaceTexture {
|
||||
index: u32,
|
||||
texture: Texture,
|
||||
wait_semaphore: vk::Semaphore,
|
||||
}
|
||||
|
||||
impl Borrow<Texture> for SurfaceTexture {
|
||||
@@ -590,43 +585,29 @@ impl crate::Queue<Api> for Queue {
|
||||
unsafe fn submit(
|
||||
&self,
|
||||
command_buffers: &[&CommandBuffer],
|
||||
surface_textures: &[&SurfaceTexture],
|
||||
signal_fence: Option<(&mut Fence, crate::FenceValue)>,
|
||||
) -> Result<(), crate::DeviceError> {
|
||||
let vk_cmd_buffers = command_buffers
|
||||
.iter()
|
||||
.map(|cmd| cmd.raw)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut vk_info = vk::SubmitInfo::builder().command_buffers(&vk_cmd_buffers);
|
||||
|
||||
let mut fence_raw = vk::Fence::null();
|
||||
|
||||
let mut wait_stage_masks = Vec::new();
|
||||
let mut wait_semaphores = Vec::new();
|
||||
let mut signal_semaphores = ArrayVec::<_, 2>::new();
|
||||
let mut signal_values = ArrayVec::<_, 2>::new();
|
||||
|
||||
for &surface_texture in surface_textures {
|
||||
wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE);
|
||||
wait_semaphores.push(surface_texture.wait_semaphore);
|
||||
}
|
||||
|
||||
let old_index = self.relay_index.load(Ordering::Relaxed);
|
||||
|
||||
let sem_index = if old_index >= 0 {
|
||||
wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE);
|
||||
wait_semaphores.push(self.relay_semaphores[old_index as usize]);
|
||||
(old_index as usize + 1) % self.relay_semaphores.len()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
signal_semaphores.push(self.relay_semaphores[sem_index]);
|
||||
|
||||
self.relay_index
|
||||
.store(sem_index as isize, Ordering::Relaxed);
|
||||
let mut vk_timeline_info;
|
||||
let mut signal_semaphores = [vk::Semaphore::null(), vk::Semaphore::null()];
|
||||
let signal_values;
|
||||
|
||||
if let Some((fence, value)) = signal_fence {
|
||||
fence.maintain(&self.device.raw)?;
|
||||
match *fence {
|
||||
Fence::TimelineSemaphore(raw) => {
|
||||
signal_semaphores.push(raw);
|
||||
signal_values.push(!0);
|
||||
signal_values.push(value);
|
||||
signal_values = [!0, value];
|
||||
signal_semaphores[1] = raw;
|
||||
vk_timeline_info = vk::TimelineSemaphoreSubmitInfo::builder()
|
||||
.signal_semaphore_values(&signal_values);
|
||||
vk_info = vk_info.push_next(&mut vk_timeline_info);
|
||||
}
|
||||
Fence::FencePool {
|
||||
ref mut active,
|
||||
@@ -646,25 +627,26 @@ impl crate::Queue<Api> for Queue {
|
||||
}
|
||||
}
|
||||
|
||||
let vk_cmd_buffers = command_buffers
|
||||
.iter()
|
||||
.map(|cmd| cmd.raw)
|
||||
.collect::<Vec<_>>();
|
||||
let wait_stage_mask = [vk::PipelineStageFlags::TOP_OF_PIPE];
|
||||
let old_index = self.relay_index.load(Ordering::Relaxed);
|
||||
let sem_index = if old_index >= 0 {
|
||||
vk_info = vk_info
|
||||
.wait_semaphores(&self.relay_semaphores[old_index as usize..old_index as usize + 1])
|
||||
.wait_dst_stage_mask(&wait_stage_mask);
|
||||
(old_index as usize + 1) % self.relay_semaphores.len()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.relay_index
|
||||
.store(sem_index as isize, Ordering::Relaxed);
|
||||
signal_semaphores[0] = self.relay_semaphores[sem_index];
|
||||
|
||||
let mut vk_info = vk::SubmitInfo::builder().command_buffers(&vk_cmd_buffers);
|
||||
|
||||
vk_info = vk_info
|
||||
.wait_semaphores(&wait_semaphores)
|
||||
.wait_dst_stage_mask(&wait_stage_masks)
|
||||
.signal_semaphores(&signal_semaphores);
|
||||
|
||||
let mut vk_timeline_info;
|
||||
|
||||
if !signal_values.is_empty() {
|
||||
vk_timeline_info =
|
||||
vk::TimelineSemaphoreSubmitInfo::builder().signal_semaphore_values(&signal_values);
|
||||
vk_info = vk_info.push_next(&mut vk_timeline_info);
|
||||
}
|
||||
let signal_count = if signal_semaphores[1] == vk::Semaphore::null() {
|
||||
1
|
||||
} else {
|
||||
2
|
||||
};
|
||||
vk_info = vk_info.signal_semaphores(&signal_semaphores[..signal_count]);
|
||||
|
||||
profiling::scope!("vkQueueSubmit");
|
||||
unsafe {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"6b0d7ddecc26e3b72cb6d47793770203147f851f048da8d1f5d8f508e40d4f82","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"d24ea48c4ddcce18997fbc101f798f647334b370746643df6fb5ad161373323e","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
|
||||
{"files":{"Cargo.toml":"577d13b5d0a571c9610e782f9aba2655e896f5959009b32d023d186a0268aca1","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"3fe98027aa73970c8ab7874a3e13dbfd6faa87df2081beb5c83aeec4c60f372f","src/lib.rs":"013810123a44be78ed2f35902c52c4fa90c84a3d8a2f15f25541e7761cc726d8","src/math.rs":"4d03039736dd6926feb139bc68734cb59df34ede310427bbf059e5c925e0af3b"},"package":null}
|
||||
2
third_party/rust/wgpu-types/Cargo.toml
vendored
2
third_party/rust/wgpu-types/Cargo.toml
vendored
@@ -53,7 +53,9 @@ features = ["serde_derive"]
|
||||
|
||||
[features]
|
||||
fragile-send-sync-non-atomic-wasm = []
|
||||
replay = ["serde"]
|
||||
strict_asserts = []
|
||||
trace = ["serde"]
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dependencies]
|
||||
js-sys = "0.3.67"
|
||||
|
||||
240
third_party/rust/wgpu-types/src/lib.rs
vendored
240
third_party/rust/wgpu-types/src/lib.rs
vendored
@@ -10,9 +10,7 @@
|
||||
#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
|
||||
|
||||
#[cfg(any(feature = "serde", test))]
|
||||
use serde::Deserialize;
|
||||
#[cfg(any(feature = "serde", test))]
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::PathBuf;
|
||||
use std::{num::NonZeroU32, ops::Range};
|
||||
@@ -98,13 +96,13 @@ pub const QUERY_SIZE: u32 = 8;
|
||||
pub enum Backend {
|
||||
/// Dummy backend, used for testing.
|
||||
Empty = 0,
|
||||
/// Vulkan API (Windows, Linux, Android, MacOS via `vulkan-portability`/MoltenVK)
|
||||
/// Vulkan API
|
||||
Vulkan = 1,
|
||||
/// Metal API (Apple platforms)
|
||||
Metal = 2,
|
||||
/// Direct3D-12 (Windows)
|
||||
Dx12 = 3,
|
||||
/// OpenGL 3.3+ (Windows), OpenGL ES 3.0+ (Linux, Android, MacOS via Angle), and WebGL2
|
||||
/// OpenGL ES-3 (Linux, Android)
|
||||
Gl = 4,
|
||||
/// WebGPU in the browser
|
||||
BrowserWebGpu = 5,
|
||||
@@ -112,7 +110,7 @@ pub enum Backend {
|
||||
|
||||
impl Backend {
|
||||
/// Returns the string name of the backend.
|
||||
pub const fn to_str(self) -> &'static str {
|
||||
pub fn to_str(self) -> &'static str {
|
||||
match self {
|
||||
Backend::Empty => "empty",
|
||||
Backend::Vulkan => "vulkan",
|
||||
@@ -124,19 +122,14 @@ impl Backend {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Backend {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.to_str())
|
||||
}
|
||||
}
|
||||
|
||||
/// Power Preference when choosing a physical adapter.
|
||||
///
|
||||
/// Corresponds to [WebGPU `GPUPowerPreference`](
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum PowerPreference {
|
||||
#[default]
|
||||
@@ -204,7 +197,8 @@ impl From<Backend> for Backends {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct RequestAdapterOptions<S> {
|
||||
/// Power preference for the adapter.
|
||||
pub power_preference: PowerPreference,
|
||||
@@ -901,14 +895,6 @@ bitflags::bitflags! {
|
||||
/// This mainly applies to a Vulkan driver's compliance version. If the major compliance version
|
||||
/// is `0`, then the driver is ignored. This flag allows that driver to be enabled for testing.
|
||||
const ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER = 1 << 3;
|
||||
/// Enable GPU-based validation. Currently, this only changes behavior on the DX12
|
||||
/// backend.
|
||||
///
|
||||
/// Supported platforms:
|
||||
///
|
||||
/// - D3D12; called ["GPU-based validation", or
|
||||
/// "GBV"](https://web.archive.org/web/20230206120404/https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-d3d12-debug-layer-gpu-based-validation)
|
||||
const GPU_BASED_VALIDATION = 1 << 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -919,9 +905,9 @@ impl Default for InstanceFlags {
|
||||
}
|
||||
|
||||
impl InstanceFlags {
|
||||
/// Enable recommended debugging and validation flags.
|
||||
/// Enable debugging and validation flags.
|
||||
pub fn debugging() -> Self {
|
||||
InstanceFlags::DEBUG | InstanceFlags::VALIDATION | InstanceFlags::GPU_BASED_VALIDATION
|
||||
InstanceFlags::DEBUG | InstanceFlags::VALIDATION
|
||||
}
|
||||
|
||||
/// Infer good defaults from the build type
|
||||
@@ -964,9 +950,6 @@ impl InstanceFlags {
|
||||
if let Some(bit) = env("WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER") {
|
||||
self.set(Self::ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER, bit);
|
||||
}
|
||||
if let Some(bit) = env("WGPU_GPU_BASED_VALIDATION") {
|
||||
self.set(Self::GPU_BASED_VALIDATION, bit);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
@@ -1006,7 +989,7 @@ impl InstanceFlags {
|
||||
/// [`downlevel_defaults()`]: Limits::downlevel_defaults
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase", default))]
|
||||
pub struct Limits {
|
||||
/// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`.
|
||||
@@ -1681,7 +1664,8 @@ pub struct AdapterInfo {
|
||||
/// https://gpuweb.github.io/gpuweb/#gpudevicedescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct DeviceDescriptor<L> {
|
||||
/// Debug label for the device.
|
||||
pub label: L,
|
||||
@@ -1743,7 +1727,8 @@ impl_bitflags!(ShaderStages);
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gputextureviewdimension).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum TextureViewDimension {
|
||||
/// A one dimensional texture. `texture_1d` in WGSL and `texture1D` in GLSL.
|
||||
#[cfg_attr(feature = "serde", serde(rename = "1d"))]
|
||||
@@ -1787,7 +1772,8 @@ impl TextureViewDimension {
|
||||
/// used with the first render target.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum BlendFactor {
|
||||
/// 0.0
|
||||
@@ -1849,7 +1835,8 @@ impl BlendFactor {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpublendoperation).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum BlendOperation {
|
||||
/// Src + Dst
|
||||
@@ -1871,7 +1858,8 @@ pub enum BlendOperation {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpublendcomponent).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct BlendComponent {
|
||||
/// Multiplier for the source, which is produced by the fragment shader.
|
||||
@@ -1926,7 +1914,8 @@ impl Default for BlendComponent {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpublendstate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct BlendState {
|
||||
/// Color equation.
|
||||
@@ -1965,7 +1954,8 @@ impl BlendState {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpucolortargetstate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct ColorTargetState {
|
||||
/// The [`TextureFormat`] of the image that this pipeline will render to. Must match the format
|
||||
@@ -1997,7 +1987,8 @@ impl From<TextureFormat> for ColorTargetState {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpuprimitivetopology).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum PrimitiveTopology {
|
||||
/// Vertex data is a list of points. Each vertex is a new point.
|
||||
@@ -2037,7 +2028,8 @@ impl PrimitiveTopology {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpufrontface).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum FrontFace {
|
||||
/// Triangles with vertices in counter clockwise order are considered the front face.
|
||||
@@ -2058,7 +2050,8 @@ pub enum FrontFace {
|
||||
/// except that the `"none"` value is represented using `Option<Face>` instead.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum Face {
|
||||
/// Front face
|
||||
@@ -2070,7 +2063,8 @@ pub enum Face {
|
||||
/// Type of drawing mode for polygons
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum PolygonMode {
|
||||
/// Polygons are filled
|
||||
@@ -2088,7 +2082,8 @@ pub enum PolygonMode {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuprimitivestate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct PrimitiveState {
|
||||
/// The primitive topology used to interpret vertices.
|
||||
@@ -2128,7 +2123,8 @@ pub struct PrimitiveState {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpumultisamplestate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct MultisampleState {
|
||||
/// The number of samples calculated per pixel (for MSAA). For non-multisampled textures,
|
||||
@@ -2227,7 +2223,7 @@ pub struct TextureFormatFeatures {
|
||||
/// ASTC block dimensions
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub enum AstcBlock {
|
||||
/// 4x4 block compressed texture. 16 bytes per block (8 bit/px).
|
||||
B4x4,
|
||||
@@ -2262,7 +2258,7 @@ pub enum AstcBlock {
|
||||
/// ASTC RGBA channel
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub enum AstcChannel {
|
||||
/// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader.
|
||||
///
|
||||
@@ -4370,7 +4366,8 @@ impl MaintainResult {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct StencilState {
|
||||
/// Front face mode.
|
||||
pub front: StencilFaceState,
|
||||
@@ -4417,7 +4414,8 @@ impl StencilState {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct DepthBiasState {
|
||||
/// Constant depth biasing factor, in basic units of the depth format.
|
||||
pub constant: i32,
|
||||
@@ -4458,7 +4456,8 @@ impl Eq for DepthBiasState {}
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct DepthStencilState {
|
||||
/// Format of the depth/stencil buffer, must be special depth format. Must match the format
|
||||
/// of the depth/stencil attachment in [`CommandEncoder::begin_render_pass`][CEbrp].
|
||||
@@ -4470,10 +4469,10 @@ pub struct DepthStencilState {
|
||||
/// Comparison function used to compare depth values in the depth test.
|
||||
pub depth_compare: CompareFunction,
|
||||
/// Stencil state.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub stencil: StencilState,
|
||||
/// Depth bias state.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub bias: DepthBiasState,
|
||||
}
|
||||
|
||||
@@ -4505,7 +4504,7 @@ impl DepthStencilState {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpuindexformat).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum IndexFormat {
|
||||
/// Indices are 16 bit unsigned integers.
|
||||
@@ -4521,7 +4520,8 @@ pub enum IndexFormat {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpustenciloperation).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum StencilOperation {
|
||||
/// Keep stencil value unchanged.
|
||||
@@ -4554,7 +4554,8 @@ pub enum StencilOperation {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpustencilfacestate).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct StencilFaceState {
|
||||
/// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer.
|
||||
@@ -4604,7 +4605,8 @@ impl Default for StencilFaceState {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum CompareFunction {
|
||||
/// Function never passes
|
||||
@@ -4698,7 +4700,8 @@ impl CompareFunction {
|
||||
/// [`Instance`]: VertexStepMode::Instance
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum VertexStepMode {
|
||||
/// Vertex data is advanced every vertex.
|
||||
@@ -4719,7 +4722,8 @@ pub enum VertexStepMode {
|
||||
/// [`vertex_attr_array`]: ../wgpu/macro.vertex_attr_array.html
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct VertexAttribute {
|
||||
/// Format of the input
|
||||
@@ -4736,7 +4740,8 @@ pub struct VertexAttribute {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
||||
pub enum VertexFormat {
|
||||
/// Two unsigned bytes (u8). `vec2<u32>` in shaders.
|
||||
@@ -4895,7 +4900,8 @@ impl_bitflags!(BufferUsages);
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferdescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BufferDescriptor<L> {
|
||||
/// Debug label of a buffer. This will show up in graphics debuggers for easy identification.
|
||||
pub label: L,
|
||||
@@ -4929,7 +4935,8 @@ impl<L> BufferDescriptor<L> {
|
||||
/// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`](
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor).
|
||||
#[repr(C)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct CommandEncoderDescriptor<L> {
|
||||
/// Debug label for the command encoder. This will show up in graphics debuggers for easy identification.
|
||||
@@ -4954,7 +4961,8 @@ impl<T> Default for CommandEncoderDescriptor<Option<T>> {
|
||||
/// Behavior of the presentation engine based on frame rate.
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum PresentMode {
|
||||
/// Chooses FifoRelaxed -> Fifo based on availability.
|
||||
///
|
||||
@@ -5026,7 +5034,8 @@ pub enum PresentMode {
|
||||
/// compositing.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
||||
pub enum CompositeAlphaMode {
|
||||
/// Chooses either `Opaque` or `Inherit` automatically,depending on the
|
||||
@@ -5125,7 +5134,8 @@ impl Default for SurfaceCapabilities {
|
||||
/// [`Surface`]: ../wgpu/struct.Surface.html
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct SurfaceConfiguration<V> {
|
||||
/// The usage of the swap chain. The only supported usage is `RENDER_ATTACHMENT`.
|
||||
pub usage: TextureUsages,
|
||||
@@ -5251,7 +5261,7 @@ impl PresentationTimestamp {
|
||||
/// This is not to be used as a generic color type, only for specific wgpu interfaces.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct Color {
|
||||
/// Red component of the color
|
||||
@@ -5310,7 +5320,8 @@ impl Color {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gputexturedimension).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum TextureDimension {
|
||||
/// 1D texture
|
||||
#[cfg_attr(feature = "serde", serde(rename = "1d"))]
|
||||
@@ -5329,7 +5340,8 @@ pub enum TextureDimension {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin2ddict).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct Origin2d {
|
||||
///
|
||||
@@ -5364,7 +5376,8 @@ impl std::fmt::Debug for Origin2d {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuorigin3ddict).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct Origin3d {
|
||||
/// X position of the origin
|
||||
@@ -5406,7 +5419,8 @@ impl std::fmt::Debug for Origin3d {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuextent3ddict).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct Extent3d {
|
||||
/// Width of the extent
|
||||
@@ -5605,7 +5619,8 @@ fn test_max_mips() {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct TextureDescriptor<L, V> {
|
||||
/// Debug label of the texture. This will show up in graphics debuggers for easy identification.
|
||||
pub label: L,
|
||||
@@ -5736,7 +5751,8 @@ impl<L, V> TextureDescriptor<L, V> {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gputextureaspect).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum TextureAspect {
|
||||
/// Depth, Stencil, and Color.
|
||||
@@ -5760,7 +5776,8 @@ pub enum TextureAspect {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum AddressMode {
|
||||
/// Clamp the value to the edge of the texture
|
||||
@@ -5793,7 +5810,8 @@ pub enum AddressMode {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpufiltermode).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum FilterMode {
|
||||
/// Nearest neighbor sampling.
|
||||
@@ -5809,7 +5827,8 @@ pub enum FilterMode {
|
||||
|
||||
/// A range of push constant memory to pass to a shader stage.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct PushConstantRange {
|
||||
/// Stage push constant range is visible from. Each stage can only be served by at most one range.
|
||||
/// One range can serve multiple stages however.
|
||||
@@ -5825,7 +5844,8 @@ pub struct PushConstantRange {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct CommandBufferDescriptor<L> {
|
||||
/// Debug label of this command buffer.
|
||||
pub label: L,
|
||||
@@ -5846,7 +5866,8 @@ impl<L> CommandBufferDescriptor<L> {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct RenderBundleDepthStencil {
|
||||
/// Format of the attachment.
|
||||
pub format: TextureFormat,
|
||||
@@ -5873,7 +5894,8 @@ pub struct RenderBundleDepthStencil {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundledescriptor).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct RenderBundleDescriptor<L> {
|
||||
/// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification.
|
||||
pub label: L,
|
||||
@@ -5909,7 +5931,8 @@ impl<T> Default for RenderBundleDescriptor<Option<T>> {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImageDataLayout {
|
||||
/// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size.
|
||||
/// For non-compressed textures, this is 1.
|
||||
@@ -5949,7 +5972,8 @@ pub struct ImageDataLayout {
|
||||
/// Corresponds to [WebGPU `GPUBufferBindingType`](
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype).
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum BufferBindingType {
|
||||
/// A buffer for uniform values.
|
||||
///
|
||||
@@ -6014,7 +6038,8 @@ pub enum BufferBindingType {
|
||||
/// Corresponds to [WebGPU `GPUTextureSampleType`](
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype).
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum TextureSampleType {
|
||||
/// Sampling returns floats.
|
||||
///
|
||||
@@ -6096,7 +6121,8 @@ impl Default for TextureSampleType {
|
||||
/// Corresponds to [WebGPU `GPUStorageTextureAccess`](
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess).
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum StorageTextureAccess {
|
||||
/// The texture can only be written in the shader and it:
|
||||
@@ -6158,7 +6184,8 @@ pub enum StorageTextureAccess {
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpusamplerbindingtype).
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum SamplerBindingType {
|
||||
/// The sampling result is produced based on more than a single color sample from a texture,
|
||||
@@ -6178,7 +6205,8 @@ pub enum SamplerBindingType {
|
||||
/// Corresponds to WebGPU's mutually exclusive fields within [`GPUBindGroupLayoutEntry`](
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum BindingType {
|
||||
/// A buffer binding.
|
||||
///
|
||||
@@ -6194,7 +6222,7 @@ pub enum BindingType {
|
||||
/// for each dynamic binding in increasing order of binding number.
|
||||
///
|
||||
/// [RPsbg]: ../wgpu/struct.RenderPass.html#method.set_bind_group
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
has_dynamic_offset: bool,
|
||||
|
||||
/// The minimum size for a [`BufferBinding`] matching this entry, in bytes.
|
||||
@@ -6222,7 +6250,7 @@ pub enum BindingType {
|
||||
/// [minimum buffer binding size]: https://www.w3.org/TR/webgpu/#minimum-buffer-binding-size
|
||||
/// [`create_render_pipeline`]: ../wgpu/struct.Device.html#method.create_render_pipeline
|
||||
/// [`create_compute_pipeline`]: ../wgpu/struct.Device.html#method.create_compute_pipeline
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
min_binding_size: Option<BufferSize>,
|
||||
},
|
||||
/// A sampler that can be used to sample a texture.
|
||||
@@ -6327,7 +6355,8 @@ impl BindingType {
|
||||
/// Corresponds to [WebGPU `GPUBindGroupLayoutEntry`](
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BindGroupLayoutEntry {
|
||||
/// Binding index. Must match shader index and be unique inside a BindGroupLayout. A binding
|
||||
/// of index 1, would be described as `layout(set = 0, binding = 1) uniform` in shaders.
|
||||
@@ -6341,7 +6370,7 @@ pub struct BindGroupLayoutEntry {
|
||||
/// If this value is Some and `ty` is `BindingType::Texture`, [`Features::TEXTURE_BINDING_ARRAY`] must be supported.
|
||||
///
|
||||
/// If this value is Some and `ty` is any other variant, bind group creation will fail.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub count: Option<NonZeroU32>,
|
||||
}
|
||||
|
||||
@@ -6351,7 +6380,8 @@ pub struct BindGroupLayoutEntry {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImageCopyBuffer<B> {
|
||||
/// The buffer to be copied to/from.
|
||||
pub buffer: B,
|
||||
@@ -6365,7 +6395,8 @@ pub struct ImageCopyBuffer<B> {
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture).
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImageCopyTexture<T> {
|
||||
/// The texture to be copied to/from.
|
||||
pub texture: T,
|
||||
@@ -6374,10 +6405,10 @@ pub struct ImageCopyTexture<T> {
|
||||
/// The base texel of the texture in the selected `mip_level`. Together
|
||||
/// with the `copy_size` argument to copy functions, defines the
|
||||
/// sub-region of the texture to copy.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub origin: Origin3d,
|
||||
/// The copy aspect.
|
||||
#[cfg_attr(feature = "serde", serde(default))]
|
||||
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
|
||||
pub aspect: TextureAspect,
|
||||
}
|
||||
|
||||
@@ -6497,7 +6528,8 @@ unsafe impl Sync for ExternalImageSource {}
|
||||
/// Corresponds to [HTML Canvas `PredefinedColorSpace`](
|
||||
/// https://html.spec.whatwg.org/multipage/canvas.html#predefinedcolorspace).
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
|
||||
pub enum PredefinedColorSpace {
|
||||
/// sRGB color space
|
||||
@@ -6512,7 +6544,8 @@ pub enum PredefinedColorSpace {
|
||||
/// Corresponds to [WebGPU `GPUImageCopyTextureTagged`](
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexturetagged).
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImageCopyTextureTagged<T> {
|
||||
/// The texture to be copied to/from.
|
||||
pub texture: T,
|
||||
@@ -6543,7 +6576,8 @@ impl<T: Copy> ImageCopyTextureTagged<T> {
|
||||
/// Subresource range within an image
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
||||
pub struct ImageSubresourceRange {
|
||||
/// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA].
|
||||
@@ -6644,7 +6678,8 @@ impl ImageSubresourceRange {
|
||||
/// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`]
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum SamplerBorderColor {
|
||||
/// [0, 0, 0, 0]
|
||||
TransparentBlack,
|
||||
@@ -6666,7 +6701,8 @@ pub enum SamplerBorderColor {
|
||||
/// Corresponds to [WebGPU `GPUQuerySetDescriptor`](
|
||||
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor).
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct QuerySetDescriptor<L> {
|
||||
/// Debug label for the query set.
|
||||
pub label: L,
|
||||
@@ -6693,7 +6729,8 @@ impl<L> QuerySetDescriptor<L> {
|
||||
/// Corresponds to [WebGPU `GPUQueryType`](
|
||||
/// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype).
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub enum QueryType {
|
||||
/// Query returns a single 64-bit number, serving as an occlusion boolean.
|
||||
Occlusion,
|
||||
@@ -6839,7 +6876,8 @@ impl DispatchIndirectArgs {
|
||||
|
||||
/// Describes how shader bound checks should be performed.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ShaderBoundChecks {
|
||||
runtime_checks: bool,
|
||||
}
|
||||
@@ -7061,18 +7099,4 @@ pub enum DeviceLostReason {
|
||||
Unknown = 0,
|
||||
/// After Device::destroy
|
||||
Destroyed = 1,
|
||||
/// After Device::drop
|
||||
///
|
||||
/// WebGPU does not invoke the device lost callback when the device is
|
||||
/// dropped to prevent garbage collection from being observable. In wgpu,
|
||||
/// we invoke the callback on drop to help with managing memory owned by
|
||||
/// the callback.
|
||||
Dropped = 2,
|
||||
/// After replacing the device_lost_callback
|
||||
///
|
||||
/// WebGPU does not have a concept of a device lost callback, but wgpu
|
||||
/// does. wgpu guarantees that any supplied callback will be invoked
|
||||
/// exactly once before it is dropped, which helps with managing the
|
||||
/// memory owned by the callback.
|
||||
ReplacedCallback = 3,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user