|
3 | 3 | // found in the LICENSE file. |
4 | 4 |
|
5 | 5 | #include <cassert> |
| 6 | +#include <optional> |
6 | 7 |
|
7 | 8 | #include "flutter/fml/logging.h" |
8 | 9 | #include "flutter/shell/common/context_options.h" |
9 | 10 | #include "flutter/testing/test_vulkan_context.h" |
10 | 11 |
|
11 | | -#include "include/gpu/GrDirectContext.h" |
12 | | -#include "include/gpu/vk/GrVkExtensions.h" |
13 | 12 | #include "third_party/skia/include/core/SkSurface.h" |
| 13 | +#include "third_party/skia/include/gpu/GrDirectContext.h" |
| 14 | +#include "third_party/skia/include/gpu/vk/GrVkExtensions.h" |
| 15 | +#include "vulkan/vulkan_core.h" |
14 | 16 |
|
15 | 17 | #ifdef OS_MACOSX |
16 | 18 | #define VULKAN_SO_PATH "libvk_swiftshader.dylib" |
@@ -90,9 +92,67 @@ TestVulkanContext::TestVulkanContext() { |
90 | 92 | context_ = GrDirectContext::MakeVulkan(backend_context, options); |
91 | 93 | } |
92 | 94 |
|
93 | | -VkImage TestVulkanContext::CreateImage(const SkISize& size) const { |
94 | | - assert(false); // TODO(bdero) |
95 | | - return nullptr; |
| 95 | +std::optional<TestVulkanImage> TestVulkanContext::CreateImage( |
| 96 | + const SkISize& size) const { |
| 97 | + TestVulkanImage result; |
| 98 | + |
| 99 | + VkImageCreateInfo info = { |
| 100 | + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, |
| 101 | + .pNext = nullptr, |
| 102 | + .flags = 0, |
| 103 | + .imageType = VK_IMAGE_TYPE_2D, |
| 104 | + .format = VK_FORMAT_R8G8B8A8_UNORM, |
| 105 | + .extent = VkExtent3D{static_cast<uint32_t>(size.width()), |
| 106 | + static_cast<uint32_t>(size.height()), 1}, |
| 107 | + .mipLevels = 1, |
| 108 | + .arrayLayers = 1, |
| 109 | + .samples = VK_SAMPLE_COUNT_1_BIT, |
| 110 | + .tiling = VK_IMAGE_TILING_OPTIMAL, |
| 111 | + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | |
| 112 | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | |
| 113 | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, |
| 114 | + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, |
| 115 | + .queueFamilyIndexCount = 0, |
| 116 | + .pQueueFamilyIndices = nullptr, |
| 117 | + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
| 118 | + }; |
| 119 | + |
| 120 | + VkImage image; |
| 121 | + if (VK_CALL_LOG_ERROR(VK_CALL_LOG_ERROR( |
| 122 | + vk_->CreateImage(device_->GetHandle(), &info, nullptr, &image)))) { |
| 123 | + return std::nullopt; |
| 124 | + } |
| 125 | + |
| 126 | + result.image_ = vulkan::VulkanHandle<VkImage>( |
| 127 | + image, [&vk = vk_, &device = device_](VkImage image) { |
| 128 | + vk->DestroyImage(device->GetHandle(), image, nullptr); |
| 129 | + }); |
| 130 | + |
| 131 | + VkMemoryRequirements mem_req; |
| 132 | + vk_->GetImageMemoryRequirements(device_->GetHandle(), image, &mem_req); |
| 133 | + VkMemoryAllocateInfo alloc_info{}; |
| 134 | + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; |
| 135 | + alloc_info.allocationSize = mem_req.size; |
| 136 | + alloc_info.memoryTypeIndex = static_cast<uint32_t>(__builtin_ctz( |
| 137 | + mem_req.memoryTypeBits & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); |
| 138 | + |
| 139 | + VkDeviceMemory memory; |
| 140 | + if (VK_CALL_LOG_ERROR(vk_->AllocateMemory(device_->GetHandle(), &alloc_info, |
| 141 | + nullptr, &memory)) != VK_SUCCESS) { |
| 142 | + return std::nullopt; |
| 143 | + } |
| 144 | + |
| 145 | + result.memory_ = vulkan::VulkanHandle<VkDeviceMemory>{ |
| 146 | + memory, [&vk = vk_, &device = device_](VkDeviceMemory memory) { |
| 147 | + vk->FreeMemory(device->GetHandle(), memory, nullptr); |
| 148 | + }}; |
| 149 | + |
| 150 | + if (VK_CALL_LOG_ERROR(VK_CALL_LOG_ERROR(vk_->BindImageMemory( |
| 151 | + device_->GetHandle(), result.image_, result.memory_, 0)))) { |
| 152 | + return std::nullopt; |
| 153 | + } |
| 154 | + |
| 155 | + return result; |
96 | 156 | } |
97 | 157 |
|
98 | 158 | sk_sp<GrDirectContext> TestVulkanContext::GetGrDirectContext() const { |
|
0 commit comments