private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress) { IGpuAccessor gpuAccessor = config.GpuAccessor; ulong address = block.Address; int bufferOffset = 0; ReadOnlySpan <ulong> buffer = ReadOnlySpan <ulong> .Empty; InstOp op = default; do { if (address + 7 >= limitAddress) { break; } // Ignore scheduling instructions, which are written every 32 bytes. if ((address & 0x1f) == 0) { address += 8; bufferOffset++; continue; } if (bufferOffset >= buffer.Length) { buffer = gpuAccessor.GetCode(startAddress + address, 8); bufferOffset = 0; } ulong opCode = buffer[bufferOffset++]; op = InstTable.GetOp(address, opCode); if (op.Props.HasFlag(InstProps.TexB)) { config.SetUsedFeature(FeatureFlags.Bindless); } if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa) { SetUserAttributeUses(config, op.Name, opCode); } else if (op.Name == InstName.Ssy || op.Name == InstName.Pbk) { block.AddPushOp(op); } block.OpCodes.Add(op); address += 8; }while (!op.Props.HasFlag(InstProps.Bra)); block.EndAddress = address; }
public ShaderHeader(IGpuAccessor gpuAccessor, ulong address) { ReadOnlySpan <int> header = MemoryMarshal.Cast <ulong, int>(gpuAccessor.GetCode(address, 0x50)); int commonWord0 = header[0]; int commonWord1 = header[1]; int commonWord2 = header[2]; int commonWord3 = header[3]; int commonWord4 = header[4]; SphType = commonWord0.Extract(0, 5); Version = commonWord0.Extract(5, 5); Stage = (ShaderStage)commonWord0.Extract(10, 4); // Invalid. if (Stage == ShaderStage.Compute) { Stage = ShaderStage.Vertex; } MrtEnable = commonWord0.Extract(14); KillsPixels = commonWord0.Extract(15); DoesGlobalStore = commonWord0.Extract(16); SassVersion = commonWord0.Extract(17, 4); GpPassthrough = commonWord0.Extract(24); DoesLoadOrStore = commonWord0.Extract(26); DoesFp64 = commonWord0.Extract(27); StreamOutMask = commonWord0.Extract(28, 4); ShaderLocalMemoryLowSize = commonWord1.Extract(0, 24); PerPatchAttributeCount = commonWord1.Extract(24, 8); ShaderLocalMemoryHighSize = commonWord2.Extract(0, 24); ThreadsPerInputPrimitive = commonWord2.Extract(24, 8); ShaderLocalMemoryCrsSize = commonWord3.Extract(0, 24); OutputTopology = (OutputTopology)commonWord3.Extract(24, 4); MaxOutputVertexCount = commonWord4.Extract(0, 12); StoreReqStart = commonWord4.Extract(12, 8); StoreReqEnd = commonWord4.Extract(24, 8); ImapTypes = new ImapPixelType[32]; for (int i = 0; i < 32; i++) { byte imap = (byte)(header[6 + (i >> 2)] >> ((i & 3) * 8)); ImapTypes[i] = new ImapPixelType( (PixelImap)((imap >> 0) & 3), (PixelImap)((imap >> 2) & 3), (PixelImap)((imap >> 4) & 3), (PixelImap)((imap >> 6) & 3)); } int type2OmapTarget = header[18]; int type2Omap = header[19]; OmapTargets = type2OmapTarget; OmapSampleMask = type2Omap.Extract(0); OmapDepth = type2Omap.Extract(1); }