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 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 39 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexAttribute& v) 40 { 41 m_vertexAttributes.push_back(v); 42 return *this; 43 } 44 45 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToFragmentVarying& v) 46 { 47 m_vertexToFragmentVaryings.push_back(v); 48 return *this; 49 } 50 51 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const VertexToGeometryVarying& v) 52 { 53 m_vertexToGeometryVaryings.push_back(v); 54 return *this; 55 } 56 57 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryToFragmentVarying& v) 58 { 59 m_geometryToFragmentVaryings.push_back(v); 60 return *this; 61 } 62 63 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const FragmentOutput& v) 64 { 65 m_fragmentOutputs.push_back(v); 66 return *this; 67 } 68 69 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const Uniform& v) 70 { 71 m_uniforms.push_back(v); 72 return *this; 73 } 74 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 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 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 99 ShaderProgramDeclaration& pdec::ShaderProgramDeclaration::operator<< (const GeometryShaderDeclaration& c) 100 { 101 m_geometryDecl = c; 102 return *this; 103 } 104 105 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 || 123 m_geometryDecl.numOutputVertices != 0 || 124 m_geometryDecl.numInvocations != 0) 125 return false; 126 } 127 128 return true; 129 } 130 131 } //pdec 132 133 ShaderProgram::ShaderProgram (const pdec::ShaderProgramDeclaration& decl) 134 : rr::VertexShader (decl.getVertexInputCount(), decl.getVertexOutputCount()) 135 , rr::GeometryShader (decl.getGeometryInputCount(), 136 decl.getGeometryOutputCount(), 137 decl.m_geometryDecl.inputType, 138 decl.m_geometryDecl.outputType, 139 decl.m_geometryDecl.numOutputVertices, 140 decl.m_geometryDecl.numInvocations) 141 , rr::FragmentShader (decl.getFragmentInputCount(), decl.getFragmentOutputCount()) 142 , m_attributeNames (decl.getVertexInputCount()) 143 , m_uniforms (decl.m_uniforms.size()) 144 , m_vertSrc (decl.m_vertexSource) 145 , m_fragSrc (decl.m_fragmentSource) 146 , m_geomSrc (decl.hasGeometryShader() ? (decl.m_geometrySource) : ("")) 147 , m_hasGeometryShader (decl.hasGeometryShader()) 148 { 149 DE_ASSERT(decl.valid()); 150 151 // Set up shader IO 152 153 for (size_t ndx = 0; ndx < decl.m_vertexAttributes.size(); ++ndx) 154 { 155 this->rr::VertexShader::m_inputs[ndx].type = decl.m_vertexAttributes[ndx].type; 156 m_attributeNames[ndx] = decl.m_vertexAttributes[ndx].name; 157 } 158 159 if (m_hasGeometryShader) 160 { 161 for (size_t ndx = 0; ndx < decl.m_vertexToGeometryVaryings.size(); ++ndx) 162 { 163 this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToGeometryVaryings[ndx].type; 164 this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToGeometryVaryings[ndx].flatshade; 165 166 this->rr::GeometryShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; 167 } 168 for (size_t ndx = 0; ndx < decl.m_geometryToFragmentVaryings.size(); ++ndx) 169 { 170 this->rr::GeometryShader::m_outputs[ndx].type = decl.m_geometryToFragmentVaryings[ndx].type; 171 this->rr::GeometryShader::m_outputs[ndx].flatshade = decl.m_geometryToFragmentVaryings[ndx].flatshade; 172 173 this->rr::FragmentShader::m_inputs[ndx] = this->rr::GeometryShader::m_outputs[ndx]; 174 } 175 } 176 else 177 { 178 for (size_t ndx = 0; ndx < decl.m_vertexToFragmentVaryings.size(); ++ndx) 179 { 180 this->rr::VertexShader::m_outputs[ndx].type = decl.m_vertexToFragmentVaryings[ndx].type; 181 this->rr::VertexShader::m_outputs[ndx].flatshade = decl.m_vertexToFragmentVaryings[ndx].flatshade; 182 183 this->rr::FragmentShader::m_inputs[ndx] = this->rr::VertexShader::m_outputs[ndx]; 184 } 185 } 186 187 for (size_t ndx = 0; ndx < decl.m_fragmentOutputs.size(); ++ndx) 188 this->rr::FragmentShader::m_outputs[ndx].type = decl.m_fragmentOutputs[ndx].type; 189 190 // Set up uniforms 191 192 for (size_t ndx = 0; ndx < decl.m_uniforms.size(); ++ndx) 193 { 194 this->m_uniforms[ndx].name = decl.m_uniforms[ndx].name; 195 this->m_uniforms[ndx].type = decl.m_uniforms[ndx].type; 196 } 197 } 198 199 ShaderProgram::~ShaderProgram (void) 200 { 201 } 202 203 const UniformSlot& ShaderProgram::getUniformByName (const char* name) const 204 { 205 DE_ASSERT(name); 206 207 for (size_t ndx = 0; ndx < m_uniforms.size(); ++ndx) 208 if (m_uniforms[ndx].name == std::string(name)) 209 return m_uniforms[ndx]; 210 211 DE_ASSERT(!"Invalid uniform name, uniform not found."); 212 return m_uniforms[0]; 213 } 214 215 void ShaderProgram::shadePrimitives (rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const 216 { 217 DE_UNREF(output); 218 DE_UNREF(verticesIn && packets && numPackets && invocationID); 219 220 // Should never be called. 221 DE_ASSERT(DE_FALSE); 222 } 223 224 } // sglr 225