| /* |
| * Copyright 2025 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/gpu/graphite/TextureFormat.h" |
| |
| #include "include/core/SkColor.h" |
| |
| namespace skgpu::graphite { |
| |
| const char* TextureFormatName(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kUnsupported: return "Unsupported"; |
| case TextureFormat::kR8: return "R8"; |
| case TextureFormat::kR16: return "R16"; |
| case TextureFormat::kR16F: return "R16F"; |
| case TextureFormat::kR32F: return "R32F"; |
| case TextureFormat::kA8: return "A8"; |
| case TextureFormat::kRG8: return "RG8"; |
| case TextureFormat::kRG16: return "RG16"; |
| case TextureFormat::kRG16F: return "RG16F"; |
| case TextureFormat::kRG32F: return "RG32F"; |
| case TextureFormat::kRGB8: return "RGB8"; |
| case TextureFormat::kBGR8: return "BGR8"; |
| case TextureFormat::kB5_G6_R5: return "B5_G6_R5"; |
| case TextureFormat::kR5_G6_B5: return "R5_G6_B5"; |
| case TextureFormat::kRGB16: return "RGB16"; |
| case TextureFormat::kRGB16F: return "RGB16F"; |
| case TextureFormat::kRGB32F: return "RGB32F"; |
| case TextureFormat::kRGB8_sRGB: return "RGB8_sRGB"; |
| case TextureFormat::kBGR10_XR: return "BGR10_XR"; |
| case TextureFormat::kRGBA8: return "RGBA8"; |
| case TextureFormat::kRGBA16: return "RBGA16"; |
| case TextureFormat::kRGBA16F: return "RGBA16F"; |
| case TextureFormat::kRGBA32F: return "RGBA32F"; |
| case TextureFormat::kRGB10_A2: return "RGB10_A2"; |
| case TextureFormat::kRGBA8_sRGB: return "RGBA8_sRGB"; |
| case TextureFormat::kBGRA8: return "BGRA8"; |
| case TextureFormat::kBGR10_A2: return "BGR10_A2"; |
| case TextureFormat::kBGRA8_sRGB: return "BGRA8_sRGB"; |
| case TextureFormat::kABGR4: return "ABGR4"; |
| case TextureFormat::kARGB4: return "ARGB4"; |
| case TextureFormat::kBGRA10x6_XR: return "BGRA10x6_XR"; |
| case TextureFormat::kRGB8_ETC2: return "RGB8_ETC2"; |
| case TextureFormat::kRGB8_ETC2_sRGB: return "RGB8_ETC2_sRGB"; |
| case TextureFormat::kRGB8_BC1: return "RGB8_BC1"; |
| case TextureFormat::kRGBA8_BC1: return "RGBA8_BC1"; |
| case TextureFormat::kRGBA8_BC1_sRGB: return "RGBA8_BC1_sRGB"; |
| case TextureFormat::kYUV8_P2_420: return "YUV8_P2_420"; |
| case TextureFormat::kYUV8_P3_420: return "YUV8_P3_420"; |
| case TextureFormat::kYUV10x6_P2_420: return "YUV10x6_P2_420"; |
| case TextureFormat::kExternal: return "External"; |
| case TextureFormat::kS8: return "S8"; |
| case TextureFormat::kD16: return "D16"; |
| case TextureFormat::kD32F: return "D32F"; |
| case TextureFormat::kD24_S8: return "D24_S8"; |
| case TextureFormat::kD32F_S8: return "D32F_S8"; |
| } |
| SkUNREACHABLE; |
| } |
| |
| SkTextureCompressionType TextureFormatCompressionType(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kRGB8_ETC2: [[fallthrough]]; |
| case TextureFormat::kRGB8_ETC2_sRGB: return SkTextureCompressionType::kETC2_RGB8_UNORM; |
| case TextureFormat::kRGB8_BC1: return SkTextureCompressionType::kBC1_RGB8_UNORM; |
| case TextureFormat::kRGBA8_BC1: [[fallthrough]]; |
| case TextureFormat::kRGBA8_BC1_sRGB: return SkTextureCompressionType::kBC1_RGBA8_UNORM; |
| default: return SkTextureCompressionType::kNone; |
| } |
| } |
| |
| size_t TextureFormatBytesPerBlock(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kUnsupported: return 0; |
| case TextureFormat::kR8: return 1; |
| case TextureFormat::kR16: return 2; |
| case TextureFormat::kR16F: return 2; |
| case TextureFormat::kR32F: return 4; |
| case TextureFormat::kA8: return 1; |
| case TextureFormat::kRG8: return 2; |
| case TextureFormat::kRG16: return 4; |
| case TextureFormat::kRG16F: return 4; |
| case TextureFormat::kRG32F: return 8; |
| case TextureFormat::kRGB8: return 3; |
| case TextureFormat::kBGR8: return 3; |
| case TextureFormat::kB5_G6_R5: return 2; |
| case TextureFormat::kR5_G6_B5: return 2; |
| case TextureFormat::kRGB16: return 6; |
| case TextureFormat::kRGB16F: return 6; |
| case TextureFormat::kRGB32F: return 12; |
| case TextureFormat::kRGB8_sRGB: return 3; |
| case TextureFormat::kBGR10_XR: return 4; |
| case TextureFormat::kRGBA8: return 4; |
| case TextureFormat::kRGBA16: return 8; |
| case TextureFormat::kRGBA16F: return 8; |
| case TextureFormat::kRGBA32F: return 16; |
| case TextureFormat::kRGB10_A2: return 4; |
| case TextureFormat::kRGBA8_sRGB: return 4; |
| case TextureFormat::kBGRA8: return 4; |
| case TextureFormat::kBGR10_A2: return 4; |
| case TextureFormat::kBGRA8_sRGB: return 4; |
| case TextureFormat::kABGR4: return 2; |
| case TextureFormat::kARGB4: return 2; |
| case TextureFormat::kBGRA10x6_XR: return 8; |
| case TextureFormat::kS8: return 1; |
| case TextureFormat::kD16: return 2; |
| case TextureFormat::kD32F: return 4; |
| case TextureFormat::kD24_S8: return 4; |
| case TextureFormat::kD32F_S8: return 8; |
| // NOTE: For compressed formats, the block size refers to an actual compressed block of |
| // multiple texels, whereas with other formats the block size represents a single pixel. |
| case TextureFormat::kRGB8_ETC2: |
| case TextureFormat::kRGB8_ETC2_sRGB: |
| case TextureFormat::kRGB8_BC1: |
| case TextureFormat::kRGBA8_BC1: |
| case TextureFormat::kRGBA8_BC1_sRGB: |
| return 8; |
| // NOTE: We don't actually know the size of external formats, so this is an arbitrary value. |
| // We will see external formats only in wrapped SkImages, so this won't impact Skia's |
| // internal budgeting. |
| case TextureFormat::kExternal: |
| return 4; |
| // TODO(b/401016699): We are just over estimating this value to be used in gpu size |
| // calculations even though the actually size is probably less. We should instead treat |
| // planar formats similar to compressed textures that go through their own special query for |
| // calculating size. |
| case TextureFormat::kYUV8_P2_420: |
| case TextureFormat::kYUV8_P3_420: |
| return 3; |
| case TextureFormat::kYUV10x6_P2_420: |
| return 6; |
| } |
| SkUNREACHABLE; |
| } |
| |
| uint32_t TextureFormatChannelMask(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kA8: return kAlpha_SkColorChannelFlag; |
| |
| case TextureFormat::kR8: [[fallthrough]]; |
| case TextureFormat::kR16: |
| case TextureFormat::kR16F: |
| case TextureFormat::kR32F: return kRed_SkColorChannelFlag; |
| |
| case TextureFormat::kRG8: [[fallthrough]]; |
| case TextureFormat::kRG16: |
| case TextureFormat::kRG16F: |
| case TextureFormat::kRG32F: return kRG_SkColorChannelFlags; |
| |
| case TextureFormat::kRGB8: [[fallthrough]]; |
| case TextureFormat::kBGR8: |
| case TextureFormat::kB5_G6_R5: |
| case TextureFormat::kR5_G6_B5: |
| case TextureFormat::kRGB16: |
| case TextureFormat::kRGB16F: |
| case TextureFormat::kRGB32F: |
| case TextureFormat::kRGB8_sRGB: |
| case TextureFormat::kBGR10_XR: |
| case TextureFormat::kRGB8_ETC2: |
| case TextureFormat::kRGB8_ETC2_sRGB: |
| case TextureFormat::kRGB8_BC1: |
| case TextureFormat::kYUV8_P2_420: |
| case TextureFormat::kYUV8_P3_420: |
| case TextureFormat::kYUV10x6_P2_420: return kRGB_SkColorChannelFlags; |
| |
| case TextureFormat::kRGBA8: [[fallthrough]]; |
| case TextureFormat::kRGBA16: |
| case TextureFormat::kRGBA16F: |
| case TextureFormat::kRGBA32F: |
| case TextureFormat::kRGB10_A2: |
| case TextureFormat::kRGBA8_sRGB: |
| case TextureFormat::kBGRA8: |
| case TextureFormat::kBGR10_A2: |
| case TextureFormat::kBGRA8_sRGB: |
| case TextureFormat::kABGR4: |
| case TextureFormat::kARGB4: |
| case TextureFormat::kBGRA10x6_XR: |
| case TextureFormat::kRGBA8_BC1: |
| case TextureFormat::kRGBA8_BC1_sRGB: |
| case TextureFormat::kExternal: return kRGBA_SkColorChannelFlags; |
| |
| case TextureFormat::kS8: [[fallthrough]]; |
| case TextureFormat::kD16: |
| case TextureFormat::kD32F: |
| case TextureFormat::kD24_S8: |
| case TextureFormat::kD32F_S8: |
| case TextureFormat::kUnsupported: return 0; |
| } |
| SkUNREACHABLE; |
| } |
| |
| bool TextureFormatAutoClamps(TextureFormat format) { |
| // Floating point formats, extended range formats, and non-normalized integer formats do not |
| // auto-clamp. Everything behaves like an unsigned normalized number. |
| return !(TextureFormatIsFloatingPoint(format) || |
| format == TextureFormat::kBGR10_XR || |
| format == TextureFormat::kBGRA10x6_XR || |
| format == TextureFormat::kS8); |
| } |
| |
| bool TextureFormatIsFloatingPoint(TextureFormat format) { |
| switch (format) { |
| // Floating point formats |
| case TextureFormat::kR16F: [[fallthrough]]; |
| case TextureFormat::kR32F: |
| case TextureFormat::kRG16F: |
| case TextureFormat::kRG32F: |
| case TextureFormat::kRGB16F: |
| case TextureFormat::kRGB32F: |
| case TextureFormat::kRGBA16F: |
| case TextureFormat::kRGBA32F: |
| case TextureFormat::kD32F: |
| case TextureFormat::kD32F_S8: return true; |
| |
| // Everything else is unorm, unorm-srgb, fixed point, or integral |
| case TextureFormat::kUnsupported: [[fallthrough]]; |
| case TextureFormat::kR8: |
| case TextureFormat::kR16: |
| case TextureFormat::kA8: |
| case TextureFormat::kRG8: |
| case TextureFormat::kRG16: |
| case TextureFormat::kRGB8: |
| case TextureFormat::kBGR8: |
| case TextureFormat::kB5_G6_R5: |
| case TextureFormat::kR5_G6_B5: |
| case TextureFormat::kRGB16: |
| case TextureFormat::kRGB8_sRGB: |
| case TextureFormat::kBGR10_XR: |
| case TextureFormat::kRGBA8: |
| case TextureFormat::kRGBA16: |
| case TextureFormat::kRGB10_A2: |
| case TextureFormat::kRGBA8_sRGB: |
| case TextureFormat::kBGRA8: |
| case TextureFormat::kBGR10_A2: |
| case TextureFormat::kBGRA8_sRGB: |
| case TextureFormat::kABGR4: |
| case TextureFormat::kARGB4: |
| case TextureFormat::kBGRA10x6_XR: |
| case TextureFormat::kRGB8_ETC2: |
| case TextureFormat::kRGB8_ETC2_sRGB: |
| case TextureFormat::kRGB8_BC1: |
| case TextureFormat::kRGBA8_BC1: |
| case TextureFormat::kRGBA8_BC1_sRGB: |
| case TextureFormat::kYUV8_P2_420: |
| case TextureFormat::kYUV8_P3_420: |
| case TextureFormat::kYUV10x6_P2_420: |
| case TextureFormat::kExternal: |
| case TextureFormat::kS8: |
| case TextureFormat::kD16: |
| case TextureFormat::kD24_S8: return false; |
| } |
| SkUNREACHABLE; |
| } |
| |
| bool TextureFormatIsDepthOrStencil(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kS8: [[fallthrough]]; |
| case TextureFormat::kD16: |
| case TextureFormat::kD32F: |
| case TextureFormat::kD24_S8: |
| case TextureFormat::kD32F_S8: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| bool TextureFormatHasDepth(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kD16: [[fallthrough]]; |
| case TextureFormat::kD32F: |
| case TextureFormat::kD24_S8: |
| case TextureFormat::kD32F_S8: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| bool TextureFormatHasStencil(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kS8: [[fallthrough]]; |
| case TextureFormat::kD24_S8: |
| case TextureFormat::kD32F_S8: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| bool TextureFormatIsMultiplanar(TextureFormat format) { |
| switch (format) { |
| case TextureFormat::kYUV8_P2_420: [[fallthrough]]; |
| case TextureFormat::kYUV8_P3_420: |
| case TextureFormat::kYUV10x6_P2_420: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| } // namespace skgpu::graphite |