// Copyright 2017 The NXT Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "backend/DepthStencilState.h" #include "backend/Device.h" namespace backend { // DepthStencilStateBase DepthStencilStateBase::DepthStencilStateBase(DepthStencilStateBuilder* builder) : mDepthInfo(builder->mDepthInfo), mStencilInfo(builder->mStencilInfo) { } bool DepthStencilStateBase::StencilTestEnabled() const { return mStencilInfo.back.compareFunction != nxt::CompareFunction::Always || mStencilInfo.back.stencilFail != nxt::StencilOperation::Keep || mStencilInfo.back.depthFail != nxt::StencilOperation::Keep || mStencilInfo.back.depthStencilPass != nxt::StencilOperation::Keep || mStencilInfo.front.compareFunction != nxt::CompareFunction::Always || mStencilInfo.front.stencilFail != nxt::StencilOperation::Keep || mStencilInfo.front.depthFail != nxt::StencilOperation::Keep || mStencilInfo.front.depthStencilPass != nxt::StencilOperation::Keep; } const DepthStencilStateBase::DepthInfo& DepthStencilStateBase::GetDepth() const { return mDepthInfo; } const DepthStencilStateBase::StencilInfo& DepthStencilStateBase::GetStencil() const { return mStencilInfo; } // DepthStencilStateBuilder enum DepthStencilStateSetProperties { DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION = 0x1, DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED = 0x2, DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION = 0x4, DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION = 0x08, DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK = 0x10, }; DepthStencilStateBuilder::DepthStencilStateBuilder(DeviceBase* device) : Builder(device) { } DepthStencilStateBase* DepthStencilStateBuilder::GetResultImpl() { return mDevice->CreateDepthStencilState(this); } void DepthStencilStateBuilder::SetDepthCompareFunction( nxt::CompareFunction depthCompareFunction) { if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION) != 0) { HandleError("Depth compare property set multiple times"); return; } mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION; mDepthInfo.compareFunction = depthCompareFunction; } void DepthStencilStateBuilder::SetDepthWriteEnabled(bool enabled) { if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED) != 0) { HandleError("Depth write enabled property set multiple times"); return; } mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_DEPTH_WRITE_ENABLED; mDepthInfo.depthWriteEnabled = enabled; } void DepthStencilStateBuilder::SetStencilFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction, nxt::StencilOperation stencilFail, nxt::StencilOperation depthFail, nxt::StencilOperation depthStencilPass) { if (face == nxt::Face::None) { HandleError("Can't set stencil function of None face"); return; } if (face & nxt::Face::Back) { if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION) != 0) { HandleError("Stencil back function property set multiple times"); return; } mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_BACK_FUNCTION; mStencilInfo.back.compareFunction = stencilCompareFunction; mStencilInfo.back.stencilFail = stencilFail; mStencilInfo.back.depthFail = depthFail; mStencilInfo.back.depthStencilPass = depthStencilPass; } if (face & nxt::Face::Front) { if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION) != 0) { HandleError("Stencil front function property set multiple times"); return; } mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_FRONT_FUNCTION; mStencilInfo.front.compareFunction = stencilCompareFunction; mStencilInfo.front.stencilFail = stencilFail; mStencilInfo.front.depthFail = depthFail; mStencilInfo.front.depthStencilPass = depthStencilPass; } } void DepthStencilStateBuilder::SetStencilMask(uint32_t readMask, uint32_t writeMask) { if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK) != 0) { HandleError("Stencilmask property set multiple times"); return; } mPropertiesSet |= DEPTH_STENCIL_STATE_PROPERTY_STENCIL_MASK; mStencilInfo.readMask = readMask; mStencilInfo.writeMask = writeMask; } } // namespace backend