зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset f4ed4d3e0e9e (bug 1634425) for hazard failure on WebGPUParent.cpp CLOSED TREE
This commit is contained in:
Родитель
4331b35ab5
Коммит
6ed3c943f7
|
@ -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
|
||||
|
||||
|
|
|
@ -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,3 +1,4 @@
|
|||
Cargo.lock
|
||||
/target
|
||||
**/*.rs.bk
|
||||
#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/
|
||||
|
|
Загрузка…
Ссылка в новой задаче