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