huangcm
2025-02-24 69ed55dec4b2116a19e4cca4393cbc014fce5fb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#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