Skip to content

Commit

Permalink
filter vulkan format/color types based on skia support
Browse files Browse the repository at this point in the history
- the first format suggested by the device may not be supported (e.g., `B8G8R8A8_SRGB` in #200)
  • Loading branch information
samizdatco committed Dec 5, 2024
1 parent 9d716b4 commit e5fdae0
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 11 deletions.
70 changes: 69 additions & 1 deletion src/gpu/vulkan/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
use vulkano::format::Format as VkFormat;
use skia_safe::{ gpu::vk, ColorType };

pub mod engine;
pub use engine::VulkanEngine;

pub mod renderer;
pub use renderer::VulkanRenderer;
pub use renderer::VulkanRenderer;

fn supported_vulkano_formats() -> Vec<VkFormat>{
vec![
VkFormat::R8G8B8A8_UNORM,
VkFormat::R8G8B8A8_SRGB,
VkFormat::R8_UNORM,
VkFormat::B8G8R8A8_UNORM,
VkFormat::R5G6B5_UNORM_PACK16,
VkFormat::B5G6R5_UNORM_PACK16,
VkFormat::R16G16B16A16_SFLOAT,
VkFormat::R16_SFLOAT,
VkFormat::R8G8B8_UNORM,
VkFormat::R8G8_UNORM,
VkFormat::A2B10G10R10_UNORM_PACK32,
VkFormat::A2R10G10B10_UNORM_PACK32,
VkFormat::R10X6G10X6B10X6A10X6_UNORM_4PACK16,
VkFormat::B4G4R4A4_UNORM_PACK16,
VkFormat::R4G4B4A4_UNORM_PACK16,
VkFormat::R16_UNORM,
VkFormat::R16G16_UNORM,
VkFormat::G8_B8_R8_3PLANE_420_UNORM,
VkFormat::G8_B8R8_2PLANE_420_UNORM,
VkFormat::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
VkFormat::R16G16B16A16_UNORM,
VkFormat::R16G16_SFLOAT,
]
}

fn to_sk_format(vulkano_format:&VkFormat) -> Option<(vk::Format, ColorType)>{
// Format / ColorType pairs
// https://github.com/google/skia/blob/4f24819404272433687a76e407bcd7877384f512/src/gpu/ganesh/vk/GrVkCaps.cpp#L880
//
// GrColorType -> SkColorType mappings
// https://github.com/google/skia/blob/4f24819404272433687a76e407bcd7877384f512/include/private/gpu/ganesh/GrTypesPriv.h#L590
//
// Present in the GrVkCaps 'supported' list but lacking supported GrColorTypes so omitted:
// - VkFormat::ETC2_R8G8B8_UNORM_BLOCK
// - VkFormat::BC1_RGB_UNORM_BLOCK
// - VkFormat::BC1_RGBA_UNORM_BLOCK
match vulkano_format {
VkFormat::R8G8B8A8_UNORM => Some(( vk::Format::R8G8B8A8_UNORM, ColorType::RGBA8888 )),
VkFormat::R8G8B8A8_SRGB => Some(( vk::Format::R8G8B8A8_SRGB, ColorType::SRGBA8888 )),
VkFormat::R8_UNORM => Some(( vk::Format::R8_UNORM, ColorType::R8UNorm )),
VkFormat::B8G8R8A8_UNORM => Some(( vk::Format::B8G8R8A8_UNORM, ColorType::BGRA8888 )),
VkFormat::R5G6B5_UNORM_PACK16 => Some(( vk::Format::R5G6B5_UNORM_PACK16, ColorType::RGB565 )),
VkFormat::B5G6R5_UNORM_PACK16 => Some(( vk::Format::B5G6R5_UNORM_PACK16, ColorType::RGB565 )),
VkFormat::R16G16B16A16_SFLOAT => Some(( vk::Format::R16G16B16A16_SFLOAT, ColorType::RGBAF16 )),
VkFormat::R16_SFLOAT => Some(( vk::Format::R16_SFLOAT, ColorType::A16Float )),
VkFormat::R8G8B8_UNORM => Some(( vk::Format::R8G8B8_UNORM, ColorType::RGB888x )),
VkFormat::R8G8_UNORM => Some(( vk::Format::R8G8_UNORM, ColorType::R8G8UNorm )),
VkFormat::A2B10G10R10_UNORM_PACK32 => Some(( vk::Format::A2B10G10R10_UNORM_PACK32, ColorType::RGBA1010102 )),
VkFormat::A2R10G10B10_UNORM_PACK32 => Some(( vk::Format::A2R10G10B10_UNORM_PACK32, ColorType::BGRA1010102 )),
VkFormat::R10X6G10X6B10X6A10X6_UNORM_4PACK16 => Some(( vk::Format::R10X6G10X6B10X6A10X6_UNORM_4PACK16, ColorType::RGBA10x6 )),
VkFormat::B4G4R4A4_UNORM_PACK16 => Some(( vk::Format::B4G4R4A4_UNORM_PACK16, ColorType::ARGB4444 )),
VkFormat::R4G4B4A4_UNORM_PACK16 => Some(( vk::Format::R4G4B4A4_UNORM_PACK16, ColorType::ARGB4444 )),
VkFormat::R16_UNORM => Some(( vk::Format::R16_UNORM, ColorType::A16UNorm )),
VkFormat::R16G16_UNORM => Some(( vk::Format::R16G16_UNORM, ColorType::R16G16UNorm )),
VkFormat::G8_B8_R8_3PLANE_420_UNORM => Some(( vk::Format::G8_B8_R8_3PLANE_420_UNORM, ColorType::RGB888x )),
VkFormat::G8_B8R8_2PLANE_420_UNORM => Some(( vk::Format::G8_B8R8_2PLANE_420_UNORM, ColorType::RGB888x )),
VkFormat::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 => Some(( vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, ColorType::RGBA1010102 )),
VkFormat::R16G16B16A16_UNORM => Some(( vk::Format::R16G16B16A16_UNORM, ColorType::R16G16B16A16UNorm )),
VkFormat::R16G16_SFLOAT => Some(( vk::Format::R16G16_SFLOAT, ColorType::R16G16Float )),
_ => None
}
}
27 changes: 17 additions & 10 deletions src/gpu/vulkan/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ use vulkano::{

use skia_safe::{
gpu::{self, backend_render_targets, direct_contexts, surfaces, vk},
ColorType,
Color, Matrix,
};

use super::{supported_vulkano_formats, to_sk_format};

#[cfg(feature = "window")]
use winit::{
dpi::{LogicalSize, PhysicalSize},
Expand Down Expand Up @@ -126,9 +128,19 @@ impl VulkanRenderer {
let surface_capabilities = physical_device
.surface_capabilities(&surface, Default::default())
.unwrap();
let (image_format, _) = physical_device


// choose the first device format that is on the supported list
let supported_formats = supported_vulkano_formats();
let device_formats = physical_device
.surface_formats(&surface, Default::default())
.unwrap()[0];
.unwrap();
let (image_format, _) = device_formats.clone()
.into_iter()
.find(|(fmt, _)| supported_formats.contains(fmt))
.unwrap_or_else(||
panic!("Vulkan: no format supported by Skia was found. Supported: {:#?} Found: {:#?}", supported_formats, device_formats)
);

Swapchain::new(
device.clone(),
Expand Down Expand Up @@ -354,13 +366,8 @@ impl VulkanBackend{
let image_object = image_access.image().handle().as_raw();

let format = image_access.format();
let (vk_format, color_type) = match format {
vulkano::format::Format::B8G8R8A8_UNORM => (
skia_safe::gpu::vk::Format::B8G8R8A8_UNORM,
ColorType::BGRA8888,
),
_ => panic!("Vulkan: unsupported color format {:?}", format),
};
let (vk_format, color_type) = to_sk_format(&format)
.unwrap_or_else(|| panic!("Vulkan: unsupported color format {:?}", format));

let image_info = &unsafe {
vk::ImageInfo::new(
Expand Down

0 comments on commit e5fdae0

Please sign in to comment.