1 /****************************************************************************
2  * Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * @file rasterizer.h
24  *
25  * @brief Definitions for the rasterizer.
26  *
27  ******************************************************************************/
28 #pragma once
29 
30 #include "context.h"
31 #include <type_traits>
32 #include "conservativeRast.h"
33 #include "multisample.h"
34 
35 void RasterizeLine(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData);
36 void RasterizeSimplePoint(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData);
37 void RasterizeTriPoint(DRAW_CONTEXT* pDC, uint32_t workerId, uint32_t macroTile, void* pData);
38 void InitRasterizerFunctions();
39 
40 INLINE
fpToFixedPoint(const __m128 vIn)41 __m128i fpToFixedPoint(const __m128 vIn)
42 {
43     __m128 vFixed = _mm_mul_ps(vIn, _mm_set1_ps(FIXED_POINT_SCALE));
44     return _mm_cvtps_epi32(vFixed);
45 }
46 
47 enum TriEdgesStates
48 {
49     STATE_NO_VALID_EDGES = 0,
50     STATE_E0_E1_VALID,
51     STATE_E0_E2_VALID,
52     STATE_E1_E2_VALID,
53     STATE_ALL_EDGES_VALID,
54     STATE_VALID_TRI_EDGE_COUNT,
55 };
56 
57 enum TriEdgesValues
58 {
59     NO_VALID_EDGES  = 0,
60     E0_E1_VALID     = 0x3,
61     E0_E2_VALID     = 0x5,
62     E1_E2_VALID     = 0x6,
63     ALL_EDGES_VALID = 0x7,
64     VALID_TRI_EDGE_COUNT,
65 };
66 
67 // Selector for correct templated RasterizeTriangle function
68 PFN_WORK_FUNC GetRasterizerFunc(SWR_MULTISAMPLE_COUNT numSamples,
69                                 bool                  IsCenter,
70                                 bool                  IsConservative,
71                                 SWR_INPUT_COVERAGE    InputCoverage,
72                                 uint32_t              EdgeEnable,
73                                 bool                  RasterizeScissorEdges);
74 
75 //////////////////////////////////////////////////////////////////////////
76 /// @brief ValidTriEdges convenience typedefs used for templated function
77 /// specialization supported Fixed Point precisions
78 typedef std::integral_constant<uint32_t, ALL_EDGES_VALID> AllEdgesValidT;
79 typedef std::integral_constant<uint32_t, E0_E1_VALID>     E0E1ValidT;
80 typedef std::integral_constant<uint32_t, E0_E2_VALID>     E0E2ValidT;
81 typedef std::integral_constant<uint32_t, E1_E2_VALID>     E1E2ValidT;
82 typedef std::integral_constant<uint32_t, NO_VALID_EDGES>  NoEdgesValidT;
83 
84 typedef std::integral_constant<uint32_t, STATE_ALL_EDGES_VALID> StateAllEdgesValidT;
85 typedef std::integral_constant<uint32_t, STATE_E0_E1_VALID>     StateE0E1ValidT;
86 typedef std::integral_constant<uint32_t, STATE_E0_E2_VALID>     StateE0E2ValidT;
87 typedef std::integral_constant<uint32_t, STATE_E1_E2_VALID>     StateE1E2ValidT;
88 typedef std::integral_constant<uint32_t, STATE_NO_VALID_EDGES>  StateNoEdgesValidT;
89 
90 // some specializations to convert from edge state to edge bitmask values
91 template <typename EdgeMask>
92 struct EdgeMaskVal
93 {
94     static_assert(EdgeMask::value > STATE_ALL_EDGES_VALID,
95                   "Primary EdgeMaskVal shouldn't be instantiated");
96 };
97 
98 template <>
99 struct EdgeMaskVal<StateAllEdgesValidT>
100 {
101     typedef AllEdgesValidT T;
102 };
103 
104 template <>
105 struct EdgeMaskVal<StateE0E1ValidT>
106 {
107     typedef E0E1ValidT T;
108 };
109 
110 template <>
111 struct EdgeMaskVal<StateE0E2ValidT>
112 {
113     typedef E0E2ValidT T;
114 };
115 
116 template <>
117 struct EdgeMaskVal<StateE1E2ValidT>
118 {
119     typedef E1E2ValidT T;
120 };
121 
122 template <>
123 struct EdgeMaskVal<StateNoEdgesValidT>
124 {
125     typedef NoEdgesValidT T;
126 };
127 
128 INLINE uint32_t EdgeValToEdgeState(uint32_t val)
129 {
130     SWR_ASSERT(val < VALID_TRI_EDGE_COUNT, "Unexpected tri edge mask");
131     static const uint32_t edgeValToEdgeState[VALID_TRI_EDGE_COUNT] = {0, 0, 0, 1, 0, 2, 3, 4};
132     return edgeValToEdgeState[val];
133 }
134 
135 //////////////////////////////////////////////////////////////////////////
136 /// @struct RasterScissorEdgesT
137 /// @brief Primary RasterScissorEdgesT templated struct that holds compile
138 /// time information about the number of edges needed to be rasterized,
139 /// If either the scissor rect or conservative rast is enabled,
140 /// the scissor test is enabled and the rasterizer will test
141 /// 3 triangle edges + 4 scissor edges for coverage.
142 /// @tparam RasterScissorEdgesT: number of multisamples
143 /// @tparam ConservativeT: is this a conservative rasterization
144 /// @tparam EdgeMaskT: Which edges are valid(not degenerate)
145 template <typename RasterScissorEdgesT, typename ConservativeT, typename EdgeMaskT>
146 struct RasterEdgeTraits
147 {
148     typedef std::true_type                      RasterizeScissorEdgesT;
149     typedef std::integral_constant<uint32_t, 7> NumEdgesT;
150     // typedef std::integral_constant<uint32_t, EdgeMaskT::value> ValidEdgeMaskT;
151     typedef typename EdgeMaskVal<EdgeMaskT>::T ValidEdgeMaskT;
152 };
153 
154 //////////////////////////////////////////////////////////////////////////
155 /// @brief specialization of RasterEdgeTraits. If neither scissor rect
156 /// nor conservative rast is enabled, only test 3 triangle edges
157 /// for coverage
158 template <typename EdgeMaskT>
159 struct RasterEdgeTraits<std::false_type, std::false_type, EdgeMaskT>
160 {
161     typedef std::false_type                     RasterizeScissorEdgesT;
162     typedef std::integral_constant<uint32_t, 3> NumEdgesT;
163     // no need for degenerate edge masking in non-conservative case; rasterize all triangle edges
164     typedef std::integral_constant<uint32_t, ALL_EDGES_VALID> ValidEdgeMaskT;
165 };
166 
167 //////////////////////////////////////////////////////////////////////////
168 /// @struct RasterizerTraits
169 /// @brief templated struct that holds compile time information used
170 /// during rasterization. Inherits EdgeTraits and ConservativeRastBETraits.
171 /// @tparam NumSamplesT: number of multisamples
172 /// @tparam ConservativeT: is this a conservative rasterization
173 /// @tparam InputCoverageT: what type of input coverage is the PS expecting?
174 /// (only used with conservative rasterization)
175 /// @tparam RasterScissorEdgesT: do we need to rasterize with a scissor?
176 template <typename NumSamplesT,
177           typename CenterPatternT,
178           typename ConservativeT,
179           typename InputCoverageT,
180           typename EdgeEnableT,
181           typename RasterScissorEdgesT>
182 struct _RasterizerTraits : public ConservativeRastBETraits<ConservativeT, InputCoverageT>,
183                            public RasterEdgeTraits<RasterScissorEdgesT, ConservativeT, EdgeEnableT>
184 {
185     typedef MultisampleTraits<static_cast<SWR_MULTISAMPLE_COUNT>(NumSamplesT::value),
186                               CenterPatternT::value>
187         MT;
188 
189     /// Fixed point precision the rasterizer is using
190     typedef FixedPointTraits<Fixed_16_8> PrecisionT;
191     /// Fixed point precision of the edge tests used during rasterization
192     typedef FixedPointTraits<Fixed_X_16> EdgePrecisionT;
193 
194     // If conservative rast or MSAA center pattern is enabled, only need a single sample coverage
195     // test, with the result copied to all samples
196     typedef std::integral_constant<int, ConservativeT::value ? 1 : MT::numCoverageSamples>
197         NumCoverageSamplesT;
198 
199     static_assert(
200         EdgePrecisionT::BitsT::value >=
201             ConservativeRastBETraits<ConservativeT,
202                                      InputCoverageT>::ConservativePrecisionT::BitsT::value,
203         "Rasterizer edge fixed point precision < required conservative rast precision");
204 
205     /// constants used to offset between different types of raster tiles
206     static const int colorRasterTileStep{
207         (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8)) *
208         MT::numSamples};
209     static const int depthRasterTileStep{
210         (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8)) *
211         MT::numSamples};
212     static const int stencilRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM *
213                                             (FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8)) *
214                                            MT::numSamples};
215     static const int colorRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) *
216                                             colorRasterTileStep};
217     static const int depthRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) *
218                                             depthRasterTileStep};
219     static const int stencilRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) *
220                                               stencilRasterTileStep};
221 };
222 
223 template <uint32_t NumSamplesT,
224           uint32_t CenterPatternT,
225           uint32_t ConservativeT,
226           uint32_t InputCoverageT,
227           uint32_t EdgeEnableT,
228           uint32_t RasterScissorEdgesT>
229 struct RasterizerTraits final
230     : public _RasterizerTraits<std::integral_constant<uint32_t, NumSamplesT>,
231                                std::integral_constant<bool, CenterPatternT != 0>,
232                                std::integral_constant<bool, ConservativeT != 0>,
233                                std::integral_constant<uint32_t, InputCoverageT>,
234                                std::integral_constant<uint32_t, EdgeEnableT>,
235                                std::integral_constant<bool, RasterScissorEdgesT != 0>>
236 {
237 };
238