ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
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
#ifndef _RRSHADINGCONTEXT_HPP
#define _RRSHADINGCONTEXT_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 Shading context
 *//*--------------------------------------------------------------------*/
 
#include "rrDefs.hpp"
#include "rrGenericVector.hpp"
#include "rrFragmentPacket.hpp"
 
namespace rr
{
 
/*--------------------------------------------------------------------*//*!
 * \brief Fragment shading context
 *
 * Contains per-primitive information used in fragment shading
 *//*--------------------------------------------------------------------*/
struct FragmentShadingContext
{
                               FragmentShadingContext (const GenericVec4* varying0, const GenericVec4* varying1, const GenericVec4* varying2, GenericVec4* outputArray, float* fragmentDepths, int primitiveID, int numFragmentOutputs, int numSamples, FaceType visibleFace_);
 
   const GenericVec4*            varyings[3];        //!< Vertex shader outputs. Pointer will be NULL if there is no such vertex.
   GenericVec4* const            outputArray;        //!< Fragment output array
   const int                    primitiveID;        //!< Geometry shader output
   const int                    numFragmentOutputs;    //!< Fragment output count
   const int                    numSamples;            //!< Number of samples
   float*                        fragmentDepths;        //!< Fragment packet depths. Pointer will be NULL if there is no depth buffer. Each sample has per-sample depth values
   FaceType                    visibleFace;        //!< Which face (front or back) is visible
};
 
// Write output
 
template <typename T>
void writeFragmentOutput (const FragmentShadingContext& context, int packetNdx, int fragNdx, int outputNdx, const T& value)
{
   DE_ASSERT(packetNdx >= 0);
   DE_ASSERT(fragNdx >= 0 && fragNdx < 4);
   DE_ASSERT(outputNdx >= 0 && outputNdx < context.numFragmentOutputs);
 
   context.outputArray[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value;
}
 
// Read Varying
 
template <typename T>
tcu::Vector<T, 4> readPointVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
   DE_UNREF(fragNdx);
   DE_UNREF(packet);
 
   return context.varyings[0][varyingLoc].get<T>();
}
 
template <typename T>
tcu::Vector<T, 4> readLineVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
   return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
          + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>();
}
 
template <typename T>
tcu::Vector<T, 4> readTriangleVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
   return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
          + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>()
          + packet.barycentric[2][fragNdx] * context.varyings[2][varyingLoc].get<T>();
}
 
template <typename T>
tcu::Vector<T, 4> readVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
{
   if (context.varyings[1] == DE_NULL)    return readPointVarying<T>        (packet, context, varyingLoc, fragNdx);
   if (context.varyings[2] == DE_NULL)    return readLineVarying<T>        (packet, context, varyingLoc, fragNdx);
                                       return readTriangleVarying<T>    (packet, context, varyingLoc, fragNdx);
}
 
// Derivative
 
template <typename T, int Size>
void dFdxLocal (tcu::Vector<T, Size> outFragmentdFdx[4], const tcu::Vector<T, Size> func[4])
{
   const tcu::Vector<T, Size> dFdx[2] =
   {
       func[1] - func[0],
       func[3] - func[2]
   };
 
   outFragmentdFdx[0] = dFdx[0];
   outFragmentdFdx[1] = dFdx[0];
   outFragmentdFdx[2] = dFdx[1];
   outFragmentdFdx[3] = dFdx[1];
}
 
template <typename T, int Size>
void dFdyLocal (tcu::Vector<T, Size> outFragmentdFdy[4], const tcu::Vector<T, Size> func[4])
{
   const tcu::Vector<T, Size> dFdy[2] =
   {
       func[2] - func[0],
       func[3] - func[1]
   };
 
   outFragmentdFdy[0] = dFdy[0];
   outFragmentdFdy[1] = dFdy[1];
   outFragmentdFdy[2] = dFdy[0];
   outFragmentdFdy[3] = dFdy[1];
}
 
template <typename T>
inline void dFdxVarying (tcu::Vector<T, 4> outFragmentdFdx[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
{
   const tcu::Vector<T, 4> func[4] =
   {
       readVarying<T>(packet, context, varyingLoc, 0),
       readVarying<T>(packet, context, varyingLoc, 1),
       readVarying<T>(packet, context, varyingLoc, 2),
       readVarying<T>(packet, context, varyingLoc, 3),
   };
 
   dFdxLocal(outFragmentdFdx, func);
}
 
template <typename T>
inline void dFdyVarying (tcu::Vector<T, 4> outFragmentdFdy[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
{
   const tcu::Vector<T, 4> func[4] =
   {
       readVarying<T>(packet, context, varyingLoc, 0),
       readVarying<T>(packet, context, varyingLoc, 1),
       readVarying<T>(packet, context, varyingLoc, 2),
       readVarying<T>(packet, context, varyingLoc, 3),
   };
 
   dFdyLocal(outFragmentdFdy, func);
}
 
// Fragent depth
 
inline float readFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx)
{
   // Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
   DE_ASSERT(context.fragmentDepths);
   return context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx];
}
 
inline void writeFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx, float depthValue)
{
   // Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
   DE_ASSERT(context.fragmentDepths);
   context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx] = depthValue;
}
 
} // rr
 
#endif // _RRSHADINGCONTEXT_HPP