Commit f0efc9c4 by Michael Spang Committed by Commit Bot

Apply compression algorithm to VulkanExternalImageTest

These tests have opaque fd and zircon handle variants that only differ in the handle operations. Turn the test into a template that runs twice with an opaque fd and fuchsia template argument. Bug: angleproject:3289 Change-Id: Ibb3baaa8eef239e3747a0e74ce17396637c8bcd9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2195686 Commit-Queue: Michael Spang <spang@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6067c7d8
...@@ -20,24 +20,6 @@ namespace ...@@ -20,24 +20,6 @@ namespace
constexpr int kInvalidFd = -1; constexpr int kInvalidFd = -1;
VkFormat ChooseAnyImageFormat(const VulkanExternalHelper &helper)
{
static constexpr VkFormat kFormats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM,
};
for (VkFormat format : kFormats)
{
if (helper.canCreateImageOpaqueFd(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL))
{
return format;
}
}
return VK_FORMAT_UNDEFINED;
}
// List of VkFormat/internalformat combinations Chrome uses. // List of VkFormat/internalformat combinations Chrome uses.
// This is compiled from the maps in // This is compiled from the maps in
// components/viz/common/resources/resource_format_utils.cc. // components/viz/common/resources/resource_format_utils.cc.
...@@ -65,6 +47,132 @@ const struct ImageFormatPair ...@@ -65,6 +47,132 @@ const struct ImageFormatPair
{VK_FORMAT_R8G8B8A8_UNORM, GL_RGB8_OES}, // RGBX_8888 {VK_FORMAT_R8G8B8A8_UNORM, GL_RGB8_OES}, // RGBX_8888
}; };
struct OpaqueFdTraits
{
using Handle = int;
static Handle InvalidHandle() { return kInvalidFd; }
static const char *MemoryObjectExtension() { return "GL_EXT_memory_object_fd"; }
static const char *SemaphoreExtension() { return "GL_EXT_semaphore_fd"; }
static bool CanCreateSemaphore(const VulkanExternalHelper &helper)
{
return helper.canCreateSemaphoreOpaqueFd();
}
static VkResult CreateSemaphore(VulkanExternalHelper *helper, VkSemaphore *semaphore)
{
return helper->createSemaphoreOpaqueFd(semaphore);
}
static VkResult ExportSemaphore(VulkanExternalHelper *helper,
VkSemaphore semaphore,
Handle *handle)
{
return helper->exportSemaphoreOpaqueFd(semaphore, handle);
}
static void ImportSemaphore(GLuint semaphore, Handle handle)
{
glImportSemaphoreFdEXT(semaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, handle);
}
static bool CanCreateImage(const VulkanExternalHelper &helper,
VkFormat format,
VkImageType type,
VkImageTiling tiling)
{
return helper.canCreateImageOpaqueFd(format, type, tiling);
}
static VkResult CreateImage2D(VulkanExternalHelper *helper,
VkFormat format,
VkExtent3D extent,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut)
{
return helper->createImage2DOpaqueFd(format, extent, imageOut, deviceMemoryOut,
deviceMemorySizeOut);
}
static VkResult ExportMemory(VulkanExternalHelper *helper,
VkDeviceMemory deviceMemory,
Handle *handle)
{
return helper->exportMemoryOpaqueFd(deviceMemory, handle);
}
static void ImportMemory(GLuint memoryObject, GLuint64 size, Handle handle)
{
glImportMemoryFdEXT(memoryObject, size, GL_HANDLE_TYPE_OPAQUE_FD_EXT, handle);
}
};
struct FuchsiaTraits
{
using Handle = zx_handle_t;
static Handle InvalidHandle() { return ZX_HANDLE_INVALID; }
static const char *MemoryObjectExtension() { return "GL_ANGLE_memory_object_fuchsia"; }
static const char *SemaphoreExtension() { return "GL_ANGLE_semaphore_fuchsia"; }
static bool CanCreateSemaphore(const VulkanExternalHelper &helper)
{
return helper.canCreateSemaphoreZirconEvent();
}
static VkResult CreateSemaphore(VulkanExternalHelper *helper, VkSemaphore *semaphore)
{
return helper->createSemaphoreZirconEvent(semaphore);
}
static VkResult ExportSemaphore(VulkanExternalHelper *helper,
VkSemaphore semaphore,
Handle *handle)
{
return helper->exportSemaphoreZirconEvent(semaphore, handle);
}
static void ImportSemaphore(GLuint semaphore, Handle handle)
{
glImportSemaphoreZirconHandleANGLE(semaphore, GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE, handle);
}
static bool CanCreateImage(const VulkanExternalHelper &helper,
VkFormat format,
VkImageType type,
VkImageTiling tiling)
{
return helper.canCreateImageZirconVmo(format, type, tiling);
}
static VkResult CreateImage2D(VulkanExternalHelper *helper,
VkFormat format,
VkExtent3D extent,
VkImage *imageOut,
VkDeviceMemory *deviceMemoryOut,
VkDeviceSize *deviceMemorySizeOut)
{
return helper->createImage2DZirconVmo(format, extent, imageOut, deviceMemoryOut,
deviceMemorySizeOut);
}
static VkResult ExportMemory(VulkanExternalHelper *helper,
VkDeviceMemory deviceMemory,
Handle *handle)
{
return helper->exportMemoryZirconVmo(deviceMemory, handle);
}
static void ImportMemory(GLuint memoryObject, GLuint64 size, Handle handle)
{
glImportMemoryZirconHandleANGLE(memoryObject, size, GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE,
handle);
}
};
} // namespace } // namespace
class VulkanExternalImageTest : public ANGLETest class VulkanExternalImageTest : public ANGLETest
...@@ -81,16 +189,17 @@ class VulkanExternalImageTest : public ANGLETest ...@@ -81,16 +189,17 @@ class VulkanExternalImageTest : public ANGLETest
} }
}; };
// glImportMemoryFdEXT must be able to import a valid opaque fd. template <typename Traits>
TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd) void RunShouldImportMemoryTest(bool isSwiftshader, bool enableDebugLayers)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd")); ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
VulkanExternalHelper helper; VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers()); helper.initialize(isSwiftshader, enableDebugLayers);
VkFormat format = ChooseAnyImageFormat(helper); VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF(format == VK_FORMAT_UNDEFINED); ANGLE_SKIP_TEST_IF(
!Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
VkImage image = VK_NULL_HANDLE; VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE; VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
...@@ -98,20 +207,20 @@ TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd) ...@@ -98,20 +207,20 @@ TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd)
VkExtent3D extent = {1, 1, 1}; VkExtent3D extent = {1, 1, 1};
VkResult result = VkResult result =
helper.createImage2DOpaqueFd(format, extent, &image, &deviceMemory, &deviceMemorySize); Traits::CreateImage2D(&helper, format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
int fd = kInvalidFd; typename Traits::Handle memoryHandle = Traits::InvalidHandle();
result = helper.exportMemoryOpaqueFd(deviceMemory, &fd); result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(fd, kInvalidFd); EXPECT_NE(memoryHandle, Traits::InvalidHandle());
{ {
GLMemoryObject memoryObject; GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE; GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory); &dedicatedMemory);
glImportMemoryFdEXT(memoryObject, deviceMemorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
// Test that after calling glImportMemoryFdEXT, the parameters of the memory object cannot // Test that after calling glImportMemoryFdEXT, the parameters of the memory object cannot
// be changed // be changed
...@@ -127,28 +236,42 @@ TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd) ...@@ -127,28 +236,42 @@ TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd)
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr); vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// glImportSemaphoreFdEXT must be able to import a valid opaque fd. // glImportMemoryFdEXT must be able to import a valid opaque fd.
TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreOpaqueFd) TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
RunShouldImportMemoryTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
}
// glImportMemoryZirconHandleANGLE must be able to import a valid vmo.
TEST_P(VulkanExternalImageTest, ShouldImportMemoryZirconVmo)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
RunShouldImportMemoryTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
}
template <typename Traits>
void RunShouldImportSemaphoreTest(bool isSwiftshader, bool enableDebugLayers)
{
ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
VulkanExternalHelper helper; VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers()); helper.initialize(isSwiftshader, enableDebugLayers);
ANGLE_SKIP_TEST_IF(!helper.canCreateSemaphoreOpaqueFd()); ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
VkSemaphore vkSemaphore = VK_NULL_HANDLE; VkSemaphore vkSemaphore = VK_NULL_HANDLE;
VkResult result = helper.createSemaphoreOpaqueFd(&vkSemaphore); VkResult result = helper.createSemaphoreOpaqueFd(&vkSemaphore);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
int fd = kInvalidFd; typename Traits::Handle semaphoreHandle = Traits::InvalidHandle();
result = helper.exportSemaphoreOpaqueFd(vkSemaphore, &fd); result = Traits::ExportSemaphore(&helper, vkSemaphore, &semaphoreHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(fd, kInvalidFd); EXPECT_NE(semaphoreHandle, Traits::InvalidHandle());
{ {
GLSemaphore glSemaphore; GLSemaphore glSemaphore;
glImportSemaphoreFdEXT(glSemaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); Traits::ImportSemaphore(glSemaphore, semaphoreHandle);
} }
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
...@@ -156,19 +279,31 @@ TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreOpaqueFd) ...@@ -156,19 +279,31 @@ TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreOpaqueFd)
vkDestroySemaphore(helper.getDevice(), vkSemaphore, nullptr); vkDestroySemaphore(helper.getDevice(), vkSemaphore, nullptr);
} }
// Test creating and clearing a simple RGBA8 texture in a opaque fd. // glImportSemaphoreFdEXT must be able to import a valid opaque fd.
TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8) TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreOpaqueFd)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
// http://anglebug.com/4630 RunShouldImportSemaphoreTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
ANGLE_SKIP_TEST_IF(IsAndroid() && (IsPixel2() || IsPixel2XL())); }
// glImportSemaphoreZirconHandleANGLE must be able to import a valid handle.
TEST_P(VulkanExternalImageTest, ShouldImportSemaphoreZirconEvent)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
RunShouldImportSemaphoreTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
}
template <typename Traits>
void RunShouldClearTest(bool isSwiftshader, bool enableDebugLayers)
{
ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
VulkanExternalHelper helper; VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers()); helper.initialize(isSwiftshader, enableDebugLayers);
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF( ANGLE_SKIP_TEST_IF(
!helper.canCreateImageOpaqueFd(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL)); !Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
VkImage image = VK_NULL_HANDLE; VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE; VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
...@@ -176,20 +311,20 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8) ...@@ -176,20 +311,20 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8)
VkExtent3D extent = {1, 1, 1}; VkExtent3D extent = {1, 1, 1};
VkResult result = VkResult result =
helper.createImage2DOpaqueFd(format, extent, &image, &deviceMemory, &deviceMemorySize); Traits::CreateImage2D(&helper, format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
int fd = kInvalidFd; typename Traits::Handle memoryHandle = Traits::InvalidHandle();
result = helper.exportMemoryOpaqueFd(deviceMemory, &fd); result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(fd, kInvalidFd); EXPECT_NE(memoryHandle, Traits::InvalidHandle());
{ {
GLMemoryObject memoryObject; GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE; GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory); &dedicatedMemory);
glImportMemoryFdEXT(memoryObject, deviceMemorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
GLTexture texture; GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
...@@ -211,71 +346,33 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8) ...@@ -211,71 +346,33 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8)
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr); vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// Test creating and clearing a simple RGBA8 texture in a opaque fd.
TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdRGBA8)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
// http://anglebug.com/4630
ANGLE_SKIP_TEST_IF(IsAndroid() && (IsPixel2() || IsPixel2XL()));
RunShouldClearTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
}
// Test creating and clearing a simple RGBA8 texture in a zircon vmo. // Test creating and clearing a simple RGBA8 texture in a zircon vmo.
TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoRGBA8) TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoRGBA8)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
RunShouldClearTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers());
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF(
!helper.canCreateImageZirconVmo(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {1, 1, 1};
VkResult result =
helper.createImage2DZirconVmo(format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS);
zx_handle_t vmo = ZX_HANDLE_INVALID;
result = helper.exportMemoryZirconVmo(deviceMemory, &vmo);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(vmo, ZX_HANDLE_INVALID);
{
GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
glImportMemoryZirconHandleANGLE(memoryObject, deviceMemorySize,
GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE, vmo);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
}
EXPECT_GL_NO_ERROR();
vkDestroyImage(helper.getDevice(), image, nullptr);
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// Test all format combinations used by Chrome import successfully (opaque fd). template <typename Traits>
TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd) void RunTextureFormatCompatChromiumTest(bool isSwiftshader, bool enableDebugLayers)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd")); ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
VulkanExternalHelper helper; VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers()); helper.initialize(isSwiftshader, enableDebugLayers);
for (const ImageFormatPair &format : kChromeFormats) for (const ImageFormatPair &format : kChromeFormats)
{ {
if (!helper.canCreateImageOpaqueFd(format.vkFormat, VK_IMAGE_TYPE_2D, if (!Traits::CanCreateImage(helper, format.vkFormat, VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL)) VK_IMAGE_TILING_OPTIMAL))
{ {
continue; continue;
} }
...@@ -290,21 +387,21 @@ TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd) ...@@ -290,21 +387,21 @@ TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd)
VkDeviceSize deviceMemorySize = 0; VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {113, 211, 1}; VkExtent3D extent = {113, 211, 1};
VkResult result = helper.createImage2DOpaqueFd(format.vkFormat, extent, &image, VkResult result = Traits::CreateImage2D(&helper, format.vkFormat, extent, &image,
&deviceMemory, &deviceMemorySize); &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
int fd = kInvalidFd; typename Traits::Handle memoryHandle = Traits::InvalidHandle();
result = helper.exportMemoryOpaqueFd(deviceMemory, &fd); result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(fd, kInvalidFd); EXPECT_NE(memoryHandle, Traits::InvalidHandle());
{ {
GLMemoryObject memoryObject; GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE; GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory); &dedicatedMemory);
glImportMemoryFdEXT(memoryObject, deviceMemorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd); Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
GLTexture texture; GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
...@@ -319,122 +416,81 @@ TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd) ...@@ -319,122 +416,81 @@ TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd)
} }
} }
// Test all format combinations used by Chrome import successfully (opaque fd).
TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumFd)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
RunTextureFormatCompatChromiumTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
}
// Test all format combinations used by Chrome import successfully (fuchsia). // Test all format combinations used by Chrome import successfully (fuchsia).
TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumZirconHandle) TEST_P(VulkanExternalImageTest, TextureFormatCompatChromiumZirconVmo)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
RunTextureFormatCompatChromiumTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers());
for (const ImageFormatPair &format : kChromeFormats)
{
if (!helper.canCreateImageZirconVmo(format.vkFormat, VK_IMAGE_TYPE_2D,
VK_IMAGE_TILING_OPTIMAL))
{
continue;
}
if (format.requiredExtension && !IsGLExtensionEnabled(format.requiredExtension))
{
continue;
}
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {113, 211, 1};
VkResult result = helper.createImage2DZirconVmo(format.vkFormat, extent, &image,
&deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS);
zx_handle_t vmo = ZX_HANDLE_INVALID;
result = helper.exportMemoryZirconVmo(deviceMemory, &vmo);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(vmo, ZX_HANDLE_INVALID);
{
GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
glImportMemoryZirconHandleANGLE(memoryObject, deviceMemorySize,
GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE, vmo);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, format.internalFormat, extent.width,
extent.height, memoryObject, 0);
}
EXPECT_GL_NO_ERROR();
vkDestroyImage(helper.getDevice(), image, nullptr);
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
}
} }
// Test creating and clearing RGBA8 texture in opaque fd with acquire/release. template <typename Traits>
TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores) void RunShouldClearWithSemaphoresTest(bool isSwiftshader, bool enableDebugLayers)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd")); ASSERT(EnsureGLExtensionEnabled(Traits::MemoryObjectExtension()));
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd")); ASSERT(EnsureGLExtensionEnabled(Traits::SemaphoreExtension()));
VulkanExternalHelper helper; VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers()); helper.initialize(isSwiftshader, enableDebugLayers);
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF( ANGLE_SKIP_TEST_IF(
!helper.canCreateImageOpaqueFd(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL)); !Traits::CanCreateImage(helper, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
ANGLE_SKIP_TEST_IF(!helper.canCreateSemaphoreOpaqueFd()); ANGLE_SKIP_TEST_IF(!Traits::CanCreateSemaphore(helper));
VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE; VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
VkResult result = helper.createSemaphoreOpaqueFd(&vkAcquireSemaphore); VkResult result = Traits::CreateSemaphore(&helper, &vkAcquireSemaphore);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE); EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE; VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
result = helper.createSemaphoreOpaqueFd(&vkReleaseSemaphore); result = Traits::CreateSemaphore(&helper, &vkReleaseSemaphore);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE); EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
int acquireSemaphoreFd = kInvalidFd; typename Traits::Handle acquireSemaphoreHandle = Traits::InvalidHandle();
result = helper.exportSemaphoreOpaqueFd(vkAcquireSemaphore, &acquireSemaphoreFd); result = Traits::ExportSemaphore(&helper, vkAcquireSemaphore, &acquireSemaphoreHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(acquireSemaphoreFd, kInvalidFd); EXPECT_NE(acquireSemaphoreHandle, Traits::InvalidHandle());
int releaseSemaphoreFd = kInvalidFd; typename Traits::Handle releaseSemaphoreHandle = Traits::InvalidHandle();
result = helper.exportSemaphoreOpaqueFd(vkReleaseSemaphore, &releaseSemaphoreFd); result = Traits::ExportSemaphore(&helper, vkReleaseSemaphore, &releaseSemaphoreHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(releaseSemaphoreFd, kInvalidFd); EXPECT_NE(releaseSemaphoreHandle, Traits::InvalidHandle());
VkImage image = VK_NULL_HANDLE; VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE; VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
VkDeviceSize deviceMemorySize = 0; VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {1, 1, 1}; VkExtent3D extent = {1, 1, 1};
result = helper.createImage2DOpaqueFd(format, extent, &image, &deviceMemory, &deviceMemorySize); result =
Traits::CreateImage2D(&helper, format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
int memoryFd = kInvalidFd; typename Traits::Handle memoryHandle = Traits::InvalidHandle();
result = helper.exportMemoryOpaqueFd(deviceMemory, &memoryFd); result = Traits::ExportMemory(&helper, deviceMemory, &memoryHandle);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(memoryFd, kInvalidFd); EXPECT_NE(memoryHandle, Traits::InvalidHandle());
{ {
GLMemoryObject memoryObject; GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE; GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory); &dedicatedMemory);
glImportMemoryFdEXT(memoryObject, deviceMemorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, memoryFd); Traits::ImportMemory(memoryObject, deviceMemorySize, memoryHandle);
GLTexture texture; GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0); glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
GLSemaphore glAcquireSemaphore; GLSemaphore glAcquireSemaphore;
glImportSemaphoreFdEXT(glAcquireSemaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, Traits::ImportSemaphore(glAcquireSemaphore, acquireSemaphoreHandle);
acquireSemaphoreFd);
helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED, helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore); VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
...@@ -460,8 +516,7 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores) ...@@ -460,8 +516,7 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
GLSemaphore glReleaseSemaphore; GLSemaphore glReleaseSemaphore;
glImportSemaphoreFdEXT(glReleaseSemaphore, GL_HANDLE_TYPE_OPAQUE_FD_EXT, Traits::ImportSemaphore(glReleaseSemaphore, releaseSemaphoreHandle);
releaseSemaphoreFd);
const GLenum textureDstLayouts[] = { const GLenum textureDstLayouts[] = {
GL_LAYOUT_TRANSFER_SRC_EXT, GL_LAYOUT_TRANSFER_SRC_EXT,
...@@ -496,128 +551,20 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores) ...@@ -496,128 +551,20 @@ TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores)
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr); vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// Test creating and clearing RGBA8 texture in opaque fd with acquire/release.
TEST_P(VulkanExternalImageTest, ShouldClearOpaqueFdWithSemaphores)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object_fd"));
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_semaphore_fd"));
RunShouldClearWithSemaphoresTest<OpaqueFdTraits>(isSwiftshader(), enableDebugLayers());
}
// Test creating and clearing RGBA8 texture in zircon vmo with acquire/release. // Test creating and clearing RGBA8 texture in zircon vmo with acquire/release.
TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphores) TEST_P(VulkanExternalImageTest, ShouldClearZirconVmoWithSemaphores)
{ {
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_memory_object_fuchsia"));
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia")); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_semaphore_fuchsia"));
RunShouldClearWithSemaphoresTest<FuchsiaTraits>(isSwiftshader(), enableDebugLayers());
VulkanExternalHelper helper;
helper.initialize(isSwiftshader(), enableDebugLayers());
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
ANGLE_SKIP_TEST_IF(
!helper.canCreateImageZirconVmo(format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL));
ANGLE_SKIP_TEST_IF(!helper.canCreateSemaphoreZirconEvent());
VkSemaphore vkAcquireSemaphore = VK_NULL_HANDLE;
VkResult result = helper.createSemaphoreZirconEvent(&vkAcquireSemaphore);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_TRUE(vkAcquireSemaphore != VK_NULL_HANDLE);
VkSemaphore vkReleaseSemaphore = VK_NULL_HANDLE;
result = helper.createSemaphoreZirconEvent(&vkReleaseSemaphore);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_TRUE(vkReleaseSemaphore != VK_NULL_HANDLE);
zx_handle_t acquireSemaphoreHandle = ZX_HANDLE_INVALID;
result = helper.exportSemaphoreZirconEvent(vkAcquireSemaphore, &acquireSemaphoreHandle);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(acquireSemaphoreHandle, ZX_HANDLE_INVALID);
zx_handle_t releaseSemaphoreHandle = ZX_HANDLE_INVALID;
result = helper.exportSemaphoreZirconEvent(vkReleaseSemaphore, &releaseSemaphoreHandle);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(releaseSemaphoreHandle, ZX_HANDLE_INVALID);
VkImage image = VK_NULL_HANDLE;
VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
VkDeviceSize deviceMemorySize = 0;
VkExtent3D extent = {1, 1, 1};
result =
helper.createImage2DZirconVmo(format, extent, &image, &deviceMemory, &deviceMemorySize);
EXPECT_EQ(result, VK_SUCCESS);
zx_handle_t memoryHandle = ZX_HANDLE_INVALID;
result = helper.exportMemoryZirconVmo(deviceMemory, &memoryHandle);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(memoryHandle, ZX_HANDLE_INVALID);
{
GLMemoryObject memoryObject;
GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
glImportMemoryZirconHandleANGLE(memoryObject, deviceMemorySize,
GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE, memoryHandle);
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexStorageMem2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, memoryObject, 0);
GLSemaphore glAcquireSemaphore;
glImportSemaphoreZirconHandleANGLE(glAcquireSemaphore, GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE,
acquireSemaphoreHandle);
helper.releaseImageAndSignalSemaphore(image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, vkAcquireSemaphore);
const GLuint barrierTextures[] = {
texture,
};
constexpr uint32_t textureBarriersCount = std::extent<decltype(barrierTextures)>();
const GLenum textureSrcLayouts[] = {
GL_LAYOUT_GENERAL_EXT,
};
constexpr uint32_t textureSrcLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
static_assert(textureBarriersCount == textureSrcLayoutsCount,
"barrierTextures and textureSrcLayouts must be the same length");
glWaitSemaphoreEXT(glAcquireSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
textureSrcLayouts);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT);
GLSemaphore glReleaseSemaphore;
glImportSemaphoreZirconHandleANGLE(glReleaseSemaphore, GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE,
releaseSemaphoreHandle);
const GLenum textureDstLayouts[] = {
GL_LAYOUT_TRANSFER_SRC_EXT,
};
constexpr uint32_t textureDstLayoutsCount = std::extent<decltype(textureSrcLayouts)>();
static_assert(textureBarriersCount == textureDstLayoutsCount,
"barrierTextures and textureDstLayouts must be the same length");
glSignalSemaphoreEXT(glReleaseSemaphore, 0, nullptr, textureBarriersCount, barrierTextures,
textureDstLayouts);
helper.waitSemaphoreAndAcquireImage(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
vkReleaseSemaphore);
uint8_t pixels[4];
VkOffset3D offset = {};
VkExtent3D extent = {1, 1, 1};
helper.readPixels(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, format, offset, extent,
pixels, sizeof(pixels));
EXPECT_NEAR(0x80, pixels[0], 1);
EXPECT_NEAR(0x80, pixels[1], 1);
EXPECT_NEAR(0x80, pixels[2], 1);
EXPECT_NEAR(0x80, pixels[3], 1);
}
EXPECT_GL_NO_ERROR();
vkDeviceWaitIdle(helper.getDevice());
vkDestroyImage(helper.getDevice(), image, nullptr);
vkDestroySemaphore(helper.getDevice(), vkAcquireSemaphore, nullptr);
vkDestroySemaphore(helper.getDevice(), vkReleaseSemaphore, nullptr);
vkFreeMemory(helper.getDevice(), deviceMemory, nullptr);
} }
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
......
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