Initial Android surface

Bug: dawn:286

Change-Id: I50b45706f031254ac5beba5c07c3c4c3d7f9ea12
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/84200
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Alexander Vestin 2022-03-25 13:18:46 +00:00 committed by Dawn LUCI CQ
parent 57e78fd258
commit f2556ab35c
12 changed files with 123 additions and 25 deletions

View File

@ -88,6 +88,9 @@ if (WIN32)
endif() endif()
elseif(APPLE) elseif(APPLE)
set(ENABLE_METAL ON) set(ENABLE_METAL ON)
elseif(ANDROID)
set(ENABLE_VULKAN ON)
set(ENABLE_OPENGLES ON)
elseif(UNIX) elseif(UNIX)
set(ENABLE_OPENGLES ON) set(ENABLE_OPENGLES ON)
set(ENABLE_DESKTOP_GL ON) set(ENABLE_DESKTOP_GL ON)
@ -96,7 +99,7 @@ elseif(UNIX)
endif() endif()
# GLFW is not supported in UWP # GLFW is not supported in UWP
if((WIN32 AND NOT WINDOWS_STORE) OR UNIX) if((WIN32 AND NOT WINDOWS_STORE) OR UNIX AND NOT ANDROID)
set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING ON) set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING ON)
endif() endif()

View File

@ -176,7 +176,8 @@
"SurfaceDescriptorFromWindowsHWND", "SurfaceDescriptorFromWindowsHWND",
"SurfaceDescriptorFromXlibWindow", "SurfaceDescriptorFromXlibWindow",
"SurfaceDescriptorFromWindowsCoreWindow", "SurfaceDescriptorFromWindowsCoreWindow",
"SurfaceDescriptorFromWindowsSwapChainPanel" "SurfaceDescriptorFromWindowsSwapChainPanel",
"SurfaceDescriptorFromAndroidNativeWindow"
], ],
"client_side_commands": [ "client_side_commands": [
"AdapterCreateDevice", "AdapterCreateDevice",

View File

@ -50,6 +50,9 @@ namespace dawn::native {
case Surface::Type::Xlib: case Surface::Type::Xlib:
s->Append("Xlib"); s->Append("Xlib");
break; break;
case Surface::Type::AndroidWindow:
s->Append("AndroidWindow");
break;
} }
return {true}; return {true};
} }
@ -65,6 +68,7 @@ namespace dawn::native {
descriptor); descriptor);
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, DAWN_TRY(ValidateSingleSType(descriptor->nextInChain,
wgpu::SType::SurfaceDescriptorFromAndroidNativeWindow,
wgpu::SType::SurfaceDescriptorFromMetalLayer, wgpu::SType::SurfaceDescriptorFromMetalLayer,
wgpu::SType::SurfaceDescriptorFromWindowsHWND, wgpu::SType::SurfaceDescriptorFromWindowsHWND,
wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow, wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow,
@ -82,6 +86,17 @@ namespace dawn::native {
} }
#endif // defined(DAWN_ENABLE_BACKEND_METAL) #endif // defined(DAWN_ENABLE_BACKEND_METAL)
#if defined(DAWN_PLATFORM_ANDROID)
const SurfaceDescriptorFromAndroidNativeWindow* androidDesc = nullptr;
FindInChain(descriptor->nextInChain, &androidDesc);
// Currently the best validation we can do since it's not possible to check if the pointer
// to a ANativeWindow is valid.
if (androidDesc) {
DAWN_INVALID_IF(androidDesc->window == nullptr, "Android window is not set.");
return {};
}
#endif // defined(DAWN_PLATFORM_ANDROID)
#if defined(DAWN_PLATFORM_WINDOWS) #if defined(DAWN_PLATFORM_WINDOWS)
# if defined(DAWN_PLATFORM_WIN32) # if defined(DAWN_PLATFORM_WIN32)
const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr; const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
@ -142,20 +157,24 @@ namespace dawn::native {
Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor) Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
: mInstance(instance) { : mInstance(instance) {
ASSERT(descriptor->nextInChain != nullptr); ASSERT(descriptor->nextInChain != nullptr);
const SurfaceDescriptorFromAndroidNativeWindow* androidDesc = nullptr;
const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr; const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr; const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr; const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr; const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
const SurfaceDescriptorFromXlibWindow* xDesc = nullptr; const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
FindInChain(descriptor->nextInChain, &androidDesc);
FindInChain(descriptor->nextInChain, &metalDesc); FindInChain(descriptor->nextInChain, &metalDesc);
FindInChain(descriptor->nextInChain, &hwndDesc); FindInChain(descriptor->nextInChain, &hwndDesc);
FindInChain(descriptor->nextInChain, &coreWindowDesc); FindInChain(descriptor->nextInChain, &coreWindowDesc);
FindInChain(descriptor->nextInChain, &swapChainPanelDesc); FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
FindInChain(descriptor->nextInChain, &xDesc); FindInChain(descriptor->nextInChain, &xDesc);
ASSERT(metalDesc || hwndDesc || xDesc);
if (metalDesc) { if (metalDesc) {
mType = Type::MetalLayer; mType = Type::MetalLayer;
mMetalLayer = metalDesc->layer; mMetalLayer = metalDesc->layer;
} else if (androidDesc) {
mType = Type::AndroidWindow;
mAndroidNativeWindow = androidDesc->window;
} else if (hwndDesc) { } else if (hwndDesc) {
mType = Type::WindowsHWND; mType = Type::WindowsHWND;
mHInstance = hwndDesc->hinstance; mHInstance = hwndDesc->hinstance;
@ -202,6 +221,11 @@ namespace dawn::native {
return mType; return mType;
} }
void* Surface::GetAndroidNativeWindow() const {
ASSERT(mType == Type::AndroidWindow);
return mAndroidNativeWindow;
}
void* Surface::GetMetalLayer() const { void* Surface::GetMetalLayer() const {
ASSERT(mType == Type::MetalLayer); ASSERT(mType == Type::MetalLayer);
return mMetalLayer; return mMetalLayer;

View File

@ -50,13 +50,23 @@ namespace dawn::native {
NewSwapChainBase* GetAttachedSwapChain(); NewSwapChainBase* GetAttachedSwapChain();
// These are valid to call on all Surfaces. // These are valid to call on all Surfaces.
enum class Type { MetalLayer, WindowsHWND, WindowsCoreWindow, WindowsSwapChainPanel, Xlib }; enum class Type {
AndroidWindow,
MetalLayer,
WindowsHWND,
WindowsCoreWindow,
WindowsSwapChainPanel,
Xlib
};
Type GetType() const; Type GetType() const;
InstanceBase* GetInstance(); InstanceBase* GetInstance();
// Valid to call if the type is MetalLayer // Valid to call if the type is MetalLayer
void* GetMetalLayer() const; void* GetMetalLayer() const;
// Valid to call if the type is Android
void* GetAndroidNativeWindow() const;
// Valid to call if the type is WindowsHWND // Valid to call if the type is WindowsHWND
void* GetHInstance() const; void* GetHInstance() const;
void* GetHWND() const; void* GetHWND() const;
@ -83,6 +93,9 @@ namespace dawn::native {
// MetalLayer // MetalLayer
void* mMetalLayer = nullptr; void* mMetalLayer = nullptr;
// ANativeWindow
void* mAndroidNativeWindow = nullptr;
// WindowsHwnd // WindowsHwnd
void* mHInstance = nullptr; void* mHInstance = nullptr;
void* mHWND = nullptr; void* mHWND = nullptr;

View File

@ -74,11 +74,17 @@ namespace dawn::native {
DAWN_TRY(ValidatePresentMode(descriptor->presentMode)); DAWN_TRY(ValidatePresentMode(descriptor->presentMode));
// TODO(crbug.com/dawn/160): Lift this restriction once // TODO(crbug.com/dawn/160): Lift this restriction once wgpu::Instance::GetPreferredSurfaceFormat is
// wgpu::Instance::GetPreferredSurfaceFormat is implemented. // implemented.
DAWN_INVALID_IF(descriptor->format != wgpu::TextureFormat::BGRA8Unorm, // TODO(dawn:286):
#if defined(DAWN_PLATFORM_ANDROID)
constexpr wgpu::TextureFormat kRequireSwapChainFormat = wgpu::TextureFormat::RGBA8Unorm;
#else
constexpr wgpu::TextureFormat kRequireSwapChainFormat = wgpu::TextureFormat::BGRA8Unorm;
#endif // !defined(DAWN_PLATFORM_ANDROID)
DAWN_INVALID_IF(descriptor->format != kRequireSwapChainFormat,
"Format (%s) is not %s, which is (currently) the only accepted format.", "Format (%s) is not %s, which is (currently) the only accepted format.",
descriptor->format, wgpu::TextureFormat::BGRA8Unorm); descriptor->format, kRequireSwapChainFormat);
DAWN_INVALID_IF(descriptor->usage != wgpu::TextureUsage::RenderAttachment, DAWN_INVALID_IF(descriptor->usage != wgpu::TextureUsage::RenderAttachment,
"Usage (%s) is not %s, which is (currently) the only accepted usage.", "Usage (%s) is not %s, which is (currently) the only accepted usage.",

View File

@ -134,6 +134,30 @@ namespace dawn::native::vulkan {
break; break;
#endif // defined(DAWN_PLATFORM_WINDOWS) #endif // defined(DAWN_PLATFORM_WINDOWS)
#if defined(DAWN_PLATFORM_ANDROID)
case Surface::Type::AndroidWindow: {
if (info.HasExt(InstanceExt::AndroidSurface)) {
ASSERT(surface->GetAndroidNativeWindow() != nullptr);
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.window =
static_cast<struct ANativeWindow*>(surface->GetAndroidNativeWindow());
VkSurfaceKHR vkSurface = VK_NULL_HANDLE;
DAWN_TRY(CheckVkSuccess(
fn.CreateAndroidSurfaceKHR(instance, &createInfo, nullptr, &*vkSurface),
"CreateAndroidSurfaceKHR"));
return vkSurface;
}
break;
}
#endif // defined(DAWN_PLATFORM_ANDROID)
#if defined(DAWN_USE_X11) #if defined(DAWN_USE_X11)
case Surface::Type::Xlib: { case Surface::Type::Xlib: {
if (info.HasExt(InstanceExt::XlibSurface)) { if (info.HasExt(InstanceExt::XlibSurface)) {
@ -382,22 +406,22 @@ namespace dawn::native::vulkan {
config.wgpuUsage = GetUsage(); config.wgpuUsage = GetUsage();
} }
// Only support BGRA8Unorm with SRGB color space for now. // Only support BGRA8Unorm (and RGBA8Unorm on android) with SRGB color space for now.
bool hasBGRA8Unorm = false; config.wgpuFormat = GetFormat();
config.format = VulkanImageFormat(ToBackend(GetDevice()), config.wgpuFormat);
config.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
bool formatIsSupported = false;
for (const VkSurfaceFormatKHR& format : surfaceInfo.formats) { for (const VkSurfaceFormatKHR& format : surfaceInfo.formats) {
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && if (format.format == config.format && format.colorSpace == config.colorSpace) {
format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { formatIsSupported = true;
hasBGRA8Unorm = true;
break; break;
} }
} }
if (!hasBGRA8Unorm) { if (!formatIsSupported) {
return DAWN_INTERNAL_ERROR( return DAWN_INTERNAL_ERROR(absl::StrFormat(
"Vulkan SwapChain must support BGRA8Unorm with sRGB colorspace."); "Vulkan SwapChain must support %s with sRGB colorspace.", config.wgpuFormat));
} }
config.format = VK_FORMAT_B8G8R8A8_UNORM;
config.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
config.wgpuFormat = wgpu::TextureFormat::BGRA8Unorm;
// Only the identity transform with opaque alpha is supported for now. // Only the identity transform with opaque alpha is supported for now.
DAWN_INVALID_IF((surfaceInfo.capabilities.supportedTransforms & DAWN_INVALID_IF((surfaceInfo.capabilities.supportedTransforms &
@ -406,11 +430,26 @@ namespace dawn::native::vulkan {
config.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; config.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
DAWN_INVALID_IF((surfaceInfo.capabilities.supportedCompositeAlpha &
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) == 0,
"Vulkan SwapChain must support opaque alpha.");
config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
#if !defined(DAWN_PLATFORM_ANDROID)
DAWN_INVALID_IF((surfaceInfo.capabilities.supportedCompositeAlpha &
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) == 0,
"Vulkan SwapChain must support opaque alpha.");
#else
// TODO(dawn:286): investigate composite alpha for WebGPU native
VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
};
for (uint32_t i = 0; i < 4; i++) {
if (surfCapabilities.supportedCompositeAlpha & compositeAlphaFlags[i]) {
config.alphaMode = compositeAlphaFlags[i];
break;
}
}
#endif // #if !defined(DAWN_PLATFORM_ANDROID)
// Choose the number of images for the swapchain= and clamp it to the min and max from the // Choose the number of images for the swapchain= and clamp it to the min and max from the
// surface capabilities. maxImageCount = 0 means there is no limit. // surface capabilities. maxImageCount = 0 means there is no limit.

View File

@ -47,6 +47,7 @@ namespace dawn::native::vulkan {
{InstanceExt::Win32Surface, "VK_KHR_win32_surface", NeverPromoted}, {InstanceExt::Win32Surface, "VK_KHR_win32_surface", NeverPromoted},
{InstanceExt::XcbSurface, "VK_KHR_xcb_surface", NeverPromoted}, {InstanceExt::XcbSurface, "VK_KHR_xcb_surface", NeverPromoted},
{InstanceExt::XlibSurface, "VK_KHR_xlib_surface", NeverPromoted}, {InstanceExt::XlibSurface, "VK_KHR_xlib_surface", NeverPromoted},
{InstanceExt::AndroidSurface, "VK_KHR_android_surface", NeverPromoted},
{InstanceExt::DebugUtils, "VK_EXT_debug_utils", NeverPromoted}, {InstanceExt::DebugUtils, "VK_EXT_debug_utils", NeverPromoted},
{InstanceExt::ValidationFeatures, "VK_EXT_validation_features", NeverPromoted}, {InstanceExt::ValidationFeatures, "VK_EXT_validation_features", NeverPromoted},
@ -99,6 +100,7 @@ namespace dawn::native::vulkan {
hasDependencies = HasDep(InstanceExt::GetPhysicalDeviceProperties2); hasDependencies = HasDep(InstanceExt::GetPhysicalDeviceProperties2);
break; break;
case InstanceExt::AndroidSurface:
case InstanceExt::FuchsiaImagePipeSurface: case InstanceExt::FuchsiaImagePipeSurface:
case InstanceExt::MetalSurface: case InstanceExt::MetalSurface:
case InstanceExt::WaylandSurface: case InstanceExt::WaylandSurface:

View File

@ -37,6 +37,7 @@ namespace dawn::native::vulkan {
Win32Surface, Win32Surface,
XcbSurface, XcbSurface,
XlibSurface, XlibSurface,
AndroidSurface,
// Others // Others
DebugUtils, DebugUtils,

View File

@ -147,6 +147,12 @@ namespace dawn::native::vulkan {
} }
#endif // defined(DAWN_PLATFORM_WINDOWS) #endif // defined(DAWN_PLATFORM_WINDOWS)
#if defined(DAWN_PLATFORM_ANDROID)
if (globalInfo.HasExt(InstanceExt::AndroidSurface)) {
GET_INSTANCE_PROC(CreateAndroidSurfaceKHR);
}
#endif // defined(DAWN_PLATFORM_ANDROID)
#if defined(DAWN_USE_X11) #if defined(DAWN_USE_X11)
if (globalInfo.HasExt(InstanceExt::XlibSurface)) { if (globalInfo.HasExt(InstanceExt::XlibSurface)) {
GET_INSTANCE_PROC(CreateXlibSurfaceKHR); GET_INSTANCE_PROC(CreateXlibSurfaceKHR);

View File

@ -132,6 +132,10 @@ namespace dawn::native::vulkan {
GetPhysicalDeviceWin32PresentationSupportKHR = nullptr; GetPhysicalDeviceWin32PresentationSupportKHR = nullptr;
#endif // defined(DAWN_PLATFORM_WINDOWS) #endif // defined(DAWN_PLATFORM_WINDOWS)
#if defined(DAWN_PLATFORM_ANDROID)
PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR = nullptr;
#endif // defined(DAWN_PLATFORM_ANDROID)
#if defined(DAWN_USE_X11) #if defined(DAWN_USE_X11)
// KHR_xlib_surface // KHR_xlib_surface
PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR = nullptr; PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR = nullptr;

View File

@ -43,7 +43,6 @@ target_link_libraries(dawn_utils
dawn_proc dawn_proc
dawn_wire dawn_wire
SPIRV-Tools-opt SPIRV-Tools-opt
glfw
) )
if(WIN32 AND NOT WINDOWS_STORE) if(WIN32 AND NOT WINDOWS_STORE)

View File

@ -32,7 +32,7 @@ if (NOT TARGET SPIRV-Tools)
add_subdirectory(${DAWN_SPIRV_TOOLS_DIR} "${CMAKE_CURRENT_BINARY_DIR}/spirv-tools") add_subdirectory(${DAWN_SPIRV_TOOLS_DIR} "${CMAKE_CURRENT_BINARY_DIR}/spirv-tools")
endif() endif()
if (NOT TARGET glfw) if (NOT TARGET glfw AND DAWN_SUPPORTS_GLFW_FOR_WINDOWING)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)