public static void Sust(EmitterContext context) { OpCodeImage op = (OpCodeImage)context.CurrOp; SamplerType type = ConvertSamplerType(op.Dimensions); if (type == SamplerType.None) { context.Config.GpuAccessor.Log("Invalid image store sampler type."); 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))); } bool isArray = op.Dimensions == ImageDimensions.Image1DArray || op.Dimensions == ImageDimensions.Image2DArray; Operand arrayIndex = isArray ? Ra() : null; List <Operand> sourcesList = new List <Operand>(); if (op.IsBindless) { sourcesList.Add(context.Copy(Register(op.Rc))); } int coordsCount = type.GetDimensions(); for (int index = 0; index < coordsCount; index++) { sourcesList.Add(Ra()); } if (isArray) { sourcesList.Add(arrayIndex); type |= SamplerType.Array; } TextureFormat format = TextureFormat.Unknown; if (op.UseComponents) { int componentMask = (int)op.Components; for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) { if ((compMask & 1) != 0) { sourcesList.Add(Rb()); } } if (!op.IsBindless) { format = context.Config.GetTextureFormat(op.Immediate); } } else { if (op.ByteAddress) { int xIndex = op.IsBindless ? 1 : 0; sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(op.Size))); } int components = GetComponents(op.Size); for (int compIndex = 0; compIndex < components; compIndex++) { sourcesList.Add(Rb()); } format = GetTextureFormat(op.Size); } Operand[] sources = sourcesList.ToArray(); int handle = !op.IsBindless ? op.Immediate : 0; TextureFlags flags = op.IsBindless ? TextureFlags.Bindless : TextureFlags.None; TextureOperation operation = new TextureOperation( Instruction.ImageStore, type, flags, handle, 0, null, sources) { Format = format }; context.Add(operation); }
public static void Sust(EmitterContext context) { OpCodeImage op = (OpCodeImage)context.CurrOp; SamplerType type = ConvertSamplerType(op.Dimensions); if (type == SamplerType.None) { context.Config.PrintLog("Invalid image store sampler type."); 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))); } bool isArray = op.Dimensions == ImageDimensions.Image1DArray || op.Dimensions == ImageDimensions.Image2DArray; Operand arrayIndex = isArray ? Ra() : null; List <Operand> sourcesList = new List <Operand>(); if (op.IsBindless) { sourcesList.Add(context.Copy(Register(op.Rc))); } int coordsCount = type.GetDimensions(); for (int index = 0; index < coordsCount; index++) { sourcesList.Add(Ra()); } if (isArray) { sourcesList.Add(arrayIndex); type |= SamplerType.Array; } if (op.UseComponents) { int componentMask = (int)op.Components; for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) { if ((compMask & 1) != 0) { sourcesList.Add(Rb()); } } } else { context.Config.PrintLog("Unsized image store not supported."); } Operand[] sources = sourcesList.ToArray(); int handle = !op.IsBindless ? op.Immediate : 0; TextureFlags flags = op.IsBindless ? TextureFlags.Bindless : TextureFlags.None; TextureOperation operation = new TextureOperation( Instruction.ImageStore, type, flags, handle, 0, null, sources); context.Add(operation); }
public static void Suld(EmitterContext context) { OpCodeImage op = (OpCodeImage)context.CurrOp; SamplerType type = ConvertSamplerType(op.Dimensions); if (type == SamplerType.None) { context.Config.GpuAccessor.Log("Invalid image store sampler type."); return; } // Rb is Rd on the SULD instruction. int rdIndex = op.Rb.Index; int raIndex = op.Ra.Index; Operand Ra() { if (raIndex > RegisterConsts.RegisterZeroIndex) { return(Const(0)); } return(context.Copy(Register(raIndex++, RegisterType.Gpr))); } bool isArray = op.Dimensions == ImageDimensions.Image1DArray || op.Dimensions == ImageDimensions.Image2DArray; Operand arrayIndex = isArray ? Ra() : null; List <Operand> sourcesList = new List <Operand>(); if (op.IsBindless) { sourcesList.Add(context.Copy(Register(op.Rc))); } int coordsCount = type.GetDimensions(); for (int index = 0; index < coordsCount; index++) { sourcesList.Add(Ra()); } if (isArray) { sourcesList.Add(arrayIndex); type |= SamplerType.Array; } Operand[] sources = sourcesList.ToArray(); int handle = !op.IsBindless ? op.Immediate : 0; TextureFlags flags = op.IsBindless ? TextureFlags.Bindless : TextureFlags.None; if (op.UseComponents) { int componentMask = (int)op.Components; for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++) { if ((compMask & 1) == 0) { continue; } if (rdIndex == RegisterConsts.RegisterZeroIndex) { break; } Operand rd = Register(rdIndex++, RegisterType.Gpr); TextureOperation operation = new TextureOperation( Instruction.ImageLoad, type, flags, handle, compIndex, rd, sources); if (!op.IsBindless) { operation.Format = context.Config.GetTextureFormat(handle); } context.Add(operation); } } else { if (op.ByteAddress) { int xIndex = op.IsBindless ? 1 : 0; sources[xIndex] = context.ShiftRightS32(sources[xIndex], Const(GetComponentSizeInBytesLog2(op.Size))); } int components = GetComponents(op.Size); for (int compIndex = 0; compIndex < components; compIndex++) { if (rdIndex == RegisterConsts.RegisterZeroIndex) { break; } Operand rd = Register(rdIndex++, RegisterType.Gpr); TextureOperation operation = new TextureOperation( Instruction.ImageLoad, type, flags, handle, compIndex, rd, sources) { Format = GetTextureFormat(op.Size) }; context.Add(operation); switch (op.Size) { case IntegerSize.U8: context.Copy(rd, ZeroExtendTo32(context, rd, 8)); break; case IntegerSize.U16: context.Copy(rd, ZeroExtendTo32(context, rd, 16)); break; case IntegerSize.S8: context.Copy(rd, SignExtendTo32(context, rd, 8)); break; case IntegerSize.S16: context.Copy(rd, SignExtendTo32(context, rd, 16)); break; } } } }