: 1 Add WebGPU formats 3 files changed, 398 insertions(+), 0 deletions(-)
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 -3Learn more about email & git
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