Example #1
0
        private static void EmitSured(
            EmitterContext context,
            SuDim dimensions,
            RedOp atomicOp,
            SuatomSize size,
            int imm,
            int srcA,
            int srcB,
            int srcC,
            bool byteAddress,
            bool isBindless)
        {
            SamplerType type = ConvertSamplerType(dimensions);

            if (type == SamplerType.None)
            {
                context.Config.GpuAccessor.Log("Invalid image reduction sampler type.");
                return;
            }

            Operand Ra()
            {
                if (srcA > RegisterConsts.RegisterZeroIndex)
                {
                    return(Const(0));
                }

                return(context.Copy(Register(srcA++, RegisterType.Gpr)));
            }

            Operand Rb()
            {
                if (srcB > RegisterConsts.RegisterZeroIndex)
                {
                    return(Const(0));
                }

                return(context.Copy(Register(srcB++, RegisterType.Gpr)));
            }

            List <Operand> sourcesList = new List <Operand>();

            if (isBindless)
            {
                sourcesList.Add(context.Copy(GetSrcReg(context, srcC)));
            }

            int coordsCount = type.GetDimensions();

            for (int index = 0; index < coordsCount; index++)
            {
                sourcesList.Add(Ra());
            }

            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
            {
                sourcesList.Add(Const(0));

                type &= ~SamplerType.Mask;
                type |= SamplerType.Texture2D;
            }

            if (type.HasFlag(SamplerType.Array))
            {
                sourcesList.Add(Ra());

                type |= SamplerType.Array;
            }

            if (byteAddress)
            {
                int xIndex = isBindless ? 1 : 0;

                sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(size)));
            }

            // TODO: FP and 64-bit formats.
            TextureFormat format = size == SuatomSize.Sd32 || size == SuatomSize.Sd64
                ? (isBindless ? TextureFormat.Unknown : context.Config.GetTextureFormatAtomic(imm))
                : GetTextureFormat(size);

            sourcesList.Add(Rb());

            Operand[] sources = sourcesList.ToArray();

            TextureFlags flags = GetAtomicOpFlags((SuatomOp)atomicOp);

            if (isBindless)
            {
                flags |= TextureFlags.Bindless;
            }

            TextureOperation operation = context.CreateTextureOperation(
                Instruction.ImageAtomic,
                type,
                format,
                flags,
                imm,
                0,
                null,
                sources);

            context.Add(operation);
        }
Example #2
0
        private static void EmitSust(
            EmitterContext context,
            CacheOpSt cacheOp,
            SuDim dimensions,
            SuSize size,
            int imm,
            SuRgba componentMask,
            int srcA,
            int srcB,
            int srcC,
            bool useComponents,
            bool byteAddress,
            bool isBindless)
        {
            SamplerType type = ConvertSamplerType(dimensions);

            if (type == SamplerType.None)
            {
                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
                return;
            }

            Operand Ra()
            {
                if (srcA > RegisterConsts.RegisterZeroIndex)
                {
                    return(Const(0));
                }

                return(context.Copy(Register(srcA++, RegisterType.Gpr)));
            }

            Operand Rb()
            {
                if (srcB > RegisterConsts.RegisterZeroIndex)
                {
                    return(Const(0));
                }

                return(context.Copy(Register(srcB++, RegisterType.Gpr)));
            }

            List <Operand> sourcesList = new List <Operand>();

            if (isBindless)
            {
                sourcesList.Add(context.Copy(Register(srcC, RegisterType.Gpr)));
            }

            int coordsCount = type.GetDimensions();

            for (int index = 0; index < coordsCount; index++)
            {
                sourcesList.Add(Ra());
            }

            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
            {
                sourcesList.Add(Const(0));

                type &= ~SamplerType.Mask;
                type |= SamplerType.Texture2D;
            }

            if (type.HasFlag(SamplerType.Array))
            {
                sourcesList.Add(Ra());
            }

            TextureFormat format = TextureFormat.Unknown;

            if (useComponents)
            {
                for (int compMask = (int)componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
                {
                    if ((compMask & 1) != 0)
                    {
                        sourcesList.Add(Rb());
                    }
                }

                if (!isBindless)
                {
                    format = context.Config.GetTextureFormat(imm);
                }
            }
            else
            {
                if (byteAddress)
                {
                    int xIndex = isBindless ? 1 : 0;

                    sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(size)));
                }

                int components = GetComponents(size);

                for (int compIndex = 0; compIndex < components; compIndex++)
                {
                    sourcesList.Add(Rb());
                }

                format = GetTextureFormat(size);
            }

            Operand[] sources = sourcesList.ToArray();

            int handle = imm;

            TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;

            if (cacheOp == CacheOpSt.Cg)
            {
                flags |= TextureFlags.Coherent;
            }

            TextureOperation operation = context.CreateTextureOperation(
                Instruction.ImageStore,
                type,
                format,
                flags,
                handle,
                0,
                null,
                sources);

            context.Add(operation);
        }
Example #3
0
        private static void EmitSuld(
            EmitterContext context,
            CacheOpLd cacheOp,
            SuDim dimensions,
            SuSize size,
            int imm,
            SuRgba componentMask,
            int srcA,
            int srcB,
            int srcC,
            bool useComponents,
            bool byteAddress,
            bool isBindless)
        {
            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);

            SamplerType type = ConvertSamplerType(dimensions);

            if (type == SamplerType.None)
            {
                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
                return;
            }

            Operand Ra()
            {
                if (srcA > RegisterConsts.RegisterZeroIndex)
                {
                    return(Const(0));
                }

                return(context.Copy(Register(srcA++, RegisterType.Gpr)));
            }

            List <Operand> sourcesList = new List <Operand>();

            if (isBindless)
            {
                sourcesList.Add(context.Copy(Register(srcC, RegisterType.Gpr)));
            }

            int coordsCount = type.GetDimensions();

            for (int index = 0; index < coordsCount; index++)
            {
                sourcesList.Add(Ra());
            }

            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
            {
                sourcesList.Add(Const(0));

                type &= ~SamplerType.Mask;
                type |= SamplerType.Texture2D;
            }

            if (type.HasFlag(SamplerType.Array))
            {
                sourcesList.Add(Ra());
            }

            Operand[] sources = sourcesList.ToArray();

            int handle = imm;

            TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;

            if (cacheOp == CacheOpLd.Cg)
            {
                flags |= TextureFlags.Coherent;
            }

            if (useComponents)
            {
                for (int compMask = (int)componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
                {
                    if ((compMask & 1) == 0)
                    {
                        continue;
                    }

                    if (srcB == RegisterConsts.RegisterZeroIndex)
                    {
                        break;
                    }

                    Operand rd = Register(srcB++, RegisterType.Gpr);

                    TextureOperation operation = context.CreateTextureOperation(
                        Instruction.ImageLoad,
                        type,
                        flags,
                        handle,
                        compIndex,
                        rd,
                        sources);

                    if (!isBindless)
                    {
                        operation.Format = context.Config.GetTextureFormat(handle);
                    }

                    context.Add(operation);
                }
            }
            else
            {
                if (byteAddress)
                {
                    int xIndex = isBindless ? 1 : 0;

                    sources[xIndex] = context.ShiftRightS32(sources[xIndex], Const(GetComponentSizeInBytesLog2(size)));
                }

                int components = GetComponents(size);

                for (int compIndex = 0; compIndex < components; compIndex++)
                {
                    if (srcB == RegisterConsts.RegisterZeroIndex)
                    {
                        break;
                    }

                    Operand rd = Register(srcB++, RegisterType.Gpr);

                    TextureOperation operation = context.CreateTextureOperation(
                        Instruction.ImageLoad,
                        type,
                        GetTextureFormat(size),
                        flags,
                        handle,
                        compIndex,
                        rd,
                        sources);

                    context.Add(operation);

                    switch (size)
                    {
                    case SuSize.U8: context.Copy(rd, ZeroExtendTo32(context, rd, 8)); break;

                    case SuSize.U16: context.Copy(rd, ZeroExtendTo32(context, rd, 16)); break;

                    case SuSize.S8: context.Copy(rd, SignExtendTo32(context, rd, 8)); break;

                    case SuSize.S16: context.Copy(rd, SignExtendTo32(context, rd, 16)); break;
                    }
                }
            }
        }