Add CTS_ARB_gl_spirv test implementation
[platform/upstream/VK-GL-CTS.git] / framework / referencerenderer / rrShadingContext.hpp
1 #ifndef _RRSHADINGCONTEXT_HPP
2 #define _RRSHADINGCONTEXT_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 Shading context
24  *//*--------------------------------------------------------------------*/
25
26 #include "rrDefs.hpp"
27 #include "rrGenericVector.hpp"
28 #include "rrFragmentPacket.hpp"
29
30 namespace rr
31 {
32
33 /*--------------------------------------------------------------------*//*!
34  * \brief Fragment shading context
35  *
36  * Contains per-primitive information used in fragment shading
37  *//*--------------------------------------------------------------------*/
38 struct FragmentShadingContext
39 {
40                                                                 FragmentShadingContext (const GenericVec4* varying0, const GenericVec4* varying1, const GenericVec4* varying2, GenericVec4* outputArray, float* fragmentDepths, int primitiveID, int numFragmentOutputs, int numSamples, FaceType visibleFace_);
41
42         const GenericVec4*                      varyings[3];            //!< Vertex shader outputs. Pointer will be NULL if there is no such vertex.
43         GenericVec4* const                      outputArray;            //!< Fragment output array
44         const int                                       primitiveID;            //!< Geometry shader output
45         const int                                       numFragmentOutputs;     //!< Fragment output count
46         const int                                       numSamples;                     //!< Number of samples
47         float*                                          fragmentDepths;         //!< Fragment packet depths. Pointer will be NULL if there is no depth buffer. Each sample has per-sample depth values
48         FaceType                                        visibleFace;            //!< Which face (front or back) is visible
49 };
50
51 // Write output
52
53 template <typename T>
54 void writeFragmentOutput (const FragmentShadingContext& context, int packetNdx, int fragNdx, int outputNdx, const T& value)
55 {
56         DE_ASSERT(packetNdx >= 0);
57         DE_ASSERT(fragNdx >= 0 && fragNdx < 4);
58         DE_ASSERT(outputNdx >= 0 && outputNdx < context.numFragmentOutputs);
59
60         context.outputArray[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value;
61 }
62
63 // Read Varying
64
65 template <typename T>
66 tcu::Vector<T, 4> readPointVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
67 {
68         DE_UNREF(fragNdx);
69         DE_UNREF(packet);
70
71         return context.varyings[0][varyingLoc].get<T>();
72 }
73
74 template <typename T>
75 tcu::Vector<T, 4> readLineVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
76 {
77         return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
78                    + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>();
79 }
80
81 template <typename T>
82 tcu::Vector<T, 4> readTriangleVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
83 {
84         return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
85                    + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>()
86                    + packet.barycentric[2][fragNdx] * context.varyings[2][varyingLoc].get<T>();
87 }
88
89 template <typename T>
90 tcu::Vector<T, 4> readVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
91 {
92         if (context.varyings[1] == DE_NULL)     return readPointVarying<T>              (packet, context, varyingLoc, fragNdx);
93         if (context.varyings[2] == DE_NULL)     return readLineVarying<T>               (packet, context, varyingLoc, fragNdx);
94                                                                                 return readTriangleVarying<T>   (packet, context, varyingLoc, fragNdx);
95 }
96
97 // Derivative
98
99 template <typename T, int Size>
100 void dFdxLocal (tcu::Vector<T, Size> outFragmentdFdx[4], const tcu::Vector<T, Size> func[4])
101 {
102         const tcu::Vector<T, Size> dFdx[2] =
103         {
104                 func[1] - func[0],
105                 func[3] - func[2]
106         };
107
108         outFragmentdFdx[0] = dFdx[0];
109         outFragmentdFdx[1] = dFdx[0];
110         outFragmentdFdx[2] = dFdx[1];
111         outFragmentdFdx[3] = dFdx[1];
112 }
113
114 template <typename T, int Size>
115 void dFdyLocal (tcu::Vector<T, Size> outFragmentdFdy[4], const tcu::Vector<T, Size> func[4])
116 {
117         const tcu::Vector<T, Size> dFdy[2] =
118         {
119                 func[2] - func[0],
120                 func[3] - func[1]
121         };
122
123         outFragmentdFdy[0] = dFdy[0];
124         outFragmentdFdy[1] = dFdy[1];
125         outFragmentdFdy[2] = dFdy[0];
126         outFragmentdFdy[3] = dFdy[1];
127 }
128
129 template <typename T>
130 inline void dFdxVarying (tcu::Vector<T, 4> outFragmentdFdx[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
131 {
132         const tcu::Vector<T, 4> func[4] =
133         {
134                 readVarying<T>(packet, context, varyingLoc, 0),
135                 readVarying<T>(packet, context, varyingLoc, 1),
136                 readVarying<T>(packet, context, varyingLoc, 2),
137                 readVarying<T>(packet, context, varyingLoc, 3),
138         };
139
140         dFdxLocal(outFragmentdFdx, func);
141 }
142
143 template <typename T>
144 inline void dFdyVarying (tcu::Vector<T, 4> outFragmentdFdy[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
145 {
146         const tcu::Vector<T, 4> func[4] =
147         {
148                 readVarying<T>(packet, context, varyingLoc, 0),
149                 readVarying<T>(packet, context, varyingLoc, 1),
150                 readVarying<T>(packet, context, varyingLoc, 2),
151                 readVarying<T>(packet, context, varyingLoc, 3),
152         };
153
154         dFdyLocal(outFragmentdFdy, func);
155 }
156
157 // Fragent depth
158
159 inline float readFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx)
160 {
161         // Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
162         DE_ASSERT(context.fragmentDepths);
163         return context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx];
164 }
165
166 inline void writeFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx, float depthValue)
167 {
168         // Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
169         DE_ASSERT(context.fragmentDepths);
170         context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx] = depthValue;
171 }
172
173 } // rr
174
175 #endif // _RRSHADINGCONTEXT_HPP