Пример #1
0
        public void Visit(ShaderType type)
        {
            // Don't double process a type
            if (type == null || mProcessedTypes.Contains(type))
            {
                return;
            }

            // If we're a pointer, visit the dereference type but don't yet add the pointer type to the processed types.
            // This is because visiting the dereference type can visit functions that use the pointer type.
            // This would cause the function type to then be declared before the pointer type here.
            if (type.mBaseType == OpType.Pointer)
            {
                Visit(type.GetDereferenceType());
                if (mProcessedTypes.Contains(type))
                {
                    return;
                }
            }
            mProcessedTypes.Add(type);

            Visit(type.mParameters);
            Visit(type.mFields);
            // Only add this as a reference type once we finish walking fields/parameters. This is so we have guaranteed visit any nested types (or dereference types).
            mReferencedTypesConstantsAndGlobals.Add(type);
            VisitRequiredCapabilities(type);

            // Now visit the body of the functions and all of their ops
            Visit(type.mFunctions);
            foreach (var entryPoint in type.mEntryPoints)
            {
                Visit(entryPoint);
            }
        }
Пример #2
0
        public ShaderOp GenerateAccessChain(IShaderIR selfIR, ShaderType resultType, uint fieldIndex, FrontEndContext context)
        {
            var selfOp              = selfIR as ShaderOp;
            var constantLiteral     = CreateConstantLiteral(fieldIndex);
            var memberIndexConstant = CreateConstantOp(FindType(typeof(uint)), constantLiteral);

            resultType = FindOrCreatePointerType(resultType.GetDereferenceType(), selfOp.mResultType.mStorageClass);
            var memberVariableOp = CreateOp(context.mCurrentBlock, OpInstructionType.OpAccessChain, resultType, new List <IShaderIR> {
                selfOp, memberIndexConstant
            });

            return(memberVariableOp);
        }
Пример #3
0
        void WriteTypeDeclaration(ShaderType type, HashSet <UInt32> visitedTypeIds)
        {
            // Handle types existing more than once (for primitive deduping)
            var id = GetId(type);

            if (visitedTypeIds.Contains(id))
            {
                return;
            }
            visitedTypeIds.Add(id);

            if (type.mBaseType == OpType.Void)
            {
                mWriter.WriteInstruction(2, Spv.Op.OpTypeVoid, GetId(type));
            }
            else if (type.mBaseType == OpType.Bool)
            {
                mWriter.WriteInstruction(2, Spv.Op.OpTypeBool, GetId(type));
            }
            else if (type.mBaseType == OpType.Int)
            {
                mWriter.WriteInstruction(4, Spv.Op.OpTypeInt, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Float)
            {
                mWriter.WriteInstruction(3, Spv.Op.OpTypeFloat, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Vector)
            {
                mWriter.WriteInstruction(4, Spv.Op.OpTypeVector, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Matrix)
            {
                mWriter.WriteInstruction(4, Spv.Op.OpTypeMatrix, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Pointer)
            {
                var dereferenceType = type.GetDereferenceType();
                if (dereferenceType.mBaseType != OpType.Function)
                {
                    var storageClass = ConvertStorageClass(type.mStorageClass);
                    mWriter.WriteInstruction(4, Spv.Op.OpTypePointer, GetId(type), (UInt32)storageClass, GetId(dereferenceType));
                }
            }
            else if (type.mBaseType == OpType.Array)
            {
                mWriter.WriteInstruction(4, Spv.Op.OpTypeArray, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Struct)
            {
                UInt16 instructionSize = (UInt16)(2 + type.mFields.Count);
                mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeStruct, GetId(type));
                foreach (var field in type.mFields)
                {
                    mWriter.Write(GetId(field.mType));
                }
            }
            else if (type.mBaseType == OpType.Sampler)
            {
                UInt16 instructionSize = (UInt16)2;
                mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeSampler, GetId(type));
            }
            else if (type.mBaseType == OpType.Image)
            {
                UInt16 instructionSize = (UInt16)9;
                mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeImage, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.SampledImage)
            {
                UInt16 instructionSize = (UInt16)3;
                mWriter.WriteInstruction(instructionSize, Spv.Op.OpTypeSampledImage, GetId(type));
                WriteArgs(type.mParameters);
            }
            else if (type.mBaseType == OpType.Function)
            {
                var instructionSize = 2 + type.mParameters.Count;
                mWriter.WriteInstruction((UInt16)(instructionSize), Spv.Op.OpTypeFunction, GetId(type));
                WriteArgs(type.mParameters);
            }
            else
            {
                throw new Exception();
            }
        }
Пример #4
0
 static public ShaderType GetValueType(ShaderType shaderType)
 {
     return(shaderType.GetDereferenceType());
 }