1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Random Shader Generator
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 Program generator.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "rsgProgramGenerator.hpp"
25 #include "rsgShaderGenerator.hpp"
26 #include "rsgGeneratorState.hpp"
27 
28 using std::vector;
29 
30 namespace rsg
31 {
32 
ProgramGenerator(void)33 ProgramGenerator::ProgramGenerator (void)
34 {
35 }
36 
~ProgramGenerator(void)37 ProgramGenerator::~ProgramGenerator (void)
38 {
39 }
40 
generate(const ProgramParameters & programParams,Shader & vertexShader,Shader & fragmentShader)41 void ProgramGenerator::generate (
42 	const ProgramParameters&	programParams,
43 	Shader&						vertexShader,
44 	Shader&						fragmentShader)
45 {
46 	// Random number generator
47 	de::Random rnd(programParams.seed);
48 
49 	GeneratorState state(programParams, rnd);
50 
51 	// Fragment shader
52 	{
53 		ShaderGenerator			shaderGen(state);
54 		vector<ShaderInput*>	emptyOutputs; // \note [pyry] gl_FragColor is added in ShaderGenerator
55 		shaderGen.generate(programParams.fragmentParameters, fragmentShader, emptyOutputs);
56 	}
57 
58 	// Vertex shader
59 	{
60 		ShaderGenerator shaderGen(state);
61 
62 		// Initialize outputs from fragment shader inputs
63 		const vector<ShaderInput*>& fragmentInputs = fragmentShader.getInputs(); // \note gl_Position and dEQP_Position are handled in ShaderGenerator
64 
65 		shaderGen.generate(programParams.vertexParameters, vertexShader, fragmentInputs);
66 	}
67 
68 	// Allocate samplers \todo [pyry] Randomize allocation.
69 	{
70 		const vector<ShaderInput*>&		vertexUniforms		= vertexShader.getUniforms();
71 		const vector<ShaderInput*>&		fragmentUniforms	= fragmentShader.getUniforms();
72 		vector<ShaderInput*>			unifiedSamplers;
73 		int								curSamplerNdx	= 0;
74 
75 		// Build unified sampler list.
76 		for (vector<ShaderInput*>::const_iterator i = vertexUniforms.begin(); i != vertexUniforms.end(); i++)
77 		{
78 			if ((*i)->getVariable()->getType().isSampler())
79 				unifiedSamplers.push_back(*i);
80 		}
81 
82 		for (vector<ShaderInput*>::const_iterator i = fragmentUniforms.begin(); i != fragmentUniforms.end(); i++)
83 		{
84 			if ((*i)->getVariable()->getType().isSampler())
85 				unifiedSamplers.push_back(*i);
86 		}
87 
88 		// Assign sampler indices.
89 		for (vector<ShaderInput*>::const_iterator i = unifiedSamplers.begin(); i != unifiedSamplers.end(); i++)
90 		{
91 			ShaderInput* input = *i;
92 			if (input->getVariable()->getType().isSampler())
93 			{
94 				input->getValueRange().getMin() = curSamplerNdx;
95 				input->getValueRange().getMax() = curSamplerNdx;
96 				curSamplerNdx += 1;
97 			}
98 		}
99 	}
100 }
101 
102 } // rsg
103