From 3826880f81c3a96a39213f665c0094c79271d93e Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Thu, 25 Apr 2019 19:37:28 +0000 Subject: [PATCH] Metal: Implement Culling and FrontFace This is implementing the feature on a single backend and without tests so we can get it in the hands of people trying WebGPU quickly. BUG=dawn:43 Change-Id: I4d0611efd21dd1af053288957f137febc78a74e8 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6721 Reviewed-by: Austin Eng Reviewed-by: Kai Ninomiya Commit-Queue: Corentin Wallez --- src/dawn_native/RenderPipeline.cpp | 10 +++++++ src/dawn_native/RenderPipeline.h | 2 ++ src/dawn_native/metal/CommandBufferMTL.mm | 2 ++ src/dawn_native/metal/RenderPipelineMTL.h | 4 +++ src/dawn_native/metal/RenderPipelineMTL.mm | 32 +++++++++++++++++++++- 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp index 4aa206fd5d..84344ee816 100644 --- a/src/dawn_native/RenderPipeline.cpp +++ b/src/dawn_native/RenderPipeline.cpp @@ -435,6 +435,16 @@ namespace dawn_native { return mPrimitiveTopology; } + dawn::CullMode RenderPipelineBase::GetCullMode() const { + ASSERT(!IsError()); + return mRasterizationState.cullMode; + } + + dawn::FrontFace RenderPipelineBase::GetFrontFace() const { + ASSERT(!IsError()); + return mRasterizationState.frontFace; + } + std::bitset RenderPipelineBase::GetColorAttachmentsMask() const { ASSERT(!IsError()); return mColorAttachmentsSet; diff --git a/src/dawn_native/RenderPipeline.h b/src/dawn_native/RenderPipeline.h index 186de2c41f..f72afd7e97 100644 --- a/src/dawn_native/RenderPipeline.h +++ b/src/dawn_native/RenderPipeline.h @@ -53,6 +53,8 @@ namespace dawn_native { const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot); const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor(); dawn::PrimitiveTopology GetPrimitiveTopology() const; + dawn::CullMode GetCullMode() const; + dawn::FrontFace GetFrontFace() const; std::bitset GetColorAttachmentsMask() const; bool HasDepthStencilAttachment() const; diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm index 9f3a5aee28..7d95ae9b64 100644 --- a/src/dawn_native/metal/CommandBufferMTL.mm +++ b/src/dawn_native/metal/CommandBufferMTL.mm @@ -684,6 +684,8 @@ namespace dawn_native { namespace metal { lastPipeline = ToBackend(cmd->pipeline).Get(); [encoder setDepthStencilState:lastPipeline->GetMTLDepthStencilState()]; + [encoder setFrontFacingWinding:lastPipeline->GetMTLFrontFace()]; + [encoder setCullMode:lastPipeline->GetMTLCullMode()]; lastPipeline->Encode(encoder); } break; diff --git a/src/dawn_native/metal/RenderPipelineMTL.h b/src/dawn_native/metal/RenderPipelineMTL.h index 1edf434db7..a027ffc806 100644 --- a/src/dawn_native/metal/RenderPipelineMTL.h +++ b/src/dawn_native/metal/RenderPipelineMTL.h @@ -30,6 +30,8 @@ namespace dawn_native { namespace metal { MTLIndexType GetMTLIndexType() const; MTLPrimitiveType GetMTLPrimitiveTopology() const; + MTLWinding GetMTLFrontFace() const; + MTLCullMode GetMTLCullMode() const; void Encode(id encoder); @@ -40,6 +42,8 @@ namespace dawn_native { namespace metal { MTLIndexType mMtlIndexType; MTLPrimitiveType mMtlPrimitiveTopology; + MTLWinding mMtlFrontFace; + MTLCullMode mMtlCullMode; id mMtlRenderPipelineState = nil; id mMtlDepthStencilState = nil; }; diff --git a/src/dawn_native/metal/RenderPipelineMTL.mm b/src/dawn_native/metal/RenderPipelineMTL.mm index fa72c797f5..0397ba6e59 100644 --- a/src/dawn_native/metal/RenderPipelineMTL.mm +++ b/src/dawn_native/metal/RenderPipelineMTL.mm @@ -282,12 +282,34 @@ namespace dawn_native { namespace metal { return mtlDepthStencilDescriptor; } + MTLWinding MTLFrontFace(dawn::FrontFace face) { + switch (face) { + case dawn::FrontFace::CCW: + return MTLWindingCounterClockwise; + case dawn::FrontFace::CW: + return MTLWindingClockwise; + } + } + + MTLCullMode ToMTLCullMode(dawn::CullMode mode) { + switch (mode) { + case dawn::CullMode::None: + return MTLCullModeNone; + case dawn::CullMode::Front: + return MTLCullModeFront; + case dawn::CullMode::Back: + return MTLCullModeBack; + } + } + } // anonymous namespace RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor) : RenderPipelineBase(device, descriptor), mMtlIndexType(MTLIndexFormat(GetInputStateDescriptor()->indexFormat)), - mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { + mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())), + mMtlFrontFace(MTLFrontFace(GetFrontFace())), + mMtlCullMode(ToMTLCullMode(GetCullMode())) { auto mtlDevice = device->GetMTLDevice(); MTLRenderPipelineDescriptor* descriptorMTL = [MTLRenderPipelineDescriptor new]; @@ -362,6 +384,14 @@ namespace dawn_native { namespace metal { return mMtlPrimitiveTopology; } + MTLWinding RenderPipeline::GetMTLFrontFace() const { + return mMtlFrontFace; + } + + MTLCullMode RenderPipeline::GetMTLCullMode() const { + return mMtlCullMode; + } + void RenderPipeline::Encode(id encoder) { [encoder setRenderPipelineState:mMtlRenderPipelineState]; }