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 ||
123 			m_geometryDecl.numOutputVertices != 0 ||
124 			m_geometryDecl.numInvocations != 0)
125 			return false;
126 	}
127 
128 	return true;
129 }
130 
131 } //pdec
132 
ShaderProgram(const pdec::ShaderProgramDeclaration & decl)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 
~ShaderProgram(void)199 ShaderProgram::~ShaderProgram (void)
200 {
201 }
202 
getUniformByName(const char * name) const203 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 
shadePrimitives(rr::GeometryEmitter & output,int verticesIn,const rr::PrimitivePacket * packets,const int numPackets,int invocationID) const215 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