Пример #1
0
 public GotoStatement(AstOperation branch, AstAssignment label, bool isLoop)
 {
     Goto   = branch;
     Label  = label;
     IsLoop = isLoop;
 }
Пример #2
0
        private static void AddOperation(StructuredProgramContext context, Operation operation)
        {
            Instruction inst = operation.Inst;

            IAstNode[] sources = new IAstNode[operation.SourcesCount];

            for (int index = 0; index < sources.Length; index++)
            {
                sources[index] = context.GetOperandUse(operation.GetSource(index));
            }

            if (operation.Dest != null)
            {
                AstOperand dest = context.GetOperandDef(operation.Dest);

                if (inst == Instruction.LoadConstant)
                {
                    Operand ldcSource = operation.GetSource(0);

                    if (ldcSource.Type != OperandType.Constant)
                    {
                        throw new InvalidOperationException("Found LDC with non-constant constant buffer slot.");
                    }

                    context.Info.CBuffers.Add(ldcSource.Value);
                }

                AstAssignment assignment;

                //If all the sources are bool, it's better to use short-circuiting
                //logical operations, rather than forcing a cast to int and doing
                //a bitwise operation with the value, as it is likely to be used as
                //a bool in the end.
                if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool))
                {
                    inst = GetLogicalFromBitwiseInst(inst);
                }

                bool isCondSel = inst == Instruction.ConditionalSelect;
                bool isCopy    = inst == Instruction.Copy;

                if (isCondSel || isCopy)
                {
                    VariableType type = GetVarTypeFromUses(operation.Dest);

                    if (isCondSel && type == VariableType.F32)
                    {
                        inst |= Instruction.FP;
                    }

                    dest.VarType = type;
                }
                else
                {
                    dest.VarType = InstructionInfo.GetDestVarType(inst);
                }

                int componentMask = 1 << operation.ComponentIndex;

                IAstNode source;

                if (operation is TextureOperation texOp)
                {
                    AstTextureOperation astTexOp = new AstTextureOperation(
                        inst,
                        texOp.Type,
                        texOp.Flags,
                        texOp.Handle,
                        componentMask,
                        sources);

                    context.Info.Samplers.Add(astTexOp);

                    source = astTexOp;
                }
                else if (!isCopy)
                {
                    source = new AstOperation(inst, componentMask, sources);
                }
                else
                {
                    source = sources[0];
                }

                assignment = new AstAssignment(dest, source);

                context.AddNode(assignment);
            }
            else
            {
                context.AddNode(new AstOperation(inst, sources));
            }
        }
Пример #3
0
        private static void AddOperation(StructuredProgramContext context, Operation operation)
        {
            Instruction inst = operation.Inst;

            IAstNode[] sources = new IAstNode[operation.SourcesCount];

            for (int index = 0; index < sources.Length; index++)
            {
                sources[index] = context.GetOperandUse(operation.GetSource(index));
            }

            AstTextureOperation GetAstTextureOperation(TextureOperation texOp)
            {
                return(new AstTextureOperation(
                           inst,
                           texOp.Type,
                           texOp.Format,
                           texOp.Flags,
                           texOp.Handle,
                           4, // TODO: Non-hardcoded array size.
                           texOp.Index,
                           sources));
            }

            if (operation.Dest != null)
            {
                AstOperand dest = context.GetOperandDef(operation.Dest);

                if (inst == Instruction.LoadConstant)
                {
                    Operand slot = operation.GetSource(0);

                    if (slot.Type == OperandType.Constant)
                    {
                        context.Info.CBuffers.Add(slot.Value);
                    }
                    else
                    {
                        // If the value is not constant, then we don't know
                        // how many constant buffers are used, so we assume
                        // all of them are used.
                        int cbCount = 32 - BitOperations.LeadingZeroCount(context.Config.GpuAccessor.QueryConstantBufferUse());

                        for (int index = 0; index < cbCount; index++)
                        {
                            context.Info.CBuffers.Add(index);
                        }

                        context.Info.UsesCbIndexing = true;
                    }
                }
                else if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                AstAssignment assignment;

                // If all the sources are bool, it's better to use short-circuiting
                // logical operations, rather than forcing a cast to int and doing
                // a bitwise operation with the value, as it is likely to be used as
                // a bool in the end.
                if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, VariableType.Bool))
                {
                    inst = GetLogicalFromBitwiseInst(inst);
                }

                bool isCondSel = inst == Instruction.ConditionalSelect;
                bool isCopy    = inst == Instruction.Copy;

                if (isCondSel || isCopy)
                {
                    VariableType type = GetVarTypeFromUses(operation.Dest);

                    if (isCondSel && type == VariableType.F32)
                    {
                        inst |= Instruction.FP32;
                    }

                    dest.VarType = type;
                }
                else
                {
                    dest.VarType = InstructionInfo.GetDestVarType(inst);
                }

                IAstNode source;

                if (operation is TextureOperation texOp)
                {
                    if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
                    {
                        dest.VarType = texOp.Format.GetComponentType();
                    }

                    AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                    if (texOp.Inst == Instruction.ImageLoad)
                    {
                        context.Info.Images.Add(astTexOp);
                    }
                    else
                    {
                        context.Info.Samplers.Add(astTexOp);
                    }

                    source = astTexOp;
                }
                else if (!isCopy)
                {
                    source = new AstOperation(inst, operation.Index, sources);
                }
                else
                {
                    source = sources[0];
                }

                assignment = new AstAssignment(dest, source);

                context.AddNode(assignment);
            }
            else if (operation.Inst == Instruction.Comment)
            {
                context.AddNode(new AstComment(((CommentNode)operation).Comment));
            }
            else if (operation is TextureOperation texOp)
            {
                AstTextureOperation astTexOp = GetAstTextureOperation(texOp);

                context.Info.Images.Add(astTexOp);

                context.AddNode(astTexOp);
            }
            else
            {
                if (UsesStorage(inst))
                {
                    AddSBufferUse(context.Info.SBuffers, operation);
                }

                context.AddNode(new AstOperation(inst, operation.Index, sources));
            }

            // Those instructions needs to be emulated by using helper functions,
            // because they are NVIDIA specific. Those flags helps the backend to
            // decide which helper functions are needed on the final generated code.
            switch (operation.Inst)
            {
            case Instruction.MultiplyHighS32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32;
                break;

            case Instruction.MultiplyHighU32:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32;
                break;

            case Instruction.Shuffle:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.Shuffle;
                break;

            case Instruction.ShuffleDown:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleDown;
                break;

            case Instruction.ShuffleUp:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleUp;
                break;

            case Instruction.ShuffleXor:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleXor;
                break;

            case Instruction.SwizzleAdd:
                context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd;
                break;
            }
        }