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 176