void GlslGeneratorInstance::PrintNodeInit(size_t nodeIndex) { Node* node = nodeInits[nodeIndex]; switch(node->GetType()) { case Node::typeFloatConst: PrintNodeInitBegin(nodeIndex); text << std::fixed << std::setprecision(10) << fast_cast<FloatConstNode*>(node)->GetValue();// << 'f'; PrintNodeInitEnd(); break; case Node::typeIntConst: PrintNodeInitBegin(nodeIndex); text << fast_cast<IntConstNode*>(node)->GetValue(); PrintNodeInitEnd(); break; case Node::typeAttribute: { AttributeNode* attributeNode = fast_cast<AttributeNode*>(node); PrintNodeInitBegin(nodeIndex); // WebGL hack for integer attributes // (only for case of using another hack - changing integer attributes to float) bool intConversion = false; if(glslVersion == GlslVersions::webgl) intConversion = PrintWebGLConversionToIntegerBegin(attributeNode->GetValueType()); text << "a" << attributeNode->GetElementIndex(); if(intConversion) PrintWebGLConversionToIntegerEnd(); PrintNodeInitEnd(); } break; case Node::typeUniform: // uniform doesn't have initialization break; case Node::typeSampler: // sampler doesn't have initialization break; case Node::typeReadUniform: { PrintNodeInitBegin(nodeIndex); ReadUniformNode* readUniformNode = fast_cast<ReadUniformNode*>(node); PrintUniform(readUniformNode->GetUniformNode()); PrintNodeInitEnd(); } break; case Node::typeIndexUniformArray: { PrintNodeInitBegin(nodeIndex); IndexUniformArrayNode* indexUniformArrayNode = fast_cast<IndexUniformArrayNode*>(node); PrintUniform(indexUniformArrayNode->GetUniformNode()); text << '['; PrintNode(indexUniformArrayNode->GetIndexNode()); text << ']'; PrintNodeInitEnd(); } break; case Node::typeTransformed: PrintNodeInitBegin(nodeIndex); text << "v" << fast_cast<TransformedNode*>(node)->GetSemantic(); PrintNodeInitEnd(); break; case Node::typeInterpolate: { InterpolateNode* interpolateNode = fast_cast<InterpolateNode*>(node); text << "\tv" << interpolateNode->GetSemantic() << " = "; PrintNode(interpolateNode->GetNode()); PrintNodeInitEnd(); } break; case Node::typeSequence: // sequence node doesn't have initialization break; case Node::typeSwizzle: { PrintNodeInitBegin(nodeIndex); SwizzleNode* swizzleNode = fast_cast<SwizzleNode*>(node); PrintNode(swizzleNode->GetA()); text << '.' << swizzleNode->GetMap(); PrintNodeInitEnd(); } break; case Node::typeOperation: PrintNodeInitBegin(nodeIndex); PrintOperationNodeInit(fast_cast<OperationNode*>(node)); PrintNodeInitEnd(); break; case Node::typeAction: PrintActionNodeInit(fast_cast<ActionNode*>(node)); break; case Node::typeSample: { PrintNodeInitBegin(nodeIndex); SampleNode* sampleNode = fast_cast<SampleNode*>(node); int slot = sampleNode->GetSamplerNode()->GetSlot(); ValueNode* coordsNode = sampleNode->GetCoordsNode(); ValueNode* offsetNode = sampleNode->GetOffsetNode(); ValueNode* lodNode = sampleNode->GetLodNode(); ValueNode* biasNode = sampleNode->GetBiasNode(); ValueNode* gradXNode = sampleNode->GetGradXNode(); ValueNode* gradYNode = sampleNode->GetGradYNode(); auto printOffsetNode = [&]() { // offset node is required to be constant expression, // but AMD driver requires it also to be compile-time expression // so HACK: print value inline, only for known node // PrintNode(offsetNode); if(offsetNode->GetType() != Node::typeOperation) THROW("wrong offset node"); OperationNode* offsetOperationNode = fast_cast<OperationNode*>(offsetNode); if( offsetOperationNode->GetOperation() != OperationNode::operationInt11to2 || offsetOperationNode->GetA()->GetType() != Node::typeIntConst || offsetOperationNode->GetB()->GetType() != Node::typeIntConst ) THROW("wrong offset node"); text << "ivec2(" << offsetOperationNode->GetA().FastCast<IntConstNode>()->GetValue() << ", " << offsetOperationNode->GetB().FastCast<IntConstNode>()->GetValue() << ")"; }; if(lodNode) { text << "textureLod"; if(offsetNode) text << "Offset"; text << '(' << samplerPrefix << slot << ", "; PrintNode(coordsNode); text << ", "; PrintNode(lodNode); if(offsetNode) { text << ", "; printOffsetNode(); } } else if(biasNode) { text << "texture"; if(offsetNode) text << "Offset"; text << '(' << samplerPrefix << slot << ", "; PrintNode(coordsNode); if(offsetNode) { text << ", "; printOffsetNode(); } text << ", "; PrintNode(biasNode); } else if(gradXNode && gradYNode) { text << "textureGrad"; if(offsetNode) text << "Offset"; text << '(' << samplerPrefix << slot << ", "; PrintNode(coordsNode); text << ", "; PrintNode(gradXNode); text << ", "; PrintNode(gradYNode); if(offsetNode) { text << ", "; printOffsetNode(); } } else { text << (glslVersion == GlslVersions::webgl ? "texture2D" : "texture"); if(offsetNode && glslVersion != GlslVersions::webgl) text << "Offset"; text << '(' << samplerPrefix << slot << ", "; PrintNode(coordsNode); if(offsetNode && glslVersion != GlslVersions::webgl) { text << ", "; printOffsetNode(); } } // close sample call text << ')'; // sample always returns four-component vector, so make some swizzle if needed int valueSize = GetVectorDataTypeDimensions(sampleNode->GetValueType()); if(valueSize < 4) { text << '.'; for(int i = 0; i < valueSize; ++i) text << "xyzw"[i]; } PrintNodeInitEnd(); } break; case Node::typeFragment: { FragmentNode* fragmentNode = fast_cast<FragmentNode*>(node); switch(glslVersion) { case GlslVersions::opengl33: text << "\tr" << fragmentNode->GetTarget(); break; case GlslVersions::webgl: if(fragmentTargetsCount > 1) text << "gl_FragData[" << fragmentNode->GetTarget() << ']'; else text << "gl_FragColor"; break; } text << " = "; PrintNode(fragmentNode->GetNode()); PrintNodeInitEnd(); } break; case Node::typeDualFragment: { DualFragmentNode* dualFragmentNode = fast_cast<DualFragmentNode*>(node); switch(glslVersion) { case GlslVersions::opengl33: text << "\tr0 = "; PrintNode(dualFragmentNode->GetNode0()); PrintNodeInitEnd(); text << "\tr1 = "; PrintNode(dualFragmentNode->GetNode1()); PrintNodeInitEnd(); break; case GlslVersions::webgl: text << "\tgl_FragData[0] = "; PrintNode(dualFragmentNode->GetNode0()); PrintNodeInitEnd(); text << "\tgl_FragData[1] = "; PrintNode(dualFragmentNode->GetNode1()); PrintNodeInitEnd(); break; } } break; case Node::typeCast: { PrintNodeInitBegin(nodeIndex); CastNode* castNode = fast_cast<CastNode*>(node); PrintDataType(castNode->GetValueType()); text << '('; PrintNode(castNode->GetA()); text << ')'; PrintNodeInitEnd(); } break; default: THROW("Unknown node type"); } }
void Hlsl11GeneratorInstance::PrintNodeInit(size_t nodeIndex) { Node* node = nodeInits[nodeIndex]; switch(node->GetType()) { case Node::typeFloatConst: PrintNodeInitBegin(nodeIndex); text << std::fixed << std::setprecision(10) << fast_cast<FloatConstNode*>(node)->GetValue() << 'f'; PrintNodeInitEnd(); break; case Node::typeIntConst: PrintNodeInitBegin(nodeIndex); text << fast_cast<IntConstNode*>(node)->GetValue(); PrintNodeInitEnd(); break; case Node::typeAttribute: PrintNodeInitBegin(nodeIndex); text << "a.a" << fast_cast<AttributeNode*>(node)->GetElementIndex(); PrintNodeInitEnd(); break; case Node::typeUniform: // uniform doesn't have initialization break; case Node::typeSampler: // sampler doesn't have initialization break; case Node::typeReadUniform: { PrintNodeInitBegin(nodeIndex); ReadUniformNode* readUniformNode = fast_cast<ReadUniformNode*>(node); PrintUniform(readUniformNode->GetUniformNode()); PrintNodeInitEnd(); } break; case Node::typeIndexUniformArray: { PrintNodeInitBegin(nodeIndex); IndexUniformArrayNode* indexUniformArrayNode = fast_cast<IndexUniformArrayNode*>(node); PrintUniform(indexUniformArrayNode->GetUniformNode()); text << '['; PrintNode(indexUniformArrayNode->GetIndexNode()); text << ']'; PrintNodeInitEnd(); } break; case Node::typeTransformed: PrintNodeInitBegin(nodeIndex); text << "v.v" << fast_cast<TransformedNode*>(node)->GetSemantic(); PrintNodeInitEnd(); break; case Node::typeInterpolate: { InterpolateNode* interpolateNode = fast_cast<InterpolateNode*>(node); text << "\tv.v" << interpolateNode->GetSemantic() << " = "; PrintNode(interpolateNode->GetNode()); PrintNodeInitEnd(); } break; case Node::typeSequence: // sequence node doesn't have initialization break; case Node::typeSwizzle: { PrintNodeInitBegin(nodeIndex); SwizzleNode* swizzleNode = fast_cast<SwizzleNode*>(node); PrintNode(swizzleNode->GetA()); text << '.' << swizzleNode->GetMap(); PrintNodeInitEnd(); } break; case Node::typeOperation: PrintNodeInitBegin(nodeIndex); PrintOperationNodeInit(fast_cast<OperationNode*>(node)); PrintNodeInitEnd(); break; case Node::typeAction: PrintActionNodeInit(fast_cast<ActionNode*>(node)); break; case Node::typeSample: { PrintNodeInitBegin(nodeIndex); SampleNode* sampleNode = fast_cast<SampleNode*>(node); int slot = sampleNode->GetSamplerNode()->GetSlot(); text << 't' << slot; ValueNode* coordsNode = sampleNode->GetCoordsNode(); ValueNode* offsetNode = sampleNode->GetOffsetNode(); ValueNode* lodNode = sampleNode->GetLodNode(); ValueNode* biasNode = sampleNode->GetBiasNode(); ValueNode* gradXNode = sampleNode->GetGradXNode(); ValueNode* gradYNode = sampleNode->GetGradYNode(); if(lodNode) { text << ".SampleLevel(s" << slot << ", "; PrintNode(coordsNode); text << ", "; PrintNode(lodNode); } else if(biasNode) { text << ".SampleBias(s" << slot << ", "; PrintNode(coordsNode); text << ", "; PrintNode(biasNode); } else if(gradXNode && gradYNode) { text << ".SampleGrad(s" << slot << ", "; PrintNode(coordsNode); text << ", "; PrintNode(gradXNode); text << ", "; PrintNode(gradYNode); } else { text << ".Sample(s" << slot << ", "; PrintNode(coordsNode); } // add offset if needed if(offsetNode) { text << ", "; PrintNode(offsetNode); } text << ')'; PrintNodeInitEnd(); } break; case Node::typeFragment: { FragmentNode* fragmentNode = fast_cast<FragmentNode*>(node); text << "\tr.r" << fragmentNode->GetTarget() << " = "; PrintNode(fragmentNode->GetNode()); PrintNodeInitEnd(); } break; case Node::typeCast: { PrintNodeInitBegin(nodeIndex); CastNode* castNode = fast_cast<CastNode*>(node); text << '('; PrintDataType(castNode->GetValueType()); text << ")"; PrintNode(castNode->GetA()); PrintNodeInitEnd(); } break; default: THROW("Unknown node type"); } }