Commit 806ba566 by Jonah Ryan-Davis Committed by Commit Bot

Extend ANGLE_iosurface_client_buffer to Vulkan backend for Swangle

Implement an IOSurface-backed pBuffer surface for the Vulkan backend on Mac, through SwANGLE. ANGLE will pass a raw pointer to Swiftshader and handle locking/unlocking the IOSurface. Bug: chromium:1015454 Change-Id: Ia3ead55334736003d405b54ba8dcc7701706fbb2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1965434 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5641d193
...@@ -55,6 +55,11 @@ New Tokens ...@@ -55,6 +55,11 @@ New Tokens
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
Accepted in the <attribute> parameter of
eglGetConfigAttrib:
EGL_BIND_TO_TEXTURE_TARGET_ANGLE 0x348D
Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
Replace the last sentence of paragraph 1 of Section 3.5.3 with the Replace the last sentence of paragraph 1 of Section 3.5.3 with the
...@@ -81,8 +86,8 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -81,8 +86,8 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
- EGL_TEXTURE_FORMAT with a value of EGL_TEXTURE_RGBA - EGL_TEXTURE_FORMAT with a value of EGL_TEXTURE_RGBA
- EGL_WIDTH with a value between 1 and the width of <buffer>. - EGL_WIDTH with a value between 1 and the width of <buffer>.
- EGL_HEIGHT with a value between 1 and the height of <buffer>. - EGL_HEIGHT with a value between 1 and the height of <buffer>.
- EGL_TEXTURE_TARGET with a value of EGL_TEXTURE_RECTANGLE_ANGLE (macOS) - EGL_TEXTURE_TARGET with a value that matches the attribute
or EGL_TEXTURE_2D (iOS) EGL_BIND_TO_TEXTURE_TARGET_ANGLE as queried from eglGetConfigAttrib.
- EGL_IOSURFACE_PLANE_ANGLE with a value between 0 and the number of - EGL_IOSURFACE_PLANE_ANGLE with a value between 0 and the number of
planes of <buffer> (exclusive). planes of <buffer> (exclusive).
...@@ -119,6 +124,15 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) ...@@ -119,6 +124,15 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors)
of the associcated IOSurface object are undefined while the pbuffer is of the associcated IOSurface object are undefined while the pbuffer is
bound to a client texture." bound to a client texture."
Append to the end of Table 3.1.
---------------------------------------------------------------------------
Attribute Type Notes
---------------------------------------------------------------------------
EGL_BIND_TO_TEXTURE_TARGET_ANGLE enum Texture target supported by
IOSurface-backed pbuffers.
---------------------------------------------------------------------------
Issues Issues
1. Can RGB formats be supported? 1. Can RGB formats be supported?
......
...@@ -197,6 +197,7 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi ...@@ -197,6 +197,7 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi
#define EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A #define EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
#define EGL_IOSURFACE_READ_HINT_ANGLE 0x0001 #define EGL_IOSURFACE_READ_HINT_ANGLE 0x0001
#define EGL_IOSURFACE_WRITE_HINT_ANGLE 0x0002 #define EGL_IOSURFACE_WRITE_HINT_ANGLE 0x0002
#define EGL_BIND_TO_TEXTURE_TARGET_ANGLE 0x348D
#endif /* EGL_ANGLE_iosurface_client_buffer */ #endif /* EGL_ANGLE_iosurface_client_buffer */
#ifndef EGL_ANGLE_create_context_extensions_enabled #ifndef EGL_ANGLE_create_context_extensions_enabled
......
...@@ -229,6 +229,12 @@ struct FeaturesVk : FeatureSetBase ...@@ -229,6 +229,12 @@ struct FeaturesVk : FeatureSetBase
"Use ANGLE's Vulkan deferred command graph.", "Use ANGLE's Vulkan deferred command graph.",
&members, &members,
}; };
// Whether the VkDevice supports the VK_EXT_external_memory_host extension, on which the
// ANGLE_iosurface_client_buffer extension can be layered.
Feature supportsExternalMemoryHost = {
"supports_external_memory_host", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_EXT_external_memory_host extension", &members};
}; };
inline FeaturesVk::FeaturesVk() = default; inline FeaturesVk::FeaturesVk() = default;
......
...@@ -18,6 +18,7 @@ namespace angle ...@@ -18,6 +18,7 @@ namespace angle
{ {
std::string GetExecutablePath(); std::string GetExecutablePath();
std::string GetExecutableDirectory(); std::string GetExecutableDirectory();
std::string GetHelperExecutableDir();
const char *GetSharedLibraryExtension(); const char *GetSharedLibraryExtension();
const char *GetExecutableExtension(); const char *GetExecutableExtension();
char GetPathSeparator(); char GetPathSeparator();
......
...@@ -55,6 +55,19 @@ const char *GetPathSeparatorForEnvironmentVar() ...@@ -55,6 +55,19 @@ const char *GetPathSeparatorForEnvironmentVar()
return ":"; return ":";
} }
std::string GetHelperExecutableDir()
{
std::string directory;
static int dummySymbol = 0;
Dl_info dlInfo;
if (dladdr(&dummySymbol, &dlInfo) != 0)
{
std::string moduleName = dlInfo.dli_fname;
directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
}
return directory;
}
class PosixLibrary : public Library class PosixLibrary : public Library
{ {
public: public:
...@@ -63,13 +76,7 @@ class PosixLibrary : public Library ...@@ -63,13 +76,7 @@ class PosixLibrary : public Library
std::string directory; std::string directory;
if (searchType == SearchType::ApplicationDir) if (searchType == SearchType::ApplicationDir)
{ {
static int dummySymbol = 0; directory = GetHelperExecutableDir();
Dl_info dlInfo;
if (dladdr(&dummySymbol, &dlInfo) != 0)
{
std::string moduleName = dlInfo.dli_fname;
directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
}
} }
std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension(); std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
......
...@@ -100,4 +100,9 @@ char GetPathSeparator() ...@@ -100,4 +100,9 @@ char GetPathSeparator()
{ {
return '\\'; return '\\';
} }
std::string GetHelperExecutableDir()
{
return "";
}
} // namespace angle } // namespace angle
...@@ -34,6 +34,7 @@ Config::Config() ...@@ -34,6 +34,7 @@ Config::Config()
alphaMaskSize(0), alphaMaskSize(0),
bindToTextureRGB(EGL_FALSE), bindToTextureRGB(EGL_FALSE),
bindToTextureRGBA(EGL_FALSE), bindToTextureRGBA(EGL_FALSE),
bindToTextureTarget(EGL_TEXTURE_2D),
colorBufferType(EGL_RGB_BUFFER), colorBufferType(EGL_RGB_BUFFER),
configCaveat(EGL_NONE), configCaveat(EGL_NONE),
configID(0), configID(0),
...@@ -318,6 +319,9 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap) ...@@ -318,6 +319,9 @@ std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap)
case EGL_BIND_TO_TEXTURE_RGBA: case EGL_BIND_TO_TEXTURE_RGBA:
match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue); match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
break; break;
case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
match = config.bindToTextureTarget == static_cast<EGLenum>(attributeValue);
break;
case EGL_MIN_SWAP_INTERVAL: case EGL_MIN_SWAP_INTERVAL:
match = config.minSwapInterval == attributeValue; match = config.minSwapInterval == attributeValue;
break; break;
......
...@@ -43,6 +43,7 @@ struct Config ...@@ -43,6 +43,7 @@ struct Config
EGLint alphaMaskSize; // Bits of Alpha Mask in the mask buffer EGLint alphaMaskSize; // Bits of Alpha Mask in the mask buffer
EGLBoolean bindToTextureRGB; // True if bindable to RGB textures. EGLBoolean bindToTextureRGB; // True if bindable to RGB textures.
EGLBoolean bindToTextureRGBA; // True if bindable to RGBA textures. EGLBoolean bindToTextureRGBA; // True if bindable to RGBA textures.
EGLenum bindToTextureTarget; // Which texture target should be used for pbuffers
EGLenum colorBufferType; // Color buffer type EGLenum colorBufferType; // Color buffer type
EGLenum configCaveat; // Any caveats for the configuration EGLenum configCaveat; // Any caveats for the configuration
EGLint configID; // Unique EGLConfig identifier EGLint configID; // Unique EGLConfig identifier
......
...@@ -3654,6 +3654,9 @@ void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value) ...@@ -3654,6 +3654,9 @@ void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
case EGL_SURFACE_TYPE: case EGL_SURFACE_TYPE:
*value = config->surfaceType; *value = config->surfaceType;
break; break;
case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
*value = config->bindToTextureTarget;
break;
case EGL_TRANSPARENT_TYPE: case EGL_TRANSPARENT_TYPE:
*value = config->transparentType; *value = config->transparentType;
break; break;
......
...@@ -259,6 +259,8 @@ egl::ConfigSet DisplayCGL::generateConfigs() ...@@ -259,6 +259,8 @@ egl::ConfigSet DisplayCGL::generateConfigs()
config.bindToTextureRGB = EGL_FALSE; config.bindToTextureRGB = EGL_FALSE;
config.bindToTextureRGBA = EGL_FALSE; config.bindToTextureRGBA = EGL_FALSE;
config.bindToTextureTarget = EGL_TEXTURE_RECTANGLE_ANGLE;
config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
config.minSwapInterval = 1; config.minSwapInterval = 1;
......
...@@ -204,6 +204,12 @@ egl::ConfigSet DisplayEAGL::generateConfigs() ...@@ -204,6 +204,12 @@ egl::ConfigSet DisplayEAGL::generateConfigs()
config.bindToTextureRGB = EGL_FALSE; config.bindToTextureRGB = EGL_FALSE;
config.bindToTextureRGBA = EGL_FALSE; config.bindToTextureRGBA = EGL_FALSE;
# if !ANGLE_PLATFORM_MACCATALYST
config.bindToTextureTarget = EGL_TEXTURE_2D;
# else
config.bindToTextureTarget = EGL_TEXTURE_RECTANGLE_ANGLE;
# endif
config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
config.minSwapInterval = 1; config.minSwapInterval = 1;
......
...@@ -45,18 +45,18 @@ _vulkan_backend_sources = [ ...@@ -45,18 +45,18 @@ _vulkan_backend_sources = [
"OverlayVk.h", "OverlayVk.h",
"PersistentCommandPool.cpp", "PersistentCommandPool.cpp",
"PersistentCommandPool.h", "PersistentCommandPool.h",
"ProgramVk.cpp",
"ProgramVk.h",
"ProgramPipelineVk.cpp", "ProgramPipelineVk.cpp",
"ProgramPipelineVk.h", "ProgramPipelineVk.h",
"ProgramVk.cpp",
"ProgramVk.h",
"QueryVk.cpp", "QueryVk.cpp",
"QueryVk.h", "QueryVk.h",
"RenderTargetVk.cpp",
"RenderTargetVk.h",
"RenderbufferVk.cpp", "RenderbufferVk.cpp",
"RenderbufferVk.h", "RenderbufferVk.h",
"RendererVk.cpp", "RendererVk.cpp",
"RendererVk.h", "RendererVk.h",
"RenderTargetVk.cpp",
"RenderTargetVk.h",
"SamplerVk.cpp", "SamplerVk.cpp",
"SamplerVk.h", "SamplerVk.h",
"SecondaryCommandBuffer.cpp", "SecondaryCommandBuffer.cpp",
...@@ -83,12 +83,12 @@ _vulkan_backend_sources = [ ...@@ -83,12 +83,12 @@ _vulkan_backend_sources = [
"vk_caps_utils.h", "vk_caps_utils.h",
"vk_ext_provoking_vertex.h", "vk_ext_provoking_vertex.h",
"vk_format_table_autogen.cpp", "vk_format_table_autogen.cpp",
"vk_format_utils.h",
"vk_format_utils.cpp", "vk_format_utils.cpp",
"vk_format_utils.h",
"vk_helpers.cpp", "vk_helpers.cpp",
"vk_helpers.h", "vk_helpers.h",
"vk_internal_shaders_autogen.h",
"vk_internal_shaders_autogen.cpp", "vk_internal_shaders_autogen.cpp",
"vk_internal_shaders_autogen.h",
"vk_mandatory_format_support_table_autogen.cpp", "vk_mandatory_format_support_table_autogen.cpp",
"vk_utils.cpp", "vk_utils.cpp",
"vk_utils.h", "vk_utils.h",
...@@ -144,10 +144,12 @@ if (is_ggp) { ...@@ -144,10 +144,12 @@ if (is_ggp) {
if (is_mac) { if (is_mac) {
_vulkan_backend_sources += [ _vulkan_backend_sources += [
"mac/DisplayVkMac.mm",
"mac/DisplayVkMac.h", "mac/DisplayVkMac.h",
"mac/WindowSurfaceVkMac.mm", "mac/DisplayVkMac.mm",
"mac/IOSurfaceSurfaceVkMac.h",
"mac/IOSurfaceSurfaceVkMac.mm",
"mac/WindowSurfaceVkMac.h", "mac/WindowSurfaceVkMac.h",
"mac/WindowSurfaceVkMac.mm",
] ]
} }
...@@ -170,9 +172,7 @@ group("angle_vulkan_entry_points") { ...@@ -170,9 +172,7 @@ group("angle_vulkan_entry_points") {
"//third_party/fuchsia-sdk/sdk:vulkan", "//third_party/fuchsia-sdk/sdk:vulkan",
] ]
} else if (!is_android && !is_ggp) { } else if (!is_android && !is_ggp) {
data_deps = [ data_deps = [ "$angle_root/third_party/vulkan-loader/src:libvulkan" ]
"$angle_root/third_party/vulkan-loader/src:libvulkan",
]
} }
} }
......
...@@ -95,10 +95,12 @@ class DisplayVk : public DisplayImpl, public vk::Context ...@@ -95,10 +95,12 @@ class DisplayVk : public DisplayImpl, public vk::Context
void populateFeatureList(angle::FeatureList *features) override; void populateFeatureList(angle::FeatureList *features) override;
protected:
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
private: private:
virtual SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state, virtual SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window) = 0; EGLNativeWindowType window) = 0;
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override; void generateCaps(egl::Caps *outCaps) const override;
mutable angle::ScratchBuffer mScratchBuffer; mutable angle::ScratchBuffer mScratchBuffer;
......
...@@ -231,6 +231,21 @@ const char *GetVkObjectTypeName(VkObjectType type) ...@@ -231,6 +231,21 @@ const char *GetVkObjectTypeName(VkObjectType type)
} }
} }
// This function is unused on Android/Fuschia/GGP
#if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA) && \
!defined(ANGLE_PLATFORM_GGP)
const std::string WrapICDEnvironment(const char *icdEnvironment)
{
# if defined(ANGLE_PLATFORM_APPLE)
// On MacOS the libraries are bundled into the application directory
std::string ret = angle::GetHelperExecutableDir() + icdEnvironment;
return ret;
# endif // defined(ANGLE_PLATFORM_APPLE)
return icdEnvironment;
}
#endif // !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_FUCHSIA) &&
// !defined(ANGLE_PLATFORM_GGP)
VKAPI_ATTR VkBool32 VKAPI_CALL VKAPI_ATTR VkBool32 VKAPI_CALL
DebugUtilsMessenger(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, DebugUtilsMessenger(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
...@@ -370,7 +385,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -370,7 +385,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
!defined(ANGLE_PLATFORM_GGP) !defined(ANGLE_PLATFORM_GGP)
if (icd == vk::ICD::Mock) if (icd == vk::ICD::Mock)
{ {
if (!setICDEnvironment(ANGLE_VK_MOCK_ICD_JSON)) if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_MOCK_ICD_JSON).c_str()))
{ {
ERR() << "Error setting environment for Mock/Null Driver."; ERR() << "Error setting environment for Mock/Null Driver.";
} }
...@@ -378,7 +393,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable ...@@ -378,7 +393,7 @@ class ScopedVkLoaderEnvironment : angle::NonCopyable
# if defined(ANGLE_VK_SWIFTSHADER_ICD_JSON) # if defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
else if (icd == vk::ICD::SwiftShader) else if (icd == vk::ICD::SwiftShader)
{ {
if (!setICDEnvironment(ANGLE_VK_SWIFTSHADER_ICD_JSON)) if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_SWIFTSHADER_ICD_JSON).c_str()))
{ {
ERR() << "Error setting environment for SwiftShader."; ERR() << "Error setting environment for SwiftShader.";
} }
...@@ -552,6 +567,7 @@ RendererVk::RendererVk() ...@@ -552,6 +567,7 @@ RendererVk::RendererVk()
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mMaxVertexAttribDivisor(1), mMaxVertexAttribDivisor(1),
mMaxVertexAttribStride(0), mMaxVertexAttribStride(0),
mMinImportedHostPointerAlignment(1),
mDevice(VK_NULL_HANDLE), mDevice(VK_NULL_HANDLE),
mLastCompletedQueueSerial(mQueueSerialFactory.generate()), mLastCompletedQueueSerial(mQueueSerialFactory.generate()),
mCurrentQueueSerial(mQueueSerialFactory.generate()), mCurrentQueueSerial(mQueueSerialFactory.generate()),
...@@ -922,6 +938,10 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt ...@@ -922,6 +938,10 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
mPhysicalDeviceSubgroupProperties = {}; mPhysicalDeviceSubgroupProperties = {};
mPhysicalDeviceSubgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; mPhysicalDeviceSubgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
mPhysicalDeviceExternalMemoryHostProperties = {};
mPhysicalDeviceExternalMemoryHostProperties.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
if (!vkGetPhysicalDeviceProperties2KHR || !vkGetPhysicalDeviceFeatures2KHR) if (!vkGetPhysicalDeviceProperties2KHR || !vkGetPhysicalDeviceFeatures2KHR)
{ {
return; return;
...@@ -959,6 +979,12 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt ...@@ -959,6 +979,12 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
vk::AddToPNextChain(&deviceFeatures, &mTransformFeedbackFeatures); vk::AddToPNextChain(&deviceFeatures, &mTransformFeedbackFeatures);
} }
// Query external memory host properties
if (ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames))
{
vk::AddToPNextChain(&deviceProperties, &mPhysicalDeviceExternalMemoryHostProperties);
}
// Query subgroup properties // Query subgroup properties
vk::AddToPNextChain(&deviceProperties, &mPhysicalDeviceSubgroupProperties); vk::AddToPNextChain(&deviceProperties, &mPhysicalDeviceSubgroupProperties);
...@@ -966,12 +992,13 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt ...@@ -966,12 +992,13 @@ void RendererVk::queryDeviceExtensionFeatures(const ExtensionNameList &deviceExt
vkGetPhysicalDeviceProperties2KHR(mPhysicalDevice, &deviceProperties); vkGetPhysicalDeviceProperties2KHR(mPhysicalDevice, &deviceProperties);
// Clean up pNext chains // Clean up pNext chains
mLineRasterizationFeatures.pNext = nullptr; mLineRasterizationFeatures.pNext = nullptr;
mProvokingVertexFeatures.pNext = nullptr; mProvokingVertexFeatures.pNext = nullptr;
mVertexAttributeDivisorFeatures.pNext = nullptr; mVertexAttributeDivisorFeatures.pNext = nullptr;
mVertexAttributeDivisorProperties.pNext = nullptr; mVertexAttributeDivisorProperties.pNext = nullptr;
mTransformFeedbackFeatures.pNext = nullptr; mTransformFeedbackFeatures.pNext = nullptr;
mPhysicalDeviceSubgroupProperties.pNext = nullptr; mPhysicalDeviceSubgroupProperties.pNext = nullptr;
mPhysicalDeviceExternalMemoryHostProperties.pNext = nullptr;
} }
angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex) angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex)
...@@ -1193,6 +1220,13 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1193,6 +1220,13 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
vk::AddToPNextChain(&createInfo, &mTransformFeedbackFeatures); vk::AddToPNextChain(&createInfo, &mTransformFeedbackFeatures);
} }
if (getFeatures().supportsExternalMemoryHost.enabled)
{
enabledDeviceExtensions.push_back(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME);
mMinImportedHostPointerAlignment =
mPhysicalDeviceExternalMemoryHostProperties.minImportedHostPointerAlignment;
}
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.queueCreateInfoCount = 1; createInfo.queueCreateInfoCount = 1;
...@@ -1563,6 +1597,10 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev ...@@ -1563,6 +1597,10 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ANGLE_FEATURE_CONDITION((&mFeatures), commandGraph, true); ANGLE_FEATURE_CONDITION((&mFeatures), commandGraph, true);
ANGLE_FEATURE_CONDITION(
(&mFeatures), supportsExternalMemoryHost,
ExtensionFound(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionNames));
angle::PlatformMethods *platform = ANGLEPlatformCurrent(); angle::PlatformMethods *platform = ANGLEPlatformCurrent();
platform->overrideFeaturesVk(platform, &mFeatures); platform->overrideFeaturesVk(platform, &mFeatures);
......
...@@ -145,6 +145,11 @@ class RendererVk : angle::NonCopyable ...@@ -145,6 +145,11 @@ class RendererVk : angle::NonCopyable
uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; } uint32_t getMaxVertexAttribDivisor() const { return mMaxVertexAttribDivisor; }
VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; } VkDeviceSize getMaxVertexAttribStride() const { return mMaxVertexAttribStride; }
VkDeviceSize getMinImportedHostPointerAlignment() const
{
return mMinImportedHostPointerAlignment;
}
bool isMockICDEnabled() const { return mEnabledICD == vk::ICD::Mock; } bool isMockICDEnabled() const { return mEnabledICD == vk::ICD::Mock; }
// Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and // Query the format properties for select bits (linearTilingFeatures, optimalTilingFeatures and
...@@ -264,6 +269,7 @@ class RendererVk : angle::NonCopyable ...@@ -264,6 +269,7 @@ class RendererVk : angle::NonCopyable
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT mVertexAttributeDivisorProperties;
VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures; VkPhysicalDeviceTransformFeedbackFeaturesEXT mTransformFeedbackFeatures;
VkPhysicalDeviceSubgroupProperties mPhysicalDeviceSubgroupProperties; VkPhysicalDeviceSubgroupProperties mPhysicalDeviceSubgroupProperties;
VkPhysicalDeviceExternalMemoryHostPropertiesEXT mPhysicalDeviceExternalMemoryHostProperties;
std::vector<VkQueueFamilyProperties> mQueueFamilyProperties; std::vector<VkQueueFamilyProperties> mQueueFamilyProperties;
std::mutex mQueueMutex; std::mutex mQueueMutex;
angle::PackedEnumMap<egl::ContextPriority, VkQueue> mQueues; angle::PackedEnumMap<egl::ContextPriority, VkQueue> mQueues;
...@@ -271,6 +277,7 @@ class RendererVk : angle::NonCopyable ...@@ -271,6 +277,7 @@ class RendererVk : angle::NonCopyable
uint32_t mCurrentQueueFamilyIndex; uint32_t mCurrentQueueFamilyIndex;
uint32_t mMaxVertexAttribDivisor; uint32_t mMaxVertexAttribDivisor;
VkDeviceSize mMaxVertexAttribStride; VkDeviceSize mMaxVertexAttribStride;
VkDeviceSize mMinImportedHostPointerAlignment;
VkDevice mDevice; VkDevice mDevice;
AtomicSerialFactory mQueueSerialFactory; AtomicSerialFactory mQueueSerialFactory;
AtomicSerialFactory mShaderSerialFactory; AtomicSerialFactory mShaderSerialFactory;
......
...@@ -155,6 +155,49 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display ...@@ -155,6 +155,49 @@ angle::Result OffscreenSurfaceVk::AttachmentImage::initialize(DisplayVk *display
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result OffscreenSurfaceVk::AttachmentImage::initializeWithExternalMemory(
DisplayVk *displayVk,
EGLint width,
EGLint height,
const vk::Format &vkFormat,
GLint samples,
void *buffer)
{
RendererVk *renderer = displayVk->getRenderer();
ASSERT(renderer->getFeatures().supportsExternalMemoryHost.enabled);
const angle::Format &textureFormat = vkFormat.actualImageFormat();
bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
const VkImageUsageFlags usage = isDepthOrStencilFormat ? kSurfaceVKDepthStencilImageUsageFlags
: kSurfaceVKColorImageUsageFlags;
VkExtent3D extents = {std::max(static_cast<uint32_t>(width), 1u),
std::max(static_cast<uint32_t>(height), 1u), 1u};
ANGLE_TRY(
image.init(displayVk, gl::TextureType::_2D, extents, vkFormat, samples, usage, 0, 0, 1, 1));
VkImportMemoryHostPointerInfoEXT importMemoryHostPointerInfo = {};
importMemoryHostPointerInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
importMemoryHostPointerInfo.pNext = nullptr;
importMemoryHostPointerInfo.handleType =
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT;
importMemoryHostPointerInfo.pHostPointer = buffer;
VkMemoryRequirements externalMemoryRequirements;
image.getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
VkMemoryPropertyFlags flags = 0;
ANGLE_TRY(image.initExternalMemory(displayVk, renderer->getMemoryProperties(),
externalMemoryRequirements, &importMemoryHostPointerInfo,
VK_QUEUE_FAMILY_EXTERNAL, flags));
// Clear the image if it has emulated channels.
image.stageClearIfEmulatedFormat(gl::ImageIndex::Make2D(0), vkFormat);
return angle::Result::Continue;
}
void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display) void OffscreenSurfaceVk::AttachmentImage::destroy(const egl::Display *display)
{ {
DisplayVk *displayVk = vk::GetImpl(display); DisplayVk *displayVk = vk::GetImpl(display);
......
...@@ -75,7 +75,7 @@ class OffscreenSurfaceVk : public SurfaceVk ...@@ -75,7 +75,7 @@ class OffscreenSurfaceVk : public SurfaceVk
vk::ImageHelper *getColorAttachmentImage(); vk::ImageHelper *getColorAttachmentImage();
private: protected:
struct AttachmentImage final : angle::NonCopyable struct AttachmentImage final : angle::NonCopyable
{ {
AttachmentImage(); AttachmentImage();
...@@ -86,13 +86,21 @@ class OffscreenSurfaceVk : public SurfaceVk ...@@ -86,13 +86,21 @@ class OffscreenSurfaceVk : public SurfaceVk
EGLint height, EGLint height,
const vk::Format &vkFormat, const vk::Format &vkFormat,
GLint samples); GLint samples);
angle::Result initializeWithExternalMemory(DisplayVk *displayVk,
EGLint width,
EGLint height,
const vk::Format &vkFormat,
GLint samples,
void *buffer);
void destroy(const egl::Display *display); void destroy(const egl::Display *display);
vk::ImageHelper image; vk::ImageHelper image;
vk::ImageViewHelper imageViews; vk::ImageViewHelper imageViews;
}; };
angle::Result initializeImpl(DisplayVk *displayVk); virtual angle::Result initializeImpl(DisplayVk *displayVk);
EGLint mWidth; EGLint mWidth;
EGLint mHeight; EGLint mHeight;
......
...@@ -25,9 +25,21 @@ class DisplayVkMac : public DisplayVk ...@@ -25,9 +25,21 @@ class DisplayVkMac : public DisplayVk
SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state, SurfaceImpl *createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window) override; EGLNativeWindowType window) override;
SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) override;
egl::ConfigSet generateConfigs() override; egl::ConfigSet generateConfigs() override;
bool checkConfigSupport(egl::Config *config) override; bool checkConfigSupport(egl::Config *config) override;
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
egl::Error validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const override;
const char *getWSIExtension() const override; const char *getWSIExtension() const override;
}; };
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/mac/IOSurfaceSurfaceVkMac.h"
#include "libANGLE/renderer/vulkan/mac/WindowSurfaceVkMac.h" #include "libANGLE/renderer/vulkan/mac/WindowSurfaceVkMac.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h" #include "libANGLE/renderer/vulkan/vk_caps_utils.h"
...@@ -34,6 +36,16 @@ SurfaceImpl *DisplayVkMac::createWindowSurfaceVk(const egl::SurfaceState &state, ...@@ -34,6 +36,16 @@ SurfaceImpl *DisplayVkMac::createWindowSurfaceVk(const egl::SurfaceState &state,
return new WindowSurfaceVkMac(state, window); return new WindowSurfaceVkMac(state, window);
} }
SurfaceImpl *DisplayVkMac::createPbufferFromClientBuffer(const egl::SurfaceState &state,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs)
{
ASSERT(buftype == EGL_IOSURFACE_ANGLE);
return new IOSurfaceSurfaceVkMac(state, clientBuffer, attribs);
}
egl::ConfigSet DisplayVkMac::generateConfigs() egl::ConfigSet DisplayVkMac::generateConfigs()
{ {
constexpr GLenum kColorFormats[] = {GL_BGRA8_EXT, GL_BGRX8_ANGLEX}; constexpr GLenum kColorFormats[] = {GL_BGRA8_EXT, GL_BGRX8_ANGLEX};
...@@ -62,4 +74,26 @@ DisplayImpl *CreateVulkanMacDisplay(const egl::DisplayState &state) ...@@ -62,4 +74,26 @@ DisplayImpl *CreateVulkanMacDisplay(const egl::DisplayState &state)
return new DisplayVkMac(state); return new DisplayVkMac(state);
} }
void DisplayVkMac::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
outExtensions->iosurfaceClientBuffer =
getRenderer()->getFeatures().supportsExternalMemoryHost.enabled;
DisplayVk::generateExtensions(outExtensions);
}
egl::Error DisplayVkMac::validateClientBuffer(const egl::Config *configuration,
EGLenum buftype,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
ASSERT(buftype == EGL_IOSURFACE_ANGLE);
if (!IOSurfaceSurfaceVkMac::ValidateAttributes(this, clientBuffer, attribs))
{
return egl::EglBadAttribute();
}
return egl::NoError();
}
} // namespace rx } // namespace rx
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IOSurfaceSurfaceVkMac.h:
// Subclasses SurfaceVk for the Mac platform to implement PBuffers using an IOSurface
//
#ifndef LIBANGLE_RENDERER_VULKAN_MAC_IOSURFACESURFACEVKMAC_H_
#define LIBANGLE_RENDERER_VULKAN_MAC_IOSURFACESURFACEVKMAC_H_
#include "libANGLE/renderer/vulkan/SurfaceVk.h"
struct __IOSurface;
typedef __IOSurface *IOSurfaceRef;
namespace egl
{
class AttributeMap;
} // namespace egl
namespace rx
{
class IOSurfaceSurfaceVkMac : public OffscreenSurfaceVk
{
public:
IOSurfaceSurfaceVkMac(const egl::SurfaceState &state,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs);
~IOSurfaceSurfaceVkMac() override;
egl::Error initialize(const egl::Display *display) override;
egl::Error unMakeCurrent(const gl::Context *context) override;
egl::Error bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer) override;
egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
static bool ValidateAttributes(const DisplayVk *displayVk,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs);
protected:
angle::Result initializeImpl(DisplayVk *displayVk) override;
private:
IOSurfaceRef mIOSurface;
int mPlane;
int mFormatIndex;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_MAC_IOSURFACESURFACEVKMAC_H_
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IOSurfaceSurfaceVkMac.mm:
// Implements methods from IOSurfaceSurfaceVkMac.
//
#include "libANGLE/renderer/vulkan/mac/IOSurfaceSurfaceVkMac.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
#include "libANGLE/renderer/vulkan/TextureVk.h"
#include <IOSurface/IOSurface.h>
namespace rx
{
namespace
{
struct IOSurfaceFormatInfo
{
GLenum internalFormat;
GLenum type;
size_t componentBytes;
GLenum nativeSizedInternalFormat;
};
// clang-format off
constexpr std::array<IOSurfaceFormatInfo, 6> kIOSurfaceFormats = {{
{GL_RED, GL_UNSIGNED_BYTE, 1, GL_R8 },
{GL_R16UI, GL_UNSIGNED_SHORT, 2, GL_R16UI },
{GL_RG, GL_UNSIGNED_BYTE, 2, GL_RG8 },
{GL_RGB, GL_UNSIGNED_BYTE, 4, GL_BGRA8_EXT},
{GL_BGRA_EXT, GL_UNSIGNED_BYTE, 4, GL_BGRA8_EXT },
{GL_RGBA, GL_HALF_FLOAT, 8, GL_RGBA16F },
}};
// clang-format on
int FindIOSurfaceFormatIndex(GLenum internalFormat, GLenum type)
{
for (int i = 0; i < static_cast<int>(kIOSurfaceFormats.size()); ++i)
{
const auto &formatInfo = kIOSurfaceFormats[i];
if (formatInfo.internalFormat == internalFormat && formatInfo.type == type)
{
return i;
}
}
return -1;
}
} // anonymous namespace
IOSurfaceSurfaceVkMac::IOSurfaceSurfaceVkMac(const egl::SurfaceState &state,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
: OffscreenSurfaceVk(state), mIOSurface(nullptr), mPlane(0), mFormatIndex(-1)
{
// Keep reference to the IOSurface so it doesn't get deleted while the pbuffer exists.
mIOSurface = reinterpret_cast<IOSurfaceRef>(buffer);
CFRetain(mIOSurface);
// Extract attribs useful for the call to CGLTexImageIOSurface2D
mWidth = static_cast<int>(attribs.get(EGL_WIDTH));
mHeight = static_cast<int>(attribs.get(EGL_HEIGHT));
mPlane = static_cast<int>(attribs.get(EGL_IOSURFACE_PLANE_ANGLE));
EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
EGLAttrib type = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
mFormatIndex =
FindIOSurfaceFormatIndex(static_cast<GLenum>(internalFormat), static_cast<GLenum>(type));
ASSERT(mFormatIndex >= 0);
}
IOSurfaceSurfaceVkMac::~IOSurfaceSurfaceVkMac()
{
if (mIOSurface != nullptr)
{
CFRelease(mIOSurface);
mIOSurface = nullptr;
}
}
egl::Error IOSurfaceSurfaceVkMac::initialize(const egl::Display *display)
{
DisplayVk *displayVk = vk::GetImpl(display);
angle::Result result = initializeImpl(displayVk);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}
angle::Result IOSurfaceSurfaceVkMac::initializeImpl(DisplayVk *displayVk)
{
RendererVk *renderer = displayVk->getRenderer();
const egl::Config *config = mState.config;
GLint samples = 1;
if (config->sampleBuffers && config->samples > 1)
{
samples = config->samples;
}
ANGLE_VK_CHECK(displayVk, samples > 0, VK_ERROR_INITIALIZATION_FAILED);
// Swiftshader will use the raw pointer to the buffer referenced by the IOSurfaceRef
ANGLE_TRY(mColorAttachment.initializeWithExternalMemory(
displayVk, mWidth, mHeight,
renderer->getFormat(kIOSurfaceFormats[mFormatIndex].nativeSizedInternalFormat), samples,
IOSurfaceGetBaseAddressOfPlane(mIOSurface, mPlane)));
mColorRenderTarget.init(&mColorAttachment.image, &mColorAttachment.imageViews, 0, 0);
return angle::Result::Continue;
}
egl::Error IOSurfaceSurfaceVkMac::unMakeCurrent(const gl::Context *context)
{
ASSERT(context != nullptr);
ContextVk *contextVk = vk::GetImpl(context);
DisplayVk *displayVk = vk::GetImpl(context->getDisplay());
angle::Result result = contextVk->flushImpl(nullptr);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}
egl::Error IOSurfaceSurfaceVkMac::bindTexImage(const gl::Context *context,
gl::Texture *texture,
EGLint buffer)
{
IOSurfaceLock(mIOSurface, 0, nullptr);
return egl::NoError();
}
egl::Error IOSurfaceSurfaceVkMac::releaseTexImage(const gl::Context *context, EGLint buffer)
{
ASSERT(context != nullptr);
ContextVk *contextVk = vk::GetImpl(context);
DisplayVk *displayVk = vk::GetImpl(context->getDisplay());
angle::Result result = contextVk->finishImpl();
IOSurfaceUnlock(mIOSurface, 0, nullptr);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}
// static
bool IOSurfaceSurfaceVkMac::ValidateAttributes(const DisplayVk *displayVk,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
ASSERT(displayVk != nullptr);
RendererVk *renderer = displayVk->getRenderer();
IOSurfaceRef ioSurface = reinterpret_cast<IOSurfaceRef>(buffer);
// The plane must exist for this IOSurface. IOSurfaceGetPlaneCount can return 0 for non-planar
// ioSurfaces but we will treat non-planar like it is a single plane.
size_t surfacePlaneCount = std::max(size_t(1), IOSurfaceGetPlaneCount(ioSurface));
EGLAttrib plane = attribs.get(EGL_IOSURFACE_PLANE_ANGLE);
if (plane < 0 || static_cast<size_t>(plane) >= surfacePlaneCount)
{
return false;
}
// The width height specified must be at least (1, 1) and at most the plane size
EGLAttrib width = attribs.get(EGL_WIDTH);
EGLAttrib height = attribs.get(EGL_HEIGHT);
if (width <= 0 || static_cast<size_t>(width) > IOSurfaceGetWidthOfPlane(ioSurface, plane) ||
height <= 0 || static_cast<size_t>(height) > IOSurfaceGetHeightOfPlane(ioSurface, plane))
{
return false;
}
// Find this IOSurface format
EGLAttrib internalFormat = attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE);
EGLAttrib type = attribs.get(EGL_TEXTURE_TYPE_ANGLE);
int formatIndex =
FindIOSurfaceFormatIndex(static_cast<GLenum>(internalFormat), static_cast<GLenum>(type));
if (formatIndex < 0)
{
return false;
}
// Check that the format matches this IOSurface plane
if (IOSurfaceGetBytesPerElementOfPlane(ioSurface, plane) !=
kIOSurfaceFormats[formatIndex].componentBytes)
{
return false;
}
void *pointer = IOSurfaceGetBaseAddressOfPlane(ioSurface, plane);
VkMemoryHostPointerPropertiesEXT memoryHostPointerProperties = {};
memoryHostPointerProperties.sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT;
vkGetMemoryHostPointerPropertiesEXT(
renderer->getDevice(), VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT,
pointer, &memoryHostPointerProperties);
bool hostVisible =
memoryHostPointerProperties.memoryTypeBits & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
if (!hostVisible)
{
return false;
}
VkDeviceSize alignment = renderer->getMinImportedHostPointerAlignment();
if (reinterpret_cast<size_t>(pointer) % alignment != 0)
{
return false;
}
return true;
}
} // namespace rx
...@@ -178,6 +178,7 @@ Error ValidateConfigAttribute(const Display *display, EGLAttrib attribute) ...@@ -178,6 +178,7 @@ Error ValidateConfigAttribute(const Display *display, EGLAttrib attribute)
case EGL_SAMPLES: case EGL_SAMPLES:
case EGL_SAMPLE_BUFFERS: case EGL_SAMPLE_BUFFERS:
case EGL_SURFACE_TYPE: case EGL_SURFACE_TYPE:
case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
case EGL_TRANSPARENT_TYPE: case EGL_TRANSPARENT_TYPE:
case EGL_TRANSPARENT_BLUE_VALUE: case EGL_TRANSPARENT_BLUE_VALUE:
case EGL_TRANSPARENT_GREEN_VALUE: case EGL_TRANSPARENT_GREEN_VALUE:
...@@ -1874,19 +1875,11 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, ...@@ -1874,19 +1875,11 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
if (buftype == EGL_IOSURFACE_ANGLE) if (buftype == EGL_IOSURFACE_ANGLE)
{ {
#if ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST if (static_cast<EGLenum>(textureTarget) != config->bindToTextureTarget)
if (textureTarget != EGL_TEXTURE_RECTANGLE_ANGLE)
{ {
return EglBadAttribute() return EglBadAttribute()
<< "EGL_IOSURFACE requires the EGL_TEXTURE_RECTANGLE target on desktop macOS"; << "EGL_IOSURFACE requires the texture target to match the config";
} }
#else // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
if (textureTarget != EGL_TEXTURE_2D)
{
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_2D target on iOS";
}
#endif // ANGLE_PLATFORM_MACOS || ANGLE_PLATFORM_MACCATALYST
if (textureFormat != EGL_TEXTURE_RGBA) if (textureFormat != EGL_TEXTURE_RGBA)
{ {
return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format"; return EglBadAttribute() << "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format";
......
...@@ -372,6 +372,12 @@ ANGLETestBase::ANGLETestBase(const PlatformParameters &params) ...@@ -372,6 +372,12 @@ ANGLETestBase::ANGLETestBase(const PlatformParameters &params)
PlatformParameters withMethods = params; PlatformParameters withMethods = params;
withMethods.eglParameters.platformMethods = &gDefaultPlatformMethods; withMethods.eglParameters.platformMethods = &gDefaultPlatformMethods;
// We don't build vulkan debug layers on Mac (http://anglebug.com/4376)
if (IsOSX() && withMethods.getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
{
withMethods.eglParameters.debugLayersEnabled = false;
}
auto iter = gFixtures.find(withMethods); auto iter = gFixtures.find(withMethods);
if (iter != gFixtures.end()) if (iter != gFixtures.end())
{ {
......
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