private static void DeclareSamplers(CodeGenContext context, TextureDescriptor[] descriptors) { foreach (var descriptor in descriptors) { var meta = new TextureMeta(descriptor.CbufSlot, descriptor.HandleIndex, descriptor.Format, descriptor.Type); if (context.Samplers.ContainsKey(meta)) { continue; } bool isBuffer = (descriptor.Type & SamplerType.Mask) == SamplerType.TextureBuffer; int setIndex = context.Config.Options.TargetApi == TargetApi.Vulkan ? (isBuffer ? 4 : 2) : 0; var dim = (meta.Type & SamplerType.Mask) switch { SamplerType.Texture1D => Dim.Dim1D, SamplerType.Texture2D => Dim.Dim2D, SamplerType.Texture3D => Dim.Dim3D, SamplerType.TextureCube => Dim.Cube, SamplerType.TextureBuffer => Dim.Buffer, _ => throw new InvalidOperationException($"Invalid sampler type \"{meta.Type & SamplerType.Mask}\".") }; var imageType = context.TypeImage( context.TypeFP32(), dim, meta.Type.HasFlag(SamplerType.Shadow), meta.Type.HasFlag(SamplerType.Array), meta.Type.HasFlag(SamplerType.Multisample), 1, ImageFormat.Unknown); var nameSuffix = meta.CbufSlot < 0 ? $"_tcb_{meta.Handle:X}" : $"_cb{meta.CbufSlot}_{meta.Handle:X}"; var sampledImageType = context.TypeSampledImage(imageType); var sampledImagePointerType = context.TypePointer(StorageClass.UniformConstant, sampledImageType); var sampledImageVariable = context.Variable(sampledImagePointerType, StorageClass.UniformConstant); context.Samplers.Add(meta, (imageType, sampledImageType, sampledImageVariable)); context.Name(sampledImageVariable, $"{GetStagePrefix(context.Config.Stage)}_tex{nameSuffix}"); context.Decorate(sampledImageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex); context.Decorate(sampledImageVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding); context.AddGlobalVariable(sampledImageVariable); } }
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); } }