#ifndef _RRFRAGMENTOPERATIONS_HPP #define _RRFRAGMENTOPERATIONS_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Reference Renderer * ----------------------------------------------- * * Copyright 2014 The Android Open Source Project * * 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. * *//*! * \file * \brief Reference implementation for per-fragment operations. * * \note In this file, a multisample buffer means a tcu::PixelBufferAccess * (or ConstPixelBufferAccess) where the x coordinate is the sample * index and the y and z coordinates are the pixel's x and y * coordinates, respectively. To prevent supplying a buffer in * a wrong format the buffers are wrapped in rr::MultisamplePixelBufferAccess * wrapper. FragmentProcessor::render() operates on * this kind of buffers. The function fromSinglesampleAccess() can be * used to get a one-sampled multisample access to a normal 2d * buffer. *//*--------------------------------------------------------------------*/ #include "rrDefs.hpp" #include "tcuVector.hpp" #include "tcuTexture.hpp" #include "rrRenderState.hpp" #include "rrGenericVector.hpp" #include "rrMultisamplePixelBufferAccess.hpp" namespace rr { struct Fragment { tcu::IVec2 pixelCoord; GenericVec4 value; GenericVec4 value1; uint32_t coverage; const float *sampleDepths; Fragment(const tcu::IVec2 &pixelCoord_, const GenericVec4 &value_, uint32_t coverage_, const float *sampleDepths_) : pixelCoord(pixelCoord_) , value(value_) , value1() , coverage(coverage_) , sampleDepths(sampleDepths_) { } Fragment(const tcu::IVec2 &pixelCoord_, const GenericVec4 &value_, const GenericVec4 &value1_, uint32_t coverage_, const float *sampleDepths_) : pixelCoord(pixelCoord_) , value(value_) , value1(value1_) , coverage(coverage_) , sampleDepths(sampleDepths_) { } Fragment(void) : pixelCoord(0), value(), coverage(0), sampleDepths(DE_NULL) { } } DE_WARN_UNUSED_TYPE; // These functions are for clearing only a specific pixel rectangle in a multisample buffer. // When clearing the entire buffer, tcu::clear, tcu::clearDepth and tcu::clearStencil can be used. void clearMultisampleColorBuffer(const tcu::PixelBufferAccess &dst, const tcu::Vec4 &value, const WindowRectangle &rect); void clearMultisampleColorBuffer(const tcu::PixelBufferAccess &dst, const tcu::IVec4 &value, const WindowRectangle &rect); void clearMultisampleColorBuffer(const tcu::PixelBufferAccess &dst, const tcu::UVec4 &value, const WindowRectangle &rect); void clearMultisampleDepthBuffer(const tcu::PixelBufferAccess &dst, float value, const WindowRectangle &rect); void clearMultisampleStencilBuffer(const tcu::PixelBufferAccess &dst, int value, const WindowRectangle &rect); /*--------------------------------------------------------------------*//*! * \brief Reference fragment renderer. * * FragmentProcessor.render() draws a given set of fragments. No two * fragments given in one render() call should have the same pixel * coordinates coordinates, and they must all have the same facing. *//*--------------------------------------------------------------------*/ class FragmentProcessor { public: FragmentProcessor(void); void render(const rr::MultisamplePixelBufferAccess &colorMultisampleBuffer, const rr::MultisamplePixelBufferAccess &depthMultisampleBuffer, const rr::MultisamplePixelBufferAccess &stencilMultisampleBuffer, const Fragment *fragments, int numFragments, FaceType fragmentFacing, const FragmentOperationState &state); private: enum { SAMPLE_REGISTER_SIZE = 64 }; struct SampleData { bool isAlive; bool stencilPassed; bool depthPassed; tcu::Vec4 clampedBlendSrcColor; tcu::Vec4 clampedBlendSrc1Color; tcu::Vec4 clampedBlendDstColor; tcu::Vec3 blendSrcFactorRGB; float blendSrcFactorA; tcu::Vec3 blendDstFactorRGB; float blendDstFactorA; tcu::Vec3 blendedRGB; float blendedA; tcu::Vector signedValue; //!< integer targets tcu::Vector unsignedValue; //!< unsigned integer targets }; // These functions operate on the values in m_sampleRegister and, in some cases, the buffers. void executeScissorTest(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const WindowRectangle &scissorRect); void executeStencilCompare(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const StencilState &stencilState, int numStencilBits, const tcu::ConstPixelBufferAccess &stencilBuffer); void executeStencilSFail(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const StencilState &stencilState, int numStencilBits, const tcu::PixelBufferAccess &stencilBuffer); void executeDepthBoundsTest(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const float minDepthBound, const float maxDepthBound, const tcu::ConstPixelBufferAccess &depthBuffer); void executeDepthCompare(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, TestFunc depthFunc, const tcu::ConstPixelBufferAccess &depthBuffer); void executeDepthWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const tcu::PixelBufferAccess &depthBuffer); void executeStencilDpFailAndPass(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const StencilState &stencilState, int numStencilBits, const tcu::PixelBufferAccess &stencilBuffer); void executeBlendFactorComputeRGB(const tcu::Vec4 &blendColor, const BlendState &blendRGBState); void executeBlendFactorComputeA(const tcu::Vec4 &blendColor, const BlendState &blendAState); void executeBlend(const BlendState &blendRGBState, const BlendState &blendAState); void executeAdvancedBlend(BlendEquationAdvanced equation); void executeColorWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, bool isSRGB, const tcu::PixelBufferAccess &colorBuffer); void executeRGBA8ColorWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const tcu::PixelBufferAccess &colorBuffer); void executeMaskedColorWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const tcu::Vec4 &colorMaskFactor, const tcu::Vec4 &colorMaskNegationFactor, bool isSRGB, const tcu::PixelBufferAccess &colorBuffer); void executeSignedValueWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const tcu::BVec4 &colorMask, const tcu::PixelBufferAccess &colorBuffer); void executeUnsignedValueWrite(int fragNdxOffset, int numSamplesPerFragment, const Fragment *inputFragments, const tcu::BVec4 &colorMask, const tcu::PixelBufferAccess &colorBuffer); SampleData m_sampleRegister[SAMPLE_REGISTER_SIZE]; } DE_WARN_UNUSED_TYPE; } // namespace rr #endif // _RRFRAGMENTOPERATIONS_HPP