Beispiel #1
0
        private static Block[][] DecodeShader(
            ulong address,
            IGpuAccessor gpuAccessor,
            TranslationOptions options,
            TranslationCounts counts,
            out ShaderConfig config)
        {
            Block[][] cfg;
            ulong     maxEndAddress = 0;

            bool hasBindless;

            if ((options.Flags & TranslationFlags.Compute) != 0)
            {
                config = new ShaderConfig(gpuAccessor, options, counts);

                cfg = Decoder.Decode(gpuAccessor, address, out hasBindless);
            }
            else
            {
                config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options, counts);

                cfg = Decoder.Decode(gpuAccessor, address + HeaderSize, out hasBindless);
            }

            if (hasBindless)
            {
                config.SetUsedFeature(FeatureFlags.Bindless);
            }

            for (int funcIndex = 0; funcIndex < cfg.Length; funcIndex++)
            {
                for (int blkIndex = 0; blkIndex < cfg[funcIndex].Length; blkIndex++)
                {
                    Block block = cfg[funcIndex][blkIndex];

                    if (maxEndAddress < block.EndAddress)
                    {
                        maxEndAddress = block.EndAddress;
                    }

                    if (!hasBindless)
                    {
                        for (int index = 0; index < block.OpCodes.Count; index++)
                        {
                            if (block.OpCodes[index] is OpCodeTextureBase texture)
                            {
                                config.TextureHandlesForCache.Add(texture.HandleOffset);
                            }
                        }
                    }
                }
            }

            config.SizeAdd((int)maxEndAddress + (options.Flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize));

            return(cfg);
        }
Beispiel #2
0
        public static TranslatorContext CreateContext(
            ulong address,
            IGpuAccessor gpuAccessor,
            TranslationOptions options,
            TranslationCounts counts = null)
        {
            counts ??= new TranslationCounts();

            return(DecodeShader(address, gpuAccessor, options, counts));
        }
 public ShaderConfig(IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts)
 {
     Stage                  = ShaderStage.Compute;
     GpuAccessor            = gpuAccessor;
     Options                = options;
     _counts                = counts;
     TextureHandlesForCache = new HashSet <int>();
     _usedTextures          = new Dictionary <TextureInfo, TextureMeta>();
     _usedImages            = new Dictionary <TextureInfo, TextureMeta>();
 }
Beispiel #4
0
        public static ShaderProgram Translate(
            ulong address,
            IGpuAccessor gpuAccessor,
            TranslationFlags flags,
            TranslationCounts counts = null)
        {
            counts ??= new TranslationCounts();

            return(Translate(DecodeShader(address, gpuAccessor, flags, counts, out ShaderConfig config), config));
        }
Beispiel #5
0
        public static TranslatorContext CreateContext(
            ulong address,
            IGpuAccessor gpuAccessor,
            TranslationFlags flags,
            TranslationCounts counts = null)
        {
            counts ??= new TranslationCounts();

            Block[][] cfg = DecodeShader(address, gpuAccessor, flags, counts, out ShaderConfig config);

            return(new TranslatorContext(address, cfg, config));
        }
Beispiel #6
0
        public static TranslatorContext CreateContext(
            ulong addressA,
            ulong addressB,
            IGpuAccessor gpuAccessor,
            TranslationFlags flags,
            TranslationCounts counts = null)
        {
            counts ??= new TranslationCounts();

            Block[][] cfgA = DecodeShader(addressA, gpuAccessor, flags | TranslationFlags.VertexA, counts, out ShaderConfig configA);
            Block[][] cfgB = DecodeShader(addressB, gpuAccessor, flags, counts, out ShaderConfig configB);

            return(new TranslatorContext(addressA, addressB, cfgA, cfgB, configA, configB));
        }
Beispiel #7
0
        public static ShaderProgram Translate(
            ulong addressA,
            ulong addressB,
            IGpuAccessor gpuAccessor,
            TranslationFlags flags,
            TranslationCounts counts = null)
        {
            counts ??= new TranslationCounts();

            FunctionCode[] funcA = DecodeShader(addressA, gpuAccessor, flags | TranslationFlags.VertexA, counts, out ShaderConfig configA);
            FunctionCode[] funcB = DecodeShader(addressB, gpuAccessor, flags, counts, out ShaderConfig config);

            config.SetUsedFeature(configA.UsedFeatures);

            return(Translate(Combine(funcA, funcB), config, configA.Size));
        }
Beispiel #8
0
 public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationFlags flags, TranslationCounts counts)
 {
     Stage             = header.Stage;
     OutputTopology    = header.OutputTopology;
     MaxOutputVertices = header.MaxOutputVertexCount;
     LocalMemorySize   = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize;
     ImapTypes         = header.ImapTypes;
     OmapTargets       = header.OmapTargets;
     OmapSampleMask    = header.OmapSampleMask;
     OmapDepth         = header.OmapDepth;
     GpuAccessor       = gpuAccessor;
     Flags             = flags;
     Size                   = 0;
     UsedFeatures           = FeatureFlags.None;
     Counts                 = counts;
     TextureHandlesForCache = new HashSet <int>();
 }
Beispiel #9
0
 public ShaderConfig(IGpuAccessor gpuAccessor, TranslationFlags flags, TranslationCounts counts)
 {
     Stage             = ShaderStage.Compute;
     OutputTopology    = OutputTopology.PointList;
     MaxOutputVertices = 0;
     LocalMemorySize   = 0;
     ImapTypes         = null;
     OmapTargets       = null;
     OmapSampleMask    = false;
     OmapDepth         = false;
     GpuAccessor       = gpuAccessor;
     Flags             = flags;
     Size                   = 0;
     UsedFeatures           = FeatureFlags.None;
     Counts                 = counts;
     TextureHandlesForCache = new HashSet <int>();
 }
Beispiel #10
0
        private static TranslatorContext DecodeShader(ulong address, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts)
        {
            ShaderConfig   config;
            DecodedProgram program;
            ulong          maxEndAddress = 0;

            if ((options.Flags & TranslationFlags.Compute) != 0)
            {
                config = new ShaderConfig(gpuAccessor, options, counts);

                program = Decoder.Decode(config, address);
            }
            else
            {
                config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options, counts);

                program = Decoder.Decode(config, address + HeaderSize);
            }

            foreach (DecodedFunction function in program)
            {
                foreach (Block block in function.Blocks)
                {
                    if (maxEndAddress < block.EndAddress)
                    {
                        maxEndAddress = block.EndAddress;
                    }

                    if (!config.UsedFeatures.HasFlag(FeatureFlags.Bindless))
                    {
                        for (int index = 0; index < block.OpCodes.Count; index++)
                        {
                            InstOp op = block.OpCodes[index];

                            if (op.Props.HasFlag(InstProps.Tex))
                            {
                                int tidB = (int)((op.RawOpCode >> 36) & 0x1fff);
                                config.TextureHandlesForCache.Add(tidB);
                            }
                        }
                    }
                }
            }

            config.SizeAdd((int)maxEndAddress + (options.Flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize));

            return(new TranslatorContext(address, program, config));
        }
Beispiel #11
0
 public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) : this(gpuAccessor, options, counts)
 {
     Stage             = header.Stage;
     GpPassthrough     = header.Stage == ShaderStage.Geometry && header.GpPassthrough;
     OutputTopology    = header.OutputTopology;
     MaxOutputVertices = header.MaxOutputVertexCount;
     LocalMemorySize   = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize;
     ImapTypes         = header.ImapTypes;
     OmapTargets       = header.OmapTargets;
     OmapSampleMask    = header.OmapSampleMask;
     OmapDepth         = header.OmapDepth;
 }
Beispiel #12
0
 public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) : this(gpuAccessor, options, counts)
 {
     Stage                    = header.Stage;
     GpPassthrough            = header.Stage == ShaderStage.Geometry && header.GpPassthrough;
     ThreadsPerInputPrimitive = header.ThreadsPerInputPrimitive;
     OutputTopology           = header.OutputTopology;
     MaxOutputVertices        = header.MaxOutputVertexCount;
     LocalMemorySize          = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize;
     ImapTypes                = header.ImapTypes;
     OmapTargets              = header.OmapTargets;
     OmapSampleMask           = header.OmapSampleMask;
     OmapDepth                = header.OmapDepth;
     TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
 }
Beispiel #13
0
        private static FunctionCode[] DecodeShader(
            ulong address,
            IGpuAccessor gpuAccessor,
            TranslationFlags flags,
            TranslationCounts counts,
            out ShaderConfig config)
        {
            Block[][] cfg;

            if ((flags & TranslationFlags.Compute) != 0)
            {
                config = new ShaderConfig(gpuAccessor, flags, counts);

                cfg = Decoder.Decode(gpuAccessor, address);
            }
            else
            {
                config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, flags, counts);

                cfg = Decoder.Decode(gpuAccessor, address + HeaderSize);
            }

            if (cfg == null)
            {
                gpuAccessor.Log("Invalid branch detected, failed to build CFG.");

                return(Array.Empty <FunctionCode>());
            }

            Dictionary <ulong, int> funcIds = new Dictionary <ulong, int>();

            for (int funcIndex = 0; funcIndex < cfg.Length; funcIndex++)
            {
                funcIds.Add(cfg[funcIndex][0].Address, funcIndex);
            }

            List <FunctionCode> funcs = new List <FunctionCode>();

            ulong maxEndAddress = 0;

            for (int funcIndex = 0; funcIndex < cfg.Length; funcIndex++)
            {
                EmitterContext context = new EmitterContext(config, funcIndex != 0, funcIds);

                for (int blkIndex = 0; blkIndex < cfg[funcIndex].Length; blkIndex++)
                {
                    Block block = cfg[funcIndex][blkIndex];

                    if (maxEndAddress < block.EndAddress)
                    {
                        maxEndAddress = block.EndAddress;
                    }

                    context.CurrBlock = block;

                    context.MarkLabel(context.GetLabel(block.Address));

                    EmitOps(context, block);
                }

                funcs.Add(new FunctionCode(context.GetOperations()));
            }

            config.SizeAdd((int)maxEndAddress + (flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize));

            return(funcs.ToArray());
        }