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); }
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>(); }
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)); }
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)); }
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)); }
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)); }
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>(); }
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>(); }
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)); }
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; }
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(); }
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()); }