xref: /aosp_15_r20/external/deqp/framework/referencerenderer/rrRasterizer.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _RRRASTERIZER_HPP
2 #define _RRRASTERIZER_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Reference Renderer
5  * -----------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Reference rasterizer
24  *//*--------------------------------------------------------------------*/
25 
26 #include "rrDefs.hpp"
27 #include "tcuVector.hpp"
28 #include "rrRenderState.hpp"
29 #include "rrFragmentPacket.hpp"
30 
31 namespace rr
32 {
33 
34 //! Rasterizer configuration
35 enum
36 {
37     RASTERIZER_MAX_SAMPLES_PER_FRAGMENT = 16
38 };
39 
40 //! Get coverage bit value.
getCoverageBit(int numSamples,int x,int y,int sampleNdx)41 inline uint64_t getCoverageBit(int numSamples, int x, int y, int sampleNdx)
42 {
43     const int numBits    = (int)sizeof(uint64_t) * 8;
44     const int maxSamples = numBits / 4;
45     DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
46     DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
47     return 1ull << ((x * 2 + y) * numSamples + sampleNdx);
48 }
49 
50 //! Get all sample bits for fragment
getCoverageFragmentSampleBits(int numSamples,int x,int y)51 inline uint64_t getCoverageFragmentSampleBits(int numSamples, int x, int y)
52 {
53     DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
54     const uint64_t fragMask = (1ull << numSamples) - 1;
55     return fragMask << (x * 2 + y) * numSamples;
56 }
57 
58 //! Set bit in coverage mask.
setCoverageValue(uint64_t mask,int numSamples,int x,int y,int sampleNdx,bool val)59 inline uint64_t setCoverageValue(uint64_t mask, int numSamples, int x, int y, int sampleNdx, bool val)
60 {
61     const uint64_t bit = getCoverageBit(numSamples, x, y, sampleNdx);
62     return val ? (mask | bit) : (mask & ~bit);
63 }
64 
65 //! Get coverage bit value in mask.
getCoverageValue(uint64_t mask,int numSamples,int x,int y,int sampleNdx)66 inline bool getCoverageValue(uint64_t mask, int numSamples, int x, int y, int sampleNdx)
67 {
68     return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
69 }
70 
71 //! Test if any sample for fragment is live
getCoverageAnyFragmentSampleLive(uint64_t mask,int numSamples,int x,int y)72 inline bool getCoverageAnyFragmentSampleLive(uint64_t mask, int numSamples, int x, int y)
73 {
74     return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
75 }
76 
77 //! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
getCoverageOffset(int numSamples,int x,int y)78 inline int getCoverageOffset(int numSamples, int x, int y)
79 {
80     return (x * 2 + y) * numSamples;
81 }
82 
83 /*--------------------------------------------------------------------*//*!
84  * \brief Edge function
85  *
86  * Edge function can be evaluated for point P (in fixed-point coordinates
87  * with SUBPIXEL_BITS fractional part) by computing
88  *  D = a*Px + b*Py + c
89  *
90  * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
91  * be fractional part.
92  *
93  * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
94  * with SUBPIXEL_BITS*2 fractional bits.
95  *//*--------------------------------------------------------------------*/
96 struct EdgeFunction
97 {
EdgeFunctionrr::EdgeFunction98     inline EdgeFunction(void) : a(0), b(0), c(0), inclusive(false)
99     {
100     }
101 
102     int64_t a;
103     int64_t b;
104     int64_t c;
105     bool inclusive; //!< True if edge is inclusive according to fill rules.
106 };
107 
108 /*--------------------------------------------------------------------*//*!
109  * \brief Triangle rasterizer
110  *
111  * Triangle rasterizer implements following features:
112  *  - Rasterization using fixed-point coordinates
113  *  - 1, 4, and 16 -sample rasterization
114  *  - Depth interpolation
115  *  - Perspective-correct barycentric computation for interpolation
116  *  - Visible face determination
117  *
118  * It does not (and will not) implement following:
119  *  - Triangle setup
120  *  - Clipping
121  *  - Degenerate elimination
122  *  - Coordinate transformation (inputs are in screen-space)
123  *  - Culling - logic can be implemented outside by querying visible face
124  *  - Scissoring (this can be done by controlling viewport rectangle)
125  *  - Any per-fragment operations
126  *//*--------------------------------------------------------------------*/
127 class TriangleRasterizer
128 {
129 public:
130     TriangleRasterizer(const tcu::IVec4 &viewport, const int numSamples, const RasterizationState &state,
131                        const int suppixelBits);
132 
133     void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, const tcu::Vec4 &v2);
134 
135     // Following functions are only available after init()
getVisibleFace(void) const136     FaceType getVisibleFace(void) const
137     {
138         return m_face;
139     }
140     void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
141                    int &numPacketsRasterized);
142 
143 private:
144     void rasterizeSingleSample(FragmentPacket *const fragmentPackets, float *const depthValues,
145                                const int maxFragmentPackets, int &numPacketsRasterized);
146 
147     template <int NumSamples>
148     void rasterizeMultiSample(FragmentPacket *const fragmentPackets, float *const depthValues,
149                               const int maxFragmentPackets, int &numPacketsRasterized);
150 
151     // Constant rasterization state.
152     const tcu::IVec4 m_viewport;
153     const int m_numSamples;
154     const Winding m_winding;
155     const HorizontalFill m_horizontalFill;
156     const VerticalFill m_verticalFill;
157     const int m_subpixelBits;
158 
159     // Per-triangle rasterization state.
160     tcu::Vec4 m_v0;
161     tcu::Vec4 m_v1;
162     tcu::Vec4 m_v2;
163     EdgeFunction m_edge01;
164     EdgeFunction m_edge12;
165     EdgeFunction m_edge20;
166     FaceType m_face;                           //!< Triangle orientation, eg. visible face.
167     tcu::IVec2 m_bboxMin;                      //!< Bounding box min (inclusive).
168     tcu::IVec2 m_bboxMax;                      //!< Bounding box max (inclusive).
169     tcu::IVec2 m_curPos;                       //!< Current rasterization position.
170     ViewportOrientation m_viewportOrientation; //!< Direction of +x+y axis
171 } DE_WARN_UNUSED_TYPE;
172 
173 /*--------------------------------------------------------------------*//*!
174  * \brief Single sample line rasterizer
175  *
176  * Line rasterizer implements following features:
177  *  - Rasterization using fixed-point coordinates
178  *  - Depth interpolation
179  *  - Perspective-correct interpolation
180  *
181  * It does not (and will not) implement following:
182  *  - Clipping
183  *  - Multisampled line rasterization
184  *//*--------------------------------------------------------------------*/
185 class SingleSampleLineRasterizer
186 {
187 public:
188     SingleSampleLineRasterizer(const tcu::IVec4 &viewport, const int subpixelBits);
189     ~SingleSampleLineRasterizer(void);
190 
191     void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, float lineWidth, uint32_t stippleFactor,
192               uint16_t stipplePattern);
193 
194     // only available after init()
195     void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
196                    int &numPacketsRasterized);
197 
resetStipple()198     void resetStipple()
199     {
200         m_stippleCounter = 0;
201     }
202 
203 private:
204     SingleSampleLineRasterizer(const SingleSampleLineRasterizer &);            // not allowed
205     SingleSampleLineRasterizer &operator=(const SingleSampleLineRasterizer &); // not allowed
206 
207     // Constant rasterization state.
208     const tcu::IVec4 m_viewport;
209     const int m_subpixelBits;
210 
211     // Per-line rasterization state.
212     tcu::Vec4 m_v0;
213     tcu::Vec4 m_v1;
214     tcu::IVec2 m_bboxMin;     //!< Bounding box min (inclusive).
215     tcu::IVec2 m_bboxMax;     //!< Bounding box max (inclusive).
216     tcu::IVec2 m_curPos;      //!< Current rasterization position.
217     int32_t m_curRowFragment; //!< Current rasterization position of one fragment in column of lineWidth fragments
218     float m_lineWidth;
219     uint32_t m_stippleFactor;
220     uint16_t m_stipplePattern;
221     uint32_t m_stippleCounter;
222 } DE_WARN_UNUSED_TYPE;
223 
224 /*--------------------------------------------------------------------*//*!
225  * \brief Multisampled line rasterizer
226  *
227  * Line rasterizer implements following features:
228  *  - Rasterization using fixed-point coordinates
229  *  - Depth interpolation
230  *  - Perspective-correct interpolation
231  *
232  * It does not (and will not) implement following:
233  *  - Clipping
234  *  - Aliased line rasterization
235  *//*--------------------------------------------------------------------*/
236 class MultiSampleLineRasterizer
237 {
238 public:
239     MultiSampleLineRasterizer(const int numSamples, const tcu::IVec4 &viewport, const int subpixelBits);
240     ~MultiSampleLineRasterizer();
241 
242     void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, float lineWidth);
243 
244     // only available after init()
245     void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
246                    int &numPacketsRasterized);
247 
248 private:
249     MultiSampleLineRasterizer(const MultiSampleLineRasterizer &);            // not allowed
250     MultiSampleLineRasterizer &operator=(const MultiSampleLineRasterizer &); // not allowed
251 
252     // Constant rasterization state.
253     const int m_numSamples;
254 
255     // Per-line rasterization state.
256     TriangleRasterizer
257         m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
258     TriangleRasterizer m_triangleRasterizer1;
259 } DE_WARN_UNUSED_TYPE;
260 
261 /*--------------------------------------------------------------------*//*!
262  * \brief Pixel diamond
263  *
264  * Structure representing a diamond a line exits.
265  *//*--------------------------------------------------------------------*/
266 struct LineExitDiamond
267 {
268     tcu::IVec2 position;
269 };
270 
271 /*--------------------------------------------------------------------*//*!
272  * \brief Line exit diamond generator
273  *
274  * For a given line, generates list of diamonds the line exits using the
275  * line-exit rules of the line rasterization. Does not do scissoring.
276  *
277  * \note Not used by rr, but provided to prevent test cases requiring
278  *       accurate diamonds from abusing SingleSampleLineRasterizer.
279  *//*--------------------------------------------------------------------*/
280 class LineExitDiamondGenerator
281 {
282 public:
283     LineExitDiamondGenerator(const int subpixelBits);
284     ~LineExitDiamondGenerator(void);
285 
286     void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1);
287 
288     // only available after init()
289     void rasterize(LineExitDiamond *const lineDiamonds, const int maxDiamonds, int &numWritten);
290 
291 private:
292     LineExitDiamondGenerator(const LineExitDiamondGenerator &);            // not allowed
293     LineExitDiamondGenerator &operator=(const LineExitDiamondGenerator &); // not allowed
294 
295     const int m_subpixelBits;
296 
297     // Per-line rasterization state.
298     tcu::Vec4 m_v0;
299     tcu::Vec4 m_v1;
300     tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
301     tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
302     tcu::IVec2 m_curPos;  //!< Current rasterization position.
303 };
304 
305 } // namespace rr
306 
307 #endif // _RRRASTERIZER_HPP
308