#ifndef _SGLRSHADERPROGRAM_HPP #define _SGLRSHADERPROGRAM_HPP /*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES Utilities * ------------------------------------------------ * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief SGLR shader program. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "rrShaders.hpp" #include "gluShaderUtil.hpp" #include #include namespace sglr { namespace rc { class Texture1D; class Texture2D; class TextureCube; class Texture2DArray; class Texture3D; class TextureCubeArray; } // rc class ShaderProgram; namespace pdec { enum VaryingFlags { VARYINGFLAG_NONE = 0, VARYINGFLAG_FLATSHADE = (1 << 0), }; struct VertexAttribute { VertexAttribute (const std::string& name_, rr::GenericVecType type_) : name(name_), type(type_) { } std::string name; rr::GenericVecType type; }; struct VertexToFragmentVarying { VertexToFragmentVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } rr::GenericVecType type; bool flatshade; }; struct VertexToGeometryVarying { VertexToGeometryVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } rr::GenericVecType type; bool flatshade; }; struct GeometryToFragmentVarying { GeometryToFragmentVarying (rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { } rr::GenericVecType type; bool flatshade; }; struct FragmentOutput { FragmentOutput (rr::GenericVecType type_) : type(type_) { } rr::GenericVecType type; }; struct Uniform { Uniform (const std::string& name_, glu::DataType type_) : name(name_), type(type_) { } std::string name; glu::DataType type; }; struct VertexSource { VertexSource (const std::string& str) : source(str) { } std::string source; }; struct FragmentSource { FragmentSource (const std::string& str) : source(str) { } std::string source; }; struct GeometrySource { GeometrySource (const std::string& str) : source(str) { } std::string source; }; struct GeometryShaderDeclaration { GeometryShaderDeclaration (rr::GeometryShaderInputType inputType_, rr::GeometryShaderOutputType outputType_, size_t numOutputVertices_, size_t numInvocations_ = 1) : inputType (inputType_) , outputType (outputType_) , numOutputVertices (numOutputVertices_) , numInvocations (numInvocations_) { } rr::GeometryShaderInputType inputType; rr::GeometryShaderOutputType outputType; size_t numOutputVertices; size_t numInvocations; }; class ShaderProgramDeclaration { public: ShaderProgramDeclaration (void); ShaderProgramDeclaration& operator<< (const VertexAttribute&); ShaderProgramDeclaration& operator<< (const VertexToFragmentVarying&); ShaderProgramDeclaration& operator<< (const VertexToGeometryVarying&); ShaderProgramDeclaration& operator<< (const GeometryToFragmentVarying&); ShaderProgramDeclaration& operator<< (const FragmentOutput&); ShaderProgramDeclaration& operator<< (const Uniform&); ShaderProgramDeclaration& operator<< (const VertexSource&); ShaderProgramDeclaration& operator<< (const FragmentSource&); ShaderProgramDeclaration& operator<< (const GeometrySource&); ShaderProgramDeclaration& operator<< (const GeometryShaderDeclaration&); private: inline bool hasGeometryShader (void) const { return m_geometryShaderSet; } inline size_t getVertexInputCount (void) const { return m_vertexAttributes.size(); } inline size_t getVertexOutputCount (void) const { return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : m_vertexToFragmentVaryings.size(); } inline size_t getFragmentInputCount (void) const { return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : m_vertexToFragmentVaryings.size(); } inline size_t getFragmentOutputCount (void) const { return m_fragmentOutputs.size(); } inline size_t getGeometryInputCount (void) const { return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : 0; } inline size_t getGeometryOutputCount (void) const { return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : 0; } bool valid (void) const; std::vector m_vertexAttributes; std::vector m_vertexToFragmentVaryings; std::vector m_vertexToGeometryVaryings; std::vector m_geometryToFragmentVaryings; std::vector m_fragmentOutputs; std::vector m_uniforms; std::string m_vertexSource; std::string m_fragmentSource; std::string m_geometrySource; GeometryShaderDeclaration m_geometryDecl; bool m_vertexShaderSet; bool m_fragmentShaderSet; bool m_geometryShaderSet; friend class ::sglr::ShaderProgram; }; } // pdec struct UniformSlot { std::string name; glu::DataType type; union { deInt32 i; deInt32 i4[4]; float f; float f4[4]; float m3[3*3]; //!< row major, can be fed directly to tcu::Matrix constructor float m4[4*4]; //!< row major, can be fed directly to tcu::Matrix constructor } value; union { const void* ptr; const rc::Texture1D* tex1D; const rc::Texture2D* tex2D; const rc::TextureCube* texCube; const rc::Texture2DArray* tex2DArray; const rc::Texture3D* tex3D; const rc::TextureCubeArray* texCubeArray; } sampler; inline UniformSlot (void) : type(glu::TYPE_LAST) { value.i = 0; sampler.ptr = DE_NULL; } }; class ShaderProgram : private rr::VertexShader, private rr::GeometryShader, private rr::FragmentShader { public: ShaderProgram (const pdec::ShaderProgramDeclaration&); virtual ~ShaderProgram (void); const UniformSlot& getUniformByName (const char* name) const; inline const rr::VertexShader* getVertexShader (void) const { return static_cast(this); } inline const rr::FragmentShader* getFragmentShader (void) const { return static_cast(this); } inline const rr::GeometryShader* getGeometryShader (void) const { return static_cast(this); } private: virtual void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const = 0; virtual void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const = 0; virtual void shadePrimitives (rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const; std::vector m_attributeNames; protected: std::vector m_uniforms; private: const std::string m_vertSrc; const std::string m_fragSrc; const std::string m_geomSrc; const bool m_hasGeometryShader; friend class ReferenceContext; // for uniform access friend class GLContext; // for source string access } DE_WARN_UNUSED_TYPE; } // sglr #endif // _SGLRSHADERPROGRAM_HPP