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