Add MTL backend for DepthStencilState. Completely untested.

This commit is contained in:
Austin Eng 2017-05-30 17:04:49 -04:00 committed by Corentin Wallez
parent 4f5521e440
commit 76e64a985d
2 changed files with 140 additions and 5 deletions

View File

@ -26,6 +26,7 @@
#include "common/BindGroupLayout.h" #include "common/BindGroupLayout.h"
#include "common/Device.h" #include "common/Device.h"
#include "common/CommandBuffer.h" #include "common/CommandBuffer.h"
#include "common/DepthStencilState.h"
#include "common/InputState.h" #include "common/InputState.h"
#include "common/Framebuffer.h" #include "common/Framebuffer.h"
#include "common/Pipeline.h" #include "common/Pipeline.h"
@ -53,6 +54,7 @@ namespace metal {
class Buffer; class Buffer;
class BufferView; class BufferView;
class CommandBuffer; class CommandBuffer;
class DepthStencilState;
class InputState; class InputState;
class Framebuffer; class Framebuffer;
class Pipeline; class Pipeline;
@ -70,6 +72,7 @@ namespace metal {
using BufferType = Buffer; using BufferType = Buffer;
using BufferViewType = BufferView; using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer; using CommandBufferType = CommandBuffer;
using DepthStencilStateType = DepthStencilState;
using InputStateType = InputState; using InputStateType = InputState;
using FramebufferType = Framebuffer; using FramebufferType = Framebuffer;
using PipelineType = Pipeline; using PipelineType = Pipeline;
@ -97,6 +100,7 @@ namespace metal {
BufferBase* CreateBuffer(BufferBuilder* builder) override; BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override; CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override; FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
PipelineBase* CreatePipeline(PipelineBuilder* builder) override; PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
@ -180,6 +184,18 @@ namespace metal {
CommandIterator commands; CommandIterator commands;
}; };
class DepthStencilState : public DepthStencilStateBase {
public:
DepthStencilState(Device* device, DepthStencilStateBuilder* builder);
~DepthStencilState();
MTLDepthStencilDescriptor* GetMTLDepthStencilDescriptor();
private:
Device* device;
MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = nil;
};
class InputState : public InputStateBase { class InputState : public InputStateBase {
public: public:
InputState(Device* device, InputStateBuilder* builder); InputState(Device* device, InputStateBuilder* builder);

View File

@ -80,6 +80,9 @@ namespace metal {
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(this, builder); return new CommandBuffer(this, builder);
} }
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilState(this, builder);
}
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) { InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(this, builder); return new InputState(this, builder);
} }
@ -469,6 +472,18 @@ namespace metal {
} }
break; break;
case Command::SetStencilReference:
{
SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>();
ASSERT(encoders.render);
[encoders.render
setStencilFrontReferenceValue:cmd->frontReference
backReferenceValue:cmd->backReference];
}
break;
case Command::SetBindGroup: case Command::SetBindGroup:
{ {
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>(); SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
@ -648,6 +663,112 @@ namespace metal {
encoders.FinishEncoders(); encoders.FinishEncoders();
} }
// DepthStencilState
static MTLCompareFunction DepthStencilCompareFunction(nxt::CompareFunction compareFunction) {
switch (compareFunction) {
case nxt::CompareFunction::Never:
return MTLCompareFunctionNever;
case nxt::CompareFunction::Less:
return MTLCompareFunctionLess;
case nxt::CompareFunction::LessEqual:
return MTLCompareFunctionLessEqual;
case nxt::CompareFunction::Greater:
return MTLCompareFunctionGreater;
case nxt::CompareFunction::GreaterEqual:
return MTLCompareFunctionGreaterEqual;
case nxt::CompareFunction::NotEqual:
return MTLCompareFunctionNotEqual;
case nxt::CompareFunction::Equal:
return MTLCompareFunctionEqual;
case nxt::CompareFunction::Always:
return MTLCompareFunctionAlways;
default:
ASSERT(false);
}
}
static MTLStencilOperation StencilOperation(nxt::StencilOperation stencilOperation) {
switch (stencilOperation) {
case nxt::StencilOperation::Keep:
return MTLStencilOperationKeep;
case nxt::StencilOperation::Zero:
return MTLStencilOperationZero;
case nxt::StencilOperation::Replace:
return MTLStencilOperationReplace;
case nxt::StencilOperation::Invert:
return MTLStencilOperationInvert;
case nxt::StencilOperation::IncrementClamp:
return MTLStencilOperationIncrementClamp;
case nxt::StencilOperation::DecrementClamp:
return MTLStencilOperationDecrementClamp;
case nxt::StencilOperation::IncrementWrap:
return MTLStencilOperationIncrementWrap;
case nxt::StencilOperation::DecrementWrap:
return MTLStencilOperationDecrementWrap;
default:
ASSERT(false);
}
}
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
: DepthStencilStateBase(builder), device(device) {
mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new];
if (DepthIsEnabled()) {
auto& depth = GetDepth();
mtlDepthStencilDescriptor.depthCompareFunction = DepthStencilCompareFunction(depth.compareFunction);
switch (depth.depthWriteMode) {
case nxt::DepthWriteMode::Disabled:
mtlDepthStencilDescriptor.depthWriteEnabled = false;
break;
case nxt::DepthWriteMode::Enabled:
mtlDepthStencilDescriptor.depthWriteEnabled = true;
break;
default:
ASSERT(false);
break;
}
}
if (StencilIsEnabled()) {
MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new];
MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new];
auto& back = GetStencil(nxt::Face::Back);
auto& front = GetStencil(nxt::Face::Front);
backFaceStencil.stencilCompareFunction = DepthStencilCompareFunction(back.compareFunction);
backFaceStencil.stencilFailureOperation = StencilOperation(back.stencilFail);
backFaceStencil.depthFailureOperation = StencilOperation(back.depthFail);
backFaceStencil.depthStencilPassOperation = StencilOperation(back.stencilPass);
backFaceStencil.readMask = back.readMask;
backFaceStencil.writeMask = back.writeMask;
frontFaceStencil.stencilCompareFunction = DepthStencilCompareFunction(front.compareFunction);
frontFaceStencil.stencilFailureOperation = StencilOperation(front.stencilFail);
frontFaceStencil.depthFailureOperation = StencilOperation(front.depthFail);
frontFaceStencil.depthStencilPassOperation = StencilOperation(front.stencilPass);
frontFaceStencil.readMask = front.readMask;
frontFaceStencil.writeMask = front.writeMask;
mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil;
mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil;
[backFaceStencil release];
[frontFaceStencil release];
}
}
DepthStencilState::~DepthStencilState() {
[mtlDepthStencilDescriptor release];
mtlDepthStencilDescriptor = nil;
}
MTLDepthStencilDescriptor* DepthStencilState::GetMTLDepthStencilDescriptor() {
return mtlDepthStencilDescriptor;
}
// InputState // InputState
static MTLVertexFormat VertexFormatType(nxt::VertexFormat format) { static MTLVertexFormat VertexFormatType(nxt::VertexFormat format) {
@ -792,14 +913,12 @@ namespace metal {
builder->HandleError("Error creating pipeline state"); builder->HandleError("Error creating pipeline state");
return; return;
} }
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new]; DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState());
dsDesc.depthWriteEnabled = true; MTLDepthStencilDescriptor* dsDesc = depthStencilState->GetMTLDepthStencilDescriptor();
dsDesc.depthCompareFunction = MTLCompareFunctionLess;
mtlDepthStencilState = [device->GetMTLDevice() mtlDepthStencilState = [device->GetMTLDevice()
newDepthStencilStateWithDescriptor:dsDesc]; newDepthStencilStateWithDescriptor:dsDesc];
[dsDesc release];
[descriptor release]; [descriptor release];
} }
} }