private void PrintAttrToOutput(string Identation = IdentationStr) { foreach (KeyValuePair <int, ShaderDeclInfo> KV in Decl.OutAttributes) { if (!Decl.Attributes.TryGetValue(KV.Key, out ShaderDeclInfo Attr)) { continue; } ShaderDeclInfo DeclInfo = KV.Value; string Name = Attr.Name; if (Decl.ShaderType == GalShaderType.Geometry) { Name += "[0]"; } SB.AppendLine(Identation + DeclInfo.Name + " = " + Name + ";"); } if (Decl.ShaderType == GalShaderType.Vertex) { SB.AppendLine(Identation + "gl_Position.xy *= " + GlslDecl.FlipUniformName + ";"); } if (Decl.ShaderType != GalShaderType.Fragment) { SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + " = gl_Position;"); SB.AppendLine(Identation + GlslDecl.PositionOutAttrName + ".w = 1;"); } }
private void PrintMain() { SB.AppendLine("void main() {"); foreach (KeyValuePair <int, ShaderDeclInfo> KV in Decl.InAttributes) { if (!Decl.Attributes.TryGetValue(KV.Key, out ShaderDeclInfo Attr)) { continue; } ShaderDeclInfo DeclInfo = KV.Value; string Swizzle = ".xyzw".Substring(0, DeclInfo.Size + 1); SB.AppendLine(IdentationStr + Attr.Name + Swizzle + " = " + DeclInfo.Name + ";"); } if (BlocksB != null) { SB.AppendLine(IdentationStr + GlslDecl.ProgramAName + "();"); SB.AppendLine(IdentationStr + GlslDecl.ProgramBName + "();"); } else { SB.AppendLine(IdentationStr + GlslDecl.ProgramName + "();"); } foreach (KeyValuePair <int, ShaderDeclInfo> KV in Decl.OutAttributes) { if (!Decl.Attributes.TryGetValue(KV.Key, out ShaderDeclInfo Attr)) { continue; } ShaderDeclInfo DeclInfo = KV.Value; string Swizzle = ".xyzw".Substring(0, DeclInfo.Size + 1); SB.AppendLine(IdentationStr + DeclInfo.Name + " = " + Attr.Name + Swizzle + ";"); } if (Decl.ShaderType == GalShaderType.Vertex) { SB.AppendLine(IdentationStr + "gl_Position.xy *= " + GlslDecl.FlipUniformName + ";"); } if (Decl.ShaderType != GalShaderType.Fragment) { SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + " = gl_Position;"); SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + ".w = 1;"); } SB.AppendLine("}"); }
private string GetDecl(ShaderDeclInfo DeclInfo) { if (DeclInfo.Size == 4) { return("vec4 " + DeclInfo.Name); } else { return("float " + DeclInfo.Name); } }
private void PrintMain() { SB.AppendLine("void main() {"); foreach (KeyValuePair <int, ShaderDeclInfo> KV in Decl.InAttributes) { if (!Decl.Attributes.TryGetValue(KV.Key, out ShaderDeclInfo Attr)) { continue; } ShaderDeclInfo DeclInfo = KV.Value; string Swizzle = ".xyzw".Substring(0, DeclInfo.Size + 1); if (Decl.ShaderType == GalShaderType.Geometry) { for (int Vertex = 0; Vertex < MaxVertexInput; Vertex++) { string Dst = Attr.Name + "[" + Vertex + "]" + Swizzle; string Src = "block_in[" + Vertex + "]." + DeclInfo.Name; SB.AppendLine(IdentationStr + Dst + " = " + Src + ";"); } } else { SB.AppendLine(IdentationStr + Attr.Name + Swizzle + " = " + DeclInfo.Name + ";"); } } if (BlocksB != null) { SB.AppendLine(IdentationStr + GlslDecl.ProgramAName + "();"); SB.AppendLine(IdentationStr + GlslDecl.ProgramBName + "();"); } else { SB.AppendLine(IdentationStr + GlslDecl.ProgramName + "();"); } if (Decl.ShaderType != GalShaderType.Geometry) { PrintAttrToOutput(); } SB.AppendLine("}"); }
private int DeclKeySelector(ShaderDeclInfo DeclInfo) { return(DeclInfo.Cbuf << 24 | DeclInfo.Index); }
private string GetDecl(ShaderDeclInfo DeclInfo) { return(ElemTypes[DeclInfo.Size - 1] + " " + DeclInfo.Name); }
private void PrintMain() { SB.AppendLine("void main() {"); foreach (KeyValuePair <int, ShaderDeclInfo> KV in Decl.InAttributes) { if (!Decl.Attributes.TryGetValue(KV.Key, out ShaderDeclInfo Attr)) { continue; } ShaderDeclInfo DeclInfo = KV.Value; if (Decl.ShaderType == GalShaderType.Geometry) { for (int Vertex = 0; Vertex < MaxVertexInput; Vertex++) { string Dst = Attr.Name + "[" + Vertex + "]"; string Src = "block_in[" + Vertex + "]." + DeclInfo.Name; SB.AppendLine(IdentationStr + Dst + " = " + Src + ";"); } } else { SB.AppendLine(IdentationStr + Attr.Name + " = " + DeclInfo.Name + ";"); } } SB.AppendLine(IdentationStr + "uint pc;"); if (BlocksB != null) { PrintProgram(Blocks, GlslDecl.BasicBlockAName); PrintProgram(BlocksB, GlslDecl.BasicBlockBName); } else { PrintProgram(Blocks, GlslDecl.BasicBlockName); } if (Decl.ShaderType != GalShaderType.Geometry) { PrintAttrToOutput(); } if (Decl.ShaderType == GalShaderType.Fragment) { if (Header.OmapDepth) { SB.AppendLine(IdentationStr + "gl_FragDepth = " + GlslDecl.GetGprName(Header.DepthRegister) + ";"); } int GprIndex = 0; for (int Attachment = 0; Attachment < 8; Attachment++) { string Output = GlslDecl.FragmentOutputName + Attachment; OmapTarget Target = Header.OmapTargets[Attachment]; for (int Component = 0; Component < 4; Component++) { if (Target.ComponentEnabled(Component)) { SB.AppendLine(IdentationStr + Output + "[" + Component + "] = " + GlslDecl.GetGprName(GprIndex) + ";"); GprIndex++; } } } } SB.AppendLine("}"); }
private void Traverse(ShaderIrNode[] Nodes, ShaderIrNode Parent, ShaderIrNode Node) { switch (Node) { case ShaderIrAsg Asg: { Traverse(Nodes, Asg, Asg.Dst); Traverse(Nodes, Asg, Asg.Src); break; } case ShaderIrCond Cond: { Traverse(Nodes, Cond, Cond.Pred); Traverse(Nodes, Cond, Cond.Child); break; } case ShaderIrOp Op: { Traverse(Nodes, Op, Op.OperandA); Traverse(Nodes, Op, Op.OperandB); Traverse(Nodes, Op, Op.OperandC); if (Op.Inst == ShaderIrInst.Texq || Op.Inst == ShaderIrInst.Texs || Op.Inst == ShaderIrInst.Txlf) { int Handle = ((ShaderIrOperImm)Op.OperandC).Value; int Index = Handle - TexStartIndex; string Name = StagePrefix + TextureName + Index; m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle)); } else if (Op.Inst == ShaderIrInst.Texb) { ShaderIrNode HandleSrc = null; int Index = Array.IndexOf(Nodes, Parent) - 1; for (; Index >= 0; Index--) { ShaderIrNode Curr = Nodes[Index]; if (Curr is ShaderIrAsg Asg && Asg.Dst is ShaderIrOperGpr Gpr) { if (Gpr.Index == ((ShaderIrOperGpr)Op.OperandC).Index) { HandleSrc = Asg.Src; break; } } } if (HandleSrc != null && HandleSrc is ShaderIrOperCbuf Cbuf) { string Name = StagePrefix + TextureName + "_cb" + Cbuf.Index + "_" + Cbuf.Pos; m_CbTextures.Add(Op, new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index)); } else { throw new NotImplementedException("Shader TEX.B instruction is not fully supported!"); } } break; } case ShaderIrOperCbuf Cbuf: { if (!m_Uniforms.ContainsKey(Cbuf.Index)) { string Name = StagePrefix + UniformName + Cbuf.Index; ShaderDeclInfo DeclInfo = new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index); m_Uniforms.Add(Cbuf.Index, DeclInfo); } break; } case ShaderIrOperAbuf Abuf: { //This is a built-in variable. if (Abuf.Offs == LayerAttr || Abuf.Offs == PointSizeAttr || Abuf.Offs == PointCoordAttrX || Abuf.Offs == PointCoordAttrY || Abuf.Offs == VertexIdAttr || Abuf.Offs == InstanceIdAttr || Abuf.Offs == FaceAttr) { break; } int Index = Abuf.Offs >> 4; int Elem = (Abuf.Offs >> 2) & 3; int GlslIndex = Index - AttrStartIndex; if (GlslIndex < 0) { return; } ShaderDeclInfo DeclInfo; if (Parent is ShaderIrAsg Asg && Asg.Dst == Node) { if (!m_OutAttributes.TryGetValue(Index, out DeclInfo)) { DeclInfo = new ShaderDeclInfo(OutAttrName + GlslIndex, GlslIndex); m_OutAttributes.Add(Index, DeclInfo); } }
private void Traverse(ShaderIrNode Parent, ShaderIrNode Node) { switch (Node) { case ShaderIrAsg Asg: { Traverse(Asg, Asg.Dst); Traverse(Asg, Asg.Src); break; } case ShaderIrCond Cond: { Traverse(Cond, Cond.Pred); Traverse(Cond, Cond.Child); break; } case ShaderIrOp Op: { Traverse(Op, Op.OperandA); Traverse(Op, Op.OperandB); Traverse(Op, Op.OperandC); if (Op.Inst == ShaderIrInst.Texq || Op.Inst == ShaderIrInst.Texs || Op.Inst == ShaderIrInst.Txlf) { int Handle = ((ShaderIrOperImm)Op.OperandC).Value; int Index = Handle - TexStartIndex; string Name = StagePrefix + TextureName + Index; m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle)); } break; } case ShaderIrOperCbuf Cbuf: { if (m_Uniforms.TryGetValue(Cbuf.Index, out ShaderDeclInfo DeclInfo)) { DeclInfo.SetCbufOffs(Cbuf.Pos); } else { string Name = StagePrefix + UniformName + Cbuf.Index; DeclInfo = new ShaderDeclInfo(Name, Cbuf.Pos, Cbuf.Index); m_Uniforms.Add(Cbuf.Index, DeclInfo); } if (Cbuf.Offs != null) { //The constant buffer is being accessed as an array, //we have no way to know the max element it may access in this case. //Here, we just assume the array size with arbitrary values. //TODO: Find a better solution for this. DeclInfo.SetCbufOffs(Cbuf.Pos + 15); } break; } case ShaderIrOperAbuf Abuf: { //This is a built-in input variable. if (Abuf.Offs == VertexIdAttr) { break; } int Index = Abuf.Offs >> 4; int Elem = (Abuf.Offs >> 2) & 3; int GlslIndex = Index - AttrStartIndex; ShaderDeclInfo DeclInfo; if (Parent is ShaderIrAsg Asg && Asg.Dst == Node) { if (!m_OutAttributes.TryGetValue(Index, out DeclInfo)) { DeclInfo = new ShaderDeclInfo(OutAttrName + GlslIndex, GlslIndex); m_OutAttributes.Add(Index, DeclInfo); } }
private void Traverse(ShaderIrNode Parent, ShaderIrNode Node) { switch (Node) { case ShaderIrAsg Asg: { Traverse(Asg, Asg.Dst); Traverse(Asg, Asg.Src); break; } case ShaderIrCond Cond: { Traverse(Cond, Cond.Pred); Traverse(Cond, Cond.Child); break; } case ShaderIrOp Op: { Traverse(Op, Op.OperandA); Traverse(Op, Op.OperandB); Traverse(Op, Op.OperandC); if (Op.Inst == ShaderIrInst.Texq || Op.Inst == ShaderIrInst.Texs || Op.Inst == ShaderIrInst.Txlf) { int Handle = ((ShaderIrOperImm)Op.OperandC).Value; int Index = Handle - TexStartIndex; string Name = StagePrefix + TextureName + Index; m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle)); } break; } case ShaderIrOperCbuf Cbuf: { if (!m_Uniforms.ContainsKey(Cbuf.Index)) { string Name = StagePrefix + UniformName + Cbuf.Index; ShaderDeclInfo DeclInfo = new ShaderDeclInfo(Name, Cbuf.Pos, Cbuf.Index); m_Uniforms.Add(Cbuf.Index, DeclInfo); } break; } case ShaderIrOperAbuf Abuf: { //This is a built-in input variable. if (Abuf.Offs == VertexIdAttr || Abuf.Offs == InstanceIdAttr || Abuf.Offs == FaceAttr || Abuf.Offs == LayerAttr) { break; } int Index = Abuf.Offs >> 4; int Elem = (Abuf.Offs >> 2) & 3; int GlslIndex = Index - AttrStartIndex; if (GlslIndex < 0) { return; } ShaderDeclInfo DeclInfo; if (Parent is ShaderIrAsg Asg && Asg.Dst == Node) { if (!m_OutAttributes.TryGetValue(Index, out DeclInfo)) { DeclInfo = new ShaderDeclInfo(OutAttrName + GlslIndex, GlslIndex); m_OutAttributes.Add(Index, DeclInfo); } }
private void Traverse(ShaderIrNode[] nodes, ShaderIrNode parent, ShaderIrNode node) { switch (node) { case ShaderIrAsg asg: { Traverse(nodes, asg, asg.Dst); Traverse(nodes, asg, asg.Src); break; } case ShaderIrCond cond: { Traverse(nodes, cond, cond.Pred); Traverse(nodes, cond, cond.Child); break; } case ShaderIrOp op: { Traverse(nodes, op, op.OperandA); Traverse(nodes, op, op.OperandB); Traverse(nodes, op, op.OperandC); if (op.Inst == ShaderIrInst.Texq || op.Inst == ShaderIrInst.Texs || op.Inst == ShaderIrInst.Tld4 || op.Inst == ShaderIrInst.Txlf) { int handle = ((ShaderIrOperImm)op.OperandC).Value; int index = handle - TexStartIndex; string name = _stagePrefix + TextureName + index; GalTextureTarget textureTarget; TextureInstructionSuffix textureInstructionSuffix; // TODO: Non 2D texture type for TEXQ? if (op.Inst == ShaderIrInst.Texq) { textureTarget = GalTextureTarget.TwoD; textureInstructionSuffix = TextureInstructionSuffix.None; } else { ShaderIrMetaTex meta = ((ShaderIrMetaTex)op.MetaData); textureTarget = meta.TextureTarget; textureInstructionSuffix = meta.TextureInstructionSuffix; } m_Textures.TryAdd(handle, new ShaderDeclInfo(name, handle, false, 0, 1, textureTarget, textureInstructionSuffix)); } else if (op.Inst == ShaderIrInst.Texb) { ShaderIrNode handleSrc = null; int index = Array.IndexOf(nodes, parent) - 1; for (; index >= 0; index--) { ShaderIrNode curr = nodes[index]; if (curr is ShaderIrAsg asg && asg.Dst is ShaderIrOperGpr gpr) { if (gpr.Index == ((ShaderIrOperGpr)op.OperandC).Index) { handleSrc = asg.Src; break; } } } if (handleSrc != null && handleSrc is ShaderIrOperCbuf cbuf) { ShaderIrMetaTex meta = ((ShaderIrMetaTex)op.MetaData); string name = _stagePrefix + TextureName + "_cb" + cbuf.Index + "_" + cbuf.Pos; m_CbTextures.Add(op, new ShaderDeclInfo(name, cbuf.Pos, true, cbuf.Index, 1, meta.TextureTarget, meta.TextureInstructionSuffix)); } else { throw new NotImplementedException("Shader TEX.B instruction is not fully supported!"); } } break; } case ShaderIrOperCbuf cbuf: { if (!m_Uniforms.ContainsKey(cbuf.Index)) { string name = _stagePrefix + UniformName + cbuf.Index; ShaderDeclInfo declInfo = new ShaderDeclInfo(name, cbuf.Pos, true, cbuf.Index); m_Uniforms.Add(cbuf.Index, declInfo); } break; } case ShaderIrOperAbuf abuf: { //This is a built-in variable. if (abuf.Offs == LayerAttr || abuf.Offs == PointSizeAttr || abuf.Offs == PointCoordAttrX || abuf.Offs == PointCoordAttrY || abuf.Offs == VertexIdAttr || abuf.Offs == InstanceIdAttr || abuf.Offs == FaceAttr) { break; } int index = abuf.Offs >> 4; int elem = (abuf.Offs >> 2) & 3; int glslIndex = index - AttrStartIndex; if (glslIndex < 0) { return; } ShaderDeclInfo declInfo; if (parent is ShaderIrAsg asg && asg.Dst == node) { if (!m_OutAttributes.TryGetValue(index, out declInfo)) { declInfo = new ShaderDeclInfo(OutAttrName + glslIndex, glslIndex); m_OutAttributes.Add(index, declInfo); } }