From 53a10a49a5c70e1af967685a6aa957e714d46a4a Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 3 Mar 2020 15:08:24 +0000 Subject: [PATCH] Bug 1614703 - WebGPU render pipeline creation r=jgilbert,webidl,baku Differential Revision: https://phabricator.services.mozilla.com/D64833 --HG-- extra : moz-landing-system : lando --- dom/webgpu/Device.cpp | 11 ++- dom/webgpu/Device.h | 2 + dom/webgpu/ipc/PWebGPU.ipdl | 2 + dom/webgpu/ipc/WebGPUChild.cpp | 149 +++++++++++++++++++++++++++-- dom/webgpu/ipc/WebGPUChild.h | 6 +- dom/webgpu/ipc/WebGPUParent.cpp | 58 ++++++++++- dom/webgpu/ipc/WebGPUParent.h | 2 + dom/webgpu/ipc/WebGPUSerialize.h | 51 ++++++++-- dom/webgpu/ipc/WebGPUTypes.h | 30 +++++- dom/webidl/WebGPU.webidl | 2 +- gfx/wgpu/wgpu-remote/src/lib.rs | 14 +++ gfx/wgpu/wgpu-remote/src/server.rs | 10 ++ 12 files changed, 314 insertions(+), 23 deletions(-) diff --git a/dom/webgpu/Device.cpp b/dom/webgpu/Device.cpp index e6d5a9602cf5..b96b3bd3a9a1 100644 --- a/dom/webgpu/Device.cpp +++ b/dom/webgpu/Device.cpp @@ -12,10 +12,12 @@ #include "Adapter.h" #include "Buffer.h" +#include "ComputePipeline.h" +#include "Queue.h" +#include "RenderPipeline.h" #include "Sampler.h" #include "Texture.h" #include "TextureView.h" -#include "Queue.h" #include "ipc/WebGPUChild.h" namespace mozilla { @@ -185,5 +187,12 @@ already_AddRefed Device::CreateComputePipeline( return object.forget(); } +already_AddRefed Device::CreateRenderPipeline( + const dom::GPURenderPipelineDescriptor& aDesc) { + RawId id = mBridge->DeviceCreateRenderPipeline(mId, aDesc); + RefPtr object = new RenderPipeline(this, id); + return object.forget(); +} + } // namespace webgpu } // namespace mozilla diff --git a/dom/webgpu/Device.h b/dom/webgpu/Device.h index 2d8790941fff..60e3f49bfe05 100644 --- a/dom/webgpu/Device.h +++ b/dom/webgpu/Device.h @@ -120,6 +120,8 @@ class Device final : public DOMEventTargetHelper { const dom::GPUShaderModuleDescriptor& aDesc); already_AddRefed CreateComputePipeline( const dom::GPUComputePipelineDescriptor& aDesc); + already_AddRefed CreateRenderPipeline( + const dom::GPURenderPipelineDescriptor& aDesc); // IMPL_EVENT_HANDLER(uncapturederror) }; diff --git a/dom/webgpu/ipc/PWebGPU.ipdl b/dom/webgpu/ipc/PWebGPU.ipdl index ef6fd15d4565..e396d3dd939d 100644 --- a/dom/webgpu/ipc/PWebGPU.ipdl +++ b/dom/webgpu/ipc/PWebGPU.ipdl @@ -11,6 +11,7 @@ using SerialBindGroupLayoutDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using SerialPipelineLayoutDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using SerialBindGroupDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using SerialComputePipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h"; +using SerialRenderPipelineDescriptor from "mozilla/webgpu/WebGPUTypes.h"; using dom::GPURequestAdapterOptions from "mozilla/dom/WebGPUBinding.h"; using dom::GPUDeviceDescriptor from "mozilla/dom/WebGPUBinding.h"; using dom::GPUBufferDescriptor from "mozilla/dom/WebGPUBinding.h"; @@ -69,6 +70,7 @@ parent: async ShaderModuleDestroy(RawId selfId); async DeviceCreateComputePipeline(RawId selfId, SerialComputePipelineDescriptor desc, RawId newId); async ComputePipelineDestroy(RawId selfId); + async DeviceCreateRenderPipeline(RawId selfId, SerialRenderPipelineDescriptor desc, RawId newId); async RenderPipelineDestroy(RawId selfId); async Shutdown(); diff --git a/dom/webgpu/ipc/WebGPUChild.cpp b/dom/webgpu/ipc/WebGPUChild.cpp index d8945e16fc3a..ac544933ecb9 100644 --- a/dom/webgpu/ipc/WebGPUChild.cpp +++ b/dom/webgpu/ipc/WebGPUChild.cpp @@ -348,13 +348,21 @@ void WebGPUChild::DestroyShaderModule(RawId aId) { ffi::wgpu_client_kill_shader_module_id(mClient, aId); } +static SerialProgrammableStageDescriptor ConvertProgrammableStageDescriptor( + const dom::GPUProgrammableStageDescriptor& aDesc) { + SerialProgrammableStageDescriptor stage = {}; + stage.mModule = aDesc.mModule->mId; + stage.mEntryPoint = aDesc.mEntryPoint; + return stage; +} + RawId WebGPUChild::DeviceCreateComputePipeline( RawId aSelfId, const dom::GPUComputePipelineDescriptor& aDesc) { RawId id = ffi::wgpu_client_make_compute_pipeline_id(mClient, aSelfId); - SerialProgrammableStageDescriptor stage = {}; - stage.mModule = aDesc.mComputeStage.mModule->mId; - stage.mEntryPoint = aDesc.mComputeStage.mEntryPoint; - SerialComputePipelineDescriptor desc = {aDesc.mLayout->mId, stage}; + const SerialComputePipelineDescriptor desc = { + aDesc.mLayout->mId, + ConvertProgrammableStageDescriptor(aDesc.mComputeStage), + }; if (!SendDeviceCreateComputePipeline(aSelfId, desc, id)) { MOZ_CRASH("IPC failure"); } @@ -366,6 +374,134 @@ void WebGPUChild::DestroyComputePipeline(RawId aId) { ffi::wgpu_client_kill_compute_pipeline_id(mClient, aId); } +static ffi::WGPURasterizationStateDescriptor ConvertRasterizationDescriptor( + const dom::GPURasterizationStateDescriptor& aDesc) { + ffi::WGPURasterizationStateDescriptor desc = {}; + desc.front_face = ffi::WGPUFrontFace(aDesc.mFrontFace); + desc.cull_mode = ffi::WGPUCullMode(aDesc.mCullMode); + desc.depth_bias = aDesc.mDepthBias; + desc.depth_bias_slope_scale = aDesc.mDepthBiasSlopeScale; + desc.depth_bias_clamp = aDesc.mDepthBiasClamp; + return desc; +} + +static ffi::WGPUBlendDescriptor ConvertBlendDescriptor( + const dom::GPUBlendDescriptor& aDesc) { + ffi::WGPUBlendDescriptor desc = {}; + desc.src_factor = ffi::WGPUBlendFactor(aDesc.mSrcFactor); + desc.dst_factor = ffi::WGPUBlendFactor(aDesc.mDstFactor); + desc.operation = ffi::WGPUBlendOperation(aDesc.mOperation); + return desc; +} + +static ffi::WGPUColorStateDescriptor ConvertColorDescriptor( + const dom::GPUColorStateDescriptor& aDesc) { + ffi::WGPUColorStateDescriptor desc = {}; + desc.format = ffi::WGPUTextureFormat(aDesc.mFormat); + const ffi::WGPUBlendDescriptor no_blend = { + ffi::WGPUBlendFactor_One, + ffi::WGPUBlendFactor_Zero, + ffi::WGPUBlendOperation_Add, + }; + desc.alpha_blend = aDesc.mAlpha.WasPassed() + ? ConvertBlendDescriptor(aDesc.mAlpha.Value()) + : no_blend; + desc.color_blend = aDesc.mColor.WasPassed() + ? ConvertBlendDescriptor(aDesc.mColor.Value()) + : no_blend; + desc.write_mask = aDesc.mWriteMask; + return desc; +} + +static ffi::WGPUStencilStateFaceDescriptor ConvertStencilFaceDescriptor( + const dom::GPUStencilStateFaceDescriptor& aDesc) { + ffi::WGPUStencilStateFaceDescriptor desc = {}; + desc.compare = ffi::WGPUCompareFunction(aDesc.mCompare); + desc.fail_op = ffi::WGPUStencilOperation(aDesc.mFailOp); + desc.depth_fail_op = ffi::WGPUStencilOperation(aDesc.mDepthFailOp); + desc.pass_op = ffi::WGPUStencilOperation(aDesc.mPassOp); + return desc; +} + +static ffi::WGPUDepthStencilStateDescriptor ConvertDepthStencilDescriptor( + const dom::GPUDepthStencilStateDescriptor& aDesc) { + ffi::WGPUDepthStencilStateDescriptor desc = {}; + desc.format = ffi::WGPUTextureFormat(aDesc.mFormat); + desc.depth_write_enabled = aDesc.mDepthWriteEnabled; + desc.depth_compare = ffi::WGPUCompareFunction(aDesc.mDepthCompare); + desc.stencil_front = ConvertStencilFaceDescriptor(aDesc.mStencilFront); + desc.stencil_back = ConvertStencilFaceDescriptor(aDesc.mStencilBack); + desc.stencil_read_mask = aDesc.mStencilReadMask; + desc.stencil_write_mask = aDesc.mStencilWriteMask; + return desc; +} + +static ffi::WGPUVertexAttributeDescriptor ConvertVertexAttributeDescriptor( + const dom::GPUVertexAttributeDescriptor& aDesc) { + ffi::WGPUVertexAttributeDescriptor desc = {}; + desc.offset = aDesc.mOffset; + desc.format = ffi::WGPUVertexFormat(aDesc.mFormat); + desc.shader_location = aDesc.mShaderLocation; + return desc; +} + +static SerialVertexBufferDescriptor ConvertVertexBufferDescriptor( + const dom::GPUVertexBufferDescriptor& aDesc) { + SerialVertexBufferDescriptor desc = {}; + desc.mStride = aDesc.mStride; + desc.mStepMode = ffi::WGPUInputStepMode(aDesc.mStepMode); + for (const auto& vat : aDesc.mAttributeSet) { + desc.mAttributes.AppendElement(ConvertVertexAttributeDescriptor(vat)); + } + return desc; +} + +RawId WebGPUChild::DeviceCreateRenderPipeline( + RawId aSelfId, const dom::GPURenderPipelineDescriptor& aDesc) { + RawId id = ffi::wgpu_client_make_render_pipeline_id(mClient, aSelfId); + SerialRenderPipelineDescriptor desc = {}; + desc.mLayout = aDesc.mLayout->mId; + desc.mVertexStage = ConvertProgrammableStageDescriptor(aDesc.mVertexStage); + if (aDesc.mFragmentStage.WasPassed()) { + desc.mFragmentStage = + ConvertProgrammableStageDescriptor(aDesc.mFragmentStage.Value()); + } + desc.mPrimitiveTopology = + ffi::WGPUPrimitiveTopology(aDesc.mPrimitiveTopology); + if (aDesc.mRasterizationState.WasPassed()) { + desc.mRasterizationState = + Some(ConvertRasterizationDescriptor(aDesc.mRasterizationState.Value())); + } + for (const auto& color_state : aDesc.mColorStates) { + desc.mColorStates.AppendElement(ConvertColorDescriptor(color_state)); + } + if (aDesc.mDepthStencilState.WasPassed()) { + desc.mDepthStencilState = + Some(ConvertDepthStencilDescriptor(aDesc.mDepthStencilState.Value())); + } + desc.mVertexInput.mIndexFormat = + ffi::WGPUIndexFormat(aDesc.mVertexInput.mIndexFormat); + for (const auto& vertex_desc : aDesc.mVertexInput.mVertexBuffers) { + SerialVertexBufferDescriptor vb_desc = {}; + if (!vertex_desc.IsNull()) { + vb_desc = ConvertVertexBufferDescriptor(vertex_desc.Value()); + } + desc.mVertexInput.mVertexBuffers.AppendElement(vb_desc); + } + desc.mSampleCount = aDesc.mSampleCount; + desc.mSampleMask = aDesc.mSampleMask; + desc.mAlphaToCoverageEnabled = aDesc.mAlphaToCoverageEnabled; + if (!SendDeviceCreateRenderPipeline(aSelfId, desc, id)) { + MOZ_CRASH("IPC failure"); + } + return id; +} + +void WebGPUChild::DestroyRenderPipeline(RawId aId) { + SendRenderPipelineDestroy(aId); + ffi::wgpu_client_kill_render_pipeline_id(mClient, aId); +} + void WebGPUChild::QueueSubmit(RawId aSelfId, const nsTArray& aCommandBufferIds) { SendQueueSubmit(aSelfId, aCommandBufferIds); @@ -374,10 +510,5 @@ void WebGPUChild::QueueSubmit(RawId aSelfId, } } -void WebGPUChild::DestroyRenderPipeline(RawId aId) { - SendRenderPipelineDestroy(aId); - ffi::wgpu_client_kill_render_pipeline_id(mClient, aId); -} - } // namespace webgpu } // namespace mozilla diff --git a/dom/webgpu/ipc/WebGPUChild.h b/dom/webgpu/ipc/WebGPUChild.h index d0af89963670..45b7d083bb62 100644 --- a/dom/webgpu/ipc/WebGPUChild.h +++ b/dom/webgpu/ipc/WebGPUChild.h @@ -79,10 +79,12 @@ class WebGPUChild final : public PWebGPUChild { RawId aSelfId, const dom::GPUComputePipelineDescriptor& aDesc); void DestroyComputePipeline(RawId aId); - void QueueSubmit(RawId aSelfId, const nsTArray& aCommandBufferIds); - + RawId DeviceCreateRenderPipeline( + RawId aSelfId, const dom::GPURenderPipelineDescriptor& aDesc); void DestroyRenderPipeline(RawId aId); + void QueueSubmit(RawId aSelfId, const nsTArray& aCommandBufferIds); + private: virtual ~WebGPUChild(); diff --git a/dom/webgpu/ipc/WebGPUParent.cpp b/dom/webgpu/ipc/WebGPUParent.cpp index 779f8e676754..e105ee02b760 100644 --- a/dom/webgpu/ipc/WebGPUParent.cpp +++ b/dom/webgpu/ipc/WebGPUParent.cpp @@ -297,7 +297,7 @@ ipc::IPCResult WebGPUParent::RecvShaderModuleDestroy(RawId aSelfId) { ipc::IPCResult WebGPUParent::RecvDeviceCreateComputePipeline( RawId aSelfId, const SerialComputePipelineDescriptor& aDesc, RawId aNewId) { - NS_LossyConvertUTF16toASCII entryPoint(aDesc.mComputeStage.mEntryPoint); + const NS_LossyConvertUTF16toASCII entryPoint(aDesc.mComputeStage.mEntryPoint); ffi::WGPUComputePipelineDescriptor desc = {}; desc.layout = aDesc.mLayout; desc.compute_stage.module = aDesc.mComputeStage.mModule; @@ -312,6 +312,62 @@ ipc::IPCResult WebGPUParent::RecvComputePipelineDestroy(RawId aSelfId) { return IPC_OK(); } +ipc::IPCResult WebGPUParent::RecvDeviceCreateRenderPipeline( + RawId aSelfId, const SerialRenderPipelineDescriptor& aDesc, RawId aNewId) { + const NS_LossyConvertUTF16toASCII vsEntryPoint( + aDesc.mVertexStage.mEntryPoint); + const NS_LossyConvertUTF16toASCII fsEntryPoint( + aDesc.mFragmentStage.mEntryPoint); + size_t totalAttributes = 0; + for (const auto& vertexBuffer : aDesc.mVertexInput.mVertexBuffers) { + totalAttributes += vertexBuffer.mAttributes.Length(); + } + nsTArray vertexBuffers( + aDesc.mVertexInput.mVertexBuffers.Length()); + nsTArray vertexAttributes( + totalAttributes); + + ffi::WGPURenderPipelineDescriptor desc = {}; + ffi::WGPUProgrammableStageDescriptor fragmentDesc = {}; + desc.layout = aDesc.mLayout; + desc.vertex_stage.module = aDesc.mVertexStage.mModule; + desc.vertex_stage.entry_point = vsEntryPoint.get(); + if (aDesc.mFragmentStage.mModule != 0) { + fragmentDesc.module = aDesc.mFragmentStage.mModule; + fragmentDesc.entry_point = fsEntryPoint.get(); + desc.fragment_stage = &fragmentDesc; + } + desc.primitive_topology = aDesc.mPrimitiveTopology; + if (aDesc.mRasterizationState.isSome()) { + desc.rasterization_state = aDesc.mRasterizationState.ptr(); + } + desc.color_states = aDesc.mColorStates.Elements(); + desc.color_states_length = aDesc.mColorStates.Length(); + if (aDesc.mDepthStencilState.isSome()) { + desc.depth_stencil_state = aDesc.mDepthStencilState.ptr(); + } + totalAttributes = 0; + for (const auto& vertexBuffer : aDesc.mVertexInput.mVertexBuffers) { + ffi::WGPUVertexBufferDescriptor vb = {}; + vb.stride = vertexBuffer.mStride; + vb.step_mode = vertexBuffer.mStepMode; + vb.attributes = vertexAttributes.Elements() + totalAttributes; + vb.attributes_length = vertexBuffer.mAttributes.Length(); + for (const auto& attribute : vertexBuffer.mAttributes) { + vertexAttributes.AppendElement(attribute); + } + } + desc.vertex_input.index_format = aDesc.mVertexInput.mIndexFormat; + desc.vertex_input.vertex_buffers = vertexBuffers.Elements(); + desc.vertex_input.vertex_buffers_length = vertexBuffers.Length(); + desc.sample_count = aDesc.mSampleCount; + desc.sample_mask = aDesc.mSampleMask; + desc.alpha_to_coverage_enabled = aDesc.mAlphaToCoverageEnabled; + ffi::wgpu_server_device_create_render_pipeline(mContext, aSelfId, &desc, + aNewId); + return IPC_OK(); +} + ipc::IPCResult WebGPUParent::RecvRenderPipelineDestroy(RawId aSelfId) { ffi::wgpu_server_render_pipeline_destroy(mContext, aSelfId); return IPC_OK(); diff --git a/dom/webgpu/ipc/WebGPUParent.h b/dom/webgpu/ipc/WebGPUParent.h index 268f1c1bbf13..e403cd098178 100644 --- a/dom/webgpu/ipc/WebGPUParent.h +++ b/dom/webgpu/ipc/WebGPUParent.h @@ -81,6 +81,8 @@ class WebGPUParent final : public PWebGPUParent { RawId aSelfId, const SerialComputePipelineDescriptor& aDesc, RawId aNewId); ipc::IPCResult RecvComputePipelineDestroy(RawId aSelfId); + ipc::IPCResult RecvDeviceCreateRenderPipeline( + RawId aSelfId, const SerialRenderPipelineDescriptor& aDesc, RawId aNewId); ipc::IPCResult RecvRenderPipelineDestroy(RawId aSelfId); ipc::IPCResult RecvShutdown(); diff --git a/dom/webgpu/ipc/WebGPUSerialize.h b/dom/webgpu/ipc/WebGPUSerialize.h index c9b309d93fe9..f133942f9983 100644 --- a/dom/webgpu/ipc/WebGPUSerialize.h +++ b/dom/webgpu/ipc/WebGPUSerialize.h @@ -24,12 +24,28 @@ namespace IPC { DEFINE_IPC_SERIALIZER_ENUM_GUARD(something, something##_Sentinel) DEFINE_IPC_SERIALIZER_DOM_ENUM(mozilla::dom::GPUPowerPreference); +DEFINE_IPC_SERIALIZER_DOM_ENUM(mozilla::webgpu::SerialBindGroupBindingType); + DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUAddressMode); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUBindingType); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUBlendFactor); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUBlendOperation); DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUCompareFunction); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUCullMode); DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUFilterMode); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUFrontFace); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUIndexFormat); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUInputStepMode); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUPrimitiveTopology); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUStencilOperation); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureAspect); DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureDimension); DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureFormat); -DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureAspect); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureViewDimension); +DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUVertexFormat); + +DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::dom::GPUCommandEncoderDescriptor); +DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::dom::GPUCommandBufferDescriptor); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPURequestAdapterOptions, mPowerPreference); @@ -40,8 +56,6 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUDeviceDescriptor, mExtensions, mLimits); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::GPUBufferDescriptor, mSize, mUsage); -DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::dom::GPUCommandEncoderDescriptor); -DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(mozilla::dom::GPUCommandBufferDescriptor); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUExtent3d, width, height, depth); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUTextureDescriptor, @@ -56,8 +70,25 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUSamplerDescriptor, mipmap_filter, lod_min_clamp, lod_max_clamp, compare_function); -DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUBindingType); -DEFINE_IPC_SERIALIZER_FFI_ENUM(mozilla::webgpu::ffi::WGPUTextureViewDimension); +DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::ffi::WGPUBlendDescriptor, + src_factor, dst_factor, operation); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::ffi::WGPURasterizationStateDescriptor, front_face, + cull_mode, depth_bias, depth_bias_slope_scale, depth_bias_clamp); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::ffi::WGPUColorStateDescriptor, format, alpha_blend, + color_blend, write_mask); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::ffi::WGPUStencilStateFaceDescriptor, compare, fail_op, + depth_fail_op, pass_op); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::ffi::WGPUDepthStencilStateDescriptor, format, + depth_write_enabled, depth_compare, stencil_front, stencil_back, + stencil_read_mask, stencil_write_mask); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::ffi::WGPUVertexAttributeDescriptor, offset, format, + shader_location); + DEFINE_IPC_SERIALIZER_WITH_FIELDS( mozilla::webgpu::ffi::WGPUBindGroupLayoutBinding, binding, visibility, ty, texture_dimension, multisampled, dynamic); @@ -65,7 +96,6 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS( mozilla::webgpu::SerialBindGroupLayoutDescriptor, mBindings); DEFINE_IPC_SERIALIZER_WITH_FIELDS( mozilla::webgpu::SerialPipelineLayoutDescriptor, mBindGroupLayouts); -DEFINE_IPC_SERIALIZER_DOM_ENUM(mozilla::webgpu::SerialBindGroupBindingType); DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupBinding, mBinding, mType, mValue, mBufferOffset, mBufferSize); @@ -74,8 +104,17 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialBindGroupDescriptor, DEFINE_IPC_SERIALIZER_WITH_FIELDS( mozilla::webgpu::SerialProgrammableStageDescriptor, mModule, mEntryPoint); +DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialVertexBufferDescriptor, + mStride, mStepMode, mAttributes); +DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::webgpu::SerialVertexInputDescriptor, + mIndexFormat, mVertexBuffers); DEFINE_IPC_SERIALIZER_WITH_FIELDS( mozilla::webgpu::SerialComputePipelineDescriptor, mLayout, mComputeStage); +DEFINE_IPC_SERIALIZER_WITH_FIELDS( + mozilla::webgpu::SerialRenderPipelineDescriptor, mLayout, mVertexStage, + mFragmentStage, mPrimitiveTopology, mRasterizationState, mColorStates, + mDepthStencilState, mVertexInput, mSampleCount, mSampleMask, + mAlphaToCoverageEnabled); #undef DEFINE_IPC_SERIALIZER_FFI_ENUM #undef DEFINE_IPC_SERIALIZER_DOM_ENUM diff --git a/dom/webgpu/ipc/WebGPUTypes.h b/dom/webgpu/ipc/WebGPUTypes.h index 6d221642e562..72ff81d1e4d7 100644 --- a/dom/webgpu/ipc/WebGPUTypes.h +++ b/dom/webgpu/ipc/WebGPUTypes.h @@ -8,12 +8,11 @@ #include #include "nsTArray.h" +#include "mozilla/Maybe.h" +#include "mozilla/webgpu/ffi/wgpu.h" namespace mozilla { namespace webgpu { -namespace ffi { -struct WGPUBindGroupLayoutBinding; -} // namespace ffi typedef uint64_t RawId; typedef uint64_t BufferAddress; @@ -56,6 +55,31 @@ struct SerialComputePipelineDescriptor { SerialProgrammableStageDescriptor mComputeStage; }; +struct SerialVertexBufferDescriptor { + ffi::WGPUBufferAddress mStride; + ffi::WGPUInputStepMode mStepMode; + nsTArray mAttributes; +}; + +struct SerialVertexInputDescriptor { + ffi::WGPUIndexFormat mIndexFormat; + nsTArray mVertexBuffers; +}; + +struct SerialRenderPipelineDescriptor { + RawId mLayout; + SerialProgrammableStageDescriptor mVertexStage; + SerialProgrammableStageDescriptor mFragmentStage; + ffi::WGPUPrimitiveTopology mPrimitiveTopology; + Maybe mRasterizationState; + nsTArray mColorStates; + Maybe mDepthStencilState; + SerialVertexInputDescriptor mVertexInput; + uint32_t mSampleCount; + uint32_t mSampleMask; + bool mAlphaToCoverageEnabled; +}; + } // namespace webgpu } // namespace mozilla diff --git a/dom/webidl/WebGPU.webidl b/dom/webidl/WebGPU.webidl index 815096456bcf..aa15b1071497 100644 --- a/dom/webidl/WebGPU.webidl +++ b/dom/webidl/WebGPU.webidl @@ -122,7 +122,7 @@ interface GPUDevice { GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); - //GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); + GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); [NewObject] GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); diff --git a/gfx/wgpu/wgpu-remote/src/lib.rs b/gfx/wgpu/wgpu-remote/src/lib.rs index c0b53585c301..53ddea933d67 100644 --- a/gfx/wgpu/wgpu-remote/src/lib.rs +++ b/gfx/wgpu/wgpu-remote/src/lib.rs @@ -443,6 +443,20 @@ pub extern "C" fn wgpu_client_kill_compute_pipeline_id( .free(id) } +#[no_mangle] +pub extern "C" fn wgpu_client_make_render_pipeline_id( + client: &Client, + device_id: id::DeviceId, +) -> id::RenderPipelineId { + let backend = device_id.backend(); + client + .identities + .lock() + .select(backend) + .render_pipelines + .alloc(backend) +} + #[no_mangle] pub extern "C" fn wgpu_client_kill_render_pipeline_id( client: &Client, diff --git a/gfx/wgpu/wgpu-remote/src/server.rs b/gfx/wgpu/wgpu-remote/src/server.rs index 95f4aef1d264..8ac9b9360e51 100644 --- a/gfx/wgpu/wgpu-remote/src/server.rs +++ b/gfx/wgpu/wgpu-remote/src/server.rs @@ -327,6 +327,16 @@ pub extern "C" fn wgpu_server_compute_pipeline_destroy( gfx_select!(self_id => global.compute_pipeline_destroy(self_id)); } +#[no_mangle] +pub extern "C" fn wgpu_server_device_create_render_pipeline( + global: &Global, + self_id: id::DeviceId, + desc: &core::pipeline::RenderPipelineDescriptor, + new_id: id::RenderPipelineId, +) { + gfx_select!(self_id => global.device_create_render_pipeline(self_id, desc, new_id)); +} + #[no_mangle] pub extern "C" fn wgpu_server_render_pipeline_destroy( global: &Global,