//---------------------------------------------------------------------------- bool FxCompiler::UpdateShader (Shader* shader, const Program& program, InputArray& inputs, OutputArray& outputs, ConstantArray& constants, SamplerArray& samplers) { int numInputs = (int)inputs.size(); if (numInputs != shader->GetNumInputs()) { ReportError("Mismatch in number of inputs.\n"); return false; } int numOutputs = (int)outputs.size(); if (numOutputs != shader->GetNumOutputs()) { ReportError("Mismatch in number of outputs.\n"); return false; } int numConstants = (int)constants.size(); if (numConstants != shader->GetNumConstants()) { ReportError("Mismatch in number of constants.\n"); return false; } int numSamplers = (int)samplers.size(); if (numSamplers != shader->GetNumSamplers()) { ReportError("Mismatch in number of samplers.\n"); return false; } std::string message; int i; for (i = 0; i < numInputs; ++i) { Input& input = inputs[i]; if (input.Name != shader->GetInputName(i)) { message = "Mismatch in input names '" + input.Name + "' and '" + shader->GetInputName(i); ReportError(message); return false; } if (input.Type != shader->GetInputType(i)) { message = "Mismatch in input types '" + msVTName[input.Type] + "' and '" + msVTName[shader->GetInputType(i)]; ReportError(message); return false; } if (input.Semantic != shader->GetInputSemantic(i)) { message = "Mismatch in input semantics '" + msVSName[input.Semantic] + "' and '" + msVSName[shader->GetInputSemantic(i)]; ReportError(message); return false; } } for (i = 0; i < numOutputs; ++i) { Output& output = outputs[i]; if (output.Name != shader->GetOutputName(i)) { message = "Mismatch in output names '" + output.Name + "' and '" + shader->GetOutputName(i); ReportError(message); return false; } if (output.Type != shader->GetOutputType(i)) { message = "Mismatch in output types '" + msVTName[output.Type] + "' and '" + msVTName[shader->GetOutputType(i)]; ReportError(message); return false; } if (output.Semantic != shader->GetOutputSemantic(i)) { message = "Mismatch in output semantics '" + msVSName[output.Semantic] + "' and '" + msVSName[shader->GetOutputSemantic(i)]; ReportError(message); return false; } } for (i = 0; i < numConstants; ++i) { Constant& constant = constants[i]; if (constant.Name != shader->GetConstantName(i)) { message = "Mismatch in constant names '" + constant.Name + "' and '" + shader->GetConstantName(i); ReportError(message); return false; } if (constant.NumRegistersUsed != shader->GetNumRegistersUsed(i)) { char number0[8], number1[8]; sprintf(number0, "%d", constant.NumRegistersUsed); sprintf(number1, "%d", shader->GetNumRegistersUsed(i)); message = "Mismatch in constant registers used '" + std::string(number0) + "' and '" + std::string(number1); ReportError(message); return false; } shader->SetBaseRegister(mActiveProfile, i, constant.BaseRegister); } for (i = 0; i < numSamplers; ++i) { Sampler& sampler = samplers[i]; if (sampler.Name != shader->GetSamplerName(i)) { message = "Mismatch in sampler names '" + sampler.Name + "' and '" + shader->GetSamplerName(i); ReportError(message); return false; } if (sampler.Type != shader->GetSamplerType(i)) { message = "Mismatch in sampler types '" + msSTName[sampler.Type] + "' and '" + msSTName[shader->GetSamplerType(i)]; ReportError(message); return false; } shader->SetTextureUnit(mActiveProfile, i, sampler.Unit); } shader->SetProgram(mActiveProfile, program.Text); return true; }
//---------------------------------------------------------------------------- bool FxCompiler::Process (const Program& program, InputArray& inputs, OutputArray& outputs, ConstantArray& constants, SamplerArray& samplers) { // Variable lines are one of the following: // var TYPE NAME : $vin.SEMANTIC : inputType : index : 1 // var TYPE NAME : $vout.SEMANTIC : outputType : index : 1 // var TYPE NAME : : c[REGISTER] : index : 1 // var TYPE NAME : : c[REGISTER], NUMREG : index : 1 // var TYPE NAME : : texunit UNITNUMBER : -1 : 1 // The last field is "used", a value of "0" or "1". However, the parser // stored in 'program' only those variables with a used value "1". The // all-capitals identifiers are needed by the Wild Magic FX system. TokenArrays::const_iterator iter = program.Variables.begin(); TokenArrays::const_iterator end = program.Variables.end(); for (/**/; iter != end; ++iter) { const TokenArray& tokens = *iter; // The token array has 10 or 11 tokens. if (tokens.size() < 10 || tokens.size() > 11) { ReportError("Invalid number of tokens", &tokens); return false; } // Get the variable type. Shader::VariableType vartype = Shader::VT_NONE; Shader::SamplerType samtype = Shader::ST_NONE; std::string::size_type begin = tokens[1].find("sampler", 0); if (begin != std::string::npos) { SamplerTypeMap::iterator iter = mSamplerTypes.find(tokens[1]); if (iter == mSamplerTypes.end()) { ReportError("Invalid sampler type", &tokens); return false; } samtype = iter->second; } else { VariableTypeMap::iterator iter = mVariableTypes.find(tokens[1]); if (iter == mVariableTypes.end()) { ReportError("Invalid variable type", &tokens); return false; } vartype = iter->second; } // Get the variable name. std::string name = tokens[2]; // Test whether the variable is a singleton or was declared as an // array. If it is an array, we need to determine how many registers // it uses. This requires processing variable lines with the same // variable index. bool varArray; begin = name.find("[", 0); if (begin != std::string::npos) { varArray = true; name = name.substr(0, begin); // strip off "[register]" } else { varArray = false; } // Get the separator before the classifier. if (tokens[3] != ":") { ReportError("Expecting separator character at index 3", &tokens); return false; } // Get the classifier. begin = tokens[4].find("$vin.", 0); if (begin != std::string::npos) { // The variable is a shader input. if (!GetInput(tokens, name, vartype, inputs)) { return false; } continue; } begin = tokens[4].find("$vout.", 0); if (begin != std::string::npos) { // The variable is a shader output. if (!GetOutput(tokens, name, vartype, outputs)) { return false; } continue; } if (tokens[4] == ":") { begin = tokens[1].find("sampler", 0); if (begin != std::string::npos) { // The variable is a shader sampler. if (!GetSampler(tokens, name, samtype, samplers)) { return false; } } else { // The variable is a shader constant. if (varArray) { if (constants.size() > 0 && name == constants.back().Name) { // This is another occurrence of the array variable. // Just increment the register count. ++constants.back().NumRegistersUsed; } else { // Create the constant with the first occurrence of // the array variable. if (!GetConstant(tokens, name, vartype, constants)) { return false; } } } else { if (!GetConstant(tokens, name, vartype, constants)) { return false; } } } continue; } ReportError("Failed to find classifier", &tokens); return false; } return true; }