Esempio n. 1
0
        ShaderType CreateIntType(FrontEndTranslator translator, Type type, uint width, uint signedness)
        {
            var floatType = translator.CreatePrimitive(type, OpType.Int);

            floatType.mParameters.Add(translator.CreateConstantLiteral(width));
            floatType.mParameters.Add(translator.CreateConstantLiteral(signedness));
            return(floatType);
        }
Esempio n. 2
0
        public static void AddDecorationMemberMatrixMajor(FrontEndTranslator translator, ShaderType shaderType, int fieldIndex, Spv.Decoration decoration, ShaderBlock decorationsBlock)
        {
            var decorationOffsetLiteral = translator.CreateConstantLiteral((int)decoration);
            var fieldIndexLiteral       = translator.CreateConstantLiteral(fieldIndex);

            translator.CreateOp(decorationsBlock, OpInstructionType.OpMemberDecorate, null, new List <IShaderIR>()
            {
                shaderType, fieldIndexLiteral, decorationOffsetLiteral
            });
        }
Esempio n. 3
0
        public static void AddDecorationLocation(FrontEndTranslator translator, ShaderOp instanceOp, int location, ShaderBlock decorationsBlock)
        {
            var decorationLocationLiteral = translator.CreateConstantLiteral((int)Spv.Decoration.DecorationLocation);
            var locationLiteral           = translator.CreateConstantLiteral(location);

            translator.CreateOp(decorationsBlock, OpInstructionType.OpDecorate, null, new List <IShaderIR>()
            {
                instanceOp, decorationLocationLiteral, locationLiteral
            });
        }
Esempio n. 4
0
        public static void AddDecorationDescriptorSet(FrontEndTranslator translator, IShaderIR ir, int descriptorSetId, ShaderBlock decorationsBlock)
        {
            var decorationBindingLiteral = translator.CreateConstantLiteral((int)Spv.Decoration.DecorationDescriptorSet);
            var descriptorSetIdLiteral   = translator.CreateConstantLiteral(descriptorSetId);

            translator.CreateOp(decorationsBlock, OpInstructionType.OpDecorate, null, new List <IShaderIR>()
            {
                ir, decorationBindingLiteral, descriptorSetIdLiteral
            });
        }
Esempio n. 5
0
        public static void AddDecorationBuiltIn(FrontEndTranslator translator, ShaderOp instanceOp, Spv.BuiltIn builtInType, ShaderBlock decorationsBlock)
        {
            var decorationBuiltInLiteral = translator.CreateConstantLiteral((int)Spv.Decoration.DecorationBuiltIn);
            var builtInTypeLiteral       = translator.CreateConstantLiteral((int)builtInType);

            translator.CreateOp(decorationsBlock, OpInstructionType.OpDecorate, null, new List <IShaderIR>()
            {
                instanceOp, decorationBuiltInLiteral, builtInTypeLiteral
            });
        }
Esempio n. 6
0
        public static ShaderType ProcessIntegerType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            var width  = (UInt32)attribute.ConstructorArguments[0].Value;
            var signed = (bool)attribute.ConstructorArguments[1].Value;

            var shaderType = translator.CreateType(typeSymbol, OpType.Int);

            shaderType.mParameters.Add(translator.CreateConstantLiteral(width));
            var signedness = translator.CreateConstantLiteral <uint>(signed ? 1u : 0u);

            shaderType.mParameters.Add(signedness);

            return(shaderType);
        }
 static void WriteArguments(FrontEndTranslator translator, FrontEndContext context, List <IShaderIR> valueOps, ImageIntrinsicAttributeData intrinsicData, List <IShaderIR> arguments, int startIndex)
 {
     // If there's no operands location, then just write the arguments as is. It's only if there's a mask and location that we write this (since not all image ops have a mask).
     if (intrinsicData.OperandsLocation == -1)
     {
         for (var i = startIndex; i < arguments.Count; ++i)
         {
             valueOps.Add(translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[i]));
         }
     }
     // Otherwise, add all of the given arguments, but put the operands mask in-between based upon the specified location.
     // This location isn't consistent for all image functions so it became an exposed value.
     else
     {
         for (var i = startIndex; i < intrinsicData.OperandsLocation && i < arguments.Count; ++i)
         {
             valueOps.Add(translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[i]));
         }
         valueOps.Add(translator.CreateConstantLiteral((UInt32)intrinsicData.Operands));
         for (var i = intrinsicData.OperandsLocation; i < arguments.Count; ++i)
         {
             valueOps.Add(translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[i]));
         }
     }
 }
Esempio n. 8
0
        public static void ResolveVectorSwizzleGetter(FrontEndTranslator translator, FrontEndContext context, AttributeData attribute, ISymbol returnType, List <IShaderIR> arguments)
        {
            var swizzleElements = attribute.ConstructorArguments[0].Values;
            var self            = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, arguments[0]);
            var resultType      = translator.mCurrentLibrary.FindType(new TypeKey(returnType));

            // By default, assume the swizzle is 1 element (just a composite extract)
            var swizzleArgs = new List <IShaderIR>()
            {
                self
            };
            var opType = OpInstructionType.OpCompositeExtract;

            // If it's multiple elements, change this to a vector shuffle
            if (swizzleElements.Length != 1)
            {
                swizzleArgs.Add(self);
                opType = OpInstructionType.OpVectorShuffle;
            }
            // Add all elements to grab for the swizzle from the attribute
            foreach (var element in swizzleElements)
            {
                swizzleArgs.Add(translator.CreateConstantLiteral((UInt32)element.Value));
            }

            var op = translator.CreateOp(context.mCurrentBlock, opType, resultType, swizzleArgs);

            context.Push(op);
        }
Esempio n. 9
0
        public static void AddDecorationBlock(FrontEndTranslator translator, ShaderType shaderType, ShaderBlock decorationsBlock)
        {
            var decorationBlockLiteral = translator.CreateConstantLiteral((int)Spv.Decoration.DecorationBlock);

            translator.CreateOp(decorationsBlock, OpInstructionType.OpDecorate, null, new List <IShaderIR>()
            {
                shaderType, decorationBlockLiteral
            });
        }
Esempio n. 10
0
        public static ShaderType ProcessFloatType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            var width = (UInt32)attribute.ConstructorArguments[0].Value;

            var shaderType = translator.CreateType(typeSymbol, OpType.Float);

            shaderType.mParameters.Add(translator.CreateConstantLiteral(width));

            return(shaderType);
        }
Esempio n. 11
0
        public static void AddExecutionMode(FrontEndTranslator translator, ShaderEntryPointInfo entryPointInfo, ShaderFunction entryPointFn, Spv.ExecutionMode executionMode)
        {
            var library = translator.mCurrentLibrary;
            var executionModeLiteral = translator.CreateConstantLiteral(library.FindType(new TypeKey(typeof(int))), ((int)executionMode).ToString());
            var executionModeOp      = translator.CreateOp(OpInstructionType.OpExecutionMode, null, new List <IShaderIR> {
                entryPointFn, executionModeLiteral
            });

            entryPointInfo.mExecutionModesBlock.mOps.Add(executionModeOp);
        }
Esempio n. 12
0
        public static ShaderType ProcessVectorType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            var componentType  = translator.FindType(new TypeKey(attribute.ConstructorArguments[0].Value as ISymbol));
            var componentCount = (UInt32)attribute.ConstructorArguments[1].Value;

            var shaderType = translator.CreateType(typeSymbol, OpType.Vector);

            shaderType.mParameters.Add(componentType);
            shaderType.mParameters.Add(translator.CreateConstantLiteral(componentCount));

            ProcessVectorDefaultConstructor(translator, typeSymbol, shaderType);

            return(shaderType);
        }
Esempio n. 13
0
        /// <summary>
        /// Does a simple extension intrinsic (one where all ops are value types).
        /// </summary>
        static void ResolveSimpleExtensionIntrinsic(FrontEndTranslator translator, FrontEndContext context, string extensionName, int extOpType, ShaderType returnType, List <IShaderIR> arguments)
        {
            var extensionImportOp = translator.mCurrentLibrary.GetOrCreateExtensionLibraryImport(extensionName);
            var extOpTypeOp       = translator.CreateConstantLiteral(extOpType);

            var valueOps = new List <IShaderIR>();

            valueOps.Add(extensionImportOp);
            valueOps.Add(extOpTypeOp);
            foreach (var argument in arguments)
            {
                valueOps.Add(translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, argument));
            }
            var op = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpExtInst, returnType, valueOps);

            context.Push(op);
        }
Esempio n. 14
0
        public void GenerateLoopHeaderBlock(ShaderBlock headerBlock, ShaderBlock branchTarget, ShaderBlock mergeBlock, ShaderBlock continueBlock, FrontEndContext context)
        {
            // Mark the header block as a loop block (so we emit the LoopMerge instruction)
            headerBlock.mBlockType = BlockType.Loop;
            // Being a LoopMerge requires setting the merge and continue points
            headerBlock.mMergePoint    = mergeBlock;
            headerBlock.mContinuePoint = continueBlock;

            var loopControlMask = mFrontEnd.CreateConstantLiteral <uint>((uint)Spv.LoopControlMask.LoopControlMaskNone);

            mFrontEnd.CreateOp(headerBlock, OpInstructionType.OpLoopMerge, null, new List <IShaderIR> {
                mergeBlock, continueBlock, loopControlMask
            });
            // The header always jumps to the branch target (typically a continue)
            mFrontEnd.CreateOp(headerBlock, OpInstructionType.OpBranch, null, new List <IShaderIR> {
                branchTarget
            });
        }
Esempio n. 15
0
        public static ShaderType ProcessMatrixType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            ShaderType columnType  = null;
            UInt32     columnCount = 0;

            if (!ValidateMatrixPrimitive(translator, typeSymbol, attribute, out columnType, out columnCount))
            {
                return(null);
            }

            var shaderType = translator.CreateType(typeSymbol, OpType.Matrix);

            shaderType.mParameters.Add(columnType);
            shaderType.mParameters.Add(translator.CreateConstantLiteral(columnCount));

            RegisterMatrixConstructors(translator, typeSymbol, shaderType, columnType, columnCount);

            return(shaderType);
        }
Esempio n. 16
0
        public static void ResolveVectorSwizzleSetter(FrontEndTranslator translator, FrontEndContext context, AttributeData attribute, ISymbol returnType, IShaderIR selfInstance, IShaderIR rhsIR)
        {
            var swizzleElements = attribute.ConstructorArguments[0].Values;
            var selfValue       = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, selfInstance);
            var selfValueType   = selfValue.mResultType.GetDereferenceType();
            var componentCount  = (UInt32)(selfValueType.mParameters[1] as ShaderConstantLiteral).mValue;

            var rhs = translator.GetOrGenerateValueTypeFromIR(context.mCurrentBlock, rhsIR);

            // If we're setting just a single element, then do an access chain and to set that element
            if (swizzleElements.Length == 1)
            {
                // Find what element we're setting
                var constantLiteral     = translator.CreateConstantLiteral((UInt32)swizzleElements[0].Value);
                var memberIndexConstant = translator.CreateConstantOp(translator.FindType(typeof(uint)), constantLiteral);
                // Lookup the result type
                var resultType = translator.mCurrentLibrary.FindType(new TypeKey(returnType));
                resultType = resultType.FindPointerType(selfValue.mResultType.mStorageClass);
                // Build the access chain to the element
                var memberVariableOp = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpAccessChain, resultType, new List <IShaderIR> {
                    selfInstance, memberIndexConstant
                });

                // Then set this back to the lhs side
                translator.CreateStoreOp(context.mCurrentBlock, memberVariableOp, rhs);
            }
            // Otherwise construct a new vector and set it over
            else
            {
                var swizzleArgs = new List <IShaderIR>()
                {
                    selfValue, rhs
                };

                // Build up a set of what element indices were in the swizzle
                var elementSet = new HashSet <UInt32>();
                foreach (var element in swizzleElements)
                {
                    elementSet.Add((UInt32)element.Value);
                }

                // Foreach element in the new vector, choose if we take it from the rhs or the lhs. If the element index is in the swizzle ops,
                // then take the next element from rhs, otherwise take the same index from lhs.
                var rhsElementIndex = 0u;
                for (uint element = 0; element < componentCount; ++element)
                {
                    if (elementSet.Contains(element))
                    {
                        swizzleArgs.Add(translator.CreateConstantLiteral(componentCount + rhsElementIndex));
                        ++rhsElementIndex;
                    }
                    else
                    {
                        swizzleArgs.Add(translator.CreateConstantLiteral(element));
                    }
                }
                // To build the setter, first create the new vector from components in the lhs/rhs as appropriate.
                var op = translator.CreateOp(context.mCurrentBlock, OpInstructionType.OpVectorShuffle, selfValueType, swizzleArgs);
                // Then set this back to the lhs side
                translator.CreateStoreOp(context.mCurrentBlock, selfInstance, op);
            }
        }
Esempio n. 17
0
        public static ShaderType ProcessImageType(FrontEndTranslator translator, INamedTypeSymbol typeSymbol, AttributeData attribute)
        {
            ShaderType sampledType = null;

            Shader.ImageDimension        dimension        = Shader.ImageDimension.Dim2D;
            Shader.ImageDepthMode        depthMode        = Shader.ImageDepthMode.None;
            Shader.ImageArrayedMode      arrayedMode      = Shader.ImageArrayedMode.None;
            Shader.ImageMultiSampledMode multiSampledMode = Shader.ImageMultiSampledMode.SingleSampled;
            Shader.ImageSampledMode      sampledMode      = Shader.ImageSampledMode.Sampling;
            Shader.ImageFormat           imageFormat      = Shader.ImageFormat.Unknown;

            // Load all constructor args by type.
            foreach (var argument in attribute.ConstructorArguments)
            {
                var argName = TypeAliases.GetTypeName(argument.Type);
                if (argName == TypeAliases.GetTypeName <Type>())
                {
                    sampledType = translator.FindType(new TypeKey(argument.Value as ITypeSymbol));
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageDimension>())
                {
                    dimension = (Shader.ImageDimension)argument.Value;
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageDepthMode>())
                {
                    depthMode = (Shader.ImageDepthMode)argument.Value;
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageArrayedMode>())
                {
                    arrayedMode = (Shader.ImageArrayedMode)argument.Value;
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageMultiSampledMode>())
                {
                    multiSampledMode = (Shader.ImageMultiSampledMode)argument.Value;
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageSampledMode>())
                {
                    sampledMode = (Shader.ImageSampledMode)argument.Value;
                }
                else if (argName == TypeAliases.GetTypeName <Shader.ImageFormat>())
                {
                    imageFormat = (Shader.ImageFormat)argument.Value;
                }
            }
            // Handle named arguments
            foreach (var pair in attribute.NamedArguments)
            {
                if (pair.Key == "SampledType")
                {
                    sampledType = translator.FindType(new TypeKey(pair.Value.Value as ITypeSymbol));
                }
                else if (pair.Key == "Dimension")
                {
                    dimension = (Shader.ImageDimension)pair.Value.Value;
                }
                else if (pair.Key == "DepthMode")
                {
                    depthMode = (Shader.ImageDepthMode)pair.Value.Value;
                }
                else if (pair.Key == "ArrayedMode")
                {
                    arrayedMode = (Shader.ImageArrayedMode)pair.Value.Value;
                }
                else if (pair.Key == "MultiSampledMode")
                {
                    multiSampledMode = (Shader.ImageMultiSampledMode)pair.Value.Value;
                }
                else if (pair.Key == "SampledMode")
                {
                    sampledMode = (Shader.ImageSampledMode)pair.Value.Value;
                }
                else if (pair.Key == "ImageFormat")
                {
                    imageFormat = (Shader.ImageFormat)pair.Value.Value;
                }
            }

            // Validate input type. SpirV spec says: "Sampled Type is the type of the components that result
            // from sampling or reading from this image type. Must be ascalar numerical type or OpTypeVoid"
            if (sampledType == null || (sampledType.mBaseType != OpType.Bool && sampledType.mBaseType != OpType.Int && sampledType.mBaseType != OpType.Float && sampledType.mBaseType != OpType.Void))
            {
                throw new Exception();
            }

            var shaderType = translator.CreateType(typeSymbol, OpType.Image);

            shaderType.mParameters.Add(sampledType);
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)dimension));
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)depthMode));
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)arrayedMode));
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)multiSampledMode));
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)sampledMode));
            shaderType.mParameters.Add(translator.CreateConstantLiteral((UInt32)imageFormat));
            shaderType.mStorageClass = StorageClass.UniformConstant;

            return(shaderType);
        }