Exemplo n.º 1
0
        private static void FillBlock(
            ReadOnlySpan <byte> code,
            Block block,
            ulong limitAddress,
            ulong startAddress)
        {
            ulong address = block.Address;

            do
            {
                if (address + 7 >= limitAddress)
                {
                    break;
                }

                // Ignore scheduling instructions, which are written every 32 bytes.
                if ((address & 0x1f) == 0)
                {
                    address += 8;

                    continue;
                }

                uint word0 = BinaryPrimitives.ReadUInt32LittleEndian(code.Slice((int)(startAddress + address)));
                uint word1 = BinaryPrimitives.ReadUInt32LittleEndian(code.Slice((int)(startAddress + address + 4)));

                ulong opAddress = address;

                address += 8;

                long opCode = word0 | (long)word1 << 32;

                (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode);

                if (emitter == null)
                {
                    // TODO: Warning, illegal encoding.

                    block.OpCodes.Add(new OpCode(null, opAddress, opCode));

                    continue;
                }

                if (opActivator == null)
                {
                    throw new ArgumentNullException(nameof(opActivator));
                }

                OpCode op = (OpCode)opActivator(emitter, opAddress, opCode);

                block.OpCodes.Add(op);
            }while (!IsBranch(block.GetLastOp()));

            block.EndAddress = address;

            block.UpdatePushOps();
        }
Exemplo n.º 2
0
        private static void FillBlock(
            IGpuAccessor gpuAccessor,
            Block block,
            ulong limitAddress,
            ulong startAddress)
        {
            ulong address = block.Address;

            do
            {
                if (address + 7 >= limitAddress)
                {
                    break;
                }

                // Ignore scheduling instructions, which are written every 32 bytes.
                if ((address & 0x1f) == 0)
                {
                    address += 8;

                    continue;
                }

                ulong opAddress = address;

                address += 8;

                long opCode = gpuAccessor.MemoryRead <long>(startAddress + opAddress);

                (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode);

                if (emitter == null)
                {
                    // TODO: Warning, illegal encoding.

                    block.OpCodes.Add(new OpCode(null, opAddress, opCode));

                    continue;
                }

                if (opActivator == null)
                {
                    throw new ArgumentNullException(nameof(opActivator));
                }

                OpCode op = (OpCode)opActivator(emitter, opAddress, opCode);

                block.OpCodes.Add(op);
            }while (!IsBranch(block.GetLastOp()));

            block.EndAddress = address;

            block.UpdatePushOps();
        }
Exemplo n.º 3
0
        private static void FillBlock(
            IGalMemory memory,
            Block block,
            ulong limitAddress,
            ulong startAddress)
        {
            ulong address = block.Address;

            do
            {
                if (address >= limitAddress)
                {
                    break;
                }

                //Ignore scheduling instructions, which are written every 32 bytes.
                if (((address - startAddress) & 0x1f) == 0)
                {
                    address += 8;

                    continue;
                }

                uint word0 = (uint)memory.ReadInt32((long)(address + 0));
                uint word1 = (uint)memory.ReadInt32((long)(address + 4));

                ulong opAddress = address;

                address += 8;

                long opCode = word0 | (long)word1 << 32;

                (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode);

                if (emitter == null)
                {
                    //TODO: Warning, illegal encoding.
                    continue;
                }

                OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode);

                block.OpCodes.Add(op);
            }while (!IsBranch(block.GetLastOp()));

            block.EndAddress = address;

            block.UpdateSsyOpCodes();
        }
Exemplo n.º 4
0
        private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress)
        {
            IGpuAccessor gpuAccessor = config.GpuAccessor;

            ulong address = block.Address;

            do
            {
                if (address + 7 >= limitAddress)
                {
                    break;
                }

                // Ignore scheduling instructions, which are written every 32 bytes.
                if ((address & 0x1f) == 0)
                {
                    address += 8;

                    continue;
                }

                ulong opAddress = address;

                address += 8;

                long opCode = gpuAccessor.MemoryRead <long>(startAddress + opAddress);

                (InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode);

                if (emitter == null)
                {
                    // TODO: Warning, illegal encoding.

                    block.OpCodes.Add(new OpCode(null, opAddress, opCode));

                    continue;
                }

                if (makeOp == null)
                {
                    throw new ArgumentNullException(nameof(makeOp));
                }

                OpCode op = makeOp(emitter, opAddress, opCode);

                // We check these patterns to figure out the presence of bindless access
                if ((op is OpCodeImage image && image.IsBindless) ||
                    (op is OpCodeTxd txd && txd.IsBindless) ||
                    (op is OpCodeTld4B) ||
                    (emitter == InstEmit.TexB) ||
                    (emitter == InstEmit.TldB) ||
                    (emitter == InstEmit.TmmlB) ||
                    (emitter == InstEmit.TxqB))
                {
                    config.SetUsedFeature(FeatureFlags.Bindless);
                }

                // Populate used attributes.
                if (op is IOpCodeAttribute opAttr)
                {
                    SetUserAttributeUses(config, opAttr);
                }

                block.OpCodes.Add(op);
            }while (!IsControlFlowChange(block.GetLastOp()));

            block.EndAddress = address;

            block.UpdatePushOps();
        }