Backed out changeset f4ed4d3e0e9e (bug 1634425) for hazard failure on WebGPUParent.cpp CLOSED TREE

This commit is contained in:
Bogdan Tara 2020-05-27 01:12:40 +03:00
Родитель 4331b35ab5
Коммит 6ed3c943f7
41 изменённых файлов: 341 добавлений и 3495 удалений

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

@ -5598,7 +5598,6 @@ dependencies = [
"log",
"parking_lot",
"peek-poke 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ron",
"serde",
"smallvec",
"vec_map",

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

@ -14,13 +14,13 @@ using SerialPipelineLayoutDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialBindGroupDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialComputePipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialRenderPipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialTextureDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using dom::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h";
using dom::GPUDeviceDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUCommandEncoderDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUPipelineLayoutDescriptor from "mozilla/dom/WebGPUBinding.h";
using webgpu::ffi::WGPUBufferDescriptor from "mozilla/webgpu/ffi/wgpu.h";
using webgpu::ffi::WGPUTextureDescriptor from "mozilla/webgpu/ffi/wgpu.h";
using webgpu::ffi::WGPUSamplerDescriptor from "mozilla/webgpu/ffi/wgpu.h";
using webgpu::ffi::WGPUTextureViewDescriptor from "mozilla/webgpu/ffi/wgpu.h";
using webgpu::ffi::WGPUBufferCopyView from "mozilla/webgpu/ffi/wgpu.h";
@ -46,16 +46,16 @@ parent:
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (RawId adapterId);
async AdapterRequestDevice(RawId selfId, GPUDeviceDescriptor desc, RawId newId);
async AdapterDestroy(RawId selfId);
async DeviceCreateBuffer(RawId selfId, WGPUBufferDescriptor desc, nsCString label, RawId newId);
async DeviceCreateBuffer(RawId selfId, GPUBufferDescriptor desc, RawId newId);
async DeviceDestroy(RawId selfId);
async DeviceUnmapBuffer(RawId selfId, RawId bufferId, Shmem shmem, bool flush);
async BufferMapRead(RawId selfId, Shmem shmem) returns (Shmem sm);
async BufferDestroy(RawId selfId);
async DeviceCreateTexture(RawId selfId, WGPUTextureDescriptor desc, nsCString label, RawId newId);
async TextureCreateView(RawId selfId, WGPUTextureViewDescriptor desc, nsCString label, RawId newId);
async DeviceCreateTexture(RawId selfId, SerialTextureDescriptor desc, RawId newId);
async TextureCreateView(RawId selfId, WGPUTextureViewDescriptor desc, RawId newId);
async TextureDestroy(RawId selfId);
async TextureViewDestroy(RawId selfId);
async DeviceCreateSampler(RawId selfId, WGPUSamplerDescriptor desc, nsCString label, RawId newId);
async DeviceCreateSampler(RawId selfId, WGPUSamplerDescriptor desc, RawId newId);
async SamplerDestroy(RawId selfId);
async DeviceCreateCommandEncoder(RawId selfId, GPUCommandEncoderDescriptor desc, RawId newId);
async CommandEncoderCopyBufferToBuffer(RawId selfId, RawId sourceId, BufferAddress sourceOffset, RawId destinationId, BufferAddress destinationOffset, BufferAddress size);

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

@ -73,12 +73,8 @@ Maybe<RawId> WebGPUChild::AdapterRequestDevice(
RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
const dom::GPUBufferDescriptor& aDesc) {
ffi::WGPUBufferDescriptor desc = {};
desc.size = aDesc.mSize;
desc.usage = aDesc.mUsage;
RawId id = ffi::wgpu_client_make_buffer_id(mClient, aSelfId);
if (!SendDeviceCreateBuffer(aSelfId, desc, nsCString(), id)) {
if (!SendDeviceCreateBuffer(aSelfId, aDesc, id)) {
MOZ_CRASH("IPC failure");
}
return id;
@ -119,28 +115,28 @@ UniquePtr<ffi::WGPUTextureViewDescriptor> WebGPUChild::GetDefaultViewDescriptor(
RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
const dom::GPUTextureDescriptor& aDesc) {
ffi::WGPUTextureDescriptor desc = {};
SerialTextureDescriptor desc = {};
if (aDesc.mSize.IsUnsignedLongSequence()) {
const auto& seq = aDesc.mSize.GetAsUnsignedLongSequence();
desc.size.width = seq.Length() > 0 ? seq[0] : 1;
desc.size.height = seq.Length() > 1 ? seq[1] : 1;
desc.size.depth = seq.Length() > 2 ? seq[2] : 1;
desc.mSize.width = seq.Length() > 0 ? seq[0] : 1;
desc.mSize.height = seq.Length() > 1 ? seq[1] : 1;
desc.mSize.depth = seq.Length() > 2 ? seq[2] : 1;
} else if (aDesc.mSize.IsGPUExtent3DDict()) {
const auto& dict = aDesc.mSize.GetAsGPUExtent3DDict();
desc.size.width = dict.mWidth;
desc.size.height = dict.mHeight;
desc.size.depth = dict.mDepth;
desc.mSize.width = dict.mWidth;
desc.mSize.height = dict.mHeight;
desc.mSize.depth = dict.mDepth;
} else {
MOZ_CRASH("Unexpected union");
}
desc.mip_level_count = aDesc.mMipLevelCount;
desc.sample_count = aDesc.mSampleCount;
desc.dimension = ffi::WGPUTextureDimension(aDesc.mDimension);
desc.format = ffi::WGPUTextureFormat(aDesc.mFormat);
desc.usage = aDesc.mUsage;
desc.mMipLevelCount = aDesc.mMipLevelCount;
desc.mSampleCount = aDesc.mSampleCount;
desc.mDimension = ffi::WGPUTextureDimension(aDesc.mDimension);
desc.mFormat = ffi::WGPUTextureFormat(aDesc.mFormat);
desc.mUsage = aDesc.mUsage;
RawId id = ffi::wgpu_client_make_texture_id(mClient, aSelfId);
if (!SendDeviceCreateTexture(aSelfId, desc, nsCString(), id)) {
if (!SendDeviceCreateTexture(aSelfId, desc, id)) {
MOZ_CRASH("IPC failure");
}
return id;
@ -169,7 +165,7 @@ RawId WebGPUChild::TextureCreateView(
: aDefaultViewDesc.array_layer_count - aDesc.mBaseArrayLayer;
RawId id = ffi::wgpu_client_make_texture_view_id(mClient, aSelfId);
if (!SendTextureCreateView(aSelfId, desc, nsCString(), id)) {
if (!SendTextureCreateView(aSelfId, desc, id)) {
MOZ_CRASH("IPC failure");
}
return id;
@ -193,7 +189,7 @@ RawId WebGPUChild::DeviceCreateSampler(RawId aSelfId,
}
RawId id = ffi::wgpu_client_make_sampler_id(mClient, aSelfId);
if (!SendDeviceCreateSampler(aSelfId, desc, nsCString(), id)) {
if (!SendDeviceCreateSampler(aSelfId, desc, id)) {
MOZ_CRASH("IPC failure");
}
return id;
@ -240,7 +236,7 @@ RawId WebGPUChild::DeviceCreateBindGroupLayout(
: ffi::WGPUTextureFormat(0);
entries.AppendElement(e);
}
SerialBindGroupLayoutDescriptor desc = {nsCString(), std::move(entries)};
SerialBindGroupLayoutDescriptor desc = {std::move(entries)};
if (!SendDeviceCreateBindGroupLayout(aSelfId, desc, id)) {
MOZ_CRASH("IPC failure");
}

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

@ -179,6 +179,7 @@ ipc::IPCResult WebGPUParent::RecvAdapterRequestDevice(
desc.limits.max_bind_groups = aDesc.mLimits.WasPassed()
? aDesc.mLimits.Value().mMaxBindGroups
: WGPUDEFAULT_BIND_GROUPS;
Unused << aDesc; // no useful fields
// TODO: fill up the descriptor
ffi::wgpu_server_adapter_request_device(mContext, aSelfId, &desc, aNewId);
return IPC_OK();
@ -195,12 +196,10 @@ ipc::IPCResult WebGPUParent::RecvDeviceDestroy(RawId aSelfId) {
}
ipc::IPCResult WebGPUParent::RecvDeviceCreateBuffer(
RawId aSelfId, const ffi::WGPUBufferDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId) {
ffi::WGPUBufferDescriptor desc = aDesc;
if (!aLabel.IsEmpty()) {
desc.label = aLabel.Data();
}
RawId aSelfId, const dom::GPUBufferDescriptor& aDesc, RawId aNewId) {
ffi::WGPUBufferDescriptor desc = {};
desc.usage = aDesc.mUsage;
desc.size = aDesc.mSize;
ffi::wgpu_server_device_create_buffer(mContext, aSelfId, &desc, aNewId);
return IPC_OK();
}
@ -253,23 +252,20 @@ ipc::IPCResult WebGPUParent::RecvBufferDestroy(RawId aSelfId) {
}
ipc::IPCResult WebGPUParent::RecvDeviceCreateTexture(
RawId aSelfId, const ffi::WGPUTextureDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId) {
ffi::WGPUTextureDescriptor desc = aDesc;
if (!aLabel.IsEmpty()) {
desc.label = aLabel.Data();
}
RawId aSelfId, const SerialTextureDescriptor& aDesc, RawId aNewId) {
ffi::WGPUTextureDescriptor desc = {};
desc.size = aDesc.mSize;
desc.mip_level_count = aDesc.mMipLevelCount;
desc.sample_count = aDesc.mSampleCount;
desc.dimension = aDesc.mDimension;
desc.format = aDesc.mFormat;
desc.usage = aDesc.mUsage;
ffi::wgpu_server_device_create_texture(mContext, aSelfId, &desc, aNewId);
return IPC_OK();
}
ipc::IPCResult WebGPUParent::RecvTextureCreateView(
RawId aSelfId, const ffi::WGPUTextureViewDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId) {
ffi::WGPUTextureViewDescriptor desc = aDesc;
if (!aLabel.IsEmpty()) {
desc.label = aLabel.Data();
}
RawId aSelfId, const ffi::WGPUTextureViewDescriptor& aDesc, RawId aNewId) {
ffi::wgpu_server_texture_create_view(mContext, aSelfId, &aDesc, aNewId);
return IPC_OK();
}
@ -285,12 +281,7 @@ ipc::IPCResult WebGPUParent::RecvTextureViewDestroy(RawId aSelfId) {
}
ipc::IPCResult WebGPUParent::RecvDeviceCreateSampler(
RawId aSelfId, const ffi::WGPUSamplerDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId) {
ffi::WGPUSamplerDescriptor desc = aDesc;
if (!aLabel.IsEmpty()) {
desc.label = aLabel.Data();
}
RawId aSelfId, const ffi::WGPUSamplerDescriptor& aDesc, RawId aNewId) {
ffi::wgpu_server_device_create_sampler(mContext, aSelfId, &aDesc, aNewId);
return IPC_OK();
}

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

@ -31,24 +31,22 @@ class WebGPUParent final : public PWebGPUParent {
ipc::IPCResult RecvAdapterDestroy(RawId aSelfId);
ipc::IPCResult RecvDeviceDestroy(RawId aSelfId);
ipc::IPCResult RecvDeviceCreateBuffer(RawId aSelfId,
const ffi::WGPUBufferDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId);
const dom::GPUBufferDescriptor& aDesc,
RawId aNewId);
ipc::IPCResult RecvDeviceUnmapBuffer(RawId aSelfId, RawId aBufferId,
Shmem&& aShmem, bool aFlush);
ipc::IPCResult RecvBufferMapRead(RawId aSelfId, Shmem&& aShmem,
BufferMapReadResolver&& aResolver);
ipc::IPCResult RecvBufferDestroy(RawId aSelfId);
ipc::IPCResult RecvDeviceCreateTexture(
RawId aSelfId, const ffi::WGPUTextureDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId);
ipc::IPCResult RecvDeviceCreateTexture(RawId aSelfId,
const SerialTextureDescriptor& aDesc,
RawId aNewId);
ipc::IPCResult RecvTextureCreateView(
RawId aSelfId, const ffi::WGPUTextureViewDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId);
RawId aSelfId, const ffi::WGPUTextureViewDescriptor& aDesc, RawId aNewId);
ipc::IPCResult RecvTextureDestroy(RawId aSelfId);
ipc::IPCResult RecvTextureViewDestroy(RawId aSelfId);
ipc::IPCResult RecvDeviceCreateSampler(
RawId aSelfId, const ffi::WGPUSamplerDescriptor& aDesc,
const nsCString& aLabel, RawId aNewId);
RawId aSelfId, const ffi::WGPUSamplerDescriptor& aDesc, RawId aNewId);
ipc::IPCResult RecvSamplerDestroy(RawId aSelfId);
ipc::IPCResult RecvDeviceCreateCommandEncoder(
RawId aSelfId, const dom::GPUCommandEncoderDescriptor& aDesc,

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

@ -13,27 +13,6 @@
namespace IPC {
// Special handling of the raw strings serialization.
// We are carrying the strings through IPC separately from the containing
// structs. So this implementation always reads nullptr for the char pointer.
template <>
struct ParamTraits<mozilla::webgpu::ffi::WGPURawString> {
typedef mozilla::webgpu::ffi::WGPURawString paramType;
static void Write(Message* aMsg, const paramType& aParam) {
mozilla::Unused << aMsg;
mozilla::Unused << aParam;
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
mozilla::Unused << aMsg;
mozilla::Unused << aIter;
*aResult = nullptr;
return true;
}
};
#define DEFINE_IPC_SERIALIZER_ENUM_GUARD(something, guard) \
template <> \
struct ParamTraits<something> \
@ -76,13 +55,11 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUExtensions,
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPULimits, mMaxBindGroups);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUDeviceDescriptor,
mExtensions, mLimits);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBufferDescriptor,
label, size, usage);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUTextureDescriptor,
label, size, mip_level_count, sample_count,
dimension, format, usage);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUBufferDescriptor, mSize,
mUsage);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUSamplerDescriptor,
label, address_mode_u, address_mode_v,
address_mode_u, address_mode_v,
address_mode_w, mag_filter, min_filter,
mipmap_filter, lod_min_clamp, lod_max_clamp,
compare);
@ -90,8 +67,8 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUExtent3d, width,
height, depth);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUOrigin3d, x, y, z);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::ffi::WGPUTextureViewDescriptor, label, format, dimension,
aspect, base_mip_level, level_count, base_array_layer, array_layer_count);
mozilla::webgpu::ffi::WGPUTextureViewDescriptor, format, dimension, aspect,
base_mip_level, level_count, base_array_layer, array_layer_count);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBlendDescriptor,
src_factor, dst_factor, operation);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(
@ -122,14 +99,14 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(
multisampled, has_dynamic_offset, view_dimension, texture_component_type,
storage_texture_format);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialBindGroupLayoutDescriptor, mLabel, mEntries);
mozilla::webgpu::SerialBindGroupLayoutDescriptor, mEntries);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialPipelineLayoutDescriptor, mBindGroupLayouts);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupEntry,
mBinding, mType, mValue, mBufferOffset,
mBufferSize);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupDescriptor,
mLabel, mLayout, mEntries);
mLayout, mEntries);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialProgrammableStageDescriptor, mModule, mEntryPoint);
@ -145,6 +122,10 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mFragmentStage, mPrimitiveTopology, mRasterizationState, mColorStates,
mDepthStencilState, mVertexState, mSampleCount, mSampleMask,
mAlphaToCoverageEnabled);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialTextureDescriptor,
mLabel, mSize, mArrayLayerCount,
mMipLevelCount, mSampleCount, mDimension,
mFormat, mUsage);
#undef DEFINE_IPC_SERIALIZER_FFI_ENUM
#undef DEFINE_IPC_SERIALIZER_DOM_ENUM

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

@ -18,7 +18,6 @@ typedef uint64_t RawId;
typedef uint64_t BufferAddress;
struct SerialBindGroupLayoutDescriptor {
nsCString mLabel;
nsTArray<ffi::WGPUBindGroupLayoutEntry> mEntries;
};
@ -42,7 +41,6 @@ struct SerialBindGroupEntry {
};
struct SerialBindGroupDescriptor {
nsCString mLabel;
RawId mLayout;
nsTArray<SerialBindGroupEntry> mEntries;
};
@ -82,6 +80,17 @@ struct SerialRenderPipelineDescriptor {
bool mAlphaToCoverageEnabled;
};
struct SerialTextureDescriptor {
nsString mLabel;
struct ffi::WGPUExtent3d mSize;
uint32_t mArrayLayerCount;
uint32_t mMipLevelCount;
uint32_t mSampleCount;
enum ffi::WGPUTextureDimension mDimension;
enum ffi::WGPUTextureFormat mFormat;
ffi::WGPUTextureUsage mUsage;
};
} // namespace webgpu
} // namespace mozilla

95
gfx/wgpu/.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -2,107 +2,64 @@ name: CI
on:
push:
branches-ignore: [staging.tmp]
branches-ignore: [ staging.tmp ]
pull_request:
branches-ignore: [staging.tmp]
branches-ignore: [ staging.tmp ]
jobs:
ios_build:
name: iOS Stable
runs-on: macos-10.15
env:
TARGET: aarch64-apple-ios
steps:
- uses: actions/checkout@v2
- run: rustup component add clippy
- run: rustup target add ${{ env.TARGET }}
- run: cargo clippy --target ${{ env.TARGET }}
android_build:
name: Android Stable
runs-on: ubuntu-18.04
env:
TARGET: aarch64-linux-android
steps:
- uses: actions/checkout@v2
- name: Install NDK
run: |
curl -LO https://dl.google.com/android/repository/android-ndk-r21b-linux-x86_64.zip
unzip -qq android-ndk-r21b-linux-x86_64.zip -d $GITHUB_WORKSPACE
export NDK_HOME_BIN=$GITHUB_WORKSPACE/android-ndk-r21b/toolchains/llvm/prebuilt/linux-x86_64/bin
ln -s $NDK_HOME_BIN/aarch64-linux-android21-clang $NDK_HOME_BIN/aarch64-linux-android-clang
echo "::add-path::$NDK_HOME_BIN"
- run: rustup component add clippy
- run: rustup target add ${{ env.TARGET }}
- run: cargo clippy --target ${{ env.TARGET }}
- name: Additional core features
run: cargo check --manifest-path wgpu-core/Cargo.toml --features trace --target ${{ env.TARGET }}
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name:
[
MacOS Stable,
MacOS Nightly,
Ubuntu Stable,
Ubuntu Nightly,
Windows Stable,
Windows Nightly,
]
name: [
iOS Stable,
MacOS Stable,
MacOS Nightly,
Ubuntu Stable,
Ubuntu Nightly,
Windows Stable,
Windows Nightly,
]
include:
- os: macos-10.15
name: iOS Stable
channel: stable
build_command: rustup target add aarch64-apple-ios; cargo clippy --target aarch64-apple-ios
- os: macos-10.15
name: MacOS Stable
channel: stable
build_command: cargo clippy
additional_core_features: trace
additional_player_features: winit
- os: macos-10.15
name: MacOS Nightly
channel: nightly
build_command: cargo test
additional_core_features:
additional_player_features:
- os: ubuntu-18.04
name: Ubuntu Stable
channel: stable
build_command: cargo clippy
additional_core_features: trace,replay
additional_player_features:
- os: ubuntu-18.04
name: Ubuntu Nightly
channel: nightly
build_command: cargo test
additional_core_features:
additional_player_features: winit
- os: windows-2019
name: Windows Stable
channel: stable
build_command: rustup default stable-msvc; cargo clippy
additional_core_features: trace
additional_player_features: renderdoc
- os: windows-2019
name: Windows Nightly
channel: nightly
build_command: rustup default nightly-msvc; cargo test
additional_core_features:
additional_player_features:
steps:
- uses: actions/checkout@v2
- if: matrix.channel == 'nightly'
name: Install latest nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- if: matrix.channel == 'stable'
run: rustup component add clippy
- name: cargo clippy/test
run: ${{ matrix.build_command }}
- if: matrix.additional_core_features != ''
run: cargo check --manifest-path wgpu-core/Cargo.toml --features ${{ matrix.additional_core_features }}
- if: matrix.additional_player_features != ''
run: cargo check --manifest-path player/Cargo.toml --features ${{ matrix.additional_player_features }}
- uses: actions/checkout@v2
- if: matrix.channel == 'nightly'
name: Install latest nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- if: contains(matrix.build_command, 'clippy')
run: rustup component add clippy
- name: cargo clippy/test
run: ${{ matrix.build_command }}

1
gfx/wgpu/.gitignore поставляемый
Просмотреть файл

@ -1,3 +1,4 @@
Cargo.lock
/target
**/*.rs.bk
#Cargo.lock

1466
gfx/wgpu/Cargo.lock сгенерированный

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

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

@ -1,6 +1,5 @@
[workspace]
members = [
"player",
"wgpu-core",
"wgpu-types",
]

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

@ -17,7 +17,6 @@ The implementation consists of the following parts:
- `wgpu-core` - internal Rust API for WebGPU implementations to use
- `wgpu-types` - Rust types shared between `wgpu-core`, `wgpu-native`, and `wgpu-rs`
- `player` - application for replaying the API traces, uses `winit`
This repository is not meant for direct use by applications.
If you are looking for the user-facing Rust API, you need [wgpu-rs](https://github.com/gfx-rs/wgpu-rs).
@ -25,7 +24,7 @@ If you are looking for the native implementation or bindings to the API in other
## Supported Platforms
API | Windows 7/10 | Linux & Android | macOS & iOS |
API | Windows | Linux | macOS & iOS |
----- | ------------------ | ------------------ | ------------------ |
DX11 | :white_check_mark: | | |
DX12 | :heavy_check_mark: | | |

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

@ -2,7 +2,6 @@ status = [
"iOS Stable",
"MacOS Stable",
"MacOS Nightly",
"Android Stable",
"Ubuntu Stable",
"Ubuntu Nightly",
"Windows Stable",

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

@ -1,35 +0,0 @@
[package]
name = "player"
version = "0.1.0"
authors = [
"Dzmitry Malyshau <kvark@mozilla.com>",
]
edition = "2018"
description = "WebGPU trace player"
homepage = "https://github.com/gfx-rs/wgpu"
repository = "https://github.com/gfx-rs/wgpu"
keywords = ["graphics"]
license = "MPL-2.0"
publish = false
[features]
[dependencies]
env_logger = "0.7"
log = "0.4"
raw-window-handle = "0.3"
renderdoc = { version = "0.8", optional = true, default_features = false }
ron = "0.5"
winit = { version = "0.22", optional = true }
[dependencies.wgt]
path = "../wgpu-types"
package = "wgpu-types"
version = "0.5"
features = ["replay"]
[dependencies.wgc]
path = "../wgpu-core"
package = "wgpu-core"
version = "0.5"
features = ["replay", "raw-window-handle"]

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

@ -1,12 +0,0 @@
# wgpu player
This is application that allows replaying the `wgpu` workloads recorded elsewhere.
Launch as:
```rust
player <trace-dir>
```
When built with "winit" feature, it's able to replay the workloads that operate on a swapchain. It renders each frame sequentially, then waits for the user to close the window. When built without "winit", it launches in console mode and can replay any trace that doesn't use swapchains.
Note: replaying is currently restricted to the same backend, as one used for recording a trace. It is straightforward, however, to just replace the backend in RON, since it's serialized as plain text. Valid values are: Vulkan, Metal, Dx12, and Dx11.

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

@ -1,573 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*! This is a player for WebGPU traces.
*
* # Notes
* - we call device_maintain_ids() before creating any refcounted resource,
* which is basically everything except for BGL and shader modules,
* so that we don't accidentally try to use the same ID.
!*/
use wgc::device::trace;
use std::{
ffi::CString,
fmt::Debug,
fs::File,
marker::PhantomData,
path::{Path, PathBuf},
ptr,
};
macro_rules! gfx_select {
($id:expr => $global:ident.$method:ident( $($param:expr),+ )) => {
match $id.backend() {
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
wgt::Backend::Vulkan => $global.$method::<wgc::backend::Vulkan>( $($param),+ ),
#[cfg(any(target_os = "ios", target_os = "macos"))]
wgt::Backend::Metal => $global.$method::<wgc::backend::Metal>( $($param),+ ),
#[cfg(windows)]
wgt::Backend::Dx12 => $global.$method::<wgc::backend::Dx12>( $($param),+ ),
#[cfg(windows)]
wgt::Backend::Dx11 => $global.$method::<wgc::backend::Dx11>( $($param),+ ),
_ => unreachable!()
}
};
}
struct Label(Option<CString>);
impl Label {
fn new(text: &str) -> Self {
Self(if text.is_empty() {
None
} else {
Some(CString::new(text).expect("invalid label"))
})
}
fn as_ptr(&self) -> *const std::os::raw::c_char {
match self.0 {
Some(ref c_string) => c_string.as_ptr(),
None => ptr::null(),
}
}
}
struct OwnedProgrammableStage {
desc: wgc::pipeline::ProgrammableStageDescriptor,
#[allow(dead_code)]
entry_point: CString,
}
impl From<trace::ProgrammableStageDescriptor> for OwnedProgrammableStage {
fn from(stage: trace::ProgrammableStageDescriptor) -> Self {
let entry_point = CString::new(stage.entry_point.as_str()).unwrap();
OwnedProgrammableStage {
desc: wgc::pipeline::ProgrammableStageDescriptor {
module: stage.module,
entry_point: entry_point.as_ptr(),
},
entry_point,
}
}
}
#[derive(Debug)]
struct IdentityPassThrough<I>(PhantomData<I>);
impl<I: Clone + Debug + wgc::id::TypedId> wgc::hub::IdentityHandler<I> for IdentityPassThrough<I> {
type Input = I;
fn process(&self, id: I, backend: wgt::Backend) -> I {
let (index, epoch, _backend) = id.unzip();
I::zip(index, epoch, backend)
}
fn free(&self, _id: I) {}
}
struct IdentityPassThroughFactory;
impl<I: Clone + Debug + wgc::id::TypedId> wgc::hub::IdentityHandlerFactory<I>
for IdentityPassThroughFactory
{
type Filter = IdentityPassThrough<I>;
fn spawn(&self, _min_index: u32) -> Self::Filter {
IdentityPassThrough(PhantomData)
}
}
impl wgc::hub::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {}
trait GlobalExt {
fn encode_commands<B: wgc::hub::GfxBackend>(
&self,
encoder: wgc::id::CommandEncoderId,
commands: Vec<trace::Command>,
) -> wgc::id::CommandBufferId;
fn process<B: wgc::hub::GfxBackend>(
&self,
device: wgc::id::DeviceId,
action: trace::Action,
dir: &PathBuf,
comb_manager: &mut wgc::hub::IdentityManager,
);
}
impl GlobalExt for wgc::hub::Global<IdentityPassThroughFactory> {
fn encode_commands<B: wgc::hub::GfxBackend>(
&self,
encoder: wgc::id::CommandEncoderId,
commands: Vec<trace::Command>,
) -> wgc::id::CommandBufferId {
for command in commands {
match command {
trace::Command::CopyBufferToBuffer {
src,
src_offset,
dst,
dst_offset,
size,
} => self.command_encoder_copy_buffer_to_buffer::<B>(
encoder, src, src_offset, dst, dst_offset, size,
),
trace::Command::CopyBufferToTexture { src, dst, size } => {
self.command_encoder_copy_buffer_to_texture::<B>(encoder, &src, &dst, size)
}
trace::Command::CopyTextureToBuffer { src, dst, size } => {
self.command_encoder_copy_texture_to_buffer::<B>(encoder, &src, &dst, size)
}
trace::Command::CopyTextureToTexture { src, dst, size } => {
self.command_encoder_copy_texture_to_texture::<B>(encoder, &src, &dst, size)
}
trace::Command::RunComputePass {
commands,
dynamic_offsets,
} => unsafe {
let mut offsets = &dynamic_offsets[..];
let mut pass = wgc::command::RawPass::new_compute(encoder);
for com in commands {
pass.encode(&com);
if let wgc::command::ComputeCommand::SetBindGroup {
num_dynamic_offsets,
..
} = com
{
pass.encode_slice(&offsets[..num_dynamic_offsets as usize]);
offsets = &offsets[num_dynamic_offsets as usize..];
}
}
let (data, _) = pass.finish_compute();
self.command_encoder_run_compute_pass::<B>(encoder, &data);
},
trace::Command::RunRenderPass {
target_colors,
target_depth_stencil,
commands,
dynamic_offsets,
} => unsafe {
let mut offsets = &dynamic_offsets[..];
let mut pass = wgc::command::RawPass::new_render(
encoder,
&wgc::command::RenderPassDescriptor {
color_attachments: target_colors.as_ptr(),
color_attachments_length: target_colors.len(),
depth_stencil_attachment: target_depth_stencil.as_ref(),
},
);
for com in commands {
pass.encode(&com);
if let wgc::command::RenderCommand::SetBindGroup {
num_dynamic_offsets,
..
} = com
{
pass.encode_slice(&offsets[..num_dynamic_offsets as usize]);
offsets = &offsets[num_dynamic_offsets as usize..];
}
}
let (data, _) = pass.finish_render();
self.command_encoder_run_render_pass::<B>(encoder, &data);
},
}
}
self.command_encoder_finish::<B>(encoder, &wgt::CommandBufferDescriptor { todo: 0 })
}
fn process<B: wgc::hub::GfxBackend>(
&self,
device: wgc::id::DeviceId,
action: trace::Action,
dir: &PathBuf,
comb_manager: &mut wgc::hub::IdentityManager,
) {
use wgc::device::trace::Action as A;
match action {
A::Init { .. } => panic!("Unexpected Action::Init: has to be the first action only"),
A::CreateSwapChain { .. } | A::PresentSwapChain(_) => {
panic!("Unexpected SwapChain action: winit feature is not enabled")
}
A::CreateBuffer { id, desc } => {
let label = Label::new(&desc.label);
self.device_maintain_ids::<B>(device);
self.device_create_buffer::<B>(device, &desc.map_label(|_| label.as_ptr()), id);
}
A::DestroyBuffer(id) => {
self.buffer_destroy::<B>(id);
}
A::CreateTexture { id, desc } => {
let label = Label::new(&desc.label);
self.device_maintain_ids::<B>(device);
self.device_create_texture::<B>(device, &desc.map_label(|_| label.as_ptr()), id);
}
A::DestroyTexture(id) => {
self.texture_destroy::<B>(id);
}
A::CreateTextureView {
id,
parent_id,
desc,
} => {
let label = desc.as_ref().map_or(Label(None), |d| Label::new(&d.label));
self.device_maintain_ids::<B>(device);
self.texture_create_view::<B>(
parent_id,
desc.map(|d| d.map_label(|_| label.as_ptr())).as_ref(),
id,
);
}
A::DestroyTextureView(id) => {
self.texture_view_destroy::<B>(id);
}
A::CreateSampler { id, desc } => {
let label = Label::new(&desc.label);
self.device_maintain_ids::<B>(device);
self.device_create_sampler::<B>(device, &desc.map_label(|_| label.as_ptr()), id);
}
A::DestroySampler(id) => {
self.sampler_destroy::<B>(id);
}
A::GetSwapChainTexture { id, parent_id } => {
self.swap_chain_get_next_texture::<B>(parent_id, id)
.unwrap();
}
A::CreateBindGroupLayout { id, label, entries } => {
let label = Label::new(&label);
self.device_create_bind_group_layout::<B>(
device,
&wgc::binding_model::BindGroupLayoutDescriptor {
label: label.as_ptr(),
entries: entries.as_ptr(),
entries_length: entries.len(),
},
id,
);
}
A::DestroyBindGroupLayout(id) => {
self.bind_group_layout_destroy::<B>(id);
}
A::CreatePipelineLayout {
id,
bind_group_layouts,
} => {
self.device_maintain_ids::<B>(device);
self.device_create_pipeline_layout::<B>(
device,
&wgc::binding_model::PipelineLayoutDescriptor {
bind_group_layouts: bind_group_layouts.as_ptr(),
bind_group_layouts_length: bind_group_layouts.len(),
},
id,
);
}
A::DestroyPipelineLayout(id) => {
self.pipeline_layout_destroy::<B>(id);
}
A::CreateBindGroup {
id,
label,
layout_id,
entries,
} => {
use wgc::binding_model as bm;
let label = Label::new(&label);
let entry_vec = entries
.into_iter()
.map(|(binding, res)| wgc::binding_model::BindGroupEntry {
binding,
resource: match res {
trace::BindingResource::Buffer { id, offset, size } => {
bm::BindingResource::Buffer(bm::BufferBinding {
buffer: id,
offset,
size,
})
}
trace::BindingResource::Sampler(id) => bm::BindingResource::Sampler(id),
trace::BindingResource::TextureView(id) => {
bm::BindingResource::TextureView(id)
}
},
})
.collect::<Vec<_>>();
self.device_maintain_ids::<B>(device);
self.device_create_bind_group::<B>(
device,
&wgc::binding_model::BindGroupDescriptor {
label: label.as_ptr(),
layout: layout_id,
entries: entry_vec.as_ptr(),
entries_length: entry_vec.len(),
},
id,
);
}
A::DestroyBindGroup(id) => {
self.bind_group_destroy::<B>(id);
}
A::CreateShaderModule { id, data } => {
let spv = wgt::read_spirv(File::open(dir.join(data)).unwrap()).unwrap();
self.device_create_shader_module::<B>(
device,
&wgc::pipeline::ShaderModuleDescriptor {
code: wgc::U32Array {
bytes: spv.as_ptr(),
length: spv.len(),
},
},
id,
);
}
A::DestroyShaderModule(id) => {
self.shader_module_destroy::<B>(id);
}
A::CreateComputePipeline { id, desc } => {
let cs_stage = OwnedProgrammableStage::from(desc.compute_stage);
self.device_maintain_ids::<B>(device);
self.device_create_compute_pipeline::<B>(
device,
&wgc::pipeline::ComputePipelineDescriptor {
layout: desc.layout,
compute_stage: cs_stage.desc,
},
id,
);
}
A::DestroyComputePipeline(id) => {
self.compute_pipeline_destroy::<B>(id);
}
A::CreateRenderPipeline { id, desc } => {
let vs_stage = OwnedProgrammableStage::from(desc.vertex_stage);
let fs_stage = desc.fragment_stage.map(OwnedProgrammableStage::from);
let vertex_buffers = desc
.vertex_state
.vertex_buffers
.iter()
.map(|vb| wgc::pipeline::VertexBufferLayoutDescriptor {
array_stride: vb.array_stride,
step_mode: vb.step_mode,
attributes: vb.attributes.as_ptr(),
attributes_length: vb.attributes.len(),
})
.collect::<Vec<_>>();
self.device_maintain_ids::<B>(device);
self.device_create_render_pipeline::<B>(
device,
&wgc::pipeline::RenderPipelineDescriptor {
layout: desc.layout,
vertex_stage: vs_stage.desc,
fragment_stage: fs_stage.as_ref().map_or(ptr::null(), |s| &s.desc),
primitive_topology: desc.primitive_topology,
rasterization_state: desc
.rasterization_state
.as_ref()
.map_or(ptr::null(), |rs| rs),
color_states: desc.color_states.as_ptr(),
color_states_length: desc.color_states.len(),
depth_stencil_state: desc
.depth_stencil_state
.as_ref()
.map_or(ptr::null(), |ds| ds),
vertex_state: wgc::pipeline::VertexStateDescriptor {
index_format: desc.vertex_state.index_format,
vertex_buffers: vertex_buffers.as_ptr(),
vertex_buffers_length: vertex_buffers.len(),
},
sample_count: desc.sample_count,
sample_mask: desc.sample_mask,
alpha_to_coverage_enabled: desc.alpha_to_coverage_enabled,
},
id,
);
}
A::DestroyRenderPipeline(id) => {
self.render_pipeline_destroy::<B>(id);
}
A::WriteBuffer { id, data, range } => {
let bin = std::fs::read(dir.join(data)).unwrap();
let size = (range.end - range.start) as usize;
self.device_wait_for_buffer::<B>(device, id);
self.device_set_buffer_sub_data::<B>(device, id, range.start, &bin[..size]);
}
A::Submit(_index, commands) => {
let encoder = self.device_create_command_encoder::<B>(
device,
&wgt::CommandEncoderDescriptor { label: ptr::null() },
comb_manager.alloc(device.backend()),
);
let comb = self.encode_commands::<B>(encoder, commands);
self.queue_submit::<B>(device, &[comb]);
}
}
}
}
fn main() {
#[cfg(feature = "winit")]
use winit::{event_loop::EventLoop, window::WindowBuilder};
env_logger::init();
#[cfg(feature = "renderdoc")]
let mut rd = renderdoc::RenderDoc::<renderdoc::V110>::new()
.expect("Failed to connect to RenderDoc: are you running without it?");
//TODO: setting for the backend bits
//TODO: setting for the target frame, or controls
let dir = match std::env::args().nth(1) {
Some(arg) if Path::new(&arg).is_dir() => PathBuf::from(arg),
_ => panic!("Provide the dir path as the parameter"),
};
log::info!("Loading trace '{:?}'", dir);
let file = File::open(dir.join(trace::FILE_NAME)).unwrap();
let mut actions: Vec<trace::Action> = ron::de::from_reader(file).unwrap();
actions.reverse(); // allows us to pop from the top
log::info!("Found {} actions", actions.len());
#[cfg(feature = "winit")]
let mut event_loop = {
log::info!("Creating a window");
EventLoop::new()
};
#[cfg(feature = "winit")]
let window = WindowBuilder::new()
.with_title("wgpu player")
.with_resizable(false)
.build(&event_loop)
.unwrap();
let global = wgc::hub::Global::new("player", IdentityPassThroughFactory);
let mut command_buffer_id_manager = wgc::hub::IdentityManager::default();
#[cfg(feature = "winit")]
let surface =
global.instance_create_surface(&window, wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty));
let device = match actions.pop() {
Some(trace::Action::Init { desc, backend }) => {
log::info!("Initializing the device for backend: {:?}", backend);
let adapter = global
.pick_adapter(
&wgc::instance::RequestAdapterOptions {
power_preference: wgt::PowerPreference::Default,
#[cfg(feature = "winit")]
compatible_surface: Some(surface),
#[cfg(not(feature = "winit"))]
compatible_surface: None,
},
wgc::instance::AdapterInputs::IdSet(
&[wgc::id::TypedId::zip(0, 0, backend)],
|id| id.backend(),
),
)
.expect("Unable to find an adapter for selected backend");
let info = gfx_select!(adapter => global.adapter_get_info(adapter));
log::info!("Picked '{}'", info.name);
gfx_select!(adapter => global.adapter_request_device(
adapter,
&desc,
None,
wgc::id::TypedId::zip(1, 0, wgt::Backend::Empty)
))
}
_ => panic!("Expected Action::Init"),
};
log::info!("Executing actions");
#[cfg(not(feature = "winit"))]
{
#[cfg(feature = "renderdoc")]
rd.start_frame_capture(ptr::null(), ptr::null());
while let Some(action) = actions.pop() {
gfx_select!(device => global.process(device, action, &dir, &mut command_buffer_id_manager));
}
#[cfg(feature = "renderdoc")]
rd.end_frame_capture(ptr::null(), ptr::null());
gfx_select!(device => global.device_poll(device, true));
}
#[cfg(feature = "winit")]
{
use winit::{
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
event_loop::ControlFlow,
platform::desktop::EventLoopExtDesktop,
};
let mut frame_count = 0;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => {
window.request_redraw();
}
Event::RedrawRequested(_) => loop {
match actions.pop() {
Some(trace::Action::CreateSwapChain { id, desc }) => {
log::info!("Initializing the swapchain");
assert_eq!(id.to_surface_id(), surface);
window.set_inner_size(winit::dpi::PhysicalSize::new(
desc.width,
desc.height,
));
gfx_select!(device => global.device_create_swap_chain(device, surface, &desc));
}
Some(trace::Action::PresentSwapChain(id)) => {
frame_count += 1;
log::debug!("Presenting frame {}", frame_count);
gfx_select!(device => global.swap_chain_present(id));
break;
}
Some(action) => {
gfx_select!(device => global.process(device, action, &dir, &mut command_buffer_id_manager));
}
None => break,
}
},
Event::WindowEvent { event, .. } => match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(VirtualKeyCode::Escape),
state: ElementState::Pressed,
..
},
..
}
| WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
_ => {}
},
Event::LoopDestroyed => {
log::info!("Closing");
gfx_select!(device => global.device_poll(device, true));
}
_ => {}
}
});
}
}

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

@ -16,9 +16,8 @@ license = "MPL-2.0"
[features]
default = []
trace = ["ron", "serde", "wgt/trace"]
replay = ["serde", "wgt/replay"]
metal-auto-capture = ["gfx-backend-metal/auto-capture"]
serde = ["wgt/serde", "serde_crate"]
#NOTE: glutin feature is not stable, use at your own risk
#glutin = ["gfx-backend-gl/glutin"]
@ -34,12 +33,15 @@ gfx-descriptor = "0.1"
gfx-memory = "0.1"
parking_lot = "0.10"
peek-poke = "0.2"
raw-window-handle = { version = "0.3", optional = true }
ron = { version = "0.5", optional = true }
serde = { version = "1.0", features = ["serde_derive"], optional = true }
smallvec = "1"
vec_map = "0.8.1"
[dependencies.serde_crate]
package = "serde"
version = "1.0"
features = ["serde_derive"]
optional = true
[dependencies.wgt]
path = "../wgpu-types"
package = "wgpu-types"

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

@ -12,16 +12,17 @@ use arrayvec::ArrayVec;
use gfx_descriptor::{DescriptorCounts, DescriptorSet};
use wgt::{BufferAddress, TextureComponentType};
#[cfg(feature = "replay")]
use serde::Deserialize;
#[cfg(feature = "trace")]
use serde::Serialize;
#[cfg(feature = "serde")]
use serde_crate::{Deserialize, Serialize};
use std::borrow::Borrow;
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub enum BindingType {
UniformBuffer = 0,
StorageBuffer = 1,
@ -35,8 +36,11 @@ pub enum BindingType {
#[repr(C)]
#[derive(Clone, Debug, Hash, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct BindGroupLayoutEntry {
pub binding: u32,
pub visibility: wgt::ShaderStage,
@ -83,8 +87,11 @@ pub struct PipelineLayout<B: hal::Backend> {
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct BufferBinding {
pub buffer: BufferId,
pub offset: BufferAddress,
@ -93,8 +100,11 @@ pub struct BufferBinding {
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub enum BindingResource {
Buffer(BufferBinding),
Sampler(SamplerId),
@ -103,8 +113,11 @@ pub enum BindingResource {
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct BindGroupEntry {
pub binding: u32,
pub resource: BindingResource,

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

@ -4,8 +4,7 @@
use super::CommandBuffer;
use crate::{
hub::GfxBackend, id::DeviceId, track::TrackerSet, LifeGuard, PrivateFeatures, Stored,
SubmissionIndex,
hub::GfxBackend, id::DeviceId, track::TrackerSet, Features, LifeGuard, Stored, SubmissionIndex,
};
use hal::{command::CommandBuffer as _, device::Device as _, pool::CommandPool as _};
@ -77,10 +76,8 @@ impl<B: GfxBackend> CommandAllocator<B> {
&self,
device_id: Stored<DeviceId>,
device: &B::Device,
limits: wgt::Limits,
private_features: PrivateFeatures,
features: Features,
lowest_active_index: SubmissionIndex,
#[cfg(feature = "trace")] enable_tracing: bool,
) -> CommandBuffer<B> {
//debug_assert_eq!(device_id.backend(), B::VARIANT);
let thread_id = thread::current().id();
@ -111,14 +108,7 @@ impl<B: GfxBackend> CommandAllocator<B> {
life_guard: LifeGuard::new(),
trackers: TrackerSet::new(B::VARIANT),
used_swap_chain: None,
limits,
private_features,
#[cfg(feature = "trace")]
commands: if enable_tracing {
Some(Vec::new())
} else {
None
},
features,
}
}
}

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

@ -26,14 +26,11 @@ enum PipelineState {
}
#[derive(Clone, Copy, Debug, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum ComputeCommand {
enum ComputeCommand {
SetBindGroup {
index: u8,
num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>,
},
SetPipeline(id::ComputePipelineId),
@ -82,7 +79,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token);
let cmb = &mut cmb_guard[encoder_id];
let raw = cmb.raw.last_mut().unwrap();
let mut binder = Binder::new(cmb.limits.max_bind_groups);
let mut binder = Binder::new(cmb.features.max_bind_groups);
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
@ -250,43 +247,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
ComputeCommand::End => break,
}
}
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => {
let mut pass_commands = Vec::new();
let mut pass_dynamic_offsets = Vec::new();
peeker = raw_data.as_ptr();
loop {
peeker = unsafe { ComputeCommand::peek_from(peeker, &mut command) };
match command {
ComputeCommand::SetBindGroup {
num_dynamic_offsets,
phantom_offsets,
..
} => {
let (new_peeker, offsets) = unsafe {
phantom_offsets.decode_unaligned(
peeker,
num_dynamic_offsets as usize,
raw_data_end,
)
};
peeker = new_peeker;
pass_dynamic_offsets.extend_from_slice(offsets);
}
ComputeCommand::End => break,
_ => {}
}
pass_commands.push(command);
}
list.push(crate::device::trace::Command::RunComputePass {
commands: pass_commands,
dynamic_offsets: pass_dynamic_offsets,
});
}
None => {}
}
}
}

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

@ -19,7 +19,7 @@ use crate::{
id,
resource::{Buffer, Texture},
track::TrackerSet,
LifeGuard, PrivateFeatures, Stored,
Features, LifeGuard, Stored,
};
use peek_poke::PeekPoke;
@ -27,7 +27,7 @@ use peek_poke::PeekPoke;
use std::{marker::PhantomData, mem, ptr, slice, thread::ThreadId};
#[derive(Clone, Copy, Debug, PeekPoke)]
pub struct PhantomSlice<T>(PhantomData<T>);
struct PhantomSlice<T>(PhantomData<T>);
impl<T> Default for PhantomSlice<T> {
fn default() -> Self {
@ -119,13 +119,13 @@ impl RawPass {
}
#[inline]
pub unsafe fn encode<C: peek_poke::Poke>(&mut self, command: &C) {
unsafe fn encode<C: peek_poke::Poke>(&mut self, command: &C) {
self.ensure_extra_size(C::max_size());
self.data = command.poke_into(self.data);
}
#[inline]
pub unsafe fn encode_slice<T: Copy>(&mut self, data: &[T]) {
unsafe fn encode_slice<T: Copy>(&mut self, data: &[T]) {
let align_offset = self.data.align_offset(mem::align_of::<T>());
let extra = align_offset + mem::size_of::<T>() * data.len();
self.ensure_extra_size(extra);
@ -148,10 +148,7 @@ pub struct CommandBuffer<B: hal::Backend> {
pub(crate) life_guard: LifeGuard,
pub(crate) trackers: TrackerSet,
pub(crate) used_swap_chain: Option<(Stored<id::SwapChainId>, B::Framebuffer)>,
limits: wgt::Limits,
private_features: PrivateFeatures,
#[cfg(feature = "trace")]
pub(crate) commands: Option<Vec<crate::device::trace::Command>>,
pub(crate) features: Features,
}
impl<B: GfxBackend> CommandBuffer<B> {

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

@ -46,8 +46,6 @@ pub struct RenderPassDescriptor<'a> {
}
#[derive(Clone, Copy, Debug, Default, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct Rect<T> {
pub x: T,
pub y: T,
@ -56,14 +54,11 @@ pub struct Rect<T> {
}
#[derive(Clone, Copy, Debug, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum RenderCommand {
enum RenderCommand {
SetBindGroup {
index: u8,
num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>,
},
SetPipeline(id::RenderPipelineId),
@ -339,8 +334,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
raw_data.len()
);
peeker = unsafe { RawRenderTargets::peek_from(peeker, &mut targets) };
#[cfg(feature = "trace")]
let command_peeker_base = peeker;
let color_attachments = targets
.colors
@ -443,10 +436,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
Some(hal::pass::Attachment {
format: Some(conv::map_texture_format(
view.format,
device.private_features,
)),
format: Some(conv::map_texture_format(view.format, device.features)),
samples: view.samples,
ops: conv::map_load_store_ops(at.depth_load_op, at.depth_store_op),
stencil_ops: conv::map_load_store_ops(
@ -513,10 +503,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
colors.push(hal::pass::Attachment {
format: Some(conv::map_texture_format(
view.format,
device.private_features,
)),
format: Some(conv::map_texture_format(view.format, device.features)),
samples: view.samples,
ops: conv::map_load_store_ops(at.load_op, at.store_op),
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
@ -569,10 +556,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
resolves.push(hal::pass::Attachment {
format: Some(conv::map_texture_format(
view.format,
device.private_features,
)),
format: Some(conv::map_texture_format(view.format, device.features)),
samples: view.samples,
ops: hal::pass::AttachmentOps::new(
hal::pass::AttachmentLoadOp::DontCare,
@ -826,7 +810,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
let mut state = State {
binder: Binder::new(cmb.limits.max_bind_groups),
binder: Binder::new(cmb.features.max_bind_groups),
blend_color: OptionalState::Unused,
stencil_reference: OptionalState::Unused,
pipeline: OptionalState::Required,
@ -1215,45 +1199,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => {
let mut pass_commands = Vec::new();
let mut pass_dynamic_offsets = Vec::new();
peeker = command_peeker_base;
loop {
peeker = unsafe { RenderCommand::peek_from(peeker, &mut command) };
match command {
RenderCommand::SetBindGroup {
num_dynamic_offsets,
phantom_offsets,
..
} => {
let (new_peeker, offsets) = unsafe {
phantom_offsets.decode_unaligned(
peeker,
num_dynamic_offsets as usize,
raw_data_end,
)
};
peeker = new_peeker;
pass_dynamic_offsets.extend_from_slice(offsets);
}
RenderCommand::End => break,
_ => {}
}
pass_commands.push(command);
}
list.push(crate::device::trace::Command::RunRenderPass {
target_colors: color_attachments.into_iter().collect(),
target_depth_stencil: depth_stencil_attachment.cloned(),
commands: pass_commands,
dynamic_offsets: pass_dynamic_offsets,
});
}
None => {}
}
log::trace!("Merging {:?} with the render pass", encoder_id);
unsafe {
raw.end_render_pass();

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

@ -2,8 +2,6 @@
* 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/. */
#[cfg(feature = "trace")]
use crate::device::trace::Command as TraceCommand;
use crate::{
conv,
device::{all_buffer_stages, all_image_stages},
@ -20,9 +18,7 @@ use std::iter;
const BITS_PER_BYTE: u32 = 8;
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
#[derive(Debug)]
pub struct BufferCopyView {
pub buffer: BufferId,
pub offset: BufferAddress,
@ -31,9 +27,7 @@ pub struct BufferCopyView {
}
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
#[derive(Debug)]
pub struct TextureCopyView {
pub texture: TextureId,
pub mip_level: u32,
@ -96,18 +90,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// borrow the buffer tracker mutably...
let mut barriers = Vec::new();
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyBufferToBuffer {
src: source,
src_offset: source_offset,
dst: destination,
dst_offset: destination_offset,
size,
}),
None => (),
}
let (src_buffer, src_pending) =
cmb.trackers
.buffers
@ -161,16 +143,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[destination.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyBufferToTexture {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_buffer, src_pending) = cmb.trackers.buffers.use_replace(
&*buffer_guard,
source.buffer,
@ -189,7 +161,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
assert!(dst_texture.usage.contains(TextureUsage::COPY_DST));
let dst_barriers = dst_pending.map(|pending| pending.into_hal(dst_texture));
let bytes_per_texel = conv::map_texture_format(dst_texture.format, cmb.private_features)
let bytes_per_texel = conv::map_texture_format(dst_texture.format, cmb.features)
.surface_desc()
.bits as u32
/ BITS_PER_BYTE;
@ -241,16 +213,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[source.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyTextureToBuffer {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard,
source.texture,
@ -277,7 +239,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
);
let dst_barrier = dst_barriers.map(|pending| pending.into_hal(dst_buffer));
let bytes_per_texel = conv::map_texture_format(src_texture.format, cmb.private_features)
let bytes_per_texel = conv::map_texture_format(src_texture.format, cmb.features)
.surface_desc()
.bits as u32
/ BITS_PER_BYTE;
@ -334,16 +296,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let aspects = texture_guard[source.texture].full_range.aspects
& texture_guard[destination.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyTextureToTexture {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard,
source.texture,

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

@ -2,7 +2,7 @@
* 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 crate::{binding_model, resource, PrivateFeatures};
use crate::{binding_model, resource, Features};
pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) {
use hal::buffer::Usage as U;
@ -321,7 +321,7 @@ fn map_stencil_operation(stencil_operation: wgt::StencilOperation) -> hal::pso::
pub(crate) fn map_texture_format(
texture_format: wgt::TextureFormat,
private_features: PrivateFeatures,
features: Features,
) -> hal::format::Format {
use hal::format::Format as H;
use wgt::TextureFormat as Tf;
@ -376,14 +376,14 @@ pub(crate) fn map_texture_format(
// Depth and stencil formats
Tf::Depth32Float => H::D32Sfloat,
Tf::Depth24Plus => {
if private_features.supports_texture_d24_s8 {
if features.supports_texture_d24_s8 {
H::D24UnormS8Uint
} else {
H::D32Sfloat
}
}
Tf::Depth24PlusStencil8 => {
if private_features.supports_texture_d24_s8 {
if features.supports_texture_d24_s8 {
H::D24UnormS8Uint
} else {
H::D32SfloatS8Uint

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

@ -2,8 +2,6 @@
* 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/. */
#[cfg(feature = "trace")]
use crate::device::trace;
use crate::{
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token},
id, resource,
@ -301,7 +299,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
&mut self,
global: &Global<G>,
trackers: &Mutex<TrackerSet>,
#[cfg(feature = "trace")] trace: Option<&Mutex<trace::Trace>>,
token: &mut Token<super::Device<B>>,
) {
let hub = B::hub(global);
@ -312,8 +309,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.bind_groups.drain(..) {
if trackers.bind_groups.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyBindGroup(id)));
hub.bind_groups.free_id(id);
let res = guard.remove(id).unwrap();
@ -348,8 +343,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.texture_views.drain(..) {
if trackers.views.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyTextureView(id)));
hub.texture_views.free_id(id);
let res = guard.remove(id).unwrap();
@ -378,8 +371,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.textures.drain(..) {
if trackers.textures.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyTexture(id)));
hub.textures.free_id(id);
let res = guard.remove(id).unwrap();
@ -400,8 +391,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.samplers.drain(..) {
if trackers.samplers.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroySampler(id)));
hub.samplers.free_id(id);
let res = guard.remove(id).unwrap();
@ -422,8 +411,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.buffers.drain(..) {
if trackers.buffers.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyBuffer(id)));
hub.buffers.free_id(id);
let res = guard.remove(id).unwrap();
log::debug!("Buffer {:?} is detached", id);
@ -445,8 +432,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.compute_pipelines.drain(..) {
if trackers.compute_pipes.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyComputePipeline(id)));
hub.compute_pipelines.free_id(id);
let res = guard.remove(id).unwrap();
@ -467,8 +452,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
for id in self.suspected_resources.render_pipelines.drain(..) {
if trackers.render_pipes.remove_abandoned(id) {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyRenderPipeline(id)));
hub.render_pipelines.free_id(id);
let res = guard.remove(id).unwrap();
@ -512,8 +495,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
{
//Note: this has to happen after all the suspected pipelines are destroyed
if ref_count.load() == 1 {
#[cfg(feature = "trace")]
trace.map(|t| t.lock().add(trace::Action::DestroyPipelineLayout(id)));
hub.pipeline_layouts.free_id(id);
let layout = guard.remove(id).unwrap();
self.free_resources.pipeline_layouts.push(layout.raw);
@ -647,24 +628,20 @@ impl<B: GfxBackend> LifetimeTracker<B> {
} else {
let mapping = match std::mem::replace(
&mut buffer.map_state,
resource::BufferMapState::Idle,
resource::BufferMapState::Active,
) {
resource::BufferMapState::Waiting(pending_mapping) => pending_mapping,
_ => panic!("No pending mapping."),
};
log::debug!("Buffer {:?} map state -> Active", buffer_id);
let host = match mapping.op {
resource::BufferMapOperation::Read { .. } => super::HostMap::Read,
resource::BufferMapOperation::Write { .. } => super::HostMap::Write,
let result = match mapping.op {
resource::BufferMapOperation::Read { .. } => {
super::map_buffer(raw, buffer, mapping.sub_range, super::HostMap::Read)
}
resource::BufferMapOperation::Write { .. } => {
super::map_buffer(raw, buffer, mapping.sub_range, super::HostMap::Write)
}
};
let result = super::map_buffer(raw, buffer, mapping.sub_range.clone(), host);
if let Ok(ptr) = result {
buffer.map_state = resource::BufferMapState::Active {
ptr,
sub_range: mapping.sub_range,
host,
};
}
pending_callbacks.push((mapping.op, result));
}
}

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

@ -7,7 +7,7 @@ use crate::{
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token},
id, pipeline, resource, swap_chain,
track::{BufferState, TextureState, TrackerSet},
FastHashMap, LifeGuard, PrivateFeatures, Stored,
FastHashMap, Features, LifeGuard, Stored,
};
use arrayvec::ArrayVec;
@ -31,22 +31,6 @@ use std::{
};
mod life;
#[cfg(any(feature = "trace", feature = "replay"))]
pub mod trace;
#[cfg(feature = "trace")]
use trace::{Action, Trace};
pub type Label = *const std::os::raw::c_char;
#[cfg(feature = "trace")]
fn own_label(label: &Label) -> String {
if label.is_null() {
String::new()
} else {
unsafe { ffi::CStr::from_ptr(*label) }
.to_string_lossy()
.to_string()
}
}
pub const MAX_COLOR_TARGETS: usize = 4;
pub const MAX_MIP_LEVELS: usize = 16;
@ -125,38 +109,50 @@ fn map_buffer<B: hal::Backend>(
sub_range: hal::buffer::SubRange,
kind: HostMap,
) -> BufferMapResult {
let (ptr, segment, needs_sync) = {
let (ptr, sync_range) = {
let segment = hal::memory::Segment {
offset: sub_range.offset,
size: sub_range.size,
};
let mapped = buffer.memory.map(raw, segment)?;
let mr = mapped.range();
let segment = hal::memory::Segment {
offset: mr.start,
size: Some(mr.end - mr.start),
let sync_range = if mapped.is_coherent() {
None
} else {
Some(mapped.range())
};
(mapped.ptr(), segment, !mapped.is_coherent())
(mapped.ptr(), sync_range)
};
buffer.sync_mapped_writes = match kind {
HostMap::Read if needs_sync => unsafe {
raw.invalidate_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment)))
.unwrap();
None
},
HostMap::Write if needs_sync => Some(segment),
_ => None,
};
if let Some(range) = sync_range {
let segment = hal::memory::Segment {
offset: range.start,
size: Some(range.end - range.start),
};
match kind {
HostMap::Read => unsafe {
raw.invalidate_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment)))
.unwrap();
},
HostMap::Write => {
buffer.mapped_write_segments.push(segment);
}
}
}
Ok(ptr.as_ptr())
}
fn unmap_buffer<B: hal::Backend>(raw: &B::Device, buffer: &mut resource::Buffer<B>) {
if let Some(segment) = buffer.sync_mapped_writes.take() {
if !buffer.mapped_write_segments.is_empty() {
unsafe {
raw.flush_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment)))
.unwrap()
raw.flush_mapped_memory_ranges(
buffer
.mapped_write_segments
.iter()
.map(|r| (buffer.memory.memory(), r.clone())),
)
.unwrap()
};
buffer.mapped_write_segments.clear();
}
}
@ -197,11 +193,7 @@ pub struct Device<B: hal::Backend> {
// Life tracker should be locked right after the device and before anything else.
life_tracker: Mutex<life::LifetimeTracker<B>>,
temp_suspected: life::SuspectedResources,
pub(crate) private_features: PrivateFeatures,
limits: wgt::Limits,
extensions: wgt::Extensions,
#[cfg(feature = "trace")]
pub(crate) trace: Option<Mutex<Trace>>,
pub(crate) features: Features,
}
impl<B: GfxBackend> Device<B> {
@ -212,8 +204,7 @@ impl<B: GfxBackend> Device<B> {
mem_props: hal::adapter::MemoryProperties,
non_coherent_atom_size: u64,
supports_texture_d24_s8: bool,
desc: &wgt::DeviceDescriptor,
trace_path: Option<&std::path::Path>,
max_bind_groups: u32,
) -> Self {
// don't start submission index at zero
let life_guard = LifeGuard::new();
@ -233,11 +224,6 @@ impl<B: GfxBackend> Device<B> {
non_coherent_atom_size,
)
};
#[cfg(not(feature = "trace"))]
match trace_path {
Some(_) => log::warn!("Tracing feature is not enabled"),
None => (),
}
Device {
raw,
@ -252,25 +238,10 @@ impl<B: GfxBackend> Device<B> {
framebuffers: Mutex::new(FastHashMap::default()),
life_tracker: Mutex::new(life::LifetimeTracker::new()),
temp_suspected: life::SuspectedResources::default(),
#[cfg(feature = "trace")]
trace: trace_path.and_then(|path| match Trace::new(path) {
Ok(mut trace) => {
trace.add(Action::Init {
desc: desc.clone(),
backend: B::VARIANT,
});
Some(Mutex::new(trace))
}
Err(e) => {
log::warn!("Unable to start a trace in '{:?}': {:?}", path, e);
None
}
}),
private_features: PrivateFeatures {
features: Features {
max_bind_groups,
supports_texture_d24_s8,
},
limits: desc.limits.clone(),
extensions: desc.extensions.clone(),
}
}
@ -289,13 +260,7 @@ impl<B: GfxBackend> Device<B> {
) -> Vec<BufferMapPendingCallback> {
let mut life_tracker = self.lock_life(token);
life_tracker.triage_suspected(
global,
&self.trackers,
#[cfg(feature = "trace")]
self.trace.as_ref(),
token,
);
life_tracker.triage_suspected(global, &self.trackers, token);
life_tracker.triage_mapped(global, token);
life_tracker.triage_framebuffers(global, &mut *self.framebuffers.lock(), token);
let _last_done = life_tracker.triage_submissions(&self.raw, force_wait);
@ -307,7 +272,7 @@ impl<B: GfxBackend> Device<B> {
fn create_buffer(
&self,
self_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>,
desc: &wgt::BufferDescriptor,
) -> resource::Buffer<B> {
use gfx_memory::{Kind, MemoryUsage};
@ -370,7 +335,7 @@ impl<B: GfxBackend> Device<B> {
memory,
size: desc.size,
full_range: (),
sync_mapped_writes: None,
mapped_write_segments: Vec::new(),
map_state: resource::BufferMapState::Idle,
life_guard: LifeGuard::new(),
}
@ -379,7 +344,7 @@ impl<B: GfxBackend> Device<B> {
fn create_texture(
&self,
self_id: id::DeviceId,
desc: &wgt::TextureDescriptor<Label>,
desc: &wgt::TextureDescriptor,
) -> resource::Texture<B> {
debug_assert_eq!(self_id.backend(), B::VARIANT);
@ -397,7 +362,7 @@ impl<B: GfxBackend> Device<B> {
}
let kind = conv::map_texture_dimension_size(desc.dimension, desc.size, desc.sample_count);
let format = conv::map_texture_format(desc.format, self.private_features);
let format = conv::map_texture_format(desc.format, self.features);
let aspects = format.surface_desc().aspects;
let usage = conv::map_texture_usage(desc.usage, aspects);
@ -525,7 +490,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_buffer<B: GfxBackend>(
&self,
device_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>,
desc: &wgt::BufferDescriptor,
id_in: Input<G, id::BufferId>,
) -> id::BufferId {
let hub = B::hub(self);
@ -540,15 +505,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let id = hub.buffers.register_identity(id_in, buffer, &mut token);
log::info!("Created buffer {:?} with {:?}", id, desc);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateBuffer {
id,
desc: desc.map_label(own_label),
}),
None => (),
};
device
.trackers
.lock()
@ -565,7 +521,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_buffer_mapped<B: GfxBackend>(
&self,
device_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>,
desc: &wgt::BufferDescriptor,
id_in: Input<G, id::BufferId>,
) -> (id::BufferId, *mut u8) {
let hub = B::hub(self);
@ -585,11 +541,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
HostMap::Write,
) {
Ok(ptr) => {
buffer.map_state = resource::BufferMapState::Active {
ptr,
sub_range: hal::buffer::SubRange::WHOLE,
host: HostMap::Write,
};
buffer.map_state = resource::BufferMapState::Active;
ptr
}
Err(e) => {
@ -600,15 +552,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let id = hub.buffers.register_identity(id_in, buffer, &mut token);
log::info!("Created mapped buffer {:?} with {:?}", id, desc);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateBuffer {
id,
desc: desc.map_label(own_label),
}),
None => (),
};
device
.trackers
.lock()
@ -623,35 +566,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
(id, pointer)
}
#[cfg(feature = "replay")]
pub fn device_wait_for_buffer<B: GfxBackend>(
&self,
device_id: id::DeviceId,
buffer_id: id::BufferId,
) {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let last_submission = {
let (buffer_guard, _) = hub.buffers.write(&mut token);
buffer_guard[buffer_id]
.life_guard
.submission_index
.load(Ordering::Acquire)
};
let device = &device_guard[device_id];
let mut life_lock = device.lock_life(&mut token);
if life_lock.lowest_active_submission() <= last_submission {
log::info!(
"Waiting for submission {:?} before accessing buffer {:?}",
last_submission,
buffer_id
);
life_lock.triage_submissions(&device.raw, true);
}
}
pub fn device_set_buffer_sub_data<B: GfxBackend>(
&self,
device_id: id::DeviceId,
@ -673,20 +587,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
);
//assert!(buffer isn't used by the GPU);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => {
let mut trace = trace.lock();
let data_path = trace.make_binary("bin", data);
trace.add(trace::Action::WriteBuffer {
id: buffer_id,
data: data_path,
range: offset..offset + data.len() as BufferAddress,
});
}
None => (),
};
match map_buffer(
&device.raw,
&mut buffer,
@ -773,7 +673,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_texture<B: GfxBackend>(
&self,
device_id: id::DeviceId,
desc: &wgt::TextureDescriptor<Label>,
desc: &wgt::TextureDescriptor,
id_in: Input<G, id::TextureId>,
) -> id::TextureId {
let hub = B::hub(self);
@ -786,15 +686,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = texture.life_guard.add_ref();
let id = hub.textures.register_identity(id_in, texture, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateTexture {
id,
desc: desc.map_label(own_label),
}),
None => (),
};
device
.trackers
.lock()
@ -826,7 +717,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn texture_create_view<B: GfxBackend>(
&self,
texture_id: id::TextureId,
desc: Option<&wgt::TextureViewDescriptor<Label>>,
desc: Option<&wgt::TextureViewDescriptor>,
id_in: Input<G, id::TextureViewId>,
) -> id::TextureViewId {
let hub = B::hub(self);
@ -875,7 +766,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.create_image_view(
&texture.raw,
view_kind,
conv::map_texture_format(format, device.private_features),
conv::map_texture_format(format, device.features),
hal::format::Swizzle::NO,
range.clone(),
)
@ -899,16 +790,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = view.life_guard.add_ref();
let id = hub.texture_views.register_identity(id_in, view, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateTextureView {
id,
parent_id: texture_id,
desc: desc.map(|d| d.map_label(own_label)),
}),
None => (),
};
device
.trackers
.lock()
@ -949,7 +830,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_sampler<B: GfxBackend>(
&self,
device_id: id::DeviceId,
desc: &wgt::SamplerDescriptor<Label>,
desc: &wgt::SamplerDescriptor,
id_in: Input<G, id::SamplerId>,
) -> id::SamplerId {
let hub = B::hub(self);
@ -985,15 +866,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = sampler.life_guard.add_ref();
let id = hub.samplers.register_identity(id_in, sampler, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateSampler {
id,
desc: desc.map_label(own_label),
}),
None => (),
};
device
.trackers
.lock()
@ -1087,19 +959,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(),
};
let id = hub
.bind_group_layouts
.register_identity(id_in, layout, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateBindGroupLayout {
id,
label: own_label(&desc.label),
entries: entries.to_owned(),
}),
None => (),
};
id
hub.bind_group_layouts
.register_identity(id_in, layout, &mut token)
}
pub fn bind_group_layout_destroy<B: GfxBackend>(
@ -1118,15 +979,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace
.lock()
.add(trace::Action::DestroyBindGroupLayout(bind_group_layout_id)),
None => (),
};
device
device_guard[device_id]
.lock_life(&mut token)
.suspected_resources
.bind_group_layouts
@ -1152,10 +1005,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
assert!(
desc.bind_group_layouts_length <= (device.limits.max_bind_groups as usize),
desc.bind_group_layouts_length <= (device.features.max_bind_groups as usize),
"Cannot set more bind groups ({}) than the `max_bind_groups` limit requested on device creation ({})",
desc.bind_group_layouts_length,
device.limits.max_bind_groups
device.features.max_bind_groups
);
// TODO: push constants
@ -1190,19 +1043,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.collect()
},
};
let id = hub
.pipeline_layouts
.register_identity(id_in, layout, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreatePipelineLayout {
id,
bind_group_layouts: bind_group_layout_ids.to_owned(),
}),
None => (),
};
id
hub.pipeline_layouts
.register_identity(id_in, layout, &mut token)
}
pub fn pipeline_layout_destroy<B: GfxBackend>(&self, pipeline_layout_id: id::PipelineLayoutId) {
@ -1444,36 +1286,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
id,
hub.bind_groups.read(&mut token).0[id].used
);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateBindGroup {
id,
label: own_label(&desc.label),
layout_id: desc.layout,
entries: entries
.iter()
.map(|entry| {
let res = match entry.resource {
binding_model::BindingResource::Buffer(ref b) => {
trace::BindingResource::Buffer {
id: b.buffer,
offset: b.offset,
size: b.size,
}
}
binding_model::BindingResource::TextureView(id) => {
trace::BindingResource::TextureView(id)
}
binding_model::BindingResource::Sampler(id) => {
trace::BindingResource::Sampler(id)
}
};
(entry.binding, res)
})
.collect(),
}),
None => (),
};
device
.trackers
@ -1524,21 +1336,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
},
};
let id = hub
.shader_modules
.register_identity(id_in, shader, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => {
let mut trace = trace.lock();
let data = trace.make_binary("spv", unsafe {
slice::from_raw_parts(desc.code.bytes as *const u8, desc.code.length * 4)
});
trace.add(trace::Action::CreateShaderModule { id, data });
}
None => {}
};
id
hub.shader_modules
.register_identity(id_in, shader, &mut token)
}
pub fn shader_module_destroy<B: GfxBackend>(&self, shader_module_id: id::ShaderModuleId) {
@ -1546,17 +1345,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let (module, _) = hub.shader_modules.unregister(shader_module_id, &mut token);
let device = &device_guard[module.device_id.value];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace
.lock()
.add(trace::Action::DestroyShaderModule(shader_module_id)),
None => (),
};
unsafe {
device.raw.destroy_shader_module(module.raw);
device_guard[module.device_id.value]
.raw
.destroy_shader_module(module.raw);
}
}
@ -1582,11 +1374,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut command_buffer = device.com_allocator.allocate(
dev_stored,
&device.raw,
device.limits.clone(),
device.private_features,
device.features,
lowest_active_index,
#[cfg(feature = "trace")]
device.trace.is_some(),
);
unsafe {
let raw_command_buffer = command_buffer.raw.last_mut().unwrap();
@ -1713,13 +1502,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// finish all the command buffers first
for &cmb_id in command_buffer_ids {
let comb = &mut command_buffer_guard[cmb_id];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace
.lock()
.add(Action::Submit(submit_index, comb.commands.take().unwrap())),
None => (),
};
if let Some((sc_id, fbo)) = comb.used_swap_chain.take() {
let sc = &mut swap_chain_guard[sc_id.value];
@ -1741,8 +1523,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
panic!("Buffer has a pending mapping.");
}
if !buffer_guard[id].life_guard.use_at(submit_index) {
if let resource::BufferMapState::Active { .. } = buffer_guard[id].map_state
{
if let resource::BufferMapState::Active = buffer_guard[id].map_state {
log::warn!("Dropped buffer has a pending mapping.");
unmap_buffer(&device.raw, &mut buffer_guard[id]);
}
@ -1868,9 +1649,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
unsafe { slice::from_raw_parts(desc.color_states, desc.color_states_length) };
let depth_stencil_state = unsafe { desc.depth_stencil_state.as_ref() };
let rasterization_state = unsafe { desc.rasterization_state.as_ref() }.cloned();
let rasterizer = conv::map_rasterization_state_descriptor(
&rasterization_state.clone().unwrap_or_default(),
&unsafe { desc.rasterization_state.as_ref() }
.cloned()
.unwrap_or_default(),
);
let desc_vbs = unsafe {
@ -1966,7 +1748,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
colors: color_states
.iter()
.map(|at| hal::pass::Attachment {
format: Some(conv::map_texture_format(at.format, device.private_features)),
format: Some(conv::map_texture_format(at.format, device.features)),
samples: sc,
ops: hal::pass::AttachmentOps::PRESERVE,
stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
@ -1979,7 +1761,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// or depth/stencil resolve modes but satisfy the other compatibility conditions.
resolves: ArrayVec::new(),
depth_stencil: depth_stencil_state.map(|at| hal::pass::Attachment {
format: Some(conv::map_texture_format(at.format, device.private_features)),
format: Some(conv::map_texture_format(at.format, device.features)),
samples: sc,
ops: hal::pass::AttachmentOps::PRESERVE,
stencil_ops: hal::pass::AttachmentOps::PRESERVE,
@ -2119,47 +1901,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
life_guard: LifeGuard::new(),
};
let id = hub
.render_pipelines
.register_identity(id_in, pipeline, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateRenderPipeline {
id,
desc: trace::RenderPipelineDescriptor {
layout: desc.layout,
vertex_stage: trace::ProgrammableStageDescriptor::new(&desc.vertex_stage),
fragment_stage: unsafe { desc.fragment_stage.as_ref() }
.map(trace::ProgrammableStageDescriptor::new),
primitive_topology: desc.primitive_topology,
rasterization_state,
color_states: color_states.to_vec(),
depth_stencil_state: depth_stencil_state.cloned(),
vertex_state: trace::VertexStateDescriptor {
index_format: desc.vertex_state.index_format,
vertex_buffers: desc_vbs
.iter()
.map(|vbl| trace::VertexBufferLayoutDescriptor {
array_stride: vbl.array_stride,
step_mode: vbl.step_mode,
attributes: unsafe {
slice::from_raw_parts(vbl.attributes, vbl.attributes_length)
}
.iter()
.cloned()
.collect(),
})
.collect(),
},
sample_count: desc.sample_count,
sample_mask: desc.sample_mask,
alpha_to_coverage_enabled: desc.alpha_to_coverage_enabled,
},
}),
None => (),
};
id
hub.render_pipelines
.register_identity(id_in, pipeline, &mut token)
}
pub fn render_pipeline_destroy<B: GfxBackend>(&self, render_pipeline_id: id::RenderPipelineId) {
@ -2244,22 +1987,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
},
life_guard: LifeGuard::new(),
};
let id = hub
.compute_pipelines
.register_identity(id_in, pipeline, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(trace::Action::CreateComputePipeline {
id,
desc: trace::ComputePipelineDescriptor {
layout: desc.layout,
compute_stage: trace::ProgrammableStageDescriptor::new(&desc.compute_stage),
},
}),
None => (),
};
id
hub.compute_pipelines
.register_identity(id_in, pipeline, &mut token)
}
pub fn compute_pipeline_destroy<B: GfxBackend>(
@ -2350,7 +2079,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.max(*caps.image_count.start())
.min(*caps.image_count.end());
let mut config =
swap_chain::swap_chain_descriptor_to_hal(&desc, num_frames, device.private_features);
swap_chain::swap_chain_descriptor_to_hal(&desc, num_frames, device.features);
if let Some(formats) = formats {
assert!(
formats.contains(&config.format),
@ -2373,15 +2102,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
device.raw.destroy_semaphore(sc.semaphore);
}
}
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(Action::CreateSwapChain {
id: sc_id,
desc: desc.clone(),
}),
None => (),
};
let swap_chain = swap_chain::SwapChain {
life_guard: LifeGuard::new(),
device_id: Stored {
@ -2398,23 +2118,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
sc_id
}
#[cfg(feature = "replay")]
/// Only triange suspected resource IDs. This helps us to avoid ID collisions
/// upon creating new resources when re-playing a trace.
pub fn device_maintain_ids<B: GfxBackend>(&self, device_id: id::DeviceId) {
let hub = B::hub(self);
let mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id];
device.lock_life(&mut token).triage_suspected(
self,
&device.trackers,
#[cfg(feature = "trace")]
None,
&mut token,
);
}
pub fn device_poll<B: GfxBackend>(&self, device_id: id::DeviceId, force_wait: bool) {
let hub = B::hub(self);
let mut token = Token::root();
@ -2505,7 +2208,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub_usage
);
buffer.map_state = match buffer.map_state {
resource::BufferMapState::Active { .. } => panic!("Buffer already mapped"),
resource::BufferMapState::Active => panic!("Buffer already mapped"),
resource::BufferMapState::Waiting(_) => {
operation.call_error();
return;
@ -2550,35 +2253,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
resource::BufferMapState::Idle => {
log::error!("Buffer already unmapped");
}
resource::BufferMapState::Waiting(_) => {}
resource::BufferMapState::Active {
ptr,
ref sub_range,
host,
} => {
let device = &device_guard[buffer.device_id.value];
if host == HostMap::Write {
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => {
let mut trace = trace.lock();
let size = sub_range.size_to(buffer.size);
let data = trace.make_binary("bin", unsafe {
slice::from_raw_parts(ptr, size as usize)
});
trace.add(trace::Action::WriteBuffer {
id: buffer_id,
data,
range: sub_range.offset..sub_range.offset + size,
});
}
None => (),
};
let _ = (ptr, sub_range);
}
unmap_buffer(&device.raw, buffer);
_ => {
buffer.map_state = resource::BufferMapState::Idle;
unmap_buffer(&device_guard[buffer.device_id.value].raw, buffer);
}
}
buffer.map_state = resource::BufferMapState::Idle;
}
}

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

@ -1,258 +0,0 @@
/* 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 crate::{
command::{BufferCopyView, TextureCopyView},
id,
};
#[cfg(feature = "trace")]
use std::io::Write as _;
use std::ops::Range;
//TODO: consider a readable Id that doesn't include the backend
type FileName = String;
pub const FILE_NAME: &str = "trace.ron";
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum BindingResource {
Buffer {
id: id::BufferId,
offset: wgt::BufferAddress,
size: wgt::BufferAddress,
},
Sampler(id::SamplerId),
TextureView(id::TextureViewId),
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ProgrammableStageDescriptor {
pub module: id::ShaderModuleId,
pub entry_point: String,
}
#[cfg(feature = "trace")]
impl ProgrammableStageDescriptor {
pub fn new(desc: &crate::pipeline::ProgrammableStageDescriptor) -> Self {
ProgrammableStageDescriptor {
module: desc.module,
entry_point: unsafe { std::ffi::CStr::from_ptr(desc.entry_point) }
.to_string_lossy()
.to_string(),
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct ComputePipelineDescriptor {
pub layout: id::PipelineLayoutId,
pub compute_stage: ProgrammableStageDescriptor,
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct VertexBufferLayoutDescriptor {
pub array_stride: wgt::BufferAddress,
pub step_mode: wgt::InputStepMode,
pub attributes: Vec<wgt::VertexAttributeDescriptor>,
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct VertexStateDescriptor {
pub index_format: wgt::IndexFormat,
pub vertex_buffers: Vec<VertexBufferLayoutDescriptor>,
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct RenderPipelineDescriptor {
pub layout: id::PipelineLayoutId,
pub vertex_stage: ProgrammableStageDescriptor,
pub fragment_stage: Option<ProgrammableStageDescriptor>,
pub primitive_topology: wgt::PrimitiveTopology,
pub rasterization_state: Option<wgt::RasterizationStateDescriptor>,
pub color_states: Vec<wgt::ColorStateDescriptor>,
pub depth_stencil_state: Option<wgt::DepthStencilStateDescriptor>,
pub vertex_state: VertexStateDescriptor,
pub sample_count: u32,
pub sample_mask: u32,
pub alpha_to_coverage_enabled: bool,
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum Action {
Init {
desc: wgt::DeviceDescriptor,
backend: wgt::Backend,
},
CreateBuffer {
id: id::BufferId,
desc: wgt::BufferDescriptor<String>,
},
DestroyBuffer(id::BufferId),
CreateTexture {
id: id::TextureId,
desc: wgt::TextureDescriptor<String>,
},
DestroyTexture(id::TextureId),
CreateTextureView {
id: id::TextureViewId,
parent_id: id::TextureId,
desc: Option<wgt::TextureViewDescriptor<String>>,
},
DestroyTextureView(id::TextureViewId),
CreateSampler {
id: id::SamplerId,
desc: wgt::SamplerDescriptor<String>,
},
DestroySampler(id::SamplerId),
CreateSwapChain {
id: id::SwapChainId,
desc: wgt::SwapChainDescriptor,
},
GetSwapChainTexture {
id: id::TextureViewId,
parent_id: id::SwapChainId,
},
PresentSwapChain(id::SwapChainId),
CreateBindGroupLayout {
id: id::BindGroupLayoutId,
label: String,
entries: Vec<crate::binding_model::BindGroupLayoutEntry>,
},
DestroyBindGroupLayout(id::BindGroupLayoutId),
CreatePipelineLayout {
id: id::PipelineLayoutId,
bind_group_layouts: Vec<id::BindGroupLayoutId>,
},
DestroyPipelineLayout(id::PipelineLayoutId),
CreateBindGroup {
id: id::BindGroupId,
label: String,
layout_id: id::BindGroupLayoutId,
entries: std::collections::BTreeMap<u32, BindingResource>,
},
DestroyBindGroup(id::BindGroupId),
CreateShaderModule {
id: id::ShaderModuleId,
data: FileName,
},
DestroyShaderModule(id::ShaderModuleId),
CreateComputePipeline {
id: id::ComputePipelineId,
desc: ComputePipelineDescriptor,
},
DestroyComputePipeline(id::ComputePipelineId),
CreateRenderPipeline {
id: id::RenderPipelineId,
desc: RenderPipelineDescriptor,
},
DestroyRenderPipeline(id::RenderPipelineId),
WriteBuffer {
id: id::BufferId,
data: FileName,
range: Range<wgt::BufferAddress>,
},
Submit(crate::SubmissionIndex, Vec<Command>),
}
#[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum Command {
CopyBufferToBuffer {
src: id::BufferId,
src_offset: wgt::BufferAddress,
dst: id::BufferId,
dst_offset: wgt::BufferAddress,
size: wgt::BufferAddress,
},
CopyBufferToTexture {
src: BufferCopyView,
dst: TextureCopyView,
size: wgt::Extent3d,
},
CopyTextureToBuffer {
src: TextureCopyView,
dst: BufferCopyView,
size: wgt::Extent3d,
},
CopyTextureToTexture {
src: TextureCopyView,
dst: TextureCopyView,
size: wgt::Extent3d,
},
RunComputePass {
commands: Vec<crate::command::ComputeCommand>,
dynamic_offsets: Vec<wgt::DynamicOffset>,
},
RunRenderPass {
target_colors: Vec<crate::command::RenderPassColorAttachmentDescriptor>,
target_depth_stencil: Option<crate::command::RenderPassDepthStencilAttachmentDescriptor>,
commands: Vec<crate::command::RenderCommand>,
dynamic_offsets: Vec<wgt::DynamicOffset>,
},
}
#[cfg(feature = "trace")]
#[derive(Debug)]
pub struct Trace {
path: std::path::PathBuf,
file: std::fs::File,
config: ron::ser::PrettyConfig,
binary_id: usize,
}
#[cfg(feature = "trace")]
impl Trace {
pub fn new(path: &std::path::Path) -> Result<Self, std::io::Error> {
log::info!("Tracing into '{:?}'", path);
let mut file = std::fs::File::create(path.join(FILE_NAME))?;
file.write(b"[\n")?;
Ok(Trace {
path: path.to_path_buf(),
file,
config: ron::ser::PrettyConfig::default(),
binary_id: 0,
})
}
pub fn make_binary(&mut self, kind: &str, data: &[u8]) -> String {
self.binary_id += 1;
let name = format!("data{}.{}", self.binary_id, kind);
let _ = std::fs::write(self.path.join(&name), data);
name
}
pub(crate) fn add(&mut self, action: Action) {
match ron::ser::to_string_pretty(&action, self.config.clone()) {
Ok(string) => {
let _ = writeln!(self.file, "{},", string);
}
Err(e) => {
log::warn!("RON serialization failure: {:?}", e);
}
}
}
}
#[cfg(feature = "trace")]
impl Drop for Trace {
fn drop(&mut self) {
let _ = self.file.write(b"]");
}
}

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

@ -25,7 +25,7 @@ use wgt::Backend;
#[cfg(debug_assertions)]
use std::cell::Cell;
use std::{fmt::Debug, marker::PhantomData, ops, thread};
use std::{fmt::Debug, iter, marker::PhantomData, ops, thread};
/// A simple structure to manage identities of objects.
#[derive(Debug)]
@ -44,13 +44,6 @@ impl Default for IdentityManager {
}
impl IdentityManager {
pub fn from_index(min_index: u32) -> Self {
IdentityManager {
free: (0..min_index).collect(),
epochs: vec![1; min_index as usize],
}
}
pub fn alloc<I: TypedId>(&mut self, backend: Backend) -> I {
match self.free.pop() {
Some(index) => I::zip(index, self.epochs[index as usize], backend),
@ -269,7 +262,10 @@ pub struct IdentityManagerFactory;
impl<I: TypedId + Debug> IdentityHandlerFactory<I> for IdentityManagerFactory {
type Filter = Mutex<IdentityManager>;
fn spawn(&self, min_index: Index) -> Self::Filter {
Mutex::new(IdentityManager::from_index(min_index))
let mut man = IdentityManager::default();
man.free.extend(0..min_index);
man.epochs.extend(iter::repeat(1).take(min_index as usize));
Mutex::new(man)
}
}

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

@ -3,6 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::{Epoch, Index};
#[cfg(feature = "serde")]
use serde_crate::{Deserialize, Serialize};
use std::{fmt, marker::PhantomData, mem, num::NonZeroU64};
use wgt::Backend;
@ -11,38 +13,13 @@ const EPOCH_MASK: u32 = (1 << (32 - BACKEND_BITS)) - 1;
type Dummy = crate::backend::Empty;
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(serde::Serialize), serde(into = "SerialId"))]
#[cfg_attr(
feature = "replay",
derive(serde::Deserialize),
serde(from = "SerialId")
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct Id<T>(NonZeroU64, PhantomData<T>);
// This type represents Id in a more readable (and editable) way.
#[allow(dead_code)]
#[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<T> From<Id<T>> for SerialId {
fn from(id: Id<T>) -> Self {
let (index, epoch, backend) = id.unzip();
SerialId::Id(index, epoch, backend)
}
}
#[cfg(feature = "replay")]
impl<T> From<SerialId> for Id<T> {
fn from(id: SerialId) -> Self {
match id {
SerialId::Id(index, epoch, backend) => TypedId::zip(index, epoch, backend),
}
}
}
// required for PeekPoke
impl<T> Default for Id<T> {
fn default() -> Self {
@ -179,7 +156,7 @@ impl SurfaceId {
}
}
impl SwapChainId {
pub fn to_surface_id(self) -> SurfaceId {
pub(crate) fn to_surface_id(self) -> SurfaceId {
let (index, epoch, _) = self.unzip();
Id::zip(index, epoch, Backend::Empty)
}

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

@ -12,10 +12,8 @@ use crate::{
use wgt::{Backend, BackendBit, DeviceDescriptor, PowerPreference, BIND_BUFFER_ALIGNMENT};
#[cfg(feature = "replay")]
use serde::Deserialize;
#[cfg(feature = "trace")]
use serde::Serialize;
#[cfg(feature = "serde")]
use serde_crate::{Deserialize, Serialize};
use hal::{
self,
@ -27,8 +25,11 @@ use hal::{
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct RequestAdapterOptions {
pub power_preference: PowerPreference,
pub compatible_surface: Option<SurfaceId>,
@ -133,8 +134,11 @@ impl<B: hal::Backend> Adapter<B> {
/// Metadata about a backend adapter.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct AdapterInfo {
/// Adapter name
pub name: String,
@ -169,8 +173,11 @@ impl AdapterInfo {
/// Supported physical device types
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub enum DeviceType {
/// Other
Other,
@ -198,7 +205,7 @@ impl From<HalDeviceType> for DeviceType {
pub enum AdapterInputs<'a, I> {
IdSet(&'a [I], fn(&I) -> Backend),
Mask(BackendBit, fn(Backend) -> I),
Mask(BackendBit, fn() -> I),
}
impl<I: Clone> AdapterInputs<'_, I> {
@ -207,7 +214,7 @@ impl<I: Clone> AdapterInputs<'_, I> {
AdapterInputs::IdSet(ids, ref fun) => ids.iter().find(|id| fun(id) == b).cloned(),
AdapterInputs::Mask(bits, ref fun) => {
if bits.contains(b.into()) {
Some(fun(b))
Some(fun())
} else {
None
}
@ -217,84 +224,6 @@ impl<I: Clone> AdapterInputs<'_, I> {
}
impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[cfg(feature = "raw-window-handle")]
pub fn instance_create_surface(
&self,
handle: &impl raw_window_handle::HasRawWindowHandle,
id_in: Input<G, SurfaceId>,
) -> SurfaceId {
use raw_window_handle::RawWindowHandle as Rwh;
let surface = match handle.raw_window_handle() {
#[cfg(target_os = "ios")]
Rwh::IOS(h) => Surface {
#[cfg(feature = "gfx-backend-vulkan")]
vulkan: None,
metal: self
.instance
.metal
.create_surface_from_uiview(h.ui_view, cfg!(debug_assertions)),
},
#[cfg(target_os = "macos")]
Rwh::MacOS(h) => {
//TODO: figure out when this is needed, and how to get that without `objc`
//use objc::{msg_send, runtime::Object, sel, sel_impl};
//let ns_view = if h.ns_view.is_null() {
// let ns_window = h.ns_window as *mut Object;
// unsafe { msg_send![ns_window, contentView] }
//} else {
// h.ns_view
//};
Surface {
#[cfg(feature = "gfx-backend-vulkan")]
vulkan: self
.instance
.vulkan
.as_ref()
.map(|inst| inst.create_surface_from_ns_view(h.ns_view)),
metal: self
.instance
.metal
.create_surface_from_nsview(h.ns_view, cfg!(debug_assertions)),
}
}
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
Rwh::Xlib(h) => Surface {
vulkan: self
.instance
.vulkan
.as_ref()
.map(|inst| inst.create_surface_from_xlib(h.display as _, h.window)),
},
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
Rwh::Wayland(h) => Surface {
vulkan: self
.instance
.vulkan
.as_ref()
.map(|inst| inst.create_surface_from_wayland(h.display, h.surface)),
},
#[cfg(windows)]
Rwh::Windows(h) => Surface {
vulkan: self
.instance
.vulkan
.as_ref()
.map(|inst| inst.create_surface_from_hwnd(std::ptr::null_mut(), h.hwnd)),
dx12: self
.instance
.dx12
.as_ref()
.map(|inst| inst.create_surface_from_hwnd(h.hwnd)),
dx11: self.instance.dx11.create_surface_from_hwnd(h.hwnd),
},
_ => panic!("Unsupported window handle"),
};
let mut token = Token::root();
self.surfaces.register_identity(id_in, surface, &mut token)
}
pub fn enumerate_adapters(&self, inputs: AdapterInputs<Input<G, AdapterId>>) -> Vec<AdapterId> {
let instance = &self.instance;
let mut token = Token::root();
@ -594,7 +523,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&self,
adapter_id: AdapterId,
desc: &DeviceDescriptor,
trace_path: Option<&std::path::Path>,
id_in: Input<G, DeviceId>,
) -> DeviceId {
let hub = B::hub(self);
@ -658,8 +586,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
mem_props,
limits.non_coherent_atom_size as u64,
supports_texture_d24_s8,
desc,
trace_path,
desc.limits.max_bind_groups,
)
};

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

@ -122,7 +122,8 @@ pub struct U32Array {
}
#[derive(Clone, Copy, Debug)]
struct PrivateFeatures {
pub(crate) struct Features {
pub max_bind_groups: u32,
pub supports_texture_d24_s8: bool,
}

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

@ -76,18 +76,11 @@ pub enum BufferMapState {
/// Waiting for GPU to be done before mapping
Waiting(BufferPendingMapping),
/// Mapped
Active {
ptr: *mut u8,
sub_range: hal::buffer::SubRange,
host: crate::device::HostMap,
},
Active,
/// Not mapped
Idle,
}
unsafe impl Send for BufferMapState {}
unsafe impl Sync for BufferMapState {}
pub enum BufferMapOperation {
Read {
callback: crate::device::BufferMapReadCallback,
@ -148,7 +141,7 @@ pub struct Buffer<B: hal::Backend> {
pub(crate) memory: MemoryBlock<B>,
pub(crate) size: BufferAddress,
pub(crate) full_range: (),
pub(crate) sync_mapped_writes: Option<hal::memory::Segment>,
pub(crate) mapped_write_segments: Vec<hal::memory::Segment>,
pub(crate) life_guard: LifeGuard,
pub(crate) map_state: BufferMapState,
}

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

@ -32,13 +32,11 @@
In `present()` we return the swap chain image back and wait on the semaphore.
!*/
#[cfg(feature = "trace")]
use crate::device::trace::Action;
use crate::{
conv,
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token},
id::{DeviceId, SwapChainId, TextureViewId},
resource, LifeGuard, PrivateFeatures, Stored,
resource, Features, LifeGuard, Stored,
};
use hal::{self, device::Device as _, queue::CommandQueue as _, window::PresentationSurface as _};
@ -61,12 +59,12 @@ pub struct SwapChain<B: hal::Backend> {
pub(crate) fn swap_chain_descriptor_to_hal(
desc: &SwapChainDescriptor,
num_frames: u32,
private_features: PrivateFeatures,
features: Features,
) -> hal::window::SwapchainConfig {
let mut config = hal::window::SwapchainConfig::new(
desc.width,
desc.height,
conv::map_texture_format(desc.format, private_features),
conv::map_texture_format(desc.format, features),
num_frames,
);
//TODO: check for supported
@ -116,11 +114,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
Err(e) => {
log::warn!("acquire_image() failed ({:?}), reconfiguring swapchain", e);
let desc = swap_chain_descriptor_to_hal(
&sc.desc,
sc.num_frames,
device.private_features,
);
let desc =
swap_chain_descriptor_to_hal(&sc.desc, sc.num_frames, device.features);
unsafe {
suf.configure_swapchain(&device.raw, desc).unwrap();
suf.acquire_image(FRAME_TIMEOUT_MS * 1_000_000).unwrap()
@ -156,15 +151,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.texture_views
.register_identity(view_id_in, view, &mut token);
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(Action::GetSwapChainTexture {
id,
parent_id: swap_chain_id,
}),
None => (),
};
assert!(
sc.acquired_view_id.is_none(),
"Swap chain image is already acquired"
@ -188,12 +174,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let sc = &mut swap_chain_guard[swap_chain_id];
let device = &mut device_guard[sc.device_id.value];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace.lock().add(Action::PresentSwapChain(swap_chain_id)),
None => (),
};
let view_id = sc
.acquired_view_id
.take()

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

@ -14,10 +14,6 @@ license = "MPL-2.0"
[lib]
[features]
trace = ["serde"]
replay = ["serde"]
[dependencies]
bitflags = "1.0"
serde = { version = "1.0", features = ["serde_derive"], optional = true }

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

@ -4,16 +4,13 @@
#[cfg(feature = "peek-poke")]
use peek_poke::PeekPoke;
#[cfg(feature = "replay")]
use serde::Deserialize;
#[cfg(feature = "trace")]
use serde::Serialize;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::{io, ptr, slice};
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Backend {
Empty = 0,
Vulkan = 1,
@ -26,8 +23,7 @@ pub enum Backend {
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PowerPreference {
Default = 0,
LowPower = 1,
@ -36,8 +32,7 @@ pub enum PowerPreference {
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BackendBit: u32 {
const VULKAN = 1 << Backend::Vulkan as u32;
const GL = 1 << Backend::Gl as u32;
@ -63,16 +58,14 @@ impl From<Backend> for BackendBit {
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Extensions {
pub anisotropic_filtering: bool,
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Limits {
pub max_bind_groups: u32,
}
@ -89,8 +82,7 @@ impl Default for Limits {
#[repr(C)]
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DeviceDescriptor {
pub extensions: Extensions,
pub limits: Limits,
@ -121,13 +113,13 @@ pub fn read_spirv<R: io::Read + io::Seek>(mut x: R) -> io::Result<Vec<u32>> {
))?;
result.set_len(words);
}
const MAGIC_NUMBER: u32 = 0x0723_0203;
if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() {
const MAGIC_NUMBER: u32 = 0x07230203;
if result.len() > 0 && result[0] == MAGIC_NUMBER.swap_bytes() {
for word in &mut result {
*word = word.swap_bytes();
}
}
if result.is_empty() || result[0] != MAGIC_NUMBER {
if result.len() == 0 || result[0] != MAGIC_NUMBER {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"input missing SPIR-V magic number",
@ -138,8 +130,7 @@ pub fn read_spirv<R: io::Read + io::Seek>(mut x: R) -> io::Result<Vec<u32>> {
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ShaderStage: u32 {
const NONE = 0;
const VERTEX = 1;
@ -150,8 +141,7 @@ bitflags::bitflags! {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TextureViewDimension {
D1,
D2,
@ -165,8 +155,7 @@ pub type BufferAddress = u64;
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendFactor {
Zero = 0,
One = 1,
@ -185,8 +174,7 @@ pub enum BlendFactor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BlendOperation {
Add = 0,
Subtract = 1,
@ -203,8 +191,7 @@ impl Default for BlendOperation {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BlendDescriptor {
pub src_factor: BlendFactor,
pub dst_factor: BlendFactor,
@ -237,8 +224,7 @@ impl Default for BlendDescriptor {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ColorStateDescriptor {
pub format: TextureFormat,
pub alpha_blend: BlendDescriptor,
@ -248,8 +234,7 @@ pub struct ColorStateDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PrimitiveTopology {
PointList = 0,
LineList = 1,
@ -260,8 +245,7 @@ pub enum PrimitiveTopology {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum FrontFace {
Ccw = 0,
Cw = 1,
@ -275,8 +259,7 @@ impl Default for FrontFace {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum CullMode {
None = 0,
Front = 1,
@ -291,8 +274,7 @@ impl Default for CullMode {
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RasterizationStateDescriptor {
pub front_face: FrontFace,
pub cull_mode: CullMode,
@ -303,8 +285,7 @@ pub struct RasterizationStateDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TextureFormat {
// Normal 8 bit formats
R8Unorm = 0,
@ -361,8 +342,7 @@ pub enum TextureFormat {
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ColorWrite: u32 {
const RED = 1;
const GREEN = 2;
@ -381,8 +361,7 @@ impl Default for ColorWrite {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DepthStencilStateDescriptor {
pub format: TextureFormat,
pub depth_write_enabled: bool,
@ -401,8 +380,7 @@ impl DepthStencilStateDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum IndexFormat {
Uint16 = 0,
Uint32 = 1,
@ -410,8 +388,7 @@ pub enum IndexFormat {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StencilOperation {
Keep = 0,
Zero = 1,
@ -431,8 +408,7 @@ impl Default for StencilOperation {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StencilStateFaceDescriptor {
pub compare: CompareFunction,
pub fail_op: StencilOperation,
@ -457,8 +433,7 @@ impl Default for StencilStateFaceDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum CompareFunction {
Undefined = 0,
Never = 1,
@ -484,8 +459,7 @@ pub type ShaderLocation = u32;
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum InputStepMode {
Vertex = 0,
Instance = 1,
@ -493,8 +467,7 @@ pub enum InputStepMode {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VertexAttributeDescriptor {
pub offset: BufferAddress,
pub format: VertexFormat,
@ -503,8 +476,7 @@ pub struct VertexAttributeDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum VertexFormat {
Uchar2 = 0,
Uchar4 = 1,
@ -540,8 +512,7 @@ pub enum VertexFormat {
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BufferUsage: u32 {
const MAP_READ = 1;
const MAP_WRITE = 2;
@ -557,24 +528,12 @@ bitflags::bitflags! {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BufferDescriptor<L> {
pub label: L,
pub struct BufferDescriptor {
pub label: *const std::os::raw::c_char,
pub size: BufferAddress,
pub usage: BufferUsage,
}
impl<L> BufferDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> BufferDescriptor<K> {
BufferDescriptor {
label: fun(&self.label),
size: self.size,
usage: self.usage,
}
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct CommandEncoderDescriptor {
@ -594,8 +553,7 @@ pub type DynamicOffset = u32;
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PresentMode {
/// The presentation engine does **not** wait for a vertical blanking period and
/// the request is presented immediately. This is a low-latency presentation mode,
@ -615,8 +573,7 @@ pub enum PresentMode {
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TextureUsage: u32 {
const COPY_SRC = 1;
const COPY_DST = 2;
@ -628,8 +585,7 @@ bitflags::bitflags! {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SwapChainDescriptor {
pub usage: TextureUsage,
pub format: TextureFormat,
@ -640,8 +596,7 @@ pub struct SwapChainDescriptor {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekPoke))]
pub enum LoadOp {
Clear = 0,
@ -650,8 +605,7 @@ pub enum LoadOp {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekPoke))]
pub enum StoreOp {
Clear = 0,
@ -660,8 +614,7 @@ pub enum StoreOp {
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekPoke))]
pub struct RenderPassColorAttachmentDescriptorBase<T> {
pub attachment: T,
@ -673,8 +626,7 @@ pub struct RenderPassColorAttachmentDescriptorBase<T> {
#[repr(C)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekPoke))]
pub struct RenderPassDepthStencilAttachmentDescriptorBase<T> {
pub attachment: T,
@ -688,8 +640,7 @@ pub struct RenderPassDepthStencilAttachmentDescriptorBase<T> {
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekPoke))]
pub struct Color {
pub r: f64,
@ -739,8 +690,7 @@ impl Color {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TextureDimension {
D1,
D2,
@ -749,8 +699,7 @@ pub enum TextureDimension {
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Origin3d {
pub x: u32,
pub y: u32,
@ -769,8 +718,7 @@ impl Default for Origin3d {
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Extent3d {
pub width: u32,
pub height: u32,
@ -779,10 +727,8 @@ pub struct Extent3d {
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextureDescriptor<L> {
pub label: L,
pub struct TextureDescriptor {
pub label: *const std::os::raw::c_char,
pub size: Extent3d,
pub mip_level_count: u32,
pub sample_count: u32,
@ -791,24 +737,9 @@ pub struct TextureDescriptor<L> {
pub usage: TextureUsage,
}
impl<L> TextureDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K> {
TextureDescriptor {
label: fun(&self.label),
size: self.size,
mip_level_count: self.mip_level_count,
sample_count: self.sample_count,
dimension: self.dimension,
format: self.format,
usage: self.usage,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TextureAspect {
All,
StencilOnly,
@ -823,10 +754,8 @@ impl Default for TextureAspect {
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct TextureViewDescriptor<L> {
pub label: L,
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TextureViewDescriptor {
pub format: TextureFormat,
pub dimension: TextureViewDimension,
pub aspect: TextureAspect,
@ -836,25 +765,9 @@ pub struct TextureViewDescriptor<L> {
pub array_layer_count: u32,
}
impl<L> TextureViewDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureViewDescriptor<K> {
TextureViewDescriptor {
label: fun(&self.label),
format: self.format,
dimension: self.dimension,
aspect: self.aspect,
base_mip_level: self.base_mip_level,
level_count: self.level_count,
base_array_layer: self.base_array_layer,
array_layer_count: self.array_layer_count,
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum AddressMode {
ClampToEdge = 0,
Repeat = 1,
@ -869,8 +782,7 @@ impl Default for AddressMode {
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum FilterMode {
Nearest = 0,
Linear = 1,
@ -884,10 +796,8 @@ impl Default for FilterMode {
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct SamplerDescriptor<L> {
pub label: L,
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SamplerDescriptor {
pub address_mode_u: AddressMode,
pub address_mode_v: AddressMode,
pub address_mode_w: AddressMode,
@ -899,35 +809,16 @@ pub struct SamplerDescriptor<L> {
pub compare: CompareFunction,
}
impl<L> SamplerDescriptor<L> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> SamplerDescriptor<K> {
SamplerDescriptor {
label: fun(&self.label),
address_mode_u: self.address_mode_u,
address_mode_v: self.address_mode_v,
address_mode_w: self.address_mode_w,
mag_filter: self.mag_filter,
min_filter: self.min_filter,
mipmap_filter: self.mipmap_filter,
lod_min_clamp: self.lod_min_clamp,
lod_max_clamp: self.lod_max_clamp,
compare: self.compare,
}
}
}
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CommandBufferDescriptor {
pub todo: u32,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TextureComponentType {
Float,
Sint,

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

@ -18,13 +18,13 @@ default = []
path = "../wgpu/wgpu-core"
package = "wgpu-core"
version = "0.5"
features = ["trace"]
features = ["serde"]
[dependencies.wgt]
path = "../wgpu/wgpu-types"
package = "wgpu-types"
version = "0.5"
features = ["trace"]
features = ["serde"]
[dependencies]
log = "0.4"

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

@ -24,12 +24,6 @@ style = "tag"
prefix = "WGPU"
exclude = ["Option_AdapterId", "Option_SurfaceId", "Option_TextureViewId"]
[export.rename]
"BufferDescriptor_RawString" = "BufferDescriptor"
"TextureDescriptor_RawString" = "TextureDescriptor"
"TextureViewDescriptor_RawString" = "TextureViewDescriptor"
"SamplerDescriptor_RawString" = "SamplerDescriptor"
[parse]
parse_deps = true
include = ["wgpu-core", "wgpu-types"]

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

@ -9,7 +9,6 @@ use wgc::{gfx_select, id};
use std::slice;
pub type Global = wgc::hub::Global<IdentityRecyclerFactory>;
pub type RawString = *const std::os::raw::c_char;
#[no_mangle]
pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Global {
@ -60,17 +59,13 @@ pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_server_adapter_request_device(
pub extern "C" fn wgpu_server_adapter_request_device(
global: &Global,
self_id: id::AdapterId,
desc: &wgt::DeviceDescriptor,
new_id: id::DeviceId,
) {
let trace_string = std::env::var("WGPU_TRACE").ok();
let trace_path = trace_string
.as_ref()
.map(|string| std::path::Path::new(string.as_str()));
gfx_select!(self_id => global.adapter_request_device(self_id, desc, trace_path, new_id));
gfx_select!(self_id => global.adapter_request_device(self_id, desc, new_id));
}
#[no_mangle]
@ -87,7 +82,7 @@ pub extern "C" fn wgpu_server_device_destroy(global: &Global, self_id: id::Devic
pub extern "C" fn wgpu_server_device_create_buffer(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::BufferDescriptor<RawString>,
desc: &wgt::BufferDescriptor,
new_id: id::BufferId,
) {
gfx_select!(self_id => global.device_create_buffer(self_id, desc, new_id));
@ -377,7 +372,7 @@ pub extern "C" fn wgpu_server_render_pipeline_destroy(
pub extern "C" fn wgpu_server_device_create_texture(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::TextureDescriptor<RawString>,
desc: &wgt::TextureDescriptor,
new_id: id::TextureId,
) {
gfx_select!(self_id => global.device_create_texture(self_id, desc, new_id));
@ -387,7 +382,7 @@ pub extern "C" fn wgpu_server_device_create_texture(
pub extern "C" fn wgpu_server_texture_create_view(
global: &Global,
self_id: id::TextureId,
desc: Option<&wgt::TextureViewDescriptor<RawString>>,
desc: Option<&wgt::TextureViewDescriptor>,
new_id: id::TextureViewId,
) {
gfx_select!(self_id => global.texture_create_view(self_id, desc, new_id));
@ -407,7 +402,7 @@ pub extern "C" fn wgpu_server_texture_view_destroy(global: &Global, self_id: id:
pub extern "C" fn wgpu_server_device_create_sampler(
global: &Global,
self_id: id::DeviceId,
desc: &wgt::SamplerDescriptor<RawString>,
desc: &wgt::SamplerDescriptor,
new_id: id::SamplerId,
) {
gfx_select!(self_id => global.device_create_sampler(self_id, desc, new_id));

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

@ -183,8 +183,6 @@ wgpu-deps:
run:
script: wgpu-deps-vendoring.sh
sparse-profile: null
resources:
- 'gfx/wgpu/Cargo.lock'
toolchain-artifact: public/build/wgpu-deps.tar.bz2
fetches:
fetch:

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

@ -46,7 +46,7 @@ jobs:
export PATH=$PATH:$MOZ_FETCHES_DIR/rustc/bin &&
cd $GECKO_PATH/gfx/wgpu &&
mv $MOZ_FETCHES_DIR/wgpu-deps/{vendor,.cargo} ./ &&
cargo test --verbose --frozen
cargo test --verbose
treeherder:
platform: linux64-qr/debug
symbol: Wgpu(test)

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

@ -59,7 +59,6 @@ clippy:
- gfx/wr/webrender_api/
- gfx/wr/wrench/
- gfx/wgpu/wgpu-core/
- gfx/wgpu/player/
- gfx/wgpu_bindings/
# not_unsafe_ptr_arg_deref
- modules/libpref/parser/