Home | History | Annotate | Download | only in referencerenderer
      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