private static void Tex(EmitterContext context, TextureFlags flags) { OpCodeTexture op = (OpCodeTexture)context.CurrOp; bool isBindless = (flags & TextureFlags.Bindless) != 0; bool intCoords = (flags & TextureFlags.IntCoords) != 0; if (op.Rd.IsRZ) { return; } int raIndex = op.Ra.Index; int rbIndex = op.Rb.Index; Operand Ra() { if (raIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(context.Copy(Register(raIndex++, RegisterType.Gpr))); } Operand Rb() { if (rbIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(context.Copy(Register(rbIndex++, RegisterType.Gpr))); } Operand arrayIndex = op.IsArray ? Ra() : null; List <Operand> sourcesList = new List <Operand>(); if (isBindless) { sourcesList.Add(Rb()); } TextureType type = GetTextureType(op.Dimensions); int coordsCount = type.GetCoordsCount(); for (int index = 0; index < coordsCount; index++) { sourcesList.Add(Ra()); } if (op.IsArray) { sourcesList.Add(arrayIndex); type |= TextureType.Array; } bool hasLod = op.LodMode > TextureLodMode.LodZero; Operand lodValue = hasLod ? Rb() : ConstF(0); Operand packedOffs = op.HasOffset ? Rb() : null; if (op.HasDepthCompare) { sourcesList.Add(Rb()); type |= TextureType.Shadow; } if ((op.LodMode == TextureLodMode.LodZero || op.LodMode == TextureLodMode.LodLevel || op.LodMode == TextureLodMode.LodLevelA) && !op.IsMultisample) { sourcesList.Add(lodValue); flags |= TextureFlags.LodLevel; } if (op.HasOffset) { for (int index = 0; index < coordsCount; index++) { sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4))); } flags |= TextureFlags.Offset; } if (op.LodMode == TextureLodMode.LodBias || op.LodMode == TextureLodMode.LodBiasA) { sourcesList.Add(lodValue); flags |= TextureFlags.LodBias; } if (op.IsMultisample) { sourcesList.Add(Rb()); type |= TextureType.Multisample; } Operand[] sources = sourcesList.ToArray(); int rdIndex = op.Rd.Index; Operand GetDest() { if (rdIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(Register(rdIndex++, RegisterType.Gpr)); } int handle = !isBindless ? op.Immediate : 0; for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) { if ((compMask & 1) != 0) { Operand dest = GetDest(); TextureOperation operation = new TextureOperation( Instruction.TextureSample, type, flags, handle, compIndex, dest, sources); context.Add(operation); } } }
public static void Tld4(EmitterContext context) { OpCodeTld4 op = (OpCodeTld4)context.CurrOp; if (op.Rd.IsRZ) { return; } int raIndex = op.Ra.Index; int rbIndex = op.Rb.Index; Operand Ra() { if (raIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(context.Copy(Register(raIndex++, RegisterType.Gpr))); } Operand Rb() { if (rbIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(context.Copy(Register(rbIndex++, RegisterType.Gpr))); } Operand arrayIndex = op.IsArray ? Ra() : null; List <Operand> sourcesList = new List <Operand>(); TextureType type = GetTextureType(op.Dimensions); TextureFlags flags = TextureFlags.Gather; int coordsCount = type.GetCoordsCount(); for (int index = 0; index < coordsCount; index++) { sourcesList.Add(Ra()); } if (op.IsArray) { sourcesList.Add(arrayIndex); type |= TextureType.Array; } Operand[] packedOffs = new Operand[2]; packedOffs[0] = op.Offset != TextureGatherOffset.None ? Rb() : null; packedOffs[1] = op.Offset == TextureGatherOffset.Offsets ? Rb() : null; if (op.HasDepthCompare) { sourcesList.Add(Rb()); type |= TextureType.Shadow; } if (op.Offset != TextureGatherOffset.None) { int offsetTexelsCount = op.Offset == TextureGatherOffset.Offsets ? 4 : 1; for (int index = 0; index < coordsCount * offsetTexelsCount; index++) { Operand packed = packedOffs[(index >> 2) & 1]; sourcesList.Add(context.BitfieldExtractS32(packed, Const((index & 3) * 8), Const(6))); } flags |= op.Offset == TextureGatherOffset.Offsets ? TextureFlags.Offsets : TextureFlags.Offset; } sourcesList.Add(Const(op.GatherCompIndex)); Operand[] sources = sourcesList.ToArray(); int rdIndex = op.Rd.Index; Operand GetDest() { if (rdIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(Register(rdIndex++, RegisterType.Gpr)); } int handle = op.Immediate; for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) { if ((compMask & 1) != 0) { Operand dest = GetDest(); TextureOperation operation = new TextureOperation( Instruction.TextureSample, type, flags, handle, compIndex, dest, sources); context.Add(operation); } } }