tzh
2024-08-22 c7d0944258c7d0943aa7b2211498fd612971ce27
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
/****************************************************************************
* Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* @file rasterizer.h
*
* @brief Definitions for the rasterizer.
*
******************************************************************************/
#pragma once
 
#include "context.h"
#include <type_traits>
#include "conservativeRast.h"
#include "multisample.h"
 
void RasterizeLine(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t macroTile, void *pData);
void RasterizeSimplePoint(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t macroTile, void *pData);
void RasterizeTriPoint(DRAW_CONTEXT *pDC, uint32_t workerId, uint32_t macroTile, void *pData);
void InitRasterizerFunctions();
 
INLINE
__m128i fpToFixedPoint(const __m128 vIn)
{
    __m128 vFixed = _mm_mul_ps(vIn, _mm_set1_ps(FIXED_POINT_SCALE));
    return _mm_cvtps_epi32(vFixed);
}
 
enum TriEdgesStates
{
    STATE_NO_VALID_EDGES = 0,
    STATE_E0_E1_VALID,
    STATE_E0_E2_VALID,
    STATE_E1_E2_VALID,
    STATE_ALL_EDGES_VALID,
    STATE_VALID_TRI_EDGE_COUNT,
};
 
enum TriEdgesValues
{
    NO_VALID_EDGES = 0,
    E0_E1_VALID = 0x3,
    E0_E2_VALID = 0x5,
    E1_E2_VALID = 0x6,
    ALL_EDGES_VALID = 0x7,
    VALID_TRI_EDGE_COUNT,
};
 
// Selector for correct templated RasterizeTriangle function
PFN_WORK_FUNC GetRasterizerFunc(
    SWR_MULTISAMPLE_COUNT numSamples,
    bool IsCenter,
    bool IsConservative,
    SWR_INPUT_COVERAGE InputCoverage,
    uint32_t EdgeEnable,
    bool RasterizeScissorEdges);
 
//////////////////////////////////////////////////////////////////////////
/// @brief ValidTriEdges convenience typedefs used for templated function 
/// specialization supported Fixed Point precisions
typedef std::integral_constant<uint32_t, ALL_EDGES_VALID> AllEdgesValidT;
typedef std::integral_constant<uint32_t, E0_E1_VALID> E0E1ValidT;
typedef std::integral_constant<uint32_t, E0_E2_VALID> E0E2ValidT;
typedef std::integral_constant<uint32_t, E1_E2_VALID> E1E2ValidT;
typedef std::integral_constant<uint32_t, NO_VALID_EDGES> NoEdgesValidT;
 
typedef std::integral_constant<uint32_t, STATE_ALL_EDGES_VALID> StateAllEdgesValidT;
typedef std::integral_constant<uint32_t, STATE_E0_E1_VALID> StateE0E1ValidT;
typedef std::integral_constant<uint32_t, STATE_E0_E2_VALID> StateE0E2ValidT;
typedef std::integral_constant<uint32_t, STATE_E1_E2_VALID> StateE1E2ValidT;
typedef std::integral_constant<uint32_t, STATE_NO_VALID_EDGES> StateNoEdgesValidT;
 
// some specializations to convert from edge state to edge bitmask values
template <typename EdgeMask>
struct EdgeMaskVal
{
    static_assert(EdgeMask::value > STATE_ALL_EDGES_VALID, "Primary EdgeMaskVal shouldn't be instantiated");
};
 
template <>
struct EdgeMaskVal<StateAllEdgesValidT>
{
    typedef AllEdgesValidT T;
};
 
template <>
struct EdgeMaskVal<StateE0E1ValidT>
{
    typedef E0E1ValidT T;
};
 
template <>
struct EdgeMaskVal<StateE0E2ValidT>
{
    typedef E0E2ValidT T;
};
 
template <>
struct EdgeMaskVal<StateE1E2ValidT>
{
    typedef E1E2ValidT T;
};
 
template <>
struct EdgeMaskVal<StateNoEdgesValidT>
{
    typedef NoEdgesValidT T;
};
 
INLINE uint32_t EdgeValToEdgeState(uint32_t val)
{
    SWR_ASSERT(val < VALID_TRI_EDGE_COUNT, "Unexpected tri edge mask");
    static const uint32_t edgeValToEdgeState[VALID_TRI_EDGE_COUNT] = { 0, 0, 0, 1, 0, 2, 3, 4 };
    return  edgeValToEdgeState[val];
}
 
//////////////////////////////////////////////////////////////////////////
/// @struct RasterScissorEdgesT
/// @brief Primary RasterScissorEdgesT templated struct that holds compile 
/// time information about the number of edges needed to be rasterized, 
/// If either the scissor rect or conservative rast is enabled, 
/// the scissor test is enabled and the rasterizer will test
/// 3 triangle edges + 4 scissor edges for coverage.
/// @tparam RasterScissorEdgesT: number of multisamples
/// @tparam ConservativeT: is this a conservative rasterization
/// @tparam EdgeMaskT: Which edges are valid(not degenerate)
template <typename RasterScissorEdgesT, typename ConservativeT, typename EdgeMaskT>
struct RasterEdgeTraits
{
    typedef std::true_type RasterizeScissorEdgesT;
    typedef std::integral_constant<uint32_t, 7> NumEdgesT;
    //typedef std::integral_constant<uint32_t, EdgeMaskT::value> ValidEdgeMaskT;
    typedef typename EdgeMaskVal<EdgeMaskT>::T ValidEdgeMaskT;
};
 
//////////////////////////////////////////////////////////////////////////
/// @brief specialization of RasterEdgeTraits. If neither scissor rect
/// nor conservative rast is enabled, only test 3 triangle edges 
/// for coverage
template <typename EdgeMaskT>
struct RasterEdgeTraits<std::false_type, std::false_type, EdgeMaskT>
{
    typedef std::false_type RasterizeScissorEdgesT;
    typedef std::integral_constant<uint32_t, 3> NumEdgesT;
    // no need for degenerate edge masking in non-conservative case; rasterize all triangle edges
    typedef std::integral_constant<uint32_t, ALL_EDGES_VALID> ValidEdgeMaskT;
};
 
//////////////////////////////////////////////////////////////////////////
/// @struct RasterizerTraits
/// @brief templated struct that holds compile time information used 
/// during rasterization. Inherits EdgeTraits and ConservativeRastBETraits.
/// @tparam NumSamplesT: number of multisamples
/// @tparam ConservativeT: is this a conservative rasterization
/// @tparam InputCoverageT: what type of input coverage is the PS expecting?
/// (only used with conservative rasterization)
/// @tparam RasterScissorEdgesT: do we need to rasterize with a scissor?
template <typename NumSamplesT, typename CenterPatternT, typename ConservativeT, typename InputCoverageT, typename EdgeEnableT, typename RasterScissorEdgesT>
struct _RasterizerTraits : public ConservativeRastBETraits<ConservativeT, InputCoverageT>,
                                public RasterEdgeTraits<RasterScissorEdgesT, ConservativeT, EdgeEnableT>
{
    typedef MultisampleTraits<static_cast<SWR_MULTISAMPLE_COUNT>(NumSamplesT::value), CenterPatternT::value> MT;
 
    /// Fixed point precision the rasterizer is using
    typedef FixedPointTraits<Fixed_16_8> PrecisionT;
    /// Fixed point precision of the edge tests used during rasterization
    typedef FixedPointTraits<Fixed_X_16> EdgePrecisionT;
 
    // If conservative rast or MSAA center pattern is enabled, only need a single sample coverage test, with the result copied to all samples
    typedef std::integral_constant<int, ConservativeT::value ? 1 : MT::numCoverageSamples> NumCoverageSamplesT;
 
    static_assert(EdgePrecisionT::BitsT::value >=  ConservativeRastBETraits<ConservativeT, InputCoverageT>::ConservativePrecisionT::BitsT::value,
                  "Rasterizer edge fixed point precision < required conservative rast precision");
 
    /// constants used to offset between different types of raster tiles
    static const int colorRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8)) * MT::numSamples};
    static const int depthRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8)) * MT::numSamples};
    static const int stencilRasterTileStep{(KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * (FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8)) * MT::numSamples};
    static const int colorRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) * colorRasterTileStep};
    static const int depthRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM)* depthRasterTileStep};
    static const int stencilRasterTileRowStep{(KNOB_MACROTILE_X_DIM / KNOB_TILE_X_DIM) * stencilRasterTileStep};
};
 
template <uint32_t NumSamplesT, uint32_t CenterPatternT, uint32_t ConservativeT, uint32_t InputCoverageT, uint32_t EdgeEnableT, uint32_t RasterScissorEdgesT>
struct RasterizerTraits final : public _RasterizerTraits <
    std::integral_constant<uint32_t, NumSamplesT>,
    std::integral_constant<bool, CenterPatternT != 0>,
    std::integral_constant<bool, ConservativeT != 0>,
    std::integral_constant<uint32_t, InputCoverageT>,
    std::integral_constant<uint32_t, EdgeEnableT>,
    std::integral_constant<bool, RasterScissorEdgesT != 0> >
{};