Add CTS_ARB_gl_spirv test implementation
[platform/upstream/VK-GL-CTS.git] / framework / referencerenderer / rrRasterizer.hpp
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
32 namespace rr
33 {
34
35 //! Rasterizer configuration
36 enum
37 {
38         RASTERIZER_SUBPIXEL_BITS                        = 8,
39         RASTERIZER_MAX_SAMPLES_PER_FRAGMENT     = 16
40 };
41
42 //! Get coverage bit value.
43 inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx)
44 {
45         const int       numBits         = (int)sizeof(deUint64)*8;
46         const int       maxSamples      = numBits/4;
47         DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
48         DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
49         return 1ull << ((x*2 + y)*numSamples + sampleNdx);
50 }
51
52 //! Get all sample bits for fragment
53 inline deUint64 getCoverageFragmentSampleBits (int numSamples, int x, int y)
54 {
55         DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
56         const deUint64 fragMask = (1ull << numSamples) - 1;
57         return fragMask << (x*2 + y)*numSamples;
58 }
59
60 //! Set bit in coverage mask.
61 inline deUint64 setCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx, bool val)
62 {
63         const deUint64 bit = getCoverageBit(numSamples, x, y, sampleNdx);
64         return val ? (mask | bit) : (mask & ~bit);
65 }
66
67 //! Get coverage bit value in mask.
68 inline bool getCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx)
69 {
70         return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
71 }
72
73 //! Test if any sample for fragment is live
74 inline bool getCoverageAnyFragmentSampleLive (deUint64 mask, int numSamples, int x, int y)
75 {
76         return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
77 }
78
79 //! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
80 inline int getCoverageOffset (int numSamples, int x, int y)
81 {
82         return (x*2 + y)*numSamples;
83 }
84
85 /*--------------------------------------------------------------------*//*!
86  * \brief Edge function
87  *
88  * Edge function can be evaluated for point P (in fixed-point coordinates
89  * with SUBPIXEL_BITS fractional part) by computing
90  *  D = a*Px + b*Py + c
91  *
92  * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
93  * be fractional part.
94  *
95  * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
96  * with SUBPIXEL_BITS*2 fractional bits.
97  *//*--------------------------------------------------------------------*/
98 struct EdgeFunction
99 {
100         inline EdgeFunction (void) : a(0), b(0), c(0), inclusive(false) {}
101
102         deInt64                 a;
103         deInt64                 b;
104         deInt64                 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
132         void                                    init                                    (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2);
133
134         // Following functions are only available after init()
135         FaceType                                getVisibleFace                  (void) const { return m_face; }
136         void                                    rasterize                               (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
137
138 private:
139         void                                    rasterizeSingleSample   (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
140
141         template<int NumSamples>
142         void                                    rasterizeMultiSample    (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
143
144         // Constant rasterization state.
145         const tcu::IVec4                m_viewport;
146         const int                               m_numSamples;
147         const Winding                   m_winding;
148         const HorizontalFill    m_horizontalFill;
149         const VerticalFill              m_verticalFill;
150
151         // Per-triangle rasterization state.
152         tcu::Vec4                               m_v0;
153         tcu::Vec4                               m_v1;
154         tcu::Vec4                               m_v2;
155         EdgeFunction                    m_edge01;
156         EdgeFunction                    m_edge12;
157         EdgeFunction                    m_edge20;
158         FaceType                                m_face;                                 //!< Triangle orientation, eg. visible face.
159         tcu::IVec2                              m_bboxMin;                              //!< Bounding box min (inclusive).
160         tcu::IVec2                              m_bboxMax;                              //!< Bounding box max (inclusive).
161         tcu::IVec2                              m_curPos;                               //!< Current rasterization position.
162         ViewportOrientation             m_viewportOrientation;  //!< Direction of +x+y axis
163 } DE_WARN_UNUSED_TYPE;
164
165
166 /*--------------------------------------------------------------------*//*!
167  * \brief Single sample line rasterizer
168  *
169  * Line rasterizer implements following features:
170  *  - Rasterization using fixed-point coordinates
171  *  - Depth interpolation
172  *  - Perspective-correct interpolation
173  *
174  * It does not (and will not) implement following:
175  *  - Clipping
176  *  - Multisampled line rasterization
177  *//*--------------------------------------------------------------------*/
178 class SingleSampleLineRasterizer
179 {
180 public:
181                                                                         SingleSampleLineRasterizer      (const tcu::IVec4& viewport);
182                                                                         ~SingleSampleLineRasterizer     (void);
183
184         void                                                    init                                            (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
185
186         // only available after init()
187         void                                                    rasterize                                       (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
188
189 private:
190                                                                         SingleSampleLineRasterizer      (const SingleSampleLineRasterizer&); // not allowed
191         SingleSampleLineRasterizer&             operator=                                       (const SingleSampleLineRasterizer&); // not allowed
192
193         // Constant rasterization state.
194         const tcu::IVec4                                m_viewport;
195
196         // Per-line rasterization state.
197         tcu::Vec4                                               m_v0;
198         tcu::Vec4                                               m_v1;
199         tcu::IVec2                                              m_bboxMin;                      //!< Bounding box min (inclusive).
200         tcu::IVec2                                              m_bboxMax;                      //!< Bounding box max (inclusive).
201         tcu::IVec2                                              m_curPos;                       //!< Current rasterization position.
202         deInt32                                                 m_curRowFragment;       //!< Current rasterization position of one fragment in column of lineWidth fragments
203         float                                                   m_lineWidth;
204 } DE_WARN_UNUSED_TYPE;
205
206
207 /*--------------------------------------------------------------------*//*!
208  * \brief Multisampled line rasterizer
209  *
210  * Line rasterizer implements following features:
211  *  - Rasterization using fixed-point coordinates
212  *  - Depth interpolation
213  *  - Perspective-correct interpolation
214  *
215  * It does not (and will not) implement following:
216  *  - Clipping
217  *  - Aliased line rasterization
218  *//*--------------------------------------------------------------------*/
219 class MultiSampleLineRasterizer
220 {
221 public:
222                                                                 MultiSampleLineRasterizer       (const int numSamples, const tcu::IVec4& viewport);
223                                                                 ~MultiSampleLineRasterizer      ();
224
225         void                                            init                                            (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
226
227         // only available after init()
228         void                                            rasterize                                       (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
229
230 private:
231                                                                 MultiSampleLineRasterizer       (const MultiSampleLineRasterizer&); // not allowed
232         MultiSampleLineRasterizer&      operator=                                       (const MultiSampleLineRasterizer&); // not allowed
233
234         // Constant rasterization state.
235         const int                                       m_numSamples;
236
237         // Per-line rasterization state.
238         TriangleRasterizer                      m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
239         TriangleRasterizer                      m_triangleRasterizer1;
240 } DE_WARN_UNUSED_TYPE;
241
242
243 /*--------------------------------------------------------------------*//*!
244  * \brief Pixel diamond
245  *
246  * Structure representing a diamond a line exits.
247  *//*--------------------------------------------------------------------*/
248 struct LineExitDiamond
249 {
250         tcu::IVec2      position;
251 };
252
253 /*--------------------------------------------------------------------*//*!
254  * \brief Line exit diamond generator
255  *
256  * For a given line, generates list of diamonds the line exits using the
257  * line-exit rules of the line rasterization. Does not do scissoring.
258  *
259  * \note Not used by rr, but provided to prevent test cases requiring
260  *       accurate diamonds from abusing SingleSampleLineRasterizer.
261  *//*--------------------------------------------------------------------*/
262 class LineExitDiamondGenerator
263 {
264 public:
265                                                                         LineExitDiamondGenerator        (void);
266                                                                         ~LineExitDiamondGenerator       (void);
267
268         void                                                    init                                            (const tcu::Vec4& v0, const tcu::Vec4& v1);
269
270         // only available after init()
271         void                                                    rasterize                                       (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten);
272
273 private:
274                                                                         LineExitDiamondGenerator        (const LineExitDiamondGenerator&); // not allowed
275         LineExitDiamondGenerator&               operator=                                       (const LineExitDiamondGenerator&); // not allowed
276
277         // Per-line rasterization state.
278         tcu::Vec4                                               m_v0;
279         tcu::Vec4                                               m_v1;
280         tcu::IVec2                                              m_bboxMin;                      //!< Bounding box min (inclusive).
281         tcu::IVec2                                              m_bboxMax;                      //!< Bounding box max (inclusive).
282         tcu::IVec2                                              m_curPos;                       //!< Current rasterization position.
283 };
284
285 } // rr
286
287 #endif // _RRRASTERIZER_HPP