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