1 #ifndef _SGLRSHADERPROGRAM_HPP 2 #define _SGLRSHADERPROGRAM_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program OpenGL ES Utilities 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 SGLR shader program. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 #include "rrShaders.hpp" 28 #include "gluShaderUtil.hpp" 29 30 #include <vector> 31 #include <string> 32 33 namespace sglr 34 { 35 36 namespace rc 37 { 38 class Texture1D; 39 class Texture2D; 40 class TextureCube; 41 class Texture2DArray; 42 class Texture3D; 43 class TextureCubeArray; 44 } // rc 45 46 class ShaderProgram; 47 48 namespace pdec 49 { 50 51 enum VaryingFlags 52 { 53 VARYINGFLAG_NONE = 0, 54 VARYINGFLAG_FLATSHADE = (1 << 0), 55 }; 56 57 struct VertexAttribute 58 { VertexAttributesglr::pdec::VertexAttribute59 VertexAttribute (const std::string& name_, rr::GenericVecType type_) : name(name_), type(type_) { } 60 61 std::string name; 62 rr::GenericVecType type; 63 }; 64 65 struct VertexToFragmentVarying 66 { VertexToFragmentVaryingsglr::pdec::VertexToFragmentVarying67 VertexToFragmentVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } 68 69 rr::GenericVecType type; 70 bool flatshade; 71 }; 72 73 struct VertexToGeometryVarying 74 { VertexToGeometryVaryingsglr::pdec::VertexToGeometryVarying75 VertexToGeometryVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } 76 77 rr::GenericVecType type; 78 bool flatshade; 79 }; 80 81 struct GeometryToFragmentVarying 82 { GeometryToFragmentVaryingsglr::pdec::GeometryToFragmentVarying83 GeometryToFragmentVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } 84 85 rr::GenericVecType type; 86 bool flatshade; 87 }; 88 89 struct FragmentOutput 90 { FragmentOutputsglr::pdec::FragmentOutput91 FragmentOutput (rr::GenericVecType type_) : type(type_) { } 92 93 rr::GenericVecType type; 94 }; 95 96 struct Uniform 97 { Uniformsglr::pdec::Uniform98 Uniform (const std::string& name_, glu::DataType type_) : name(name_), type(type_) { } 99 100 std::string name; 101 glu::DataType type; 102 }; 103 104 struct VertexSource 105 { VertexSourcesglr::pdec::VertexSource106 VertexSource (const std::string& str) : source(str) { } 107 108 std::string source; 109 }; 110 111 struct FragmentSource 112 { FragmentSourcesglr::pdec::FragmentSource113 FragmentSource (const std::string& str) : source(str) { } 114 115 std::string source; 116 }; 117 118 struct GeometrySource 119 { GeometrySourcesglr::pdec::GeometrySource120 GeometrySource (const std::string& str) : source(str) { } 121 122 std::string source; 123 }; 124 125 struct GeometryShaderDeclaration 126 { GeometryShaderDeclarationsglr::pdec::GeometryShaderDeclaration127 GeometryShaderDeclaration (rr::GeometryShaderInputType inputType_, 128 rr::GeometryShaderOutputType outputType_, 129 size_t numOutputVertices_, 130 size_t numInvocations_ = 1) 131 : inputType (inputType_) 132 , outputType (outputType_) 133 , numOutputVertices (numOutputVertices_) 134 , numInvocations (numInvocations_) 135 { 136 } 137 138 rr::GeometryShaderInputType inputType; 139 rr::GeometryShaderOutputType outputType; 140 size_t numOutputVertices; 141 size_t numInvocations; 142 }; 143 144 class ShaderProgramDeclaration 145 { 146 public: 147 ShaderProgramDeclaration (void); 148 149 ShaderProgramDeclaration& operator<< (const VertexAttribute&); 150 ShaderProgramDeclaration& operator<< (const VertexToFragmentVarying&); 151 ShaderProgramDeclaration& operator<< (const VertexToGeometryVarying&); 152 ShaderProgramDeclaration& operator<< (const GeometryToFragmentVarying&); 153 ShaderProgramDeclaration& operator<< (const FragmentOutput&); 154 ShaderProgramDeclaration& operator<< (const Uniform&); 155 ShaderProgramDeclaration& operator<< (const VertexSource&); 156 ShaderProgramDeclaration& operator<< (const FragmentSource&); 157 ShaderProgramDeclaration& operator<< (const GeometrySource&); 158 ShaderProgramDeclaration& operator<< (const GeometryShaderDeclaration&); 159 160 private: hasGeometryShader(void) const161 inline bool hasGeometryShader (void) const { return m_geometryShaderSet; } getVertexInputCount(void) const162 inline size_t getVertexInputCount (void) const { return m_vertexAttributes.size(); } getVertexOutputCount(void) const163 inline size_t getVertexOutputCount (void) const { return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : m_vertexToFragmentVaryings.size(); } getFragmentInputCount(void) const164 inline size_t getFragmentInputCount (void) const { return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : m_vertexToFragmentVaryings.size(); } getFragmentOutputCount(void) const165 inline size_t getFragmentOutputCount (void) const { return m_fragmentOutputs.size(); } getGeometryInputCount(void) const166 inline size_t getGeometryInputCount (void) const { return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : 0; } getGeometryOutputCount(void) const167 inline size_t getGeometryOutputCount (void) const { return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : 0; } 168 169 bool valid (void) const; 170 171 std::vector<VertexAttribute> m_vertexAttributes; 172 std::vector<VertexToFragmentVarying> m_vertexToFragmentVaryings; 173 std::vector<VertexToGeometryVarying> m_vertexToGeometryVaryings; 174 std::vector<GeometryToFragmentVarying> m_geometryToFragmentVaryings; 175 std::vector<FragmentOutput> m_fragmentOutputs; 176 std::vector<Uniform> m_uniforms; 177 std::string m_vertexSource; 178 std::string m_fragmentSource; 179 std::string m_geometrySource; 180 GeometryShaderDeclaration m_geometryDecl; 181 182 bool m_vertexShaderSet; 183 bool m_fragmentShaderSet; 184 bool m_geometryShaderSet; 185 186 friend class ::sglr::ShaderProgram; 187 }; 188 189 } // pdec 190 191 struct UniformSlot 192 { 193 std::string name; 194 glu::DataType type; 195 196 union 197 { 198 deInt32 i; 199 deInt32 i4[4]; 200 float f; 201 float f4[4]; 202 float m3[3*3]; //!< row major, can be fed directly to tcu::Matrix constructor 203 float m4[4*4]; //!< row major, can be fed directly to tcu::Matrix constructor 204 } value; 205 206 union 207 { 208 const void* ptr; 209 210 const rc::Texture1D* tex1D; 211 const rc::Texture2D* tex2D; 212 const rc::TextureCube* texCube; 213 const rc::Texture2DArray* tex2DArray; 214 const rc::Texture3D* tex3D; 215 const rc::TextureCubeArray* texCubeArray; 216 } sampler; 217 UniformSlotsglr::UniformSlot218 inline UniformSlot (void) 219 : type(glu::TYPE_LAST) 220 { 221 value.i = 0; 222 sampler.ptr = DE_NULL; 223 } 224 }; 225 226 class ShaderProgram : private rr::VertexShader, private rr::GeometryShader, private rr::FragmentShader 227 { 228 public: 229 ShaderProgram (const pdec::ShaderProgramDeclaration&); 230 virtual ~ShaderProgram (void); 231 232 const UniformSlot& getUniformByName (const char* name) const; 233 getVertexShader(void) const234 inline const rr::VertexShader* getVertexShader (void) const { return static_cast<const rr::VertexShader*>(this); } getFragmentShader(void) const235 inline const rr::FragmentShader* getFragmentShader (void) const { return static_cast<const rr::FragmentShader*>(this); } getGeometryShader(void) const236 inline const rr::GeometryShader* getGeometryShader (void) const { return static_cast<const rr::GeometryShader*>(this); } 237 238 private: 239 virtual void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const = 0; 240 virtual void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const = 0; 241 virtual void shadePrimitives (rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const; 242 243 std::vector<std::string> m_attributeNames; 244 protected: 245 std::vector<UniformSlot> m_uniforms; 246 247 private: 248 const std::string m_vertSrc; 249 const std::string m_fragSrc; 250 const std::string m_geomSrc; 251 const bool m_hasGeometryShader; 252 253 friend class ReferenceContext; // for uniform access 254 friend class GLContext; // for source string access 255 } DE_WARN_UNUSED_TYPE; 256 257 } // sglr 258 259 #endif // _SGLRSHADERPROGRAM_HPP 260