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 } // namespace 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 } 62 63 std::string name; 64 rr::GenericVecType type; 65 }; 66 67 struct VertexToFragmentVarying 68 { VertexToFragmentVaryingsglr::pdec::VertexToFragmentVarying69 VertexToFragmentVarying(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) 70 : type(type_) 71 , flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) 72 { 73 } 74 75 rr::GenericVecType type; 76 bool flatshade; 77 }; 78 79 struct VertexToGeometryVarying 80 { VertexToGeometryVaryingsglr::pdec::VertexToGeometryVarying81 VertexToGeometryVarying(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) 82 : type(type_) 83 , flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) 84 { 85 } 86 87 rr::GenericVecType type; 88 bool flatshade; 89 }; 90 91 struct GeometryToFragmentVarying 92 { GeometryToFragmentVaryingsglr::pdec::GeometryToFragmentVarying93 GeometryToFragmentVarying(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) 94 : type(type_) 95 , flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) 96 { 97 } 98 99 rr::GenericVecType type; 100 bool flatshade; 101 }; 102 103 struct FragmentOutput 104 { FragmentOutputsglr::pdec::FragmentOutput105 FragmentOutput(rr::GenericVecType type_) : type(type_) 106 { 107 } 108 109 rr::GenericVecType type; 110 }; 111 112 struct Uniform 113 { Uniformsglr::pdec::Uniform114 Uniform(const std::string &name_, glu::DataType type_) : name(name_), type(type_) 115 { 116 } 117 118 std::string name; 119 glu::DataType type; 120 }; 121 122 struct VertexSource 123 { VertexSourcesglr::pdec::VertexSource124 VertexSource(const std::string &str) : source(str) 125 { 126 } 127 128 std::string source; 129 }; 130 131 struct FragmentSource 132 { FragmentSourcesglr::pdec::FragmentSource133 FragmentSource(const std::string &str) : source(str) 134 { 135 } 136 137 std::string source; 138 }; 139 140 struct GeometrySource 141 { GeometrySourcesglr::pdec::GeometrySource142 GeometrySource(const std::string &str) : source(str) 143 { 144 } 145 146 std::string source; 147 }; 148 149 struct GeometryShaderDeclaration 150 { GeometryShaderDeclarationsglr::pdec::GeometryShaderDeclaration151 GeometryShaderDeclaration(rr::GeometryShaderInputType inputType_, rr::GeometryShaderOutputType outputType_, 152 size_t numOutputVertices_, size_t numInvocations_ = 1) 153 : inputType(inputType_) 154 , outputType(outputType_) 155 , numOutputVertices(numOutputVertices_) 156 , numInvocations(numInvocations_) 157 { 158 } 159 160 rr::GeometryShaderInputType inputType; 161 rr::GeometryShaderOutputType outputType; 162 size_t numOutputVertices; 163 size_t numInvocations; 164 }; 165 166 class ShaderProgramDeclaration 167 { 168 public: 169 ShaderProgramDeclaration(void); 170 171 ShaderProgramDeclaration &operator<<(const VertexAttribute &); 172 ShaderProgramDeclaration &operator<<(const VertexToFragmentVarying &); 173 ShaderProgramDeclaration &operator<<(const VertexToGeometryVarying &); 174 ShaderProgramDeclaration &operator<<(const GeometryToFragmentVarying &); 175 ShaderProgramDeclaration &operator<<(const FragmentOutput &); 176 ShaderProgramDeclaration &operator<<(const Uniform &); 177 ShaderProgramDeclaration &operator<<(const VertexSource &); 178 ShaderProgramDeclaration &operator<<(const FragmentSource &); 179 ShaderProgramDeclaration &operator<<(const GeometrySource &); 180 ShaderProgramDeclaration &operator<<(const GeometryShaderDeclaration &); 181 182 private: hasGeometryShader(void) const183 inline bool hasGeometryShader(void) const 184 { 185 return m_geometryShaderSet; 186 } getVertexInputCount(void) const187 inline size_t getVertexInputCount(void) const 188 { 189 return m_vertexAttributes.size(); 190 } getVertexOutputCount(void) const191 inline size_t getVertexOutputCount(void) const 192 { 193 return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : m_vertexToFragmentVaryings.size(); 194 } getFragmentInputCount(void) const195 inline size_t getFragmentInputCount(void) const 196 { 197 return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : m_vertexToFragmentVaryings.size(); 198 } getFragmentOutputCount(void) const199 inline size_t getFragmentOutputCount(void) const 200 { 201 return m_fragmentOutputs.size(); 202 } getGeometryInputCount(void) const203 inline size_t getGeometryInputCount(void) const 204 { 205 return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : 0; 206 } getGeometryOutputCount(void) const207 inline size_t getGeometryOutputCount(void) const 208 { 209 return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : 0; 210 } 211 212 bool valid(void) const; 213 214 std::vector<VertexAttribute> m_vertexAttributes; 215 std::vector<VertexToFragmentVarying> m_vertexToFragmentVaryings; 216 std::vector<VertexToGeometryVarying> m_vertexToGeometryVaryings; 217 std::vector<GeometryToFragmentVarying> m_geometryToFragmentVaryings; 218 std::vector<FragmentOutput> m_fragmentOutputs; 219 std::vector<Uniform> m_uniforms; 220 std::string m_vertexSource; 221 std::string m_fragmentSource; 222 std::string m_geometrySource; 223 GeometryShaderDeclaration m_geometryDecl; 224 225 bool m_vertexShaderSet; 226 bool m_fragmentShaderSet; 227 bool m_geometryShaderSet; 228 229 friend class ::sglr::ShaderProgram; 230 }; 231 232 } // namespace pdec 233 234 struct UniformSlot 235 { 236 std::string name; 237 glu::DataType type; 238 239 union 240 { 241 int32_t i; 242 int32_t i4[4]; 243 float f; 244 float f4[4]; 245 float m3[3 * 3]; //!< row major, can be fed directly to tcu::Matrix constructor 246 float m4[4 * 4]; //!< row major, can be fed directly to tcu::Matrix constructor 247 } value; 248 249 union 250 { 251 const void *ptr; 252 253 const rc::Texture1D *tex1D; 254 const rc::Texture2D *tex2D; 255 const rc::TextureCube *texCube; 256 const rc::Texture2DArray *tex2DArray; 257 const rc::Texture3D *tex3D; 258 const rc::TextureCubeArray *texCubeArray; 259 } sampler; 260 UniformSlotsglr::UniformSlot261 inline UniformSlot(void) : type(glu::TYPE_LAST) 262 { 263 value.i = 0; 264 sampler.ptr = DE_NULL; 265 } 266 }; 267 268 class ShaderProgram : private rr::VertexShader, private rr::GeometryShader, private rr::FragmentShader 269 { 270 public: 271 ShaderProgram(const pdec::ShaderProgramDeclaration &); 272 virtual ~ShaderProgram(void); 273 274 const UniformSlot &getUniformByName(const char *name) const; 275 getVertexShader(void) const276 inline const rr::VertexShader *getVertexShader(void) const 277 { 278 return static_cast<const rr::VertexShader *>(this); 279 } getFragmentShader(void) const280 inline const rr::FragmentShader *getFragmentShader(void) const 281 { 282 return static_cast<const rr::FragmentShader *>(this); 283 } getGeometryShader(void) const284 inline const rr::GeometryShader *getGeometryShader(void) const 285 { 286 return static_cast<const rr::GeometryShader *>(this); 287 } 288 289 private: 290 virtual void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, 291 const int numPackets) const = 0; 292 virtual void shadeFragments(rr::FragmentPacket *packets, const int numPackets, 293 const rr::FragmentShadingContext &context) const = 0; 294 virtual void shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets, 295 const int numPackets, int invocationID) const; 296 297 std::vector<std::string> m_attributeNames; 298 299 protected: 300 std::vector<UniformSlot> m_uniforms; 301 302 private: 303 const std::string m_vertSrc; 304 const std::string m_fragSrc; 305 const std::string m_geomSrc; 306 const bool m_hasGeometryShader; 307 308 friend class ReferenceContext; // for uniform access 309 friend class GLContext; // for source string access 310 } DE_WARN_UNUSED_TYPE; 311 312 } // namespace sglr 313 314 #endif // _SGLRSHADERPROGRAM_HPP 315