// 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/opengl/DepthStencilStateGL.h" #include "backend/opengl/PersistentPipelineStateGL.h" #include "common/Assert.h" namespace backend { namespace opengl { namespace { GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) { switch (compareFunction) { case nxt::CompareFunction::Never: return GL_NEVER; case nxt::CompareFunction::Less: return GL_LESS; case nxt::CompareFunction::LessEqual: return GL_LEQUAL; case nxt::CompareFunction::Greater: return GL_GREATER; case nxt::CompareFunction::GreaterEqual: return GL_GEQUAL; case nxt::CompareFunction::NotEqual: return GL_NOTEQUAL; case nxt::CompareFunction::Equal: return GL_EQUAL; case nxt::CompareFunction::Always: return GL_ALWAYS; default: UNREACHABLE(); } } GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) { switch (stencilOperation) { case nxt::StencilOperation::Keep: return GL_KEEP; case nxt::StencilOperation::Zero: return GL_ZERO; case nxt::StencilOperation::Replace: return GL_REPLACE; case nxt::StencilOperation::Invert: return GL_INVERT; case nxt::StencilOperation::IncrementClamp: return GL_INCR; case nxt::StencilOperation::DecrementClamp: return GL_DECR; case nxt::StencilOperation::IncrementWrap: return GL_INCR_WRAP; case nxt::StencilOperation::DecrementWrap: return GL_DECR_WRAP; default: UNREACHABLE(); } } } // namespace DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder) : DepthStencilStateBase(builder) { } void DepthStencilState::ApplyNow(PersistentPipelineState& persistentPipelineState) const { auto& depthInfo = GetDepth(); // Depth writes only occur if depth is enabled if (depthInfo.compareFunction == nxt::CompareFunction::Always && !depthInfo.depthWriteEnabled) { glDisable(GL_DEPTH_TEST); } else { glEnable(GL_DEPTH_TEST); } if (depthInfo.depthWriteEnabled) { glDepthMask(GL_TRUE); } else { glDepthMask(GL_FALSE); } glDepthFunc(OpenGLCompareFunction(depthInfo.compareFunction)); if (StencilTestEnabled()) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } auto& stencilInfo = GetStencil(); GLenum backCompareFunction = OpenGLCompareFunction(stencilInfo.back.compareFunction); GLenum frontCompareFunction = OpenGLCompareFunction(stencilInfo.front.compareFunction); persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction, stencilInfo.readMask); glStencilOpSeparate(GL_BACK, OpenGLStencilOperation(stencilInfo.back.stencilFail), OpenGLStencilOperation(stencilInfo.back.depthFail), OpenGLStencilOperation(stencilInfo.back.depthStencilPass)); glStencilOpSeparate(GL_FRONT, OpenGLStencilOperation(stencilInfo.front.stencilFail), OpenGLStencilOperation(stencilInfo.front.depthFail), OpenGLStencilOperation(stencilInfo.front.depthStencilPass)); glStencilMask(stencilInfo.writeMask); } }} // namespace backend::opengl