void FractionInput::value( MixedNumber &amount, double &amount_offset ) const { MixedNumberRange range = valueRange(); amount = range.first; double dummy; range.toAmountAndOffset( &dummy, &amount_offset ); }
MixedNumber FractionInput::maxValue() const { return valueRange().second; }
MixedNumber FractionInput::minValue() const { return valueRange().first; }
void FractionInput::value( double &amount, double &amount_offset ) const { MixedNumberRange range = valueRange(); range.toAmountAndOffset( &amount, &amount_offset ); }
void ShaderGenerator::generate (const ShaderParameters& shaderParams, Shader& shader, const vector<ShaderInput*>& outputs) { // Global scopes VariableScope& globalVariableScope = shader.getGlobalScope(); ValueScope globalValueScope; // Init state m_state.setShader(shaderParams, shader); DE_ASSERT(m_state.getExpressionFlags() == 0); // Reserve some scalars for gl_Position & dEQP_Position ReservedScalars reservedScalars; if (shader.getType() == Shader::TYPE_VERTEX) m_state.getVariableManager().reserve(reservedScalars, 4*2); // Push global scopes m_varManager.pushVariableScope(globalVariableScope); m_varManager.pushValueScope(globalValueScope); // Init shader outputs. { for (vector<ShaderInput*>::const_iterator i = outputs.begin(); i != outputs.end(); i++) { const ShaderInput* input = *i; Variable* variable = m_state.getVariableManager().allocate(input->getVariable()->getType(), Variable::STORAGE_SHADER_OUT, input->getVariable()->getName()); m_state.getVariableManager().setValue(variable, input->getValueRange()); } if (shader.getType() == Shader::TYPE_FRAGMENT) { // gl_FragColor // \todo [2011-11-22 pyry] Multiple outputs from fragment shader! Variable* fragColorVar = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, getFragColorName(m_state)); ValueRange valueRange(fragColorVar->getType()); valueRange.getMin() = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f); valueRange.getMax() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f); fragColorVar->setLayoutLocation(0); // Bind color output to location 0 (applies to GLSL ES 3.0 onwards). m_state.getVariableManager().setValue(fragColorVar, valueRange.asAccess()); } } // Construct shader code. { Function& main = shader.getMain(); main.setReturnType(VariableType(VariableType::TYPE_VOID)); if (shaderParams.randomize) { FunctionGenerator funcGen(m_state, main); // Mandate assignment into to all shader outputs in main() const vector<Variable*>& liveVars = globalVariableScope.getLiveVariables(); for (vector<Variable*>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++) { Variable* variable = *i; if (variable->getStorage() == Variable::STORAGE_SHADER_OUT) funcGen.requireAssignment(variable); } funcGen.generate(); } else { if (shader.getType() == Shader::TYPE_VERTEX) genVertexPassthrough(m_state, shader); else { DE_ASSERT(shader.getType() == Shader::TYPE_FRAGMENT); genFragmentPassthrough(m_state, shader); } } if (shader.getType() == Shader::TYPE_VERTEX) { // Add gl_Position = dEQP_Position; m_state.getVariableManager().release(reservedScalars); Variable* glPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, "gl_Position"); Variable* qpPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_IN, "dEQP_Position"); ValueRange valueRange(glPosVariable->getType()); valueRange.getMin() = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f); valueRange.getMax() = tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f); m_state.getVariableManager().setValue(qpPosVariable, valueRange.asAccess()); // \todo [2011-05-24 pyry] No expression should be able to use gl_Position or dEQP_Position.. createAssignment(main.getBody(), glPosVariable, qpPosVariable); } } // Declare live global variables. { vector<Variable*> liveVariables; std::copy(globalVariableScope.getLiveVariables().begin(), globalVariableScope.getLiveVariables().end(), std::inserter(liveVariables, liveVariables.begin())); vector<Variable*> createDeclarationStatementVars; for (vector<Variable*>::iterator i = liveVariables.begin(); i != liveVariables.end(); i++) { Variable* variable = *i; const char* name = variable->getName(); bool declare = !deStringBeginsWith(name, "gl_"); // Do not declare built-in types. // Create input entries (store value range) if necessary vector<ShaderInput*>& inputs = shader.getInputs(); vector<ShaderInput*>& uniforms = shader.getUniforms(); switch (variable->getStorage()) { case Variable::STORAGE_SHADER_IN: { const ValueEntry* value = m_state.getVariableManager().getValue(variable); inputs.reserve(inputs.size()+1); inputs.push_back(new ShaderInput(variable, value->getValueRange())); break; } case Variable::STORAGE_UNIFORM: { const ValueEntry* value = m_state.getVariableManager().getValue(variable); uniforms.reserve(uniforms.size()+1); uniforms.push_back(new ShaderInput(variable, value->getValueRange())); break; } default: break; } if (declare) createDeclarationStatementVars.push_back(variable); else { // Just move to global scope without declaration statement. m_state.getVariableManager().declareVariable(variable); } } // All global initializers must be constant expressions, no variable allocation is allowed DE_ASSERT(m_state.getExpressionFlags() == 0); m_state.pushExpressionFlags(CONST_EXPR|NO_VAR_ALLOCATION); // Create declaration statements for (vector<Variable*>::iterator i = createDeclarationStatementVars.begin(); i != createDeclarationStatementVars.end(); i++) { shader.getGlobalStatements().reserve(shader.getGlobalStatements().size()); shader.getGlobalStatements().push_back(new DeclarationStatement(m_state, *i)); } m_state.popExpressionFlags(); } // Pop global scopes m_varManager.popVariableScope(); m_varManager.popValueScope(); // Fill undefined (unused) components in inputs with dummy values fillUndefinedShaderInputs(shader.getInputs()); fillUndefinedShaderInputs(shader.getUniforms()); // Tokenize shader and write source { TokenStream tokenStr; shader.tokenize(m_state, tokenStr); std::ostringstream str; PrettyPrinter printer(str); // Append #version if necessary. if (m_state.getProgramParameters().version == VERSION_300) str << "#version 300 es\n"; printer.append(tokenStr); shader.setSource(str.str().c_str()); } }