~emersion/public-inbox

Add WebGPU formats v1 APPLIED

: 1
 Add WebGPU formats

 3 files changed, 398 insertions(+), 0 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/public-inbox/patches/38860/mbox | git am -3
Learn more about email & git

[PATCH] Add WebGPU formats Export this patch

From: i509VCB <git@i509.me>

Signed-off-by: i509VCB <git@i509.me>
---
 cmd/go-kdf/main.go |   8 +
 webgpu/formats.go  | 363 +++++++++++++++++++++++++++++++++++++++++++++
 webgpu/webgpu.go   |  27 ++++
 3 files changed, 398 insertions(+)
 create mode 100644 webgpu/formats.go
 create mode 100644 webgpu/webgpu.go

diff --git a/cmd/go-kdf/main.go b/cmd/go-kdf/main.go
index 31ce175..e6c8911 100644
--- a/cmd/go-kdf/main.go
+++ b/cmd/go-kdf/main.go
@@ -16,6 +16,7 @@ import (
	"git.sr.ht/~emersion/go-kdf/opengl"
	"git.sr.ht/~emersion/go-kdf/pixman"
	"git.sr.ht/~emersion/go-kdf/vulkan"
	"git.sr.ht/~emersion/go-kdf/webgpu"
)

const usage = `usage: go-kdf <command>
@@ -120,6 +121,13 @@ func main() {
				log.Fatalf("unknown Cairo format: %v", name)
			}
			block = cairo.GetBlock(fmt, endianness)
		} else if strings.HasPrefix(name, "GPUTextureFormat.") {
			fmt, ok := webgpu.FormatTable[strings.TrimPrefix(name, "GPUTextureFormat.")]
			if !ok {
				log.Fatalf("unknown WebGPU format: %v", name)
			}
			// TODO: How to deal with runtime params
			block = webgpu.GetBlock(fmt, endianness, true, true, true)
		} else if strings.HasPrefix(name, "AV_PIX_FMT_") {
			fmt, ok := ffmpeg.FormatTable[strings.TrimPrefix(name, "AV_PIX_FMT_")]
			if !ok {
diff --git a/webgpu/formats.go b/webgpu/formats.go
new file mode 100644
index 0000000..c72bf37
--- /dev/null
+++ b/webgpu/formats.go
@@ -0,0 +1,363 @@
package webgpu

import (
	"git.sr.ht/~emersion/go-kdf/vulkan"
)

const (
	// 8-bit formats
	FormatR8Unorm Format = 0
	FormatR8Snorm Format = 1
	FormatR8Uint Format = 2
	FormatR8Sint Format = 3

	// 16-bit formats
	FormatR16Uint Format = 4
	FormatR16Sint Format = 5
	FormatR16Float Format = 6
	FormatRg8Unorm Format = 7
	FormatRg8Snorm Format = 8
	FormatRg8Uint Format = 9
	FormatRg8Sint Format = 10

	// 32-bit formats
	FormatR32Uint Format = 11
	FormatR32Sint Format = 12
	FormatR32Float Format = 13
	FormatRg16Uint Format = 14
	FormatRg16Sint Format = 15
	FormatRg16Float Format = 16
	FormatRgba8Unorm Format = 17
	FormatRgba8UnormSrgb Format = 18
	FormatRgba8Snorm Format = 19
	FormatRgba8Uint Format = 20
	FormatRgba8Sint Format = 21
	FormatBgra8Unorm Format = 22
	FormatBgra8UnormSrgb Format = 23
	// Packed 32-bit formats
	FormatRgb9e5uFloat Format = 24
	FormatRgb10a2Unorm Format = 25
	FormatRg11b10Ufloat Format = 26

	// 64-bit formats
	FormatRg32Uint Format = 27
	FormatRg32Sint Format = 28
	FormatRg32Float Format = 29
	FormatRgba16Uint Format = 30
	FormatRgba16Sint Format = 31
	FormatRgba16Float Format = 32

	// 128-bit formats
	FormatRgba32Uint Format = 33
	FormatRgba32Sint Format = 34
	FormatRgba32Float Format = 35

	// Depth/stencil formats
	FormatStencil8 Format = 36
	FormatDepth16Unorm Format = 37
	FormatDepth24Plus Format = 38
	FormatDepth24PlusStencil8 Format = 39
	FormatDepth32Float Format = 40

	// "depth32float-stencil8" feature
	FormatDepth32FloatStencil8 Format = 41

	// BC compressed formats, "texture-compression-bc"
	FormatBc1RgbaUnorm Format = 42
	FormatBc1RgbaUnormSrgb Format = 43
	FormatBc2RgbaUnorm Format = 44
	FormatBc2RgbaUnormSrgb Format = 45
	FormatBc3RgbaUnorm Format = 46
	FormatBc3RgbaUnormSrgb Format = 47
	FormatBc4RUnorm Format = 48
	FormatBc4RSnorm Format = 49
	FormatBc5RgUnorm Format = 50
	FormatBc5RgSnorm Format = 51
	FormatBc6hRgbUfloat Format = 52
	FormatBc6hRgbFloat Format = 53
	FormatBc7RgbaUnorm Format = 54
	FormatBc7RgbaUnormSrgb Format = 55

	// ETC2 compressed formats, "texture-compression-etc2"
	FormatEtc2Rgb8Unorm Format = 56
	FormatEtc2Rgb8UnormSrgb Format = 57
	FormatEtc2Rgb8a1Unorm Format = 58
	FormatEtc2Rgb8a1UnormSrgb Format = 59
	FormatEtc2Rgba8Unorm Format = 60
	FormatEtc2Rgba8UnormSrgb Format = 61
	FormatEacR11Unorm Format = 62
	FormatEacR11Snorm Format = 63
	FormatEacRg11Unorm Format = 64
	FormatEacRg11Snorm Format = 65

	// ASTC compressed formats, "texture-compression-astc"
	FormatAstc4x4Unorm Format = 66
	FormatAstc4x4UnormSrgb Format = 67
	FormatAstc5x4Unorm Format = 68
	FormatAstc5x4UnormSrgb Format = 69
	FormatAstc5x5Unorm Format = 70
	FormatAstc5x5UnormSrgb Format = 71
	FormatAstc6x5Unorm Format = 72
	FormatAstc6x5UnormSrgb Format = 73
	FormatAstc6x6Unorm Format = 74
	FormatAstc6x6UnormSrgb Format = 75
	FormatAstc8x5Unorm Format = 76
	FormatAstc8x5UnormSrgb Format = 77
	FormatAstc8x6Unorm Format = 78
	FormatAstc8x6UnormSrgb Format = 79
	FormatAstc8x8Unorm Format = 80
	FormatAstc8x8UnormSrgb Format = 81
	FormatAstc10x5Unorm Format = 82
	FormatAstc10x5UnormSrgb Format = 83
	FormatAstc10x6Unorm Format = 84
	FormatAstc10x6UnormSrgb Format = 85
	FormatAstc10x8Unorm Format = 86
	FormatAstc10x8UnormSrgb Format = 87
	FormatAstc10x10Unorm Format = 88
	FormatAstc10x10UnormSrgb Format = 89
	FormatAstc12x10Unorm Format = 90
	FormatAstc12x10UnormSrgb Format = 91
	FormatAstc12x12Unorm Format = 92
	FormatAstc12x12UnormSrgb Format = 93
)

var formatTable = map[string]Format{
	// 8-bit formats
	"r8unorm": FormatR8Unorm,
	"r8snorm": FormatR8Snorm,
	"r8uint": FormatR8Uint,
	"r8sint": FormatR8Sint,

	// 16-bit formats
	"r16uint": FormatR16Uint,
	"r16sint": FormatR16Sint,
	"r16float": FormatR16Float,
	"rg8unorm": FormatRg8Unorm,
	"rg8snorm": FormatRg8Snorm,
	"rg8uint": FormatRg8Uint,
	"rg8sint": FormatRg8Sint,

	// 32-bit formats
	"r32uint": FormatR32Uint,
	"r32sint": FormatR32Sint,
	"r32float": FormatR32Float,
	"rg16uint": FormatRg16Uint,
	"rg16sint": FormatRg16Sint,
	"rg16float": FormatRg16Float,
	"rgba8unorm": FormatRgba8Unorm,
	"rgba8unorm-srgb": FormatRgba8UnormSrgb,
	"rgba8snorm": FormatRgba8Snorm,
	"rgba8uint": FormatRgba8Uint,
	"rgba8sint": FormatRgba8Sint,
	"bgra8unorm": FormatBgra8Unorm,
	"bgra8unorm-srgb": FormatBgra8UnormSrgb,
	// Packed 32-bit formats
	"rgb9e5ufloat": FormatRgb9e5uFloat,
	"rgb10a2unorm": FormatRgb10a2Unorm,
	"rg11b10ufloat": FormatRg11b10Ufloat,

	// 64-bit formats
	"rg32uint": FormatRg32Uint,
	"rg32sint": FormatRg32Sint,
	"rg32float": FormatRg32Float,
	"rgba16uint": FormatRgba16Uint,
	"rgba16sint": FormatRgba16Sint,
	"rgba16float": FormatRgba16Float,

	// 128-bit formats
	"rgba32uint": FormatRgba32Uint,
	"rgba32sint": FormatRgba32Sint,
	"rgba32float": FormatRgba32Float,

	// Depth/stencil formats
	"stencil8": FormatStencil8,
	"depth16unorm": FormatDepth16Unorm,
	"depth24plus": FormatDepth24Plus,
	"depth24plus-stencil8": FormatDepth24PlusStencil8,
	"depth32float": FormatDepth32Float,

	// "depth32float-stencil8" feature
	"depth32float-stencil8": FormatDepth32FloatStencil8,

	// BC compressed formats, "texture-compression-bc"
	"bc1-rgba-unorm": FormatBc1RgbaUnorm,
	"bc1-rgba-unorm-srgb": FormatBc1RgbaUnormSrgb,
	"bc2-rgba-unorm": FormatBc1RgbaUnorm,
	"bc2-rgba-unorm-srgb": FormatBc2RgbaUnormSrgb,
	"bc3-rgba-unorm": FormatBc3RgbaUnorm,
	"bc3-rgba-unorm-srgb": FormatBc3RgbaUnormSrgb,
	"bc4-r-unorm": FormatBc4RUnorm,
	"bc4-r-snorm": FormatBc4RSnorm,
	"bc5-rg-unorm": FormatBc5RgUnorm,
	"bc5-rg-snorm": FormatBc5RgSnorm,
	"bc6h-rgb-ufloat": FormatBc6hRgbUfloat,
	"bc6h-rgb-float": FormatBc6hRgbFloat,
	"bc7-rgba-unorm": FormatBc7RgbaUnorm,
	"bc7-rgba-unorm-srgb": FormatBc7RgbaUnormSrgb,

	// ETC2 compressed formats, "texture-compression-etc2"
	"etc2-rgb8unorm": FormatEtc2Rgb8Unorm,
	"etc2-rgb8unorm-srgb": FormatEtc2Rgb8UnormSrgb,
	"etc2-rgb8a1unorm": FormatEtc2Rgb8a1Unorm,
	"etc2-rgb8a1unorm-srgb": FormatEtc2Rgb8a1UnormSrgb,
	"etc2-rgba8unorm": FormatEtc2Rgba8Unorm,
	"etc2-rgba8unorm-srgb": FormatEtc2Rgba8UnormSrgb,
	"eac-r11unorm": FormatEacR11Unorm,
	"eac-r11snorm": FormatEacR11Snorm,
	"eac-rg11unorm": FormatEacRg11Unorm,
	"eac-rg11snorm": FormatEacRg11Snorm,

	// ASTC compressed formats, "texture-compression-astc"
	"astc-4x4-unorm": FormatAstc4x4Unorm,
	"astc-4x4-unorm-srgb": FormatAstc4x4UnormSrgb,
	"astc-5x4-unorm": FormatAstc5x4Unorm,
	"astc-5x4-unorm-srgb": FormatAstc5x4UnormSrgb,
	"astc-5x5-unorm": FormatAstc5x5Unorm,
	"astc-5x5-unorm-srgb": FormatAstc5x5UnormSrgb,
	"astc-6x5-unorm": FormatAstc6x5Unorm,
	"astc-6x5-unorm-srgb": FormatAstc6x5UnormSrgb,
	"astc-6x6-unorm": FormatAstc6x6Unorm,
	"astc-6x6-unorm-srgb": FormatAstc6x6UnormSrgb,
	"astc-8x5-unorm": FormatAstc8x5Unorm,
	"astc-8x5-unorm-srgb": FormatAstc8x5UnormSrgb,
	"astc-8x6-unorm": FormatAstc8x6Unorm,
	"astc-8x6-unorm-srgb": FormatAstc8x6UnormSrgb,
	"astc-8x8-unorm": FormatAstc8x8Unorm,
	"astc-8x8-unorm-srgb": FormatAstc8x8UnormSrgb,
	"astc-10x5-unorm": FormatAstc10x5Unorm,
	"astc-10x5-unorm-srgb": FormatAstc10x5UnormSrgb,
	"astc-10x6-unorm": FormatAstc10x6Unorm,
	"astc-10x6-unorm-srgb": FormatAstc10x6UnormSrgb,
	"astc-10x8-unorm": FormatAstc10x8Unorm,
	"astc-10x8-unorm-srgb": FormatAstc10x8UnormSrgb,
	"astc-10x10-unorm": FormatAstc10x10Unorm,
	"astc-10x10-unorm-srgb": FormatAstc10x10UnormSrgb,
	"astc-12x10-unorm": FormatAstc12x10Unorm,
	"astc-12x10-unorm-srgb": FormatAstc12x10UnormSrgb,
	"astc-12x12-unorm": FormatAstc12x12Unorm,
	"astc-12x12-unorm-srgb": FormatAstc12x12UnormSrgb,
}

// vulkanTable converts a WebGPU format to a Vulkan format.
//
// Not every format can be converted this way, but nearly every format has a direct vulkan equvilant.
//
// Based on map_texture_format in wgpu and VulkanImageFormat in Dawn:
// https://github.com/gfx-rs/wgpu/blob/master/wgpu-hal/src/vulkan/conv.rs
// https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/native/vulkan/TextureVk.cpp
var vulkanTable = map[Format]vulkan.Format{
	// 8-bit formats
	FormatR8Unorm: vulkan.FormatR8_UNORM,
	FormatR8Snorm: vulkan.FormatR8_SNORM,
	FormatR8Uint: vulkan.FormatR8_UINT,
	FormatR8Sint: vulkan.FormatR8_SINT,

	// 16-bit formats
	FormatR16Uint: vulkan.FormatR16_UINT,
	FormatR16Sint: vulkan.FormatR16_SINT,
	FormatR16Float: vulkan.FormatR16_SFLOAT,
	FormatRg8Unorm: vulkan.FormatR8G8_UNORM,
	FormatRg8Snorm: vulkan.FormatR8G8_SNORM,
	FormatRg8Uint: vulkan.FormatR8G8_UINT,
	FormatRg8Sint: vulkan.FormatR8G8_SINT,

	// 32-bit formats
	FormatR32Uint: vulkan.FormatR32_UINT,
	FormatR32Sint: vulkan.FormatR32_SINT,
	FormatR32Float: vulkan.FormatR32_SFLOAT,
	FormatRg16Uint: vulkan.FormatR16G16_UINT,
	FormatRg16Sint: vulkan.FormatR16G16_SINT,
	FormatRg16Float: vulkan.FormatR16G16_SFLOAT,
	FormatRgba8Unorm: vulkan.FormatR8G8B8A8_UNORM,
	FormatRgba8UnormSrgb: vulkan.FormatR8G8B8A8_SRGB,
	FormatRgba8Snorm: vulkan.FormatR8G8B8A8_SNORM,
	FormatRgba8Uint: vulkan.FormatR8G8B8A8_UINT,
	FormatRgba8Sint: vulkan.FormatR8G8B8A8_SINT,
	FormatBgra8Unorm: vulkan.FormatB8G8R8A8_UNORM,
	FormatBgra8UnormSrgb: vulkan.FormatB8G8R8A8_SRGB,
	// Packed 32-bit formats
	FormatRgb9e5uFloat: vulkan.FormatE5B9G9R9_UFLOAT_PACK32,
	FormatRgb10a2Unorm: vulkan.FormatA2B10G10R10_UNORM_PACK32,
	FormatRg11b10Ufloat: vulkan.FormatB10G11R11_UFLOAT_PACK32,

	// 64-bit formats
	FormatRg32Uint: vulkan.FormatR32G32_UINT,
	FormatRg32Sint: vulkan.FormatR32G32_SINT,
	FormatRg32Float: vulkan.FormatR32G32_SFLOAT,
	FormatRgba16Uint: vulkan.FormatR16G16B16A16_UINT,
	FormatRgba16Sint: vulkan.FormatR16G16B16A16_SINT,
	FormatRgba16Float: vulkan.FormatR16G16B16A16_SFLOAT,

	// 128-bit formats
	FormatRgba32Uint: vulkan.FormatR32G32B32A32_UINT,
	FormatRgba32Sint: vulkan.FormatR32G32B32A32_SFLOAT,
	FormatRgba32Float: vulkan.FormatR32G32B32A32_SFLOAT,

	// Depth/stencil formats
	// FormatStencil8: manual conversion because Stencil8 can be an S8_UINT or D24_UNORM_S8_UINT
	FormatDepth16Unorm: vulkan.FormatD16_UNORM,
	// FormatDepth24Plus: manual conversion because FormatDepth24Plus can be an X8_D24_UNORM_PACK32 or D32_SFLOAT
	// FormatDepth24PlusStencil8:  manual conversion because Depth24PlusStencil8 can be an D24_UNORM_S8_UINT or D32_SFLOAT_S8_UINT
	FormatDepth32Float: vulkan.FormatD32_SFLOAT,

	// "depth32float-stencil8" feature
	FormatDepth32FloatStencil8: vulkan.FormatD32_SFLOAT_S8_UINT,

	// BC compressed formats, "texture-compression-bc"
	FormatBc1RgbaUnorm: vulkan.FormatBC1_RGBA_SRGB_BLOCK,
	FormatBc1RgbaUnormSrgb: vulkan.FormatBC1_RGBA_UNORM_BLOCK,
	FormatBc2RgbaUnorm: vulkan.FormatBC2_UNORM_BLOCK,
	FormatBc2RgbaUnormSrgb: vulkan.FormatBC2_SRGB_BLOCK,
	FormatBc3RgbaUnorm: vulkan.FormatBC3_UNORM_BLOCK,
	FormatBc3RgbaUnormSrgb: vulkan.FormatBC3_SRGB_BLOCK,
	FormatBc4RUnorm: vulkan.FormatBC4_UNORM_BLOCK,
	FormatBc4RSnorm: vulkan.FormatBC4_SNORM_BLOCK,
	FormatBc5RgUnorm: vulkan.FormatBC5_UNORM_BLOCK,
	FormatBc5RgSnorm: vulkan.FormatBC5_SNORM_BLOCK,
	FormatBc6hRgbUfloat: vulkan.FormatBC6H_UFLOAT_BLOCK,
	FormatBc6hRgbFloat: vulkan.FormatBC6H_SFLOAT_BLOCK,
	FormatBc7RgbaUnorm: vulkan.FormatBC7_UNORM_BLOCK,
	FormatBc7RgbaUnormSrgb: vulkan.FormatBC7_SRGB_BLOCK,

	// ETC2 compressed formats, "texture-compression-etc2"
	FormatEtc2Rgb8Unorm: vulkan.FormatETC2_R8G8B8_UNORM_BLOCK,
	FormatEtc2Rgb8UnormSrgb: vulkan.FormatETC2_R8G8B8_SRGB_BLOCK,
	FormatEtc2Rgb8a1Unorm: vulkan.FormatETC2_R8G8B8A1_UNORM_BLOCK,
	FormatEtc2Rgb8a1UnormSrgb: vulkan.FormatETC2_R8G8B8A1_SRGB_BLOCK,
	FormatEtc2Rgba8Unorm: vulkan.FormatETC2_R8G8B8A8_UNORM_BLOCK,
	FormatEtc2Rgba8UnormSrgb: vulkan.FormatETC2_R8G8B8A8_SRGB_BLOCK,
	FormatEacR11Unorm: vulkan.FormatEAC_R11_UNORM_BLOCK,
	FormatEacR11Snorm: vulkan.FormatEAC_R11_SNORM_BLOCK,
	FormatEacRg11Unorm: vulkan.FormatEAC_R11G11_UNORM_BLOCK,
	FormatEacRg11Snorm: vulkan.FormatEAC_R11G11_SNORM_BLOCK,

	// ASTC compressed formats, "texture-compression-astc"
	FormatAstc4x4Unorm: vulkan.FormatASTC_4x4_UNORM_BLOCK,
	FormatAstc4x4UnormSrgb: vulkan.FormatASTC_4x4_SRGB_BLOCK,
	FormatAstc5x4Unorm: vulkan.FormatASTC_5x4_UNORM_BLOCK,
	FormatAstc5x4UnormSrgb: vulkan.FormatASTC_5x4_SRGB_BLOCK,
	FormatAstc5x5Unorm: vulkan.FormatASTC_5x5_UNORM_BLOCK,
	FormatAstc5x5UnormSrgb: vulkan.FormatASTC_5x5_SRGB_BLOCK,
	FormatAstc6x5Unorm: vulkan.FormatASTC_6x5_UNORM_BLOCK,
	FormatAstc6x5UnormSrgb: vulkan.FormatASTC_6x5_SRGB_BLOCK,
	FormatAstc6x6Unorm: vulkan.FormatASTC_6x6_UNORM_BLOCK,
	FormatAstc6x6UnormSrgb: vulkan.FormatASTC_6x6_SRGB_BLOCK,
	FormatAstc8x5Unorm: vulkan.FormatASTC_8x5_UNORM_BLOCK,
	FormatAstc8x5UnormSrgb: vulkan.FormatASTC_8x5_SRGB_BLOCK,
	FormatAstc8x6Unorm: vulkan.FormatASTC_8x6_UNORM_BLOCK,
	FormatAstc8x6UnormSrgb: vulkan.FormatASTC_8x6_SRGB_BLOCK,
	FormatAstc8x8Unorm: vulkan.FormatASTC_8x8_UNORM_BLOCK,
	FormatAstc8x8UnormSrgb: vulkan.FormatASTC_8x8_SRGB_BLOCK,
	FormatAstc10x5Unorm: vulkan.FormatASTC_10x5_UNORM_BLOCK,
	FormatAstc10x5UnormSrgb: vulkan.FormatASTC_10x5_SRGB_BLOCK,
	FormatAstc10x6Unorm: vulkan.FormatASTC_10x6_UNORM_BLOCK,
	FormatAstc10x6UnormSrgb: vulkan.FormatASTC_10x6_SRGB_BLOCK,
	FormatAstc10x8Unorm: vulkan.FormatASTC_10x8_UNORM_BLOCK,
	FormatAstc10x8UnormSrgb: vulkan.FormatASTC_10x8_SRGB_BLOCK,
	FormatAstc10x10Unorm: vulkan.FormatASTC_10x10_UNORM_BLOCK,
	FormatAstc10x10UnormSrgb: vulkan.FormatASTC_10x10_SRGB_BLOCK,
	FormatAstc12x10Unorm: vulkan.FormatASTC_12x10_UNORM_BLOCK,
	FormatAstc12x10UnormSrgb: vulkan.FormatASTC_12x10_SRGB_BLOCK,
	FormatAstc12x12Unorm: vulkan.FormatASTC_12x12_UNORM_BLOCK,
	FormatAstc12x12UnormSrgb: vulkan.FormatASTC_12x12_SRGB_BLOCK,
}
diff --git a/webgpu/webgpu.go b/webgpu/webgpu.go
new file mode 100644
index 0000000..24ca91a
--- /dev/null
+++ b/webgpu/webgpu.go
@@ -0,0 +1,27 @@
package webgpu

import (
	"git.sr.ht/~emersion/go-kdf"
	"git.sr.ht/~emersion/go-kdf/vulkan"
)

type Format int

var FormatTable map[string]Format = formatTable

// webgpu's conversions sometimes depend on the runtime environment.
//
// The depth24plus format may be implemented as a 24-bit depth format or a depth32float.
//
// The depth24plus-stencil8 format may be implemented as a 24-bit depth or a depth32float.
//
// The stencil8 format may be implemented as a real stencil8 format or depth24stencil8 where the depth is inaccessible.
func GetBlock(fmt Format, endianness kdf.Endianness, depth24Is32bit bool, depth24Stencil8Is32Bit bool, stencil8IsReal bool) *kdf.Block{
	// TODO: Handle runtime conversion options

	vulkanFmt, ok := vulkanTable[fmt]
	if !ok {
		return nil
	}
	return vulkan.GetBlock(vulkanFmt, endianness)
}
-- 
2.39.1