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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#ifndef _RRRASTERIZER_HPP
#define _RRRASTERIZER_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 rasterizer
 *//*--------------------------------------------------------------------*/
 
#include "rrDefs.hpp"
#include "tcuVector.hpp"
#include "rrRenderState.hpp"
#include "rrFragmentPacket.hpp"
 
 
namespace rr
{
 
//! Rasterizer configuration
enum
{
   RASTERIZER_SUBPIXEL_BITS            = 8,
   RASTERIZER_MAX_SAMPLES_PER_FRAGMENT    = 16
};
 
//! Get coverage bit value.
inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx)
{
   const int    numBits        = (int)sizeof(deUint64)*8;
   const int    maxSamples    = numBits/4;
   DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
   DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
   return 1ull << ((x*2 + y)*numSamples + sampleNdx);
}
 
//! Get all sample bits for fragment
inline deUint64 getCoverageFragmentSampleBits (int numSamples, int x, int y)
{
   DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
   const deUint64 fragMask = (1ull << numSamples) - 1;
   return fragMask << (x*2 + y)*numSamples;
}
 
//! Set bit in coverage mask.
inline deUint64 setCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx, bool val)
{
   const deUint64 bit = getCoverageBit(numSamples, x, y, sampleNdx);
   return val ? (mask | bit) : (mask & ~bit);
}
 
//! Get coverage bit value in mask.
inline bool getCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx)
{
   return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
}
 
//! Test if any sample for fragment is live
inline bool getCoverageAnyFragmentSampleLive (deUint64 mask, int numSamples, int x, int y)
{
   return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
}
 
//! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
inline int getCoverageOffset (int numSamples, int x, int y)
{
   return (x*2 + y)*numSamples;
}
 
/*--------------------------------------------------------------------*//*!
 * \brief Edge function
 *
 * Edge function can be evaluated for point P (in fixed-point coordinates
 * with SUBPIXEL_BITS fractional part) by computing
 *  D = a*Px + b*Py + c
 *
 * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
 * be fractional part.
 *
 * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
 * with SUBPIXEL_BITS*2 fractional bits.
 *//*--------------------------------------------------------------------*/
struct EdgeFunction
{
   inline EdgeFunction (void) : a(0), b(0), c(0), inclusive(false) {}
 
   deInt64            a;
   deInt64            b;
   deInt64            c;
   bool            inclusive;    //!< True if edge is inclusive according to fill rules.
};
 
/*--------------------------------------------------------------------*//*!
 * \brief Triangle rasterizer
 *
 * Triangle rasterizer implements following features:
 *  - Rasterization using fixed-point coordinates
 *  - 1, 4, and 16 -sample rasterization
 *  - Depth interpolation
 *  - Perspective-correct barycentric computation for interpolation
 *  - Visible face determination
 *
 * It does not (and will not) implement following:
 *  - Triangle setup
 *  - Clipping
 *  - Degenerate elimination
 *  - Coordinate transformation (inputs are in screen-space)
 *  - Culling - logic can be implemented outside by querying visible face
 *  - Scissoring (this can be done by controlling viewport rectangle)
 *  - Any per-fragment operations
 *//*--------------------------------------------------------------------*/
class TriangleRasterizer
{
public:
                           TriangleRasterizer        (const tcu::IVec4& viewport, const int numSamples, const RasterizationState& state);
 
   void                    init                    (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2);
 
   // Following functions are only available after init()
   FaceType                getVisibleFace            (void) const { return m_face; }
   void                    rasterize                (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
 
private:
   void                    rasterizeSingleSample    (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
 
   template<int NumSamples>
   void                    rasterizeMultiSample    (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
 
   // Constant rasterization state.
   const tcu::IVec4        m_viewport;
   const int                m_numSamples;
   const Winding            m_winding;
   const HorizontalFill    m_horizontalFill;
   const VerticalFill        m_verticalFill;
 
   // Per-triangle rasterization state.
   tcu::Vec4                m_v0;
   tcu::Vec4                m_v1;
   tcu::Vec4                m_v2;
   EdgeFunction            m_edge01;
   EdgeFunction            m_edge12;
   EdgeFunction            m_edge20;
   FaceType                m_face;                    //!< Triangle orientation, eg. visible face.
   tcu::IVec2                m_bboxMin;                //!< Bounding box min (inclusive).
   tcu::IVec2                m_bboxMax;                //!< Bounding box max (inclusive).
   tcu::IVec2                m_curPos;                //!< Current rasterization position.
   ViewportOrientation        m_viewportOrientation;    //!< Direction of +x+y axis
} DE_WARN_UNUSED_TYPE;
 
 
/*--------------------------------------------------------------------*//*!
 * \brief Single sample line rasterizer
 *
 * Line rasterizer implements following features:
 *  - Rasterization using fixed-point coordinates
 *  - Depth interpolation
 *  - Perspective-correct interpolation
 *
 * It does not (and will not) implement following:
 *  - Clipping
 *  - Multisampled line rasterization
 *//*--------------------------------------------------------------------*/
class SingleSampleLineRasterizer
{
public:
                                   SingleSampleLineRasterizer    (const tcu::IVec4& viewport);
                                   ~SingleSampleLineRasterizer    (void);
 
   void                            init                        (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
 
   // only available after init()
   void                            rasterize                    (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
 
private:
                                   SingleSampleLineRasterizer    (const SingleSampleLineRasterizer&); // not allowed
   SingleSampleLineRasterizer&        operator=                    (const SingleSampleLineRasterizer&); // not allowed
 
   // Constant rasterization state.
   const tcu::IVec4                m_viewport;
 
   // Per-line rasterization state.
   tcu::Vec4                        m_v0;
   tcu::Vec4                        m_v1;
   tcu::IVec2                        m_bboxMin;            //!< Bounding box min (inclusive).
   tcu::IVec2                        m_bboxMax;            //!< Bounding box max (inclusive).
   tcu::IVec2                        m_curPos;            //!< Current rasterization position.
   deInt32                            m_curRowFragment;    //!< Current rasterization position of one fragment in column of lineWidth fragments
   float                            m_lineWidth;
} DE_WARN_UNUSED_TYPE;
 
 
/*--------------------------------------------------------------------*//*!
 * \brief Multisampled line rasterizer
 *
 * Line rasterizer implements following features:
 *  - Rasterization using fixed-point coordinates
 *  - Depth interpolation
 *  - Perspective-correct interpolation
 *
 * It does not (and will not) implement following:
 *  - Clipping
 *  - Aliased line rasterization
 *//*--------------------------------------------------------------------*/
class MultiSampleLineRasterizer
{
public:
                               MultiSampleLineRasterizer    (const int numSamples, const tcu::IVec4& viewport);
                               ~MultiSampleLineRasterizer    ();
 
   void                        init                        (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
 
   // only available after init()
   void                        rasterize                    (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
 
private:
                               MultiSampleLineRasterizer    (const MultiSampleLineRasterizer&); // not allowed
   MultiSampleLineRasterizer&    operator=                    (const MultiSampleLineRasterizer&); // not allowed
 
   // Constant rasterization state.
   const int                    m_numSamples;
 
   // Per-line rasterization state.
   TriangleRasterizer            m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
   TriangleRasterizer            m_triangleRasterizer1;
} DE_WARN_UNUSED_TYPE;
 
 
/*--------------------------------------------------------------------*//*!
 * \brief Pixel diamond
 *
 * Structure representing a diamond a line exits.
 *//*--------------------------------------------------------------------*/
struct LineExitDiamond
{
   tcu::IVec2    position;
};
 
/*--------------------------------------------------------------------*//*!
 * \brief Line exit diamond generator
 *
 * For a given line, generates list of diamonds the line exits using the
 * line-exit rules of the line rasterization. Does not do scissoring.
 *
 * \note Not used by rr, but provided to prevent test cases requiring
 *       accurate diamonds from abusing SingleSampleLineRasterizer.
 *//*--------------------------------------------------------------------*/
class LineExitDiamondGenerator
{
public:
                                   LineExitDiamondGenerator    (void);
                                   ~LineExitDiamondGenerator    (void);
 
   void                            init                        (const tcu::Vec4& v0, const tcu::Vec4& v1);
 
   // only available after init()
   void                            rasterize                    (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten);
 
private:
                                   LineExitDiamondGenerator    (const LineExitDiamondGenerator&); // not allowed
   LineExitDiamondGenerator&        operator=                    (const LineExitDiamondGenerator&); // not allowed
 
   // Per-line rasterization state.
   tcu::Vec4                        m_v0;
   tcu::Vec4                        m_v1;
   tcu::IVec2                        m_bboxMin;            //!< Bounding box min (inclusive).
   tcu::IVec2                        m_bboxMax;            //!< Bounding box max (inclusive).
   tcu::IVec2                        m_curPos;            //!< Current rasterization position.
};
 
} // rr
 
#endif // _RRRASTERIZER_HPP