mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 00:47:13 +00:00
Refactor DepthStencilState. TODO: add validation tests
- defaults to depth and stencil tests off - whether or not depth and stencil tests are enabled is inferred from the comparison functions and stencil operations - only one stencil reference. D3D12 does not support separate references - change SetDepthWriteMode to SetDepthWriteEnabled and use a bool instead of enum - Create PersistentPipelineState class for OpenGL backend with simple state tracking - Add validation so DepthStencilState properties are only set once - Update API usage in HelloDepthStencil - refactor tracking of the DepthStencilState in the Metal backend - validate that compute pipeline does not have a depth stencil state
This commit is contained in:
committed by
Corentin Wallez
parent
f51be34864
commit
1063439d5d
@@ -189,11 +189,12 @@ namespace metal {
|
||||
DepthStencilState(Device* device, DepthStencilStateBuilder* builder);
|
||||
~DepthStencilState();
|
||||
|
||||
MTLDepthStencilDescriptor* GetMTLDepthStencilDescriptor();
|
||||
id<MTLDepthStencilState> GetMTLDepthStencilState();
|
||||
|
||||
private:
|
||||
Device* device;
|
||||
MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = nil;
|
||||
|
||||
id<MTLDepthStencilState> mtlDepthStencilState = nil;
|
||||
};
|
||||
|
||||
class InputState : public InputStateBase {
|
||||
@@ -230,8 +231,6 @@ namespace metal {
|
||||
Device* device;
|
||||
|
||||
id<MTLRenderPipelineState> mtlRenderPipelineState = nil;
|
||||
id<MTLDepthStencilState> mtlDepthStencilState = nil;
|
||||
|
||||
id<MTLComputePipelineState> mtlComputePipelineState = nil;
|
||||
MTLSize localWorkgroupSize;
|
||||
};
|
||||
|
||||
@@ -456,6 +456,8 @@ namespace metal {
|
||||
lastPipeline->Encode(encoders.compute);
|
||||
} else {
|
||||
ASSERT(encoders.render);
|
||||
DepthStencilState* depthStencilState = ToBackend(lastPipeline->GetDepthStencilState());
|
||||
[encoders.render setDepthStencilState:depthStencilState->GetMTLDepthStencilState()];
|
||||
lastPipeline->Encode(encoders.render);
|
||||
}
|
||||
}
|
||||
@@ -478,9 +480,7 @@ namespace metal {
|
||||
|
||||
ASSERT(encoders.render);
|
||||
|
||||
[encoders.render
|
||||
setStencilFrontReferenceValue:cmd->frontReference
|
||||
backReferenceValue:cmd->backReference];
|
||||
[encoders.render setStencilReferenceValue:cmd->reference];
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -665,7 +665,7 @@ namespace metal {
|
||||
|
||||
// DepthStencilState
|
||||
|
||||
static MTLCompareFunction DepthStencilCompareFunction(nxt::CompareFunction compareFunction) {
|
||||
static MTLCompareFunction MetalDepthStencilCompareFunction(nxt::CompareFunction compareFunction) {
|
||||
switch (compareFunction) {
|
||||
case nxt::CompareFunction::Never:
|
||||
return MTLCompareFunctionNever;
|
||||
@@ -683,12 +683,10 @@ namespace metal {
|
||||
return MTLCompareFunctionEqual;
|
||||
case nxt::CompareFunction::Always:
|
||||
return MTLCompareFunctionAlways;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
static MTLStencilOperation StencilOperation(nxt::StencilOperation stencilOperation) {
|
||||
static MTLStencilOperation MetalStencilOperation(nxt::StencilOperation stencilOperation) {
|
||||
switch (stencilOperation) {
|
||||
case nxt::StencilOperation::Keep:
|
||||
return MTLStencilOperationKeep;
|
||||
@@ -706,51 +704,38 @@ namespace metal {
|
||||
return MTLStencilOperationIncrementWrap;
|
||||
case nxt::StencilOperation::DecrementWrap:
|
||||
return MTLStencilOperationDecrementWrap;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
|
||||
: DepthStencilStateBase(builder), device(device) {
|
||||
mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new];
|
||||
MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = [MTLDepthStencilDescriptor new];
|
||||
|
||||
if (DepthIsEnabled()) {
|
||||
if (DepthTestEnabled()) {
|
||||
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;
|
||||
}
|
||||
mtlDepthStencilDescriptor.depthCompareFunction = MetalDepthStencilCompareFunction(depth.compareFunction);
|
||||
mtlDepthStencilDescriptor.depthWriteEnabled = depth.depthWriteEnabled;
|
||||
}
|
||||
|
||||
if (StencilIsEnabled()) {
|
||||
auto& stencil = GetStencil();
|
||||
|
||||
if (StencilTestEnabled()) {
|
||||
MTLStencilDescriptor* backFaceStencil = [MTLStencilDescriptor new];
|
||||
MTLStencilDescriptor* frontFaceStencil = [MTLStencilDescriptor new];
|
||||
|
||||
auto& back = GetBackStencil();
|
||||
auto& front = GetFrontStencil();
|
||||
backFaceStencil.stencilCompareFunction = MetalDepthStencilCompareFunction(stencil.back.compareFunction);
|
||||
backFaceStencil.stencilFailureOperation = MetalStencilOperation(stencil.back.stencilFail);
|
||||
backFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.back.depthFail);
|
||||
backFaceStencil.depthStencilPassOperation = MetalStencilOperation(stencil.back.depthStencilPass);
|
||||
backFaceStencil.readMask = stencil.back.mask;
|
||||
backFaceStencil.writeMask = stencil.back.mask;
|
||||
|
||||
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;
|
||||
frontFaceStencil.stencilCompareFunction = MetalDepthStencilCompareFunction(stencil.front.compareFunction);
|
||||
frontFaceStencil.stencilFailureOperation = MetalStencilOperation(stencil.front.stencilFail);
|
||||
frontFaceStencil.depthFailureOperation = MetalStencilOperation(stencil.front.depthFail);
|
||||
frontFaceStencil.depthStencilPassOperation = MetalStencilOperation(stencil.front.depthStencilPass);
|
||||
frontFaceStencil.readMask = stencil.front.mask;
|
||||
frontFaceStencil.writeMask = stencil.front.mask;
|
||||
|
||||
mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil;
|
||||
mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil;
|
||||
@@ -758,15 +743,17 @@ namespace metal {
|
||||
[frontFaceStencil release];
|
||||
}
|
||||
|
||||
mtlDepthStencilState = [device->GetMTLDevice() newDepthStencilStateWithDescriptor:mtlDepthStencilDescriptor];
|
||||
[mtlDepthStencilDescriptor release];
|
||||
}
|
||||
|
||||
DepthStencilState::~DepthStencilState() {
|
||||
[mtlDepthStencilDescriptor release];
|
||||
mtlDepthStencilDescriptor = nil;
|
||||
[mtlDepthStencilState release];
|
||||
mtlDepthStencilState = nil;
|
||||
}
|
||||
|
||||
MTLDepthStencilDescriptor* DepthStencilState::GetMTLDepthStencilDescriptor() {
|
||||
return mtlDepthStencilDescriptor;
|
||||
id<MTLDepthStencilState> DepthStencilState::GetMTLDepthStencilState() {
|
||||
return mtlDepthStencilState;
|
||||
}
|
||||
|
||||
// InputState
|
||||
@@ -914,24 +901,17 @@ namespace metal {
|
||||
return;
|
||||
}
|
||||
|
||||
DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState());
|
||||
MTLDepthStencilDescriptor* dsDesc = depthStencilState->GetMTLDepthStencilDescriptor();
|
||||
mtlDepthStencilState = [device->GetMTLDevice()
|
||||
newDepthStencilStateWithDescriptor:dsDesc];
|
||||
|
||||
[descriptor release];
|
||||
}
|
||||
}
|
||||
|
||||
Pipeline::~Pipeline() {
|
||||
[mtlRenderPipelineState release];
|
||||
[mtlDepthStencilState release];
|
||||
[mtlComputePipelineState release];
|
||||
}
|
||||
|
||||
void Pipeline::Encode(id<MTLRenderCommandEncoder> encoder) {
|
||||
ASSERT(!IsCompute());
|
||||
[encoder setDepthStencilState:mtlDepthStencilState];
|
||||
[encoder setRenderPipelineState:mtlRenderPipelineState];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user