1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief SGLR shader program. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "sglrShaderProgram.hpp" 25 26 namespace sglr 27 { 28 namespace pdec 29 { 30 ShaderProgramDeclaration(void)31 ShaderProgramDeclaration::ShaderProgramDeclaration(void) 32 : m_geometryDecl(rr::GEOMETRYSHADERINPUTTYPE_LAST, rr::GEOMETRYSHADEROUTPUTTYPE_LAST, 0, 0) 33 , m_vertexShaderSet(false) 34 , m_fragmentShaderSet(false) 35 , m_geometryShaderSet(false) 36 { 37 } 38 operator <<(const VertexAttribute & v)39 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const VertexAttribute &v) 40 { 41 m_vertexAttributes.push_back(v); 42 return *this; 43 } 44 operator <<(const VertexToFragmentVarying & v)45 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const VertexToFragmentVarying &v) 46 { 47 m_vertexToFragmentVaryings.push_back(v); 48 return *this; 49 } 50 operator <<(const VertexToGeometryVarying & v)51 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const VertexToGeometryVarying &v) 52 { 53 m_vertexToGeometryVaryings.push_back(v); 54 return *this; 55 } 56 operator <<(const GeometryToFragmentVarying & v)57 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const GeometryToFragmentVarying &v) 58 { 59 m_geometryToFragmentVaryings.push_back(v); 60 return *this; 61 } 62 operator <<(const FragmentOutput & v)63 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const FragmentOutput &v) 64 { 65 m_fragmentOutputs.push_back(v); 66 return *this; 67 } 68 operator <<(const Uniform & v)69 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const Uniform &v) 70 { 71 m_uniforms.push_back(v); 72 return *this; 73 } 74 operator <<(const VertexSource & c)75 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const VertexSource &c) 76 { 77 DE_ASSERT(!m_vertexShaderSet); 78 m_vertexSource = c.source; 79 m_vertexShaderSet = true; 80 return *this; 81 } 82 operator <<(const FragmentSource & c)83 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const FragmentSource &c) 84 { 85 DE_ASSERT(!m_fragmentShaderSet); 86 m_fragmentSource = c.source; 87 m_fragmentShaderSet = true; 88 return *this; 89 } 90 operator <<(const GeometrySource & c)91 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const GeometrySource &c) 92 { 93 DE_ASSERT(!m_geometryShaderSet); 94 m_geometrySource = c.source; 95 m_geometryShaderSet = true; 96 return *this; 97 } 98 operator <<(const GeometryShaderDeclaration & c)99 ShaderProgramDeclaration &pdec::ShaderProgramDeclaration::operator<<(const GeometryShaderDeclaration &c) 100 { 101 m_geometryDecl = c; 102 return *this; 103 } 104 valid(void) const105 bool ShaderProgramDeclaration::valid(void) const 106 { 107 if (!m_vertexShaderSet || !m_fragmentShaderSet) 108 return false; 109 110 if (m_fragmentOutputs.empty()) 111 return false; 112 113 if (hasGeometryShader()) 114 { 115 if (m_geometryDecl.inputType == rr::GEOMETRYSHADERINPUTTYPE_LAST || 116 m_geometryDecl.outputType == rr::GEOMETRYSHADEROUTPUTTYPE_LAST) 117 return false; 118 } 119 else 120 { 121 if (m_geometryDecl.inputType != rr::GEOMETRYSHADERINPUTTYPE_LAST || 122 m_geometryDecl.outputType != rr::GEOMETRYSHADEROUTPUTTYPE_LAST || m_geometryDecl.numOutputVertices != 0 || 123 m_geometryDecl.numInvocations != 0) 124 return false; 125 } 126 127 return true; 128 } 129 130 } // namespace pdec 131 ShaderProgram(const pdec::ShaderProgramDeclaration & decl)132 ShaderProgram::ShaderProgram(const pdec::ShaderProgramDeclaration &decl) 133 : rr::VertexShader(decl.getVertexInputCount(), decl.getVertexOutputCount()) 134 , rr::GeometryShader(decl.getGeometryInputCount(), decl.getGeometryOutputCount(), decl.m_geometryDecl.inputType, 135 decl.m_geometryDecl.outputType, decl.m_geometryDecl.numOutputVertices, 136 decl.m_geometryDecl.numInvocations) 137 , rr::FragmentShader(decl.getFragmentInputCount(), decl.getFragmentOutputCount()) 138 , m_attributeNames(decl.getVertexInputCount()) 139 , m_uniforms(decl.m_uniforms.size()) 140 , m_vertSrc(decl.m_vertexSource) 141 , m_fragSrc(decl.m_fragmentSource) 142 , m_geomSrc(decl.hasGeometryShader() ? (decl.m_geometrySource) : ("")) 143 , m_hasGeometryShader(decl.hasGeometryShader()) 144 { 145 DE_ASSERT(decl.valid()); 146 147 // Set up shader IO 148 149 for (size_t ndx = 0; ndx < decl.m_vertexAttributes.size(); ++ndx) 150 { 151 this->rr::VertexShader::m_inputs[ndx].type = decl.m_vertexAttributes[ndx].type; 152 m_attributeNames[ndx] = decl.m_vertexAttributes[ndx].name; 153 } 154 155 if (m_hasGeometryShader) 156 { 157 for (size_t ndx = 0; ndx < decl.m_vertexToGeometryVaryings.size(); ++ndx) 158 { 159 this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToGeometryVaryings[ndx].type; 160 this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToGeometryVaryings[ndx].flatshade; 161 162 this->rr::GeometryShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; 163 } 164 for (size_t ndx = 0; ndx < decl.m_geometryToFragmentVaryings.size(); ++ndx) 165 { 166 this->rr::GeometryShader::m_outputs[ndx].type = decl.m_geometryToFragmentVaryings[ndx].type; 167 this->rr::GeometryShader::m_outputs[ndx].flatshade = decl.m_geometryToFragmentVaryings[ndx].flatshade; 168 169 this->rr::FragmentShader::m_inputs[ndx] = this->rr::GeometryShader::m_outputs[ndx]; 170 } 171 } 172 else 173 { 174 for (size_t ndx = 0; ndx < decl.m_vertexToFragmentVaryings.size(); ++ndx) 175 { 176 this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToFragmentVaryings[ndx].type; 177 this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToFragmentVaryings[ndx].flatshade; 178 179 this->rr::FragmentShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; 180 } 181 } 182 183 for (size_t ndx = 0; ndx < decl.m_fragmentOutputs.size(); ++ndx) 184 this->rr::FragmentShader::m_outputs[ndx].type = decl.m_fragmentOutputs[ndx].type; 185 186 // Set up uniforms 187 188 for (size_t ndx = 0; ndx < decl.m_uniforms.size(); ++ndx) 189 { 190 this->m_uniforms[ndx].name = decl.m_uniforms[ndx].name; 191 this->m_uniforms[ndx].type = decl.m_uniforms[ndx].type; 192 } 193 } 194 ~ShaderProgram(void)195 ShaderProgram::~ShaderProgram(void) 196 { 197 } 198 getUniformByName(const char * name) const199 const UniformSlot &ShaderProgram::getUniformByName(const char *name) const 200 { 201 DE_ASSERT(name); 202 203 for (size_t ndx = 0; ndx < m_uniforms.size(); ++ndx) 204 if (m_uniforms[ndx].name == std::string(name)) 205 return m_uniforms[ndx]; 206 207 DE_FATAL("Invalid uniform name, uniform not found."); 208 return m_uniforms[0]; 209 } 210 shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const211 void ShaderProgram::shadePrimitives(rr::GeometryEmitter &output, int verticesIn, const rr::PrimitivePacket *packets, 212 const int numPackets, int invocationID) const 213 { 214 DE_UNREF(output); 215 DE_UNREF(verticesIn && packets && numPackets && invocationID); 216 217 // Should never be called. 218 DE_ASSERT(false); 219 } 220 221 } // namespace sglr 222