| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fuchsia/sysmem/cpp/fidl.h> |
| #include <lib/fdio/directory.h> |
| #include <lib/zx/channel.h> |
| |
| #include <cstdint> |
| #include <cstdio> |
| #include <cstdlib> |
| #include <cstring> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| #include <vulkan/vulkan.h> |
| |
| #include "config_query.h" |
| #include "src/graphics/tests/common/utils.h" |
| #include "src/graphics/tests/common/vulkan_context.h" |
| #include "src/lib/fsl/handles/object_info.h" |
| #include "vulkan_extension_test.h" |
| |
| #include "vulkan/vulkan_enums.hpp" |
| #include "vulkan/vulkan_handles.hpp" |
| #include <vulkan/vulkan.hpp> |
| |
| namespace { |
| constexpr uint32_t kDefaultWidth = 64; |
| constexpr uint32_t kDefaultHeight = 64; |
| constexpr VkFormat kDefaultFormat = VK_FORMAT_R8G8B8A8_UNORM; |
| |
| // Parameter is true if the image should be linear. |
| class VulkanProtectedImageExtensionTest : public VulkanExtensionTest, |
| public ::testing::WithParamInterface<bool> {}; |
| |
| TEST_P(VulkanProtectedImageExtensionTest, BufferCollectionProtectedRGBA) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| set_use_protected_memory(true); |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| ASSERT_TRUE(Exec(VK_FORMAT_R8G8B8A8_UNORM, 64, 64, GetParam(), false)); |
| } |
| |
| TEST_P(VulkanProtectedImageExtensionTest, ProtectedAndNonprotectedConstraints) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| set_use_protected_memory(true); |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| ASSERT_TRUE(Exec(VK_FORMAT_R8G8B8A8_UNORM, 64, 64, GetParam(), true)); |
| } |
| |
| TEST_P(VulkanProtectedImageExtensionTest, ProtectedCpuAccessible) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| auto [vulkan_token] = MakeSharedCollection<1>(); |
| |
| bool linear = GetParam(); |
| vk::ImageFormatConstraintsInfoFUCHSIA format_constraints = |
| GetDefaultRgbImageFormatConstraintsInfo(); |
| format_constraints.imageCreateInfo = |
| GetDefaultImageCreateInfo(true, kDefaultFormat, kDefaultWidth, kDefaultHeight, linear); |
| |
| vk::BufferCollectionCreateInfoFUCHSIA import_info(vulkan_token.Unbind().TakeChannel().release()); |
| auto [result, collection] = |
| ctx_->device()->createBufferCollectionFUCHSIAUnique(import_info, nullptr, loader_); |
| EXPECT_EQ(result, vk::Result::eSuccess); |
| |
| vk::ImageConstraintsInfoFUCHSIA constraints_info; |
| constraints_info.pFormatConstraints = &format_constraints; |
| constraints_info.formatConstraintsCount = 1; |
| constraints_info.bufferCollectionConstraints.minBufferCount = 1; |
| constraints_info.flags = vk::ImageConstraintsInfoFlagBitsFUCHSIA::eCpuReadOften | |
| vk::ImageConstraintsInfoFlagBitsFUCHSIA::eCpuWriteOften; |
| |
| // This function should fail because protected images can't be CPU accessible. |
| EXPECT_NE(vk::Result::eSuccess, ctx_->device()->setBufferCollectionImageConstraintsFUCHSIA( |
| *collection, constraints_info, loader_)); |
| } |
| |
| TEST_P(VulkanProtectedImageExtensionTest, ProtectedOptionalCompatible) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| for (uint32_t i = 0; i < 2; i++) { |
| auto tokens = MakeSharedCollection(2u); |
| |
| bool linear = GetParam(); |
| bool protected_mem = (i == 0); |
| auto image_create_info = GetDefaultImageCreateInfo(protected_mem, kDefaultFormat, kDefaultWidth, |
| kDefaultHeight, linear); |
| vk::ImageFormatConstraintsInfoFUCHSIA format_constraints = |
| GetDefaultRgbImageFormatConstraintsInfo(); |
| format_constraints.imageCreateInfo = image_create_info; |
| |
| auto image_create_info2 = |
| GetDefaultImageCreateInfo(false, kDefaultFormat, kDefaultWidth, kDefaultHeight, linear); |
| vk::ImageFormatConstraintsInfoFUCHSIA format_constraints_2 = |
| GetDefaultRgbImageFormatConstraintsInfo(); |
| format_constraints_2.imageCreateInfo = image_create_info2; |
| |
| UniqueBufferCollection collection1 = |
| CreateVkBufferCollectionForImage(std::move(tokens[0]), format_constraints); |
| |
| UniqueBufferCollection collection2 = CreateVkBufferCollectionForImage( |
| std::move(tokens[1]), format_constraints_2, |
| vk::ImageConstraintsInfoFlagBitsFUCHSIA::eProtectedOptional); |
| |
| vk::BufferCollectionPropertiesFUCHSIA properties; |
| EXPECT_EQ(vk::Result::eSuccess, ctx_->device()->getBufferCollectionPropertiesFUCHSIA( |
| *collection1, &properties, loader_)) |
| << i; |
| |
| vk::BufferCollectionPropertiesFUCHSIA properties2; |
| EXPECT_EQ(vk::Result::eSuccess, ctx_->device()->getBufferCollectionPropertiesFUCHSIA( |
| *collection2, &properties2, loader_)) |
| << i; |
| EXPECT_EQ(properties.memoryTypeBits, properties2.memoryTypeBits) << i; |
| |
| VkPhysicalDeviceMemoryProperties memory_properties; |
| vkGetPhysicalDeviceMemoryProperties(ctx_->physical_device(), &memory_properties); |
| |
| for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) { |
| if (properties.memoryTypeBits & (1 << i)) { |
| EXPECT_EQ(protected_mem, !!(memory_properties.memoryTypes[i].propertyFlags & |
| VK_MEMORY_PROPERTY_PROTECTED_BIT)); |
| } |
| } |
| |
| // Use |image_create_info| for both because |image_create_info2| may not have the right flags |
| // set. |
| ASSERT_TRUE(InitializeDirectImage(*collection1, image_create_info)); |
| ASSERT_TRUE(InitializeDirectImage(*collection2, image_create_info)); |
| } |
| } |
| |
| TEST_P(VulkanProtectedImageExtensionTest, ProtectedUnprotectedIncompatible) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| auto tokens = MakeSharedCollection(2u); |
| |
| bool linear = GetParam(); |
| |
| vk::ImageFormatConstraintsInfoFUCHSIA constraints = GetDefaultRgbImageFormatConstraintsInfo(); |
| constraints.imageCreateInfo = |
| GetDefaultImageCreateInfo(true, kDefaultFormat, kDefaultWidth, kDefaultHeight, linear); |
| |
| vk::ImageFormatConstraintsInfoFUCHSIA constraints2 = GetDefaultRgbImageFormatConstraintsInfo(); |
| constraints2.imageCreateInfo = |
| GetDefaultImageCreateInfo(false, kDefaultFormat, kDefaultWidth, kDefaultHeight, linear); |
| |
| UniqueBufferCollection collection1 = |
| CreateVkBufferCollectionForImage(std::move(tokens[0]), constraints); |
| |
| UniqueBufferCollection collection2 = |
| CreateVkBufferCollectionForImage(std::move(tokens[1]), constraints2); |
| |
| vk::BufferCollectionPropertiesFUCHSIA properties; |
| EXPECT_NE(vk::Result::eSuccess, ctx_->device()->getBufferCollectionPropertiesFUCHSIA( |
| *collection1, &properties, loader_)); |
| } |
| |
| TEST_F(VulkanExtensionTest, BufferCollectionProtectedBuffer) { |
| if (!SupportsProtectedMemory()) { |
| GTEST_SKIP(); |
| } |
| set_use_protected_memory(true); |
| ASSERT_TRUE(Initialize()); |
| ASSERT_TRUE(device_supports_protected_memory()); |
| ASSERT_TRUE(ExecBuffer(16384)); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P(, VulkanProtectedImageExtensionTest, ::testing::Bool(), |
| [](testing::TestParamInfo<bool> info) { |
| return info.param ? "Linear" : "Tiled"; |
| }); |
| } // namespace |