Exemplo n.º 1
0
        public static byte[] Generate(StructuredProgramInfo info, ShaderConfig config)
        {
            CodeGenContext context = new CodeGenContext(config);

            context.AddCapability(Capability.GroupNonUniformBallot);
            context.AddCapability(Capability.ImageBuffer);
            context.AddCapability(Capability.SampledBuffer);
            context.AddCapability(Capability.SubgroupBallotKHR);
            context.AddCapability(Capability.SubgroupVoteKHR);
            context.AddExtension("SPV_KHR_shader_ballot");
            context.AddExtension("SPV_KHR_subgroup_vote");

            Declarations.DeclareAll(context, info);

            if ((info.HelperFunctionsMask & NeedsInvocationIdMask) != 0)
            {
                Declarations.DeclareInvocationId(context);
            }

            for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
            {
                var function = info.Functions[funcIndex];
                var retType  = context.GetType(function.ReturnType.Convert());

                var funcArgs = new SpvInstruction[function.InArguments.Length + function.OutArguments.Length];

                for (int argIndex = 0; argIndex < funcArgs.Length; argIndex++)
                {
                    var argType        = context.GetType(function.GetArgumentType(argIndex).Convert());
                    var argPointerType = context.TypePointer(StorageClass.Function, argType);
                    funcArgs[argIndex] = argPointerType;
                }

                var funcType = context.TypeFunction(retType, false, funcArgs);
                var spvFunc  = context.Function(retType, FunctionControlMask.MaskNone, funcType);

                context.DeclareFunction(funcIndex, function, spvFunc);
            }

            for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
            {
                Generate(context, info, funcIndex);
            }

            return(context.Generate());
        }
Exemplo n.º 2
0
        private static void DeclareParameters(CodeGenContext context, IEnumerable <VariableType> argTypes, int argIndex)
        {
            foreach (var argType in argTypes)
            {
                var argPointerType = context.TypePointer(StorageClass.Function, context.GetType(argType.Convert()));
                var spvArg         = context.FunctionParameter(argPointerType);

                context.DeclareArgument(argIndex++, spvArg);
            }
        }
Exemplo n.º 3
0
        public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
        {
            foreach (AstOperand local in function.Locals)
            {
                var localPointerType = context.TypePointer(StorageClass.Function, context.GetType(local.VarType.Convert()));
                var spvLocal         = context.Variable(localPointerType, StorageClass.Function);

                context.AddLocalVariable(spvLocal);
                context.DeclareLocal(local, spvLocal);
            }
        }
Exemplo n.º 4
0
        private static void DeclareImages(CodeGenContext context, TextureDescriptor[] descriptors)
        {
            foreach (var descriptor in descriptors)
            {
                var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format);

                if (context.Images.ContainsKey(meta))
                {
                    continue;
                }

                int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? 3 : 0;

                var dim = GetDim(descriptor.Type);

                var imageType = context.TypeImage(
                    context.GetType(meta.Format.GetComponentType().Convert()),
                    dim,
                    descriptor.Type.HasFlag(SamplerType.Shadow),
                    descriptor.Type.HasFlag(SamplerType.Array),
                    descriptor.Type.HasFlag(SamplerType.Multisample),
                    AccessQualifier.ReadWrite,
                    GetImageFormat(meta.Format));

                var nameSuffix = meta.CbufSlot < 0 ?
                                 $"_tcb_{meta.Handle:X}_{meta.Format.ToGlslFormat()}" :
                                 $"_cb{meta.CbufSlot}_{meta.Handle:X}_{meta.Format.ToGlslFormat()}";

                var imagePointerType = context.TypePointer(StorageClass.UniformConstant, imageType);
                var imageVariable    = context.Variable(imagePointerType, StorageClass.UniformConstant);

                context.Images.Add(meta, (imageType, imageVariable));

                context.Name(imageVariable, $"{GetStagePrefix(context.Config.Stage)}_img{nameSuffix}");
                context.Decorate(imageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
                context.Decorate(imageVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding);

                if (descriptor.Flags.HasFlag(TextureUsageFlags.ImageCoherent))
                {
                    context.Decorate(imageVariable, Decoration.Coherent);
                }

                context.AddGlobalVariable(imageVariable);
            }
        }
Exemplo n.º 5
0
        public static void DeclareLocalForArgs(CodeGenContext context, List <StructuredFunction> functions)
        {
            for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++)
            {
                StructuredFunction function = functions[funcIndex];
                SpvInstruction[]   locals   = new SpvInstruction[function.InArguments.Length];

                for (int i = 0; i < function.InArguments.Length; i++)
                {
                    var type             = function.GetArgumentType(i).Convert();
                    var localPointerType = context.TypePointer(StorageClass.Function, context.GetType(type));
                    var spvLocal         = context.Variable(localPointerType, StorageClass.Function);

                    context.AddLocalVariable(spvLocal);

                    locals[i] = spvLocal;
                }

                context.DeclareLocalForArgs(funcIndex, locals);
            }
        }
Exemplo n.º 6
0
        public static byte[] Generate(StructuredProgramInfo info, ShaderConfig config)
        {
            SpvInstructionPool    instPool;
            SpvLiteralIntegerPool integerPool;

            lock (PoolLock)
            {
                instPool    = InstructionPool.Allocate();
                integerPool = IntegerPool.Allocate();
            }

            CodeGenContext context = new CodeGenContext(info, config, instPool, integerPool);

            context.AddCapability(Capability.GroupNonUniformBallot);
            context.AddCapability(Capability.ImageBuffer);
            context.AddCapability(Capability.ImageGatherExtended);
            context.AddCapability(Capability.ImageQuery);
            context.AddCapability(Capability.SampledBuffer);
            context.AddCapability(Capability.SubgroupBallotKHR);
            context.AddCapability(Capability.SubgroupVoteKHR);

            if (config.TransformFeedbackEnabled && config.LastInVertexPipeline)
            {
                context.AddCapability(Capability.TransformFeedback);
            }

            if (config.Stage == ShaderStage.Fragment && context.Config.GpuAccessor.QueryHostSupportsFragmentShaderInterlock())
            {
                context.AddCapability(Capability.FragmentShaderPixelInterlockEXT);
                context.AddExtension("SPV_EXT_fragment_shader_interlock");
            }
            else if (config.Stage == ShaderStage.Geometry)
            {
                context.AddCapability(Capability.Geometry);

                if (config.GpPassthrough && context.Config.GpuAccessor.QueryHostSupportsGeometryShaderPassthrough())
                {
                    context.AddExtension("SPV_NV_geometry_shader_passthrough");
                    context.AddCapability(Capability.GeometryShaderPassthroughNV);
                }
            }
            else if (config.Stage == ShaderStage.TessellationControl || config.Stage == ShaderStage.TessellationEvaluation)
            {
                context.AddCapability(Capability.Tessellation);
            }

            context.AddExtension("SPV_KHR_shader_ballot");
            context.AddExtension("SPV_KHR_subgroup_vote");

            Declarations.DeclareAll(context, info);

            if ((info.HelperFunctionsMask & NeedsInvocationIdMask) != 0)
            {
                Declarations.DeclareInvocationId(context);
            }

            for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
            {
                var function = info.Functions[funcIndex];
                var retType  = context.GetType(function.ReturnType.Convert());

                var funcArgs = new SpvInstruction[function.InArguments.Length + function.OutArguments.Length];

                for (int argIndex = 0; argIndex < funcArgs.Length; argIndex++)
                {
                    var argType        = context.GetType(function.GetArgumentType(argIndex).Convert());
                    var argPointerType = context.TypePointer(StorageClass.Function, argType);
                    funcArgs[argIndex] = argPointerType;
                }

                var funcType = context.TypeFunction(retType, false, funcArgs);
                var spvFunc  = context.Function(retType, FunctionControlMask.MaskNone, funcType);

                context.DeclareFunction(funcIndex, function, spvFunc);
            }

            for (int funcIndex = 0; funcIndex < info.Functions.Count; funcIndex++)
            {
                Generate(context, info, funcIndex);
            }

            byte[] result = context.Generate();

            lock (PoolLock)
            {
                InstructionPool.Release(instPool);
                IntegerPool.Release(integerPool);
            }

            return(result);
        }