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 30namespace rr 31{ 32 33/*--------------------------------------------------------------------*//*! 34 * \brief Fragment shading context 35 * 36 * Contains per-primitive information used in fragment shading 37 *//*--------------------------------------------------------------------*/ 38struct 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 54template <typename T> 55void 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 64template <typename T> 65void 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 77template <typename T> 78tcu::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 86template <typename T> 87tcu::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 93template <typename T> 94tcu::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 101template <typename T> 102tcu::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 111template <typename T, int Size> 112void 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 126template <typename T, int Size> 127void 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 141template <typename T> 142inline 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 155template <typename T> 156inline 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 171inline 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 178inline 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