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); } }