{"record":{"id":"21fd7bfc18262448","repo":"stride3d/stride","slug":"vulkan-only-simple-bordercolor-are-supported","errorCode":null,"errorMessage":"Vulkan: only simple BorderColor are supported","messagePattern":"Vulkan: only simple BorderColor are supported","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Vulkan/SamplerState.Vulkan.cs","lineNumber":76,"sourceCode":"                mipLodBias = Description.MipMapLevelOfDetailBias,\n                maxAnisotropy = Description.MaxAnisotropy,\n                compareOp = VulkanConvertExtensions.ConvertComparisonFunction(Description.CompareFunction),\n                minLod = Description.MinMipLevel,\n                maxLod = Description.MaxMipLevel,\n            };\n\n            if (Description.AddressU == TextureAddressMode.Border ||\n                Description.AddressV == TextureAddressMode.Border ||\n                Description.AddressW == TextureAddressMode.Border)\n            {\n                if (Description.BorderColor == Color4.White)\n                    createInfo.borderColor = VkBorderColor.FloatOpaqueWhite;\n                else if (Description.BorderColor == Color4.Black)\n                    createInfo.borderColor = VkBorderColor.FloatOpaqueBlack;\n                else if (Description.BorderColor == Color.Transparent)\n                    createInfo.borderColor = VkBorderColor.FloatTransparentBlack;\n                else\n                    throw new NotImplementedException(\"Vulkan: only simple BorderColor are supported\");\n            }\n\n            ConvertMinFilter(Description.Filter, out createInfo.minFilter, out createInfo.magFilter, out createInfo.mipmapMode, out createInfo.compareEnable, out createInfo.anisotropyEnable);\n\n            GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateSampler(GraphicsDevice.NativeDevice, &createInfo, null, out NativeSampler));\n        }\n\n        private static VkSamplerAddressMode ConvertAddressMode(TextureAddressMode addressMode)\n        {\n            switch (addressMode)\n            {\n                case TextureAddressMode.Wrap:\n                    return VkSamplerAddressMode.Repeat;\n                case TextureAddressMode.Border:\n                    return VkSamplerAddressMode.ClampToBorder;\n                case TextureAddressMode.Clamp:\n                    return VkSamplerAddressMode.ClampToEdge;\n                case TextureAddressMode.Mirror:","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Vulkan/SamplerState.Vulkan.cs#L58-L94","documentation":"Vulkan only accepts a fixed VkBorderColor enum (transparent/opaque black/white, float or int) for sampler border colors, while Stride's SamplerState lets you specify any Color. CreateNativeSampler maps only the well-known values (white, black, transparent) to Vulkan border colors and throws NotImplementedException for anything else, because an arbitrary color would require an integer border color setup or clamping workaround the backend doesn't implement.","triggerScenarios":"Creating (or recreating after device loss) a SamplerState whose Description.BorderColor is not Color4.White, Color4.Black, or Color.Transparent.","commonSituations":"Setting a custom tinted border color (e.g. Color.Red) on a sampler for clamp-to-border addressing; porting D3D11 code where arbitrary float border colors were allowed.","solutions":["Set SamplerStateDescription.BorderColor to one of the supported values: Color4.White, Color4.Black, or Color.Transparent.","If a custom border color is required, implement it in-shader (e.g. detect out-of-range UVs and output the color) instead of relying on the sampler.","Consider extending CreateNativeSampler to map nearest matching VkBorderColor (Float variants) if you control the engine code."],"exampleFix":"// before\nvar desc = new SamplerStateDescription(TextureAddressMode.ClampToBorder, Filter.Linear) { BorderColor = new Color4(1f, 0f, 0f, 1f) };\n// after\ndesc.BorderColor = Color4.Black;","handlingStrategy":"validation","validationCode":"static readonly Color4[] supported = { Color4.White, Color4.Black, Color.Transparent };\nif (!supported.Contains(desc.BorderColor))\n    throw new NotSupportedException(\"BorderColor must be White, Black, or Transparent on Vulkan\");","typeGuard":"bool HasSimpleBorderColor(SamplerStateDescription d) =>\n    d.BorderColor == Color4.White || d.BorderColor == Color4.Black || d.BorderColor == Color.Transparent;","tryCatchPattern":"try { sampler = new SamplerState(device, desc); }\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"BorderColor\")) { desc.BorderColor = Color4.Black; sampler = new SamplerState(device, desc); }","preventionTips":["Restrict sampler border colors to White/Black/Transparent in shared config","Remember D3D allows arbitrary border colors but this Vulkan backend does not","Implement custom border tinting in shaders if needed","Centralize sampler description creation so border values are validated once"],"tags":["vulkan","sampler","border-color","unsupported"],"backgroundTag":"unsupported-config-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}