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:
parent
57e78fd258
commit
f2556ab35c
|
@ -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()
|
||||
|
||||
|
|
|
@ -176,7 +176,8 @@
|
|||
"SurfaceDescriptorFromWindowsHWND",
|
||||
"SurfaceDescriptorFromXlibWindow",
|
||||
"SurfaceDescriptorFromWindowsCoreWindow",
|
||||
"SurfaceDescriptorFromWindowsSwapChainPanel"
|
||||
"SurfaceDescriptorFromWindowsSwapChainPanel",
|
||||
"SurfaceDescriptorFromAndroidNativeWindow"
|
||||
],
|
||||
"client_side_commands": [
|
||||
"AdapterCreateDevice",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace dawn::native::vulkan {
|
|||
Win32Surface,
|
||||
XcbSurface,
|
||||
XlibSurface,
|
||||
AndroidSurface,
|
||||
|
||||
// Others
|
||||
DebugUtils,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -43,7 +43,6 @@ target_link_libraries(dawn_utils
|
|||
dawn_proc
|
||||
dawn_wire
|
||||
SPIRV-Tools-opt
|
||||
glfw
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT WINDOWS_STORE)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue