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

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

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

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

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

@ -14,13 +14,13 @@ using SerialPipelineLayoutDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialBindGroupDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using SerialBindGroupDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialComputePipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using SerialComputePipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h";
using SerialRenderPipelineDescriptor 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::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h";
using dom::GPUDeviceDescriptor 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::GPUCommandEncoderDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h"; using dom::GPUCommandBufferDescriptor from "mozilla/dom/WebGPUBinding.h";
using dom::GPUPipelineLayoutDescriptor 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::WGPUSamplerDescriptor from "mozilla/webgpu/ffi/wgpu.h";
using webgpu::ffi::WGPUTextureViewDescriptor 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"; 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 InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (RawId adapterId);
async AdapterRequestDevice(RawId selfId, GPUDeviceDescriptor desc, RawId newId); async AdapterRequestDevice(RawId selfId, GPUDeviceDescriptor desc, RawId newId);
async AdapterDestroy(RawId selfId); 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 DeviceDestroy(RawId selfId);
async DeviceUnmapBuffer(RawId selfId, RawId bufferId, Shmem shmem, bool flush); async DeviceUnmapBuffer(RawId selfId, RawId bufferId, Shmem shmem, bool flush);
async BufferMapRead(RawId selfId, Shmem shmem) returns (Shmem sm); async BufferMapRead(RawId selfId, Shmem shmem) returns (Shmem sm);
async BufferDestroy(RawId selfId); async BufferDestroy(RawId selfId);
async DeviceCreateTexture(RawId selfId, WGPUTextureDescriptor desc, nsCString label, RawId newId); async DeviceCreateTexture(RawId selfId, SerialTextureDescriptor desc, RawId newId);
async TextureCreateView(RawId selfId, WGPUTextureViewDescriptor desc, nsCString label, RawId newId); async TextureCreateView(RawId selfId, WGPUTextureViewDescriptor desc, RawId newId);
async TextureDestroy(RawId selfId); async TextureDestroy(RawId selfId);
async TextureViewDestroy(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 SamplerDestroy(RawId selfId);
async DeviceCreateCommandEncoder(RawId selfId, GPUCommandEncoderDescriptor desc, RawId newId); async DeviceCreateCommandEncoder(RawId selfId, GPUCommandEncoderDescriptor desc, RawId newId);
async CommandEncoderCopyBufferToBuffer(RawId selfId, RawId sourceId, BufferAddress sourceOffset, RawId destinationId, BufferAddress destinationOffset, BufferAddress size); 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, RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
const dom::GPUBufferDescriptor& aDesc) { 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); 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"); MOZ_CRASH("IPC failure");
} }
return id; return id;
@ -119,28 +115,28 @@ UniquePtr<ffi::WGPUTextureViewDescriptor> WebGPUChild::GetDefaultViewDescriptor(
RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId, RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
const dom::GPUTextureDescriptor& aDesc) { const dom::GPUTextureDescriptor& aDesc) {
ffi::WGPUTextureDescriptor desc = {}; SerialTextureDescriptor desc = {};
if (aDesc.mSize.IsUnsignedLongSequence()) { if (aDesc.mSize.IsUnsignedLongSequence()) {
const auto& seq = aDesc.mSize.GetAsUnsignedLongSequence(); const auto& seq = aDesc.mSize.GetAsUnsignedLongSequence();
desc.size.width = seq.Length() > 0 ? seq[0] : 1; desc.mSize.width = seq.Length() > 0 ? seq[0] : 1;
desc.size.height = seq.Length() > 1 ? seq[1] : 1; desc.mSize.height = seq.Length() > 1 ? seq[1] : 1;
desc.size.depth = seq.Length() > 2 ? seq[2] : 1; desc.mSize.depth = seq.Length() > 2 ? seq[2] : 1;
} else if (aDesc.mSize.IsGPUExtent3DDict()) { } else if (aDesc.mSize.IsGPUExtent3DDict()) {
const auto& dict = aDesc.mSize.GetAsGPUExtent3DDict(); const auto& dict = aDesc.mSize.GetAsGPUExtent3DDict();
desc.size.width = dict.mWidth; desc.mSize.width = dict.mWidth;
desc.size.height = dict.mHeight; desc.mSize.height = dict.mHeight;
desc.size.depth = dict.mDepth; desc.mSize.depth = dict.mDepth;
} else { } else {
MOZ_CRASH("Unexpected union"); MOZ_CRASH("Unexpected union");
} }
desc.mip_level_count = aDesc.mMipLevelCount; desc.mMipLevelCount = aDesc.mMipLevelCount;
desc.sample_count = aDesc.mSampleCount; desc.mSampleCount = aDesc.mSampleCount;
desc.dimension = ffi::WGPUTextureDimension(aDesc.mDimension); desc.mDimension = ffi::WGPUTextureDimension(aDesc.mDimension);
desc.format = ffi::WGPUTextureFormat(aDesc.mFormat); desc.mFormat = ffi::WGPUTextureFormat(aDesc.mFormat);
desc.usage = aDesc.mUsage; desc.mUsage = aDesc.mUsage;
RawId id = ffi::wgpu_client_make_texture_id(mClient, aSelfId); 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"); MOZ_CRASH("IPC failure");
} }
return id; return id;
@ -169,7 +165,7 @@ RawId WebGPUChild::TextureCreateView(
: aDefaultViewDesc.array_layer_count - aDesc.mBaseArrayLayer; : aDefaultViewDesc.array_layer_count - aDesc.mBaseArrayLayer;
RawId id = ffi::wgpu_client_make_texture_view_id(mClient, aSelfId); 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"); MOZ_CRASH("IPC failure");
} }
return id; return id;
@ -193,7 +189,7 @@ RawId WebGPUChild::DeviceCreateSampler(RawId aSelfId,
} }
RawId id = ffi::wgpu_client_make_sampler_id(mClient, 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"); MOZ_CRASH("IPC failure");
} }
return id; return id;
@ -240,7 +236,7 @@ RawId WebGPUChild::DeviceCreateBindGroupLayout(
: ffi::WGPUTextureFormat(0); : ffi::WGPUTextureFormat(0);
entries.AppendElement(e); entries.AppendElement(e);
} }
SerialBindGroupLayoutDescriptor desc = {nsCString(), std::move(entries)}; SerialBindGroupLayoutDescriptor desc = {std::move(entries)};
if (!SendDeviceCreateBindGroupLayout(aSelfId, desc, id)) { if (!SendDeviceCreateBindGroupLayout(aSelfId, desc, id)) {
MOZ_CRASH("IPC failure"); MOZ_CRASH("IPC failure");
} }

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

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

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

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

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

@ -13,27 +13,6 @@
namespace IPC { 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) \ #define DEFINE_IPC_SERIALIZER_ENUM_GUARD(something, guard) \
template <> \ template <> \
struct ParamTraits<something> \ 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::GPULimits, mMaxBindGroups);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUDeviceDescriptor, DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUDeviceDescriptor,
mExtensions, mLimits); mExtensions, mLimits);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBufferDescriptor, DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUBufferDescriptor, mSize,
label, size, usage); mUsage);
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::webgpu::ffi::WGPUSamplerDescriptor, 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, address_mode_w, mag_filter, min_filter,
mipmap_filter, lod_min_clamp, lod_max_clamp, mipmap_filter, lod_min_clamp, lod_max_clamp,
compare); compare);
@ -90,8 +67,8 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUExtent3d, width,
height, depth); height, depth);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUOrigin3d, x, y, z); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUOrigin3d, x, y, z);
DEFINE_IPC_SERIALIZER_WITH_FIELDS( DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::ffi::WGPUTextureViewDescriptor, label, format, dimension, mozilla::webgpu::ffi::WGPUTextureViewDescriptor, format, dimension, aspect,
aspect, base_mip_level, level_count, base_array_layer, array_layer_count); base_mip_level, level_count, base_array_layer, array_layer_count);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBlendDescriptor, DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBlendDescriptor,
src_factor, dst_factor, operation); src_factor, dst_factor, operation);
DEFINE_IPC_SERIALIZER_WITH_FIELDS( DEFINE_IPC_SERIALIZER_WITH_FIELDS(
@ -122,14 +99,14 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(
multisampled, has_dynamic_offset, view_dimension, texture_component_type, multisampled, has_dynamic_offset, view_dimension, texture_component_type,
storage_texture_format); storage_texture_format);
DEFINE_IPC_SERIALIZER_WITH_FIELDS( DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialBindGroupLayoutDescriptor, mLabel, mEntries); mozilla::webgpu::SerialBindGroupLayoutDescriptor, mEntries);
DEFINE_IPC_SERIALIZER_WITH_FIELDS( DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialPipelineLayoutDescriptor, mBindGroupLayouts); mozilla::webgpu::SerialPipelineLayoutDescriptor, mBindGroupLayouts);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupEntry, DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupEntry,
mBinding, mType, mValue, mBufferOffset, mBinding, mType, mValue, mBufferOffset,
mBufferSize); mBufferSize);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupDescriptor, DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupDescriptor,
mLabel, mLayout, mEntries); mLayout, mEntries);
DEFINE_IPC_SERIALIZER_WITH_FIELDS( DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mozilla::webgpu::SerialProgrammableStageDescriptor, mModule, mEntryPoint); mozilla::webgpu::SerialProgrammableStageDescriptor, mModule, mEntryPoint);
@ -145,6 +122,10 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(
mFragmentStage, mPrimitiveTopology, mRasterizationState, mColorStates, mFragmentStage, mPrimitiveTopology, mRasterizationState, mColorStates,
mDepthStencilState, mVertexState, mSampleCount, mSampleMask, mDepthStencilState, mVertexState, mSampleCount, mSampleMask,
mAlphaToCoverageEnabled); 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_FFI_ENUM
#undef DEFINE_IPC_SERIALIZER_DOM_ENUM #undef DEFINE_IPC_SERIALIZER_DOM_ENUM

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

@ -18,7 +18,6 @@ typedef uint64_t RawId;
typedef uint64_t BufferAddress; typedef uint64_t BufferAddress;
struct SerialBindGroupLayoutDescriptor { struct SerialBindGroupLayoutDescriptor {
nsCString mLabel;
nsTArray<ffi::WGPUBindGroupLayoutEntry> mEntries; nsTArray<ffi::WGPUBindGroupLayoutEntry> mEntries;
}; };
@ -42,7 +41,6 @@ struct SerialBindGroupEntry {
}; };
struct SerialBindGroupDescriptor { struct SerialBindGroupDescriptor {
nsCString mLabel;
RawId mLayout; RawId mLayout;
nsTArray<SerialBindGroupEntry> mEntries; nsTArray<SerialBindGroupEntry> mEntries;
}; };
@ -82,6 +80,17 @@ struct SerialRenderPipelineDescriptor {
bool mAlphaToCoverageEnabled; 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 webgpu
} // namespace mozilla } // namespace mozilla

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

@ -2,107 +2,64 @@ name: CI
on: on:
push: push:
branches-ignore: [staging.tmp] branches-ignore: [ staging.tmp ]
pull_request: pull_request:
branches-ignore: [staging.tmp] branches-ignore: [ staging.tmp ]
jobs: 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: build:
name: ${{ matrix.name }} name: ${{ matrix.name }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
name: name: [
[ iOS Stable,
MacOS Stable, MacOS Stable,
MacOS Nightly, MacOS Nightly,
Ubuntu Stable, Ubuntu Stable,
Ubuntu Nightly, Ubuntu Nightly,
Windows Stable, Windows Stable,
Windows Nightly, Windows Nightly,
] ]
include: 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 - os: macos-10.15
name: MacOS Stable name: MacOS Stable
channel: stable channel: stable
build_command: cargo clippy build_command: cargo clippy
additional_core_features: trace
additional_player_features: winit
- os: macos-10.15 - os: macos-10.15
name: MacOS Nightly name: MacOS Nightly
channel: nightly channel: nightly
build_command: cargo test build_command: cargo test
additional_core_features:
additional_player_features:
- os: ubuntu-18.04 - os: ubuntu-18.04
name: Ubuntu Stable name: Ubuntu Stable
channel: stable channel: stable
build_command: cargo clippy build_command: cargo clippy
additional_core_features: trace,replay
additional_player_features:
- os: ubuntu-18.04 - os: ubuntu-18.04
name: Ubuntu Nightly name: Ubuntu Nightly
channel: nightly channel: nightly
build_command: cargo test build_command: cargo test
additional_core_features:
additional_player_features: winit
- os: windows-2019 - os: windows-2019
name: Windows Stable name: Windows Stable
channel: stable channel: stable
build_command: rustup default stable-msvc; cargo clippy build_command: rustup default stable-msvc; cargo clippy
additional_core_features: trace
additional_player_features: renderdoc
- os: windows-2019 - os: windows-2019
name: Windows Nightly name: Windows Nightly
channel: nightly channel: nightly
build_command: rustup default nightly-msvc; cargo test build_command: rustup default nightly-msvc; cargo test
additional_core_features:
additional_player_features:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- if: matrix.channel == 'nightly' - if: matrix.channel == 'nightly'
name: Install latest nightly name: Install latest nightly
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: nightly toolchain: nightly
override: true override: true
- if: matrix.channel == 'stable' - if: contains(matrix.build_command, 'clippy')
run: rustup component add clippy run: rustup component add clippy
- name: cargo clippy/test - name: cargo clippy/test
run: ${{ matrix.build_command }} 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 }}

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

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

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

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

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

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

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

@ -17,7 +17,6 @@ The implementation consists of the following parts:
- `wgpu-core` - internal Rust API for WebGPU implementations to use - `wgpu-core` - internal Rust API for WebGPU implementations to use
- `wgpu-types` - Rust types shared between `wgpu-core`, `wgpu-native`, and `wgpu-rs` - `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. 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). 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 ## Supported Platforms
API | Windows 7/10 | Linux & Android | macOS & iOS | API | Windows | Linux | macOS & iOS |
----- | ------------------ | ------------------ | ------------------ | ----- | ------------------ | ------------------ | ------------------ |
DX11 | :white_check_mark: | | | DX11 | :white_check_mark: | | |
DX12 | :heavy_check_mark: | | | DX12 | :heavy_check_mark: | | |

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

@ -2,7 +2,6 @@ status = [
"iOS Stable", "iOS Stable",
"MacOS Stable", "MacOS Stable",
"MacOS Nightly", "MacOS Nightly",
"Android Stable",
"Ubuntu Stable", "Ubuntu Stable",
"Ubuntu Nightly", "Ubuntu Nightly",
"Windows Stable", "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] [features]
default = [] default = []
trace = ["ron", "serde", "wgt/trace"]
replay = ["serde", "wgt/replay"]
metal-auto-capture = ["gfx-backend-metal/auto-capture"] metal-auto-capture = ["gfx-backend-metal/auto-capture"]
serde = ["wgt/serde", "serde_crate"]
#NOTE: glutin feature is not stable, use at your own risk #NOTE: glutin feature is not stable, use at your own risk
#glutin = ["gfx-backend-gl/glutin"] #glutin = ["gfx-backend-gl/glutin"]
@ -34,12 +33,15 @@ gfx-descriptor = "0.1"
gfx-memory = "0.1" gfx-memory = "0.1"
parking_lot = "0.10" parking_lot = "0.10"
peek-poke = "0.2" 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" smallvec = "1"
vec_map = "0.8.1" vec_map = "0.8.1"
[dependencies.serde_crate]
package = "serde"
version = "1.0"
features = ["serde_derive"]
optional = true
[dependencies.wgt] [dependencies.wgt]
path = "../wgpu-types" path = "../wgpu-types"
package = "wgpu-types" package = "wgpu-types"

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

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

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

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

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

@ -26,14 +26,11 @@ enum PipelineState {
} }
#[derive(Clone, Copy, Debug, PeekPoke)] #[derive(Clone, Copy, Debug, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))] enum ComputeCommand {
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum ComputeCommand {
SetBindGroup { SetBindGroup {
index: u8, index: u8,
num_dynamic_offsets: u8, num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId, bind_group_id: id::BindGroupId,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>, phantom_offsets: PhantomSlice<DynamicOffset>,
}, },
SetPipeline(id::ComputePipelineId), 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 (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token);
let cmb = &mut cmb_guard[encoder_id]; let cmb = &mut cmb_guard[encoder_id];
let raw = cmb.raw.last_mut().unwrap(); 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 (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let (bind_group_guard, mut token) = hub.bind_groups.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, 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, id,
resource::{Buffer, Texture}, resource::{Buffer, Texture},
track::TrackerSet, track::TrackerSet,
LifeGuard, PrivateFeatures, Stored, Features, LifeGuard, Stored,
}; };
use peek_poke::PeekPoke; use peek_poke::PeekPoke;
@ -27,7 +27,7 @@ use peek_poke::PeekPoke;
use std::{marker::PhantomData, mem, ptr, slice, thread::ThreadId}; use std::{marker::PhantomData, mem, ptr, slice, thread::ThreadId};
#[derive(Clone, Copy, Debug, PeekPoke)] #[derive(Clone, Copy, Debug, PeekPoke)]
pub struct PhantomSlice<T>(PhantomData<T>); struct PhantomSlice<T>(PhantomData<T>);
impl<T> Default for PhantomSlice<T> { impl<T> Default for PhantomSlice<T> {
fn default() -> Self { fn default() -> Self {
@ -119,13 +119,13 @@ impl RawPass {
} }
#[inline] #[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.ensure_extra_size(C::max_size());
self.data = command.poke_into(self.data); self.data = command.poke_into(self.data);
} }
#[inline] #[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 align_offset = self.data.align_offset(mem::align_of::<T>());
let extra = align_offset + mem::size_of::<T>() * data.len(); let extra = align_offset + mem::size_of::<T>() * data.len();
self.ensure_extra_size(extra); self.ensure_extra_size(extra);
@ -148,10 +148,7 @@ pub struct CommandBuffer<B: hal::Backend> {
pub(crate) life_guard: LifeGuard, pub(crate) life_guard: LifeGuard,
pub(crate) trackers: TrackerSet, pub(crate) trackers: TrackerSet,
pub(crate) used_swap_chain: Option<(Stored<id::SwapChainId>, B::Framebuffer)>, pub(crate) used_swap_chain: Option<(Stored<id::SwapChainId>, B::Framebuffer)>,
limits: wgt::Limits, pub(crate) features: Features,
private_features: PrivateFeatures,
#[cfg(feature = "trace")]
pub(crate) commands: Option<Vec<crate::device::trace::Command>>,
} }
impl<B: GfxBackend> CommandBuffer<B> { impl<B: GfxBackend> CommandBuffer<B> {

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

@ -46,8 +46,6 @@ pub struct RenderPassDescriptor<'a> {
} }
#[derive(Clone, Copy, Debug, Default, PeekPoke)] #[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 struct Rect<T> {
pub x: T, pub x: T,
pub y: T, pub y: T,
@ -56,14 +54,11 @@ pub struct Rect<T> {
} }
#[derive(Clone, Copy, Debug, PeekPoke)] #[derive(Clone, Copy, Debug, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))] enum RenderCommand {
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub enum RenderCommand {
SetBindGroup { SetBindGroup {
index: u8, index: u8,
num_dynamic_offsets: u8, num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId, bind_group_id: id::BindGroupId,
#[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>, phantom_offsets: PhantomSlice<DynamicOffset>,
}, },
SetPipeline(id::RenderPipelineId), SetPipeline(id::RenderPipelineId),
@ -339,8 +334,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
raw_data.len() raw_data.len()
); );
peeker = unsafe { RawRenderTargets::peek_from(peeker, &mut targets) }; peeker = unsafe { RawRenderTargets::peek_from(peeker, &mut targets) };
#[cfg(feature = "trace")]
let command_peeker_base = peeker;
let color_attachments = targets let color_attachments = targets
.colors .colors
@ -443,10 +436,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
Some(hal::pass::Attachment { Some(hal::pass::Attachment {
format: Some(conv::map_texture_format( format: Some(conv::map_texture_format(view.format, device.features)),
view.format,
device.private_features,
)),
samples: view.samples, samples: view.samples,
ops: conv::map_load_store_ops(at.depth_load_op, at.depth_store_op), ops: conv::map_load_store_ops(at.depth_load_op, at.depth_store_op),
stencil_ops: conv::map_load_store_ops( stencil_ops: conv::map_load_store_ops(
@ -513,10 +503,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
colors.push(hal::pass::Attachment { colors.push(hal::pass::Attachment {
format: Some(conv::map_texture_format( format: Some(conv::map_texture_format(view.format, device.features)),
view.format,
device.private_features,
)),
samples: view.samples, samples: view.samples,
ops: conv::map_load_store_ops(at.load_op, at.store_op), ops: conv::map_load_store_ops(at.load_op, at.store_op),
stencil_ops: hal::pass::AttachmentOps::DONT_CARE, stencil_ops: hal::pass::AttachmentOps::DONT_CARE,
@ -569,10 +556,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
resolves.push(hal::pass::Attachment { resolves.push(hal::pass::Attachment {
format: Some(conv::map_texture_format( format: Some(conv::map_texture_format(view.format, device.features)),
view.format,
device.private_features,
)),
samples: view.samples, samples: view.samples,
ops: hal::pass::AttachmentOps::new( ops: hal::pass::AttachmentOps::new(
hal::pass::AttachmentLoadOp::DontCare, hal::pass::AttachmentLoadOp::DontCare,
@ -826,7 +810,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
let mut state = State { let mut state = State {
binder: Binder::new(cmb.limits.max_bind_groups), binder: Binder::new(cmb.features.max_bind_groups),
blend_color: OptionalState::Unused, blend_color: OptionalState::Unused,
stencil_reference: OptionalState::Unused, stencil_reference: OptionalState::Unused,
pipeline: OptionalState::Required, 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); log::trace!("Merging {:?} with the render pass", encoder_id);
unsafe { unsafe {
raw.end_render_pass(); raw.end_render_pass();

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

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[cfg(feature = "trace")]
use crate::device::trace::Command as TraceCommand;
use crate::{ use crate::{
conv, conv,
device::{all_buffer_stages, all_image_stages}, device::{all_buffer_stages, all_image_stages},
@ -20,9 +18,7 @@ use std::iter;
const BITS_PER_BYTE: u32 = 8; const BITS_PER_BYTE: u32 = 8;
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug)] #[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct BufferCopyView { pub struct BufferCopyView {
pub buffer: BufferId, pub buffer: BufferId,
pub offset: BufferAddress, pub offset: BufferAddress,
@ -31,9 +27,7 @@ pub struct BufferCopyView {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug)] #[derive(Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct TextureCopyView { pub struct TextureCopyView {
pub texture: TextureId, pub texture: TextureId,
pub mip_level: u32, pub mip_level: u32,
@ -96,18 +90,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// borrow the buffer tracker mutably... // borrow the buffer tracker mutably...
let mut barriers = Vec::new(); 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) = let (src_buffer, src_pending) =
cmb.trackers cmb.trackers
.buffers .buffers
@ -161,16 +143,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[destination.texture].full_range.aspects; 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( let (src_buffer, src_pending) = cmb.trackers.buffers.use_replace(
&*buffer_guard, &*buffer_guard,
source.buffer, source.buffer,
@ -189,7 +161,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
assert!(dst_texture.usage.contains(TextureUsage::COPY_DST)); assert!(dst_texture.usage.contains(TextureUsage::COPY_DST));
let dst_barriers = dst_pending.map(|pending| pending.into_hal(dst_texture)); 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() .surface_desc()
.bits as u32 .bits as u32
/ BITS_PER_BYTE; / BITS_PER_BYTE;
@ -241,16 +213,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[source.texture].full_range.aspects; 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( let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard, &*texture_guard,
source.texture, source.texture,
@ -277,7 +239,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
); );
let dst_barrier = dst_barriers.map(|pending| pending.into_hal(dst_buffer)); 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() .surface_desc()
.bits as u32 .bits as u32
/ BITS_PER_BYTE; / BITS_PER_BYTE;
@ -334,16 +296,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let aspects = texture_guard[source.texture].full_range.aspects let aspects = texture_guard[source.texture].full_range.aspects
& texture_guard[destination.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( let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard, &*texture_guard,
source.texture, source.texture,

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

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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) { pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) {
use hal::buffer::Usage as U; 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( pub(crate) fn map_texture_format(
texture_format: wgt::TextureFormat, texture_format: wgt::TextureFormat,
private_features: PrivateFeatures, features: Features,
) -> hal::format::Format { ) -> hal::format::Format {
use hal::format::Format as H; use hal::format::Format as H;
use wgt::TextureFormat as Tf; use wgt::TextureFormat as Tf;
@ -376,14 +376,14 @@ pub(crate) fn map_texture_format(
// Depth and stencil formats // Depth and stencil formats
Tf::Depth32Float => H::D32Sfloat, Tf::Depth32Float => H::D32Sfloat,
Tf::Depth24Plus => { Tf::Depth24Plus => {
if private_features.supports_texture_d24_s8 { if features.supports_texture_d24_s8 {
H::D24UnormS8Uint H::D24UnormS8Uint
} else { } else {
H::D32Sfloat H::D32Sfloat
} }
} }
Tf::Depth24PlusStencil8 => { Tf::Depth24PlusStencil8 => {
if private_features.supports_texture_d24_s8 { if features.supports_texture_d24_s8 {
H::D24UnormS8Uint H::D24UnormS8Uint
} else { } else {
H::D32SfloatS8Uint H::D32SfloatS8Uint

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

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

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

@ -7,7 +7,7 @@ use crate::{
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token}, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Input, Token},
id, pipeline, resource, swap_chain, id, pipeline, resource, swap_chain,
track::{BufferState, TextureState, TrackerSet}, track::{BufferState, TextureState, TrackerSet},
FastHashMap, LifeGuard, PrivateFeatures, Stored, FastHashMap, Features, LifeGuard, Stored,
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
@ -31,22 +31,6 @@ use std::{
}; };
mod life; 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_COLOR_TARGETS: usize = 4;
pub const MAX_MIP_LEVELS: usize = 16; pub const MAX_MIP_LEVELS: usize = 16;
@ -125,38 +109,50 @@ fn map_buffer<B: hal::Backend>(
sub_range: hal::buffer::SubRange, sub_range: hal::buffer::SubRange,
kind: HostMap, kind: HostMap,
) -> BufferMapResult { ) -> BufferMapResult {
let (ptr, segment, needs_sync) = { let (ptr, sync_range) = {
let segment = hal::memory::Segment { let segment = hal::memory::Segment {
offset: sub_range.offset, offset: sub_range.offset,
size: sub_range.size, size: sub_range.size,
}; };
let mapped = buffer.memory.map(raw, segment)?; let mapped = buffer.memory.map(raw, segment)?;
let mr = mapped.range(); let sync_range = if mapped.is_coherent() {
let segment = hal::memory::Segment { None
offset: mr.start, } else {
size: Some(mr.end - mr.start), Some(mapped.range())
}; };
(mapped.ptr(), segment, !mapped.is_coherent()) (mapped.ptr(), sync_range)
}; };
buffer.sync_mapped_writes = match kind { if let Some(range) = sync_range {
HostMap::Read if needs_sync => unsafe { let segment = hal::memory::Segment {
raw.invalidate_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment))) offset: range.start,
.unwrap(); size: Some(range.end - range.start),
None };
}, match kind {
HostMap::Write if needs_sync => Some(segment), HostMap::Read => unsafe {
_ => None, raw.invalidate_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment)))
}; .unwrap();
},
HostMap::Write => {
buffer.mapped_write_segments.push(segment);
}
}
}
Ok(ptr.as_ptr()) Ok(ptr.as_ptr())
} }
fn unmap_buffer<B: hal::Backend>(raw: &B::Device, buffer: &mut resource::Buffer<B>) { 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 { unsafe {
raw.flush_mapped_memory_ranges(iter::once((buffer.memory.memory(), segment))) raw.flush_mapped_memory_ranges(
.unwrap() 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 should be locked right after the device and before anything else.
life_tracker: Mutex<life::LifetimeTracker<B>>, life_tracker: Mutex<life::LifetimeTracker<B>>,
temp_suspected: life::SuspectedResources, temp_suspected: life::SuspectedResources,
pub(crate) private_features: PrivateFeatures, pub(crate) features: Features,
limits: wgt::Limits,
extensions: wgt::Extensions,
#[cfg(feature = "trace")]
pub(crate) trace: Option<Mutex<Trace>>,
} }
impl<B: GfxBackend> Device<B> { impl<B: GfxBackend> Device<B> {
@ -212,8 +204,7 @@ impl<B: GfxBackend> Device<B> {
mem_props: hal::adapter::MemoryProperties, mem_props: hal::adapter::MemoryProperties,
non_coherent_atom_size: u64, non_coherent_atom_size: u64,
supports_texture_d24_s8: bool, supports_texture_d24_s8: bool,
desc: &wgt::DeviceDescriptor, max_bind_groups: u32,
trace_path: Option<&std::path::Path>,
) -> Self { ) -> Self {
// don't start submission index at zero // don't start submission index at zero
let life_guard = LifeGuard::new(); let life_guard = LifeGuard::new();
@ -233,11 +224,6 @@ impl<B: GfxBackend> Device<B> {
non_coherent_atom_size, non_coherent_atom_size,
) )
}; };
#[cfg(not(feature = "trace"))]
match trace_path {
Some(_) => log::warn!("Tracing feature is not enabled"),
None => (),
}
Device { Device {
raw, raw,
@ -252,25 +238,10 @@ impl<B: GfxBackend> Device<B> {
framebuffers: Mutex::new(FastHashMap::default()), framebuffers: Mutex::new(FastHashMap::default()),
life_tracker: Mutex::new(life::LifetimeTracker::new()), life_tracker: Mutex::new(life::LifetimeTracker::new()),
temp_suspected: life::SuspectedResources::default(), temp_suspected: life::SuspectedResources::default(),
#[cfg(feature = "trace")] features: Features {
trace: trace_path.and_then(|path| match Trace::new(path) { max_bind_groups,
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 {
supports_texture_d24_s8, supports_texture_d24_s8,
}, },
limits: desc.limits.clone(),
extensions: desc.extensions.clone(),
} }
} }
@ -289,13 +260,7 @@ impl<B: GfxBackend> Device<B> {
) -> Vec<BufferMapPendingCallback> { ) -> Vec<BufferMapPendingCallback> {
let mut life_tracker = self.lock_life(token); let mut life_tracker = self.lock_life(token);
life_tracker.triage_suspected( life_tracker.triage_suspected(global, &self.trackers, token);
global,
&self.trackers,
#[cfg(feature = "trace")]
self.trace.as_ref(),
token,
);
life_tracker.triage_mapped(global, token); life_tracker.triage_mapped(global, token);
life_tracker.triage_framebuffers(global, &mut *self.framebuffers.lock(), token); life_tracker.triage_framebuffers(global, &mut *self.framebuffers.lock(), token);
let _last_done = life_tracker.triage_submissions(&self.raw, force_wait); let _last_done = life_tracker.triage_submissions(&self.raw, force_wait);
@ -307,7 +272,7 @@ impl<B: GfxBackend> Device<B> {
fn create_buffer( fn create_buffer(
&self, &self,
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>, desc: &wgt::BufferDescriptor,
) -> resource::Buffer<B> { ) -> resource::Buffer<B> {
use gfx_memory::{Kind, MemoryUsage}; use gfx_memory::{Kind, MemoryUsage};
@ -370,7 +335,7 @@ impl<B: GfxBackend> Device<B> {
memory, memory,
size: desc.size, size: desc.size,
full_range: (), full_range: (),
sync_mapped_writes: None, mapped_write_segments: Vec::new(),
map_state: resource::BufferMapState::Idle, map_state: resource::BufferMapState::Idle,
life_guard: LifeGuard::new(), life_guard: LifeGuard::new(),
} }
@ -379,7 +344,7 @@ impl<B: GfxBackend> Device<B> {
fn create_texture( fn create_texture(
&self, &self,
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::TextureDescriptor<Label>, desc: &wgt::TextureDescriptor,
) -> resource::Texture<B> { ) -> resource::Texture<B> {
debug_assert_eq!(self_id.backend(), B::VARIANT); 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 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 aspects = format.surface_desc().aspects;
let usage = conv::map_texture_usage(desc.usage, 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>( pub fn device_create_buffer<B: GfxBackend>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>, desc: &wgt::BufferDescriptor,
id_in: Input<G, id::BufferId>, id_in: Input<G, id::BufferId>,
) -> id::BufferId { ) -> id::BufferId {
let hub = B::hub(self); 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); let id = hub.buffers.register_identity(id_in, buffer, &mut token);
log::info!("Created buffer {:?} with {:?}", id, desc); 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 device
.trackers .trackers
.lock() .lock()
@ -565,7 +521,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_buffer_mapped<B: GfxBackend>( pub fn device_create_buffer_mapped<B: GfxBackend>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>, desc: &wgt::BufferDescriptor,
id_in: Input<G, id::BufferId>, id_in: Input<G, id::BufferId>,
) -> (id::BufferId, *mut u8) { ) -> (id::BufferId, *mut u8) {
let hub = B::hub(self); let hub = B::hub(self);
@ -585,11 +541,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
HostMap::Write, HostMap::Write,
) { ) {
Ok(ptr) => { Ok(ptr) => {
buffer.map_state = resource::BufferMapState::Active { buffer.map_state = resource::BufferMapState::Active;
ptr,
sub_range: hal::buffer::SubRange::WHOLE,
host: HostMap::Write,
};
ptr ptr
} }
Err(e) => { Err(e) => {
@ -600,15 +552,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let id = hub.buffers.register_identity(id_in, buffer, &mut token); let id = hub.buffers.register_identity(id_in, buffer, &mut token);
log::info!("Created mapped buffer {:?} with {:?}", id, desc); 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 device
.trackers .trackers
.lock() .lock()
@ -623,35 +566,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
(id, pointer) (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>( pub fn device_set_buffer_sub_data<B: GfxBackend>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
@ -673,20 +587,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
); );
//assert!(buffer isn't used by the GPU); //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( match map_buffer(
&device.raw, &device.raw,
&mut buffer, &mut buffer,
@ -773,7 +673,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_texture<B: GfxBackend>( pub fn device_create_texture<B: GfxBackend>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
desc: &wgt::TextureDescriptor<Label>, desc: &wgt::TextureDescriptor,
id_in: Input<G, id::TextureId>, id_in: Input<G, id::TextureId>,
) -> id::TextureId { ) -> id::TextureId {
let hub = B::hub(self); let hub = B::hub(self);
@ -786,15 +686,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = texture.life_guard.add_ref(); let ref_count = texture.life_guard.add_ref();
let id = hub.textures.register_identity(id_in, texture, &mut token); 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 device
.trackers .trackers
.lock() .lock()
@ -826,7 +717,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn texture_create_view<B: GfxBackend>( pub fn texture_create_view<B: GfxBackend>(
&self, &self,
texture_id: id::TextureId, texture_id: id::TextureId,
desc: Option<&wgt::TextureViewDescriptor<Label>>, desc: Option<&wgt::TextureViewDescriptor>,
id_in: Input<G, id::TextureViewId>, id_in: Input<G, id::TextureViewId>,
) -> id::TextureViewId { ) -> id::TextureViewId {
let hub = B::hub(self); let hub = B::hub(self);
@ -875,7 +766,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.create_image_view( .create_image_view(
&texture.raw, &texture.raw,
view_kind, view_kind,
conv::map_texture_format(format, device.private_features), conv::map_texture_format(format, device.features),
hal::format::Swizzle::NO, hal::format::Swizzle::NO,
range.clone(), range.clone(),
) )
@ -899,16 +790,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = view.life_guard.add_ref(); let ref_count = view.life_guard.add_ref();
let id = hub.texture_views.register_identity(id_in, view, &mut token); 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 device
.trackers .trackers
.lock() .lock()
@ -949,7 +830,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn device_create_sampler<B: GfxBackend>( pub fn device_create_sampler<B: GfxBackend>(
&self, &self,
device_id: id::DeviceId, device_id: id::DeviceId,
desc: &wgt::SamplerDescriptor<Label>, desc: &wgt::SamplerDescriptor,
id_in: Input<G, id::SamplerId>, id_in: Input<G, id::SamplerId>,
) -> id::SamplerId { ) -> id::SamplerId {
let hub = B::hub(self); let hub = B::hub(self);
@ -985,15 +866,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = sampler.life_guard.add_ref(); let ref_count = sampler.life_guard.add_ref();
let id = hub.samplers.register_identity(id_in, sampler, &mut token); 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 device
.trackers .trackers
.lock() .lock()
@ -1087,19 +959,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(), dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(),
}; };
let id = hub hub.bind_group_layouts
.bind_group_layouts .register_identity(id_in, layout, &mut token)
.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
} }
pub fn bind_group_layout_destroy<B: GfxBackend>( 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_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id]; 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
.lock_life(&mut token) .lock_life(&mut token)
.suspected_resources .suspected_resources
.bind_group_layouts .bind_group_layouts
@ -1152,10 +1005,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
assert!( 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 ({})", "Cannot set more bind groups ({}) than the `max_bind_groups` limit requested on device creation ({})",
desc.bind_group_layouts_length, desc.bind_group_layouts_length,
device.limits.max_bind_groups device.features.max_bind_groups
); );
// TODO: push constants // TODO: push constants
@ -1190,19 +1043,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.collect() .collect()
}, },
}; };
hub.pipeline_layouts
let id = hub .register_identity(id_in, layout, &mut token)
.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
} }
pub fn pipeline_layout_destroy<B: GfxBackend>(&self, pipeline_layout_id: id::PipelineLayoutId) { pub fn pipeline_layout_destroy<B: GfxBackend>(&self, pipeline_layout_id: id::PipelineLayoutId) {
@ -1444,36 +1286,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
id, id,
hub.bind_groups.read(&mut token).0[id].used 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 device
.trackers .trackers
@ -1524,21 +1336,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}, },
}; };
let id = hub hub.shader_modules
.shader_modules .register_identity(id_in, shader, &mut token)
.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
} }
pub fn shader_module_destroy<B: GfxBackend>(&self, shader_module_id: id::ShaderModuleId) { 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 mut token = Token::root();
let (device_guard, mut token) = hub.devices.read(&mut token); let (device_guard, mut token) = hub.devices.read(&mut token);
let (module, _) = hub.shader_modules.unregister(shader_module_id, &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 { 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( let mut command_buffer = device.com_allocator.allocate(
dev_stored, dev_stored,
&device.raw, &device.raw,
device.limits.clone(), device.features,
device.private_features,
lowest_active_index, lowest_active_index,
#[cfg(feature = "trace")]
device.trace.is_some(),
); );
unsafe { unsafe {
let raw_command_buffer = command_buffer.raw.last_mut().unwrap(); 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 // finish all the command buffers first
for &cmb_id in command_buffer_ids { for &cmb_id in command_buffer_ids {
let comb = &mut command_buffer_guard[cmb_id]; 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() { if let Some((sc_id, fbo)) = comb.used_swap_chain.take() {
let sc = &mut swap_chain_guard[sc_id.value]; let sc = &mut swap_chain_guard[sc_id.value];
@ -1741,8 +1523,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
panic!("Buffer has a pending mapping."); panic!("Buffer has a pending mapping.");
} }
if !buffer_guard[id].life_guard.use_at(submit_index) { 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."); log::warn!("Dropped buffer has a pending mapping.");
unmap_buffer(&device.raw, &mut buffer_guard[id]); 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) }; unsafe { slice::from_raw_parts(desc.color_states, desc.color_states_length) };
let depth_stencil_state = unsafe { desc.depth_stencil_state.as_ref() }; 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( 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 { let desc_vbs = unsafe {
@ -1966,7 +1748,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
colors: color_states colors: color_states
.iter() .iter()
.map(|at| hal::pass::Attachment { .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, samples: sc,
ops: hal::pass::AttachmentOps::PRESERVE, ops: hal::pass::AttachmentOps::PRESERVE,
stencil_ops: hal::pass::AttachmentOps::DONT_CARE, 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. // or depth/stencil resolve modes but satisfy the other compatibility conditions.
resolves: ArrayVec::new(), resolves: ArrayVec::new(),
depth_stencil: depth_stencil_state.map(|at| hal::pass::Attachment { 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, samples: sc,
ops: hal::pass::AttachmentOps::PRESERVE, ops: hal::pass::AttachmentOps::PRESERVE,
stencil_ops: hal::pass::AttachmentOps::PRESERVE, stencil_ops: hal::pass::AttachmentOps::PRESERVE,
@ -2119,47 +1901,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
life_guard: LifeGuard::new(), life_guard: LifeGuard::new(),
}; };
let id = hub hub.render_pipelines
.render_pipelines .register_identity(id_in, pipeline, &mut token)
.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
} }
pub fn render_pipeline_destroy<B: GfxBackend>(&self, render_pipeline_id: id::RenderPipelineId) { 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(), life_guard: LifeGuard::new(),
}; };
let id = hub hub.compute_pipelines
.compute_pipelines .register_identity(id_in, pipeline, &mut token)
.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
} }
pub fn compute_pipeline_destroy<B: GfxBackend>( pub fn compute_pipeline_destroy<B: GfxBackend>(
@ -2350,7 +2079,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.max(*caps.image_count.start()) .max(*caps.image_count.start())
.min(*caps.image_count.end()); .min(*caps.image_count.end());
let mut config = 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 { if let Some(formats) = formats {
assert!( assert!(
formats.contains(&config.format), formats.contains(&config.format),
@ -2373,15 +2102,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
device.raw.destroy_semaphore(sc.semaphore); 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 { let swap_chain = swap_chain::SwapChain {
life_guard: LifeGuard::new(), life_guard: LifeGuard::new(),
device_id: Stored { device_id: Stored {
@ -2398,23 +2118,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
sc_id 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) { pub fn device_poll<B: GfxBackend>(&self, device_id: id::DeviceId, force_wait: bool) {
let hub = B::hub(self); let hub = B::hub(self);
let mut token = Token::root(); let mut token = Token::root();
@ -2505,7 +2208,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub_usage pub_usage
); );
buffer.map_state = match buffer.map_state { buffer.map_state = match buffer.map_state {
resource::BufferMapState::Active { .. } => panic!("Buffer already mapped"), resource::BufferMapState::Active => panic!("Buffer already mapped"),
resource::BufferMapState::Waiting(_) => { resource::BufferMapState::Waiting(_) => {
operation.call_error(); operation.call_error();
return; return;
@ -2550,35 +2253,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
resource::BufferMapState::Idle => { resource::BufferMapState::Idle => {
log::error!("Buffer already unmapped"); log::error!("Buffer already unmapped");
} }
resource::BufferMapState::Waiting(_) => {} _ => {
resource::BufferMapState::Active { buffer.map_state = resource::BufferMapState::Idle;
ptr, unmap_buffer(&device_guard[buffer.device_id.value].raw, buffer);
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;
} }
} }

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

@ -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)] #[cfg(debug_assertions)]
use std::cell::Cell; 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. /// A simple structure to manage identities of objects.
#[derive(Debug)] #[derive(Debug)]
@ -44,13 +44,6 @@ impl Default for IdentityManager {
} }
impl 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 { pub fn alloc<I: TypedId>(&mut self, backend: Backend) -> I {
match self.free.pop() { match self.free.pop() {
Some(index) => I::zip(index, self.epochs[index as usize], backend), 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 { impl<I: TypedId + Debug> IdentityHandlerFactory<I> for IdentityManagerFactory {
type Filter = Mutex<IdentityManager>; type Filter = Mutex<IdentityManager>;
fn spawn(&self, min_index: Index) -> Self::Filter { 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::{Epoch, Index}; use crate::{Epoch, Index};
#[cfg(feature = "serde")]
use serde_crate::{Deserialize, Serialize};
use std::{fmt, marker::PhantomData, mem, num::NonZeroU64}; use std::{fmt, marker::PhantomData, mem, num::NonZeroU64};
use wgt::Backend; use wgt::Backend;
@ -11,38 +13,13 @@ const EPOCH_MASK: u32 = (1 << (32 - BACKEND_BITS)) - 1;
type Dummy = crate::backend::Empty; type Dummy = crate::backend::Empty;
#[repr(transparent)] #[repr(transparent)]
#[cfg_attr(feature = "trace", derive(serde::Serialize), serde(into = "SerialId"))]
#[cfg_attr( #[cfg_attr(
feature = "replay", feature = "serde",
derive(serde::Deserialize), derive(Serialize, Deserialize),
serde(from = "SerialId") serde(crate = "serde_crate")
)] )]
pub struct Id<T>(NonZeroU64, PhantomData<T>); 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 // required for PeekPoke
impl<T> Default for Id<T> { impl<T> Default for Id<T> {
fn default() -> Self { fn default() -> Self {
@ -179,7 +156,7 @@ impl SurfaceId {
} }
} }
impl SwapChainId { impl SwapChainId {
pub fn to_surface_id(self) -> SurfaceId { pub(crate) fn to_surface_id(self) -> SurfaceId {
let (index, epoch, _) = self.unzip(); let (index, epoch, _) = self.unzip();
Id::zip(index, epoch, Backend::Empty) Id::zip(index, epoch, Backend::Empty)
} }

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

@ -12,10 +12,8 @@ use crate::{
use wgt::{Backend, BackendBit, DeviceDescriptor, PowerPreference, BIND_BUFFER_ALIGNMENT}; use wgt::{Backend, BackendBit, DeviceDescriptor, PowerPreference, BIND_BUFFER_ALIGNMENT};
#[cfg(feature = "replay")] #[cfg(feature = "serde")]
use serde::Deserialize; use serde_crate::{Deserialize, Serialize};
#[cfg(feature = "trace")]
use serde::Serialize;
use hal::{ use hal::{
self, self,
@ -27,8 +25,11 @@ use hal::{
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(
#[cfg_attr(feature = "replay", derive(Deserialize))] feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct RequestAdapterOptions { pub struct RequestAdapterOptions {
pub power_preference: PowerPreference, pub power_preference: PowerPreference,
pub compatible_surface: Option<SurfaceId>, pub compatible_surface: Option<SurfaceId>,
@ -133,8 +134,11 @@ impl<B: hal::Backend> Adapter<B> {
/// Metadata about a backend adapter. /// Metadata about a backend adapter.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(
#[cfg_attr(feature = "replay", derive(Deserialize))] feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub struct AdapterInfo { pub struct AdapterInfo {
/// Adapter name /// Adapter name
pub name: String, pub name: String,
@ -169,8 +173,11 @@ impl AdapterInfo {
/// Supported physical device types /// Supported physical device types
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(
#[cfg_attr(feature = "replay", derive(Deserialize))] feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate")
)]
pub enum DeviceType { pub enum DeviceType {
/// Other /// Other
Other, Other,
@ -198,7 +205,7 @@ impl From<HalDeviceType> for DeviceType {
pub enum AdapterInputs<'a, I> { pub enum AdapterInputs<'a, I> {
IdSet(&'a [I], fn(&I) -> Backend), IdSet(&'a [I], fn(&I) -> Backend),
Mask(BackendBit, fn(Backend) -> I), Mask(BackendBit, fn() -> I),
} }
impl<I: Clone> AdapterInputs<'_, 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::IdSet(ids, ref fun) => ids.iter().find(|id| fun(id) == b).cloned(),
AdapterInputs::Mask(bits, ref fun) => { AdapterInputs::Mask(bits, ref fun) => {
if bits.contains(b.into()) { if bits.contains(b.into()) {
Some(fun(b)) Some(fun())
} else { } else {
None None
} }
@ -217,84 +224,6 @@ impl<I: Clone> AdapterInputs<'_, I> {
} }
impl<G: GlobalIdentityHandlerFactory> Global<G> { 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> { pub fn enumerate_adapters(&self, inputs: AdapterInputs<Input<G, AdapterId>>) -> Vec<AdapterId> {
let instance = &self.instance; let instance = &self.instance;
let mut token = Token::root(); let mut token = Token::root();
@ -594,7 +523,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&self, &self,
adapter_id: AdapterId, adapter_id: AdapterId,
desc: &DeviceDescriptor, desc: &DeviceDescriptor,
trace_path: Option<&std::path::Path>,
id_in: Input<G, DeviceId>, id_in: Input<G, DeviceId>,
) -> DeviceId { ) -> DeviceId {
let hub = B::hub(self); let hub = B::hub(self);
@ -658,8 +586,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
mem_props, mem_props,
limits.non_coherent_atom_size as u64, limits.non_coherent_atom_size as u64,
supports_texture_d24_s8, supports_texture_d24_s8,
desc, desc.limits.max_bind_groups,
trace_path,
) )
}; };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -9,7 +9,6 @@ use wgc::{gfx_select, id};
use std::slice; use std::slice;
pub type Global = wgc::hub::Global<IdentityRecyclerFactory>; pub type Global = wgc::hub::Global<IdentityRecyclerFactory>;
pub type RawString = *const std::os::raw::c_char;
#[no_mangle] #[no_mangle]
pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Global { 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] #[no_mangle]
pub unsafe extern "C" fn wgpu_server_adapter_request_device( pub extern "C" fn wgpu_server_adapter_request_device(
global: &Global, global: &Global,
self_id: id::AdapterId, self_id: id::AdapterId,
desc: &wgt::DeviceDescriptor, desc: &wgt::DeviceDescriptor,
new_id: id::DeviceId, new_id: id::DeviceId,
) { ) {
let trace_string = std::env::var("WGPU_TRACE").ok(); gfx_select!(self_id => global.adapter_request_device(self_id, desc, new_id));
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));
} }
#[no_mangle] #[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( pub extern "C" fn wgpu_server_device_create_buffer(
global: &Global, global: &Global,
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::BufferDescriptor<RawString>, desc: &wgt::BufferDescriptor,
new_id: id::BufferId, new_id: id::BufferId,
) { ) {
gfx_select!(self_id => global.device_create_buffer(self_id, desc, new_id)); 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( pub extern "C" fn wgpu_server_device_create_texture(
global: &Global, global: &Global,
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::TextureDescriptor<RawString>, desc: &wgt::TextureDescriptor,
new_id: id::TextureId, new_id: id::TextureId,
) { ) {
gfx_select!(self_id => global.device_create_texture(self_id, desc, new_id)); 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( pub extern "C" fn wgpu_server_texture_create_view(
global: &Global, global: &Global,
self_id: id::TextureId, self_id: id::TextureId,
desc: Option<&wgt::TextureViewDescriptor<RawString>>, desc: Option<&wgt::TextureViewDescriptor>,
new_id: id::TextureViewId, new_id: id::TextureViewId,
) { ) {
gfx_select!(self_id => global.texture_create_view(self_id, desc, new_id)); 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( pub extern "C" fn wgpu_server_device_create_sampler(
global: &Global, global: &Global,
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::SamplerDescriptor<RawString>, desc: &wgt::SamplerDescriptor,
new_id: id::SamplerId, new_id: id::SamplerId,
) { ) {
gfx_select!(self_id => global.device_create_sampler(self_id, desc, new_id)); gfx_select!(self_id => global.device_create_sampler(self_id, desc, new_id));

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

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

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

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

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

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