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