blob: a51018e9dc5fa26c71b4acbf7bae1bc1ad91aca9 [file] [log] [blame]
#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;
deUint32 coverage;
const float* sampleDepths;
Fragment (const tcu::IVec2& pixelCoord_, const GenericVec4& value_, deUint32 coverage_, const float* sampleDepths_)
: pixelCoord (pixelCoord_)
, value (value_)
, value1 ()
, coverage (coverage_)
, sampleDepths (sampleDepths_)
{
}
Fragment (const tcu::IVec2& pixelCoord_, const GenericVec4& value_, const GenericVec4& value1_, deUint32 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<deInt32, 4> signedValue; //!< integer targets
tcu::Vector<deUint32, 4> 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;
} // rr
#endif // _RRFRAGMENTOPERATIONS_HPP