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()
elseif(APPLE)
set(ENABLE_METAL ON)
elseif(ANDROID)
set(ENABLE_VULKAN ON)
set(ENABLE_OPENGLES ON)
elseif(UNIX)
set(ENABLE_OPENGLES ON)
set(ENABLE_DESKTOP_GL ON)
@ -96,7 +99,7 @@ elseif(UNIX)
endif()
# 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)
endif()

View File

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

View File

@ -50,6 +50,9 @@ namespace dawn::native {
case Surface::Type::Xlib:
s->Append("Xlib");
break;
case Surface::Type::AndroidWindow:
s->Append("AndroidWindow");
break;
}
return {true};
}
@ -65,6 +68,7 @@ namespace dawn::native {
descriptor);
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain,
wgpu::SType::SurfaceDescriptorFromAndroidNativeWindow,
wgpu::SType::SurfaceDescriptorFromMetalLayer,
wgpu::SType::SurfaceDescriptorFromWindowsHWND,
wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow,
@ -82,6 +86,17 @@ namespace dawn::native {
}
#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_WIN32)
const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
@ -142,20 +157,24 @@ namespace dawn::native {
Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
: mInstance(instance) {
ASSERT(descriptor->nextInChain != nullptr);
const SurfaceDescriptorFromAndroidNativeWindow* androidDesc = nullptr;
const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
FindInChain(descriptor->nextInChain, &androidDesc);
FindInChain(descriptor->nextInChain, &metalDesc);
FindInChain(descriptor->nextInChain, &hwndDesc);
FindInChain(descriptor->nextInChain, &coreWindowDesc);
FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
FindInChain(descriptor->nextInChain, &xDesc);
ASSERT(metalDesc || hwndDesc || xDesc);
if (metalDesc) {
mType = Type::MetalLayer;
mMetalLayer = metalDesc->layer;
} else if (androidDesc) {
mType = Type::AndroidWindow;
mAndroidNativeWindow = androidDesc->window;
} else if (hwndDesc) {
mType = Type::WindowsHWND;
mHInstance = hwndDesc->hinstance;
@ -202,6 +221,11 @@ namespace dawn::native {
return mType;
}
void* Surface::GetAndroidNativeWindow() const {
ASSERT(mType == Type::AndroidWindow);
return mAndroidNativeWindow;
}
void* Surface::GetMetalLayer() const {
ASSERT(mType == Type::MetalLayer);
return mMetalLayer;

View File

@ -50,13 +50,23 @@ namespace dawn::native {
NewSwapChainBase* GetAttachedSwapChain();
// 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;
InstanceBase* GetInstance();
// Valid to call if the type is MetalLayer
void* GetMetalLayer() const;
// Valid to call if the type is Android
void* GetAndroidNativeWindow() const;
// Valid to call if the type is WindowsHWND
void* GetHInstance() const;
void* GetHWND() const;
@ -83,6 +93,9 @@ namespace dawn::native {
// MetalLayer
void* mMetalLayer = nullptr;
// ANativeWindow
void* mAndroidNativeWindow = nullptr;
// WindowsHwnd
void* mHInstance = nullptr;
void* mHWND = nullptr;

View File

@ -74,11 +74,17 @@ namespace dawn::native {
DAWN_TRY(ValidatePresentMode(descriptor->presentMode));
// TODO(crbug.com/dawn/160): Lift this restriction once
// wgpu::Instance::GetPreferredSurfaceFormat is implemented.
DAWN_INVALID_IF(descriptor->format != wgpu::TextureFormat::BGRA8Unorm,
// TODO(crbug.com/dawn/160): Lift this restriction once wgpu::Instance::GetPreferredSurfaceFormat is
// implemented.
// 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.",
descriptor->format, wgpu::TextureFormat::BGRA8Unorm);
descriptor->format, kRequireSwapChainFormat);
DAWN_INVALID_IF(descriptor->usage != wgpu::TextureUsage::RenderAttachment,
"Usage (%s) is not %s, which is (currently) the only accepted usage.",

View File

@ -134,6 +134,30 @@ namespace dawn::native::vulkan {
break;
#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)
case Surface::Type::Xlib: {
if (info.HasExt(InstanceExt::XlibSurface)) {
@ -382,22 +406,22 @@ namespace dawn::native::vulkan {
config.wgpuUsage = GetUsage();
}
// Only support BGRA8Unorm with SRGB color space for now.
bool hasBGRA8Unorm = false;
// Only support BGRA8Unorm (and RGBA8Unorm on android) with SRGB color space for now.
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) {
if (format.format == VK_FORMAT_B8G8R8A8_UNORM &&
format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
hasBGRA8Unorm = true;
if (format.format == config.format && format.colorSpace == config.colorSpace) {
formatIsSupported = true;
break;
}
}
if (!hasBGRA8Unorm) {
return DAWN_INTERNAL_ERROR(
"Vulkan SwapChain must support BGRA8Unorm with sRGB colorspace.");
if (!formatIsSupported) {
return DAWN_INTERNAL_ERROR(absl::StrFormat(
"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.
DAWN_INVALID_IF((surfaceInfo.capabilities.supportedTransforms &
@ -406,11 +430,26 @@ namespace dawn::native::vulkan {
config.transform = VK_SURFACE_TRANSFORM_IDENTITY_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.");
config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
#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
// 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::XcbSurface, "VK_KHR_xcb_surface", NeverPromoted},
{InstanceExt::XlibSurface, "VK_KHR_xlib_surface", NeverPromoted},
{InstanceExt::AndroidSurface, "VK_KHR_android_surface", NeverPromoted},
{InstanceExt::DebugUtils, "VK_EXT_debug_utils", NeverPromoted},
{InstanceExt::ValidationFeatures, "VK_EXT_validation_features", NeverPromoted},
@ -99,6 +100,7 @@ namespace dawn::native::vulkan {
hasDependencies = HasDep(InstanceExt::GetPhysicalDeviceProperties2);
break;
case InstanceExt::AndroidSurface:
case InstanceExt::FuchsiaImagePipeSurface:
case InstanceExt::MetalSurface:
case InstanceExt::WaylandSurface:

View File

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

View File

@ -147,6 +147,12 @@ namespace dawn::native::vulkan {
}
#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 (globalInfo.HasExt(InstanceExt::XlibSurface)) {
GET_INSTANCE_PROC(CreateXlibSurfaceKHR);

View File

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

View File

@ -43,7 +43,6 @@ target_link_libraries(dawn_utils
dawn_proc
dawn_wire
SPIRV-Tools-opt
glfw
)
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")
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_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)