Commit 0662a4af by Alexis Hetu Committed by Alexis Hétu

MacOS WSI

This cl implements the VK_MVK_macos_surface extension, which adds the vkCreateMacOSSurfaceMVK function on MacOS. According to the spec: "The VK_MVK_macos_surface extension is an instance extension. It provides a mechanism to create a VkSurfaceKHR object (defined by the VK_KHR_surface extension) that refers to an NSView, the native surface type of macOS, which is underpinned by a CAMetalLayer, to support rendering to the surface using Apple’s Metal framework." Bug b/137673628 Change-Id: Iacf7696b1d9e52d7349ea4efa01f0acdd09a6c8f Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33848Reviewed-by: 's avatarHernan Liatis <hliatis@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 64f2cec3
...@@ -394,9 +394,13 @@ else() ...@@ -394,9 +394,13 @@ else()
set_cpp_flag("-fPIC") set_cpp_flag("-fPIC")
endif() endif()
if(LINUX) if(WIN32)
set_cpp_flag("-DVK_USE_PLATFORM_WIN32_KHR")
elseif(LINUX)
set_cpp_flag("-DUSE_X11=1") set_cpp_flag("-DUSE_X11=1")
set_cpp_flag("-DVK_USE_PLATFORM_XLIB_KHR") set_cpp_flag("-DVK_USE_PLATFORM_XLIB_KHR")
elseif(APPLE)
set_cpp_flag("-DVK_USE_PLATFORM_MACOS_MVK")
endif() endif()
# Use -g3 to have even more debug info # Use -g3 to have even more debug info
...@@ -1812,6 +1816,11 @@ elseif(APPLE) ...@@ -1812,6 +1816,11 @@ elseif(APPLE)
list(APPEND OPENGL_COMPILER_LIST list(APPEND OPENGL_COMPILER_LIST
${OPENGL_COMPILER_DIR}/ossource_posix.cpp ${OPENGL_COMPILER_DIR}/ossource_posix.cpp
) )
list(APPEND VULKAN_LIST
${SOURCE_DIR}/WSI/MacOSSurfaceMVK.mm
${SOURCE_DIR}/WSI/MacOSSurfaceMVK.h
)
elseif(ANDROID) elseif(ANDROID)
list(APPEND SWIFTSHADER_LIST list(APPEND SWIFTSHADER_LIST
${SOURCE_DIR}/Main/FrameBufferAndroid.cpp ${SOURCE_DIR}/Main/FrameBufferAndroid.cpp
......
...@@ -93,6 +93,10 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctio ...@@ -93,6 +93,10 @@ static const std::unordered_map<std::string, PFN_vkVoidFunction> instanceFunctio
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR), MAKE_VULKAN_INSTANCE_ENTRY(vkCreateXlibSurfaceKHR),
MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceXlibPresentationSupportKHR), MAKE_VULKAN_INSTANCE_ENTRY(vkGetPhysicalDeviceXlibPresentationSupportKHR),
#endif #endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
// VK_MVK_macos_surface
MAKE_VULKAN_INSTANCE_ENTRY(vkCreateMacOSSurfaceMVK),
#endif
}; };
#undef MAKE_VULKAN_INSTANCE_ENTRY #undef MAKE_VULKAN_INSTANCE_ENTRY
......
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
#include "VkShaderModule.hpp" #include "VkShaderModule.hpp"
#include "VkRenderPass.hpp" #include "VkRenderPass.hpp"
#ifdef VK_USE_PLATFORM_MACOS_MVK
#include "WSI/MacOSSurfaceMVK.h"
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR #ifdef VK_USE_PLATFORM_XLIB_KHR
#include "WSI/XlibSurfaceKHR.hpp" #include "WSI/XlibSurfaceKHR.hpp"
#endif #endif
...@@ -135,6 +139,9 @@ static const VkExtensionProperties instanceExtensionProperties[] = ...@@ -135,6 +139,9 @@ static const VkExtensionProperties instanceExtensionProperties[] =
#ifdef VK_USE_PLATFORM_XLIB_KHR #ifdef VK_USE_PLATFORM_XLIB_KHR
{ VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION }, { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION },
#endif #endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
{ VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_SPEC_VERSION },
#endif
}; };
static const VkExtensionProperties deviceExtensionProperties[] = static const VkExtensionProperties deviceExtensionProperties[] =
...@@ -2611,6 +2618,16 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkP ...@@ -2611,6 +2618,16 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkP
} }
#endif #endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
{
TRACE("(VkInstance instance = %p, VkMacOSSurfaceCreateInfoMVK* pCreateInfo = %p, VkAllocationCallbacks* pAllocator = %p, VkSurface* pSurface = %p)",
instance, pCreateInfo, pAllocator, pSurface);
return vk::MacOSSurfaceMVK::Create(pAllocator, pCreateInfo, pSurface);
}
#endif
#ifndef __ANDROID__ #ifndef __ANDROID__
VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator) VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator)
{ {
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SWIFTSHADER_MACOSSURFACEMVK_HPP
#define SWIFTSHADER_MACOSSURFACEMVK_HPP
#include "Vulkan/VkObject.hpp"
#include "VkSurfaceKHR.hpp"
#include "vulkan/vulkan_macos.h"
namespace vk {
class MetalLayer;
class MacOSSurfaceMVK : public SurfaceKHR, public ObjectBase<MacOSSurfaceMVK, VkSurfaceKHR> {
public:
MacOSSurfaceMVK(const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, void *mem);
void destroySurface(const VkAllocationCallbacks *pAllocator) override;
static size_t ComputeRequiredAllocationSize(const VkMacOSSurfaceCreateInfoMVK *pCreateInfo);
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
virtual void attachImage(PresentImage* image) override {}
virtual void detachImage(PresentImage* image) override {}
void present(PresentImage* image) override;
private:
MetalLayer* metalLayer = nullptr;
};
}
#endif //SWIFTSHADER_MACOSSURFACEMVK_HPP
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "MacOSSurfaceMVK.h"
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkImage.hpp"
#include <Metal/Metal.h>
#include <QuartzCore/CAMetalLayer.h>
#include <AppKit/NSView.h>
namespace vk {
class MetalLayer
{
public:
void init(const void* pView)
{
view = nullptr;
layer = nullptr;
id<NSObject> obj = (id<NSObject>)pView;
if([obj isKindOfClass: [NSView class]])
{
if(!NSThread.isMainThread)
{
UNREACHABLE("MetalLayer::init(): not called from main thread");
}
view = (NSView*)[obj retain];
obj = view.layer;
if ([obj isKindOfClass: [CAMetalLayer class]])
{
layer = (CAMetalLayer*)[obj retain];
}
else
{
UNREACHABLE("MetalLayer::init(): view doesn't have metal backed layer");
}
}
}
void release()
{
if(layer)
{
[layer release];
}
if(view)
{
[view release];
}
}
VkExtent2D getExtent() const
{
if(layer)
{
CGSize drawSize = layer.bounds.size;
CGFloat scaleFactor = layer.contentsScale;
drawSize.width = trunc(drawSize.width * scaleFactor);
drawSize.height = trunc(drawSize.height * scaleFactor);
return { static_cast<uint32_t>(drawSize.width), static_cast<uint32_t>(drawSize.height) };
}
else
{
return { 0, 0 };
}
}
id<CAMetalDrawable> getNextDrawable() const
{
if(layer)
{
return [layer nextDrawable];
}
return nil;
}
private:
NSView* view;
CAMetalLayer* layer;
};
MacOSSurfaceMVK::MacOSSurfaceMVK(const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, void *mem) :
metalLayer(reinterpret_cast<MetalLayer*>(mem))
{
metalLayer->init(pCreateInfo->pView);
}
void MacOSSurfaceMVK::destroySurface(const VkAllocationCallbacks *pAllocator)
{
if(metalLayer)
{
metalLayer->release();
}
vk::deallocate(metalLayer, pAllocator);
}
size_t MacOSSurfaceMVK::ComputeRequiredAllocationSize(const VkMacOSSurfaceCreateInfoMVK *pCreateInfo)
{
return sizeof(MetalLayer);
}
void MacOSSurfaceMVK::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
{
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
VkExtent2D extent = metalLayer->getExtent();
pSurfaceCapabilities->currentExtent = extent;
pSurfaceCapabilities->minImageExtent = extent;
pSurfaceCapabilities->maxImageExtent = extent;
}
void MacOSSurfaceMVK::present(PresentImage* image)
{
auto drawable = metalLayer->getNextDrawable();
if(drawable)
{
VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
[drawable.texture replaceRegion:MTLRegionMake2D(0, 0, extent.width, extent.height)
mipmapLevel:0
withBytes:image->getImageMemory()->getOffsetPointer(0)
bytesPerRow:image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0)];
[drawable present];
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment