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, GenericVec4* outputArraySrc1, 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 	GenericVec4* const			outputArraySrc1;	//!< Fragment output array for source 1.
45 	const int					primitiveID;		//!< Geometry shader output
46 	const int					numFragmentOutputs;	//!< Fragment output count
47 	const int					numSamples;			//!< Number of samples
48 	float*						fragmentDepths;		//!< Fragment packet depths. Pointer will be NULL if there is no depth buffer. Each sample has per-sample depth values
49 	FaceType					visibleFace;		//!< Which face (front or back) is visible
50 };
51 
52 // Write output
53 
54 template <typename T>
writeFragmentOutput(const FragmentShadingContext & context,int packetNdx,int fragNdx,int outputNdx,const T & value)55 void writeFragmentOutput (const FragmentShadingContext& context, int packetNdx, int fragNdx, int outputNdx, const T& value)
56 {
57 	DE_ASSERT(packetNdx >= 0);
58 	DE_ASSERT(fragNdx >= 0 && fragNdx < 4);
59 	DE_ASSERT(outputNdx >= 0 && outputNdx < context.numFragmentOutputs);
60 
61 	context.outputArray[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value;
62 }
63 
64 template <typename T>
writeFragmentOutputDualSource(const FragmentShadingContext & context,int packetNdx,int fragNdx,int outputNdx,const T & value,const T & value1)65 void writeFragmentOutputDualSource (const FragmentShadingContext& context, int packetNdx, int fragNdx, int outputNdx, const T& value, const T& value1)
66 {
67 	DE_ASSERT(packetNdx >= 0);
68 	DE_ASSERT(fragNdx >= 0 && fragNdx < 4);
69 	DE_ASSERT(outputNdx >= 0 && outputNdx < context.numFragmentOutputs);
70 
71 	context.outputArray[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value;
72 	context.outputArraySrc1[outputNdx + context.numFragmentOutputs*(fragNdx + packetNdx*4)] = value1;
73 }
74 
75 // Read Varying
76 
77 template <typename T>
readPointVarying(const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc,int fragNdx)78 tcu::Vector<T, 4> readPointVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
79 {
80 	DE_UNREF(fragNdx);
81 	DE_UNREF(packet);
82 
83 	return context.varyings[0][varyingLoc].get<T>();
84 }
85 
86 template <typename T>
readLineVarying(const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc,int fragNdx)87 tcu::Vector<T, 4> readLineVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
88 {
89 	return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
90 		   + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>();
91 }
92 
93 template <typename T>
readTriangleVarying(const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc,int fragNdx)94 tcu::Vector<T, 4> readTriangleVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
95 {
96 	return   packet.barycentric[0][fragNdx] * context.varyings[0][varyingLoc].get<T>()
97 		   + packet.barycentric[1][fragNdx] * context.varyings[1][varyingLoc].get<T>()
98 		   + packet.barycentric[2][fragNdx] * context.varyings[2][varyingLoc].get<T>();
99 }
100 
101 template <typename T>
readVarying(const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc,int fragNdx)102 tcu::Vector<T, 4> readVarying (const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc, int fragNdx)
103 {
104 	if (context.varyings[1] == DE_NULL)	return readPointVarying<T>		(packet, context, varyingLoc, fragNdx);
105 	if (context.varyings[2] == DE_NULL)	return readLineVarying<T>		(packet, context, varyingLoc, fragNdx);
106 										return readTriangleVarying<T>	(packet, context, varyingLoc, fragNdx);
107 }
108 
109 // Derivative
110 
111 template <typename T, int Size>
dFdxLocal(tcu::Vector<T,Size> outFragmentdFdx[4],const tcu::Vector<T,Size> func[4])112 void dFdxLocal (tcu::Vector<T, Size> outFragmentdFdx[4], const tcu::Vector<T, Size> func[4])
113 {
114 	const tcu::Vector<T, Size> dFdx[2] =
115 	{
116 		func[1] - func[0],
117 		func[3] - func[2]
118 	};
119 
120 	outFragmentdFdx[0] = dFdx[0];
121 	outFragmentdFdx[1] = dFdx[0];
122 	outFragmentdFdx[2] = dFdx[1];
123 	outFragmentdFdx[3] = dFdx[1];
124 }
125 
126 template <typename T, int Size>
dFdyLocal(tcu::Vector<T,Size> outFragmentdFdy[4],const tcu::Vector<T,Size> func[4])127 void dFdyLocal (tcu::Vector<T, Size> outFragmentdFdy[4], const tcu::Vector<T, Size> func[4])
128 {
129 	const tcu::Vector<T, Size> dFdy[2] =
130 	{
131 		func[2] - func[0],
132 		func[3] - func[1]
133 	};
134 
135 	outFragmentdFdy[0] = dFdy[0];
136 	outFragmentdFdy[1] = dFdy[1];
137 	outFragmentdFdy[2] = dFdy[0];
138 	outFragmentdFdy[3] = dFdy[1];
139 }
140 
141 template <typename T>
dFdxVarying(tcu::Vector<T,4> outFragmentdFdx[4],const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc)142 inline void dFdxVarying (tcu::Vector<T, 4> outFragmentdFdx[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
143 {
144 	const tcu::Vector<T, 4> func[4] =
145 	{
146 		readVarying<T>(packet, context, varyingLoc, 0),
147 		readVarying<T>(packet, context, varyingLoc, 1),
148 		readVarying<T>(packet, context, varyingLoc, 2),
149 		readVarying<T>(packet, context, varyingLoc, 3),
150 	};
151 
152 	dFdxLocal(outFragmentdFdx, func);
153 }
154 
155 template <typename T>
dFdyVarying(tcu::Vector<T,4> outFragmentdFdy[4],const FragmentPacket & packet,const FragmentShadingContext & context,int varyingLoc)156 inline void dFdyVarying (tcu::Vector<T, 4> outFragmentdFdy[4], const FragmentPacket& packet, const FragmentShadingContext& context, int varyingLoc)
157 {
158 	const tcu::Vector<T, 4> func[4] =
159 	{
160 		readVarying<T>(packet, context, varyingLoc, 0),
161 		readVarying<T>(packet, context, varyingLoc, 1),
162 		readVarying<T>(packet, context, varyingLoc, 2),
163 		readVarying<T>(packet, context, varyingLoc, 3),
164 	};
165 
166 	dFdyLocal(outFragmentdFdy, func);
167 }
168 
169 // Fragent depth
170 
readFragmentDepth(const FragmentShadingContext & context,int packetNdx,int fragNdx,int sampleNdx)171 inline float readFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx)
172 {
173 	// Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
174 	DE_ASSERT(context.fragmentDepths);
175 	return context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx];
176 }
177 
writeFragmentDepth(const FragmentShadingContext & context,int packetNdx,int fragNdx,int sampleNdx,float depthValue)178 inline void writeFragmentDepth (const FragmentShadingContext& context, int packetNdx, int fragNdx, int sampleNdx, float depthValue)
179 {
180 	// Reading or writing to fragment depth values while there is no depth buffer is legal but not supported by rr
181 	DE_ASSERT(context.fragmentDepths);
182 	context.fragmentDepths[(packetNdx * 4 + fragNdx) * context.numSamples + sampleNdx] = depthValue;
183 }
184 
185 } // rr
186 
187 #endif // _RRSHADINGCONTEXT_HPP
188