7 #include "flutter/fml/paths.h"
10 #define GLFW_INCLUDE_VULKAN
11 #include <GLFW/glfw3.h>
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/mapping.h"
15 #include "impeller/entity/vk/entity_shaders_vk.h"
16 #include "impeller/entity/vk/framebuffer_blend_shaders_vk.h"
17 #include "impeller/entity/vk/modern_shaders_vk.h"
18 #include "impeller/fixtures/vk/fixtures_shaders_vk.h"
19 #include "impeller/fixtures/vk/modern_fixtures_shaders_vk.h"
20 #include "impeller/playground/imgui/vk/imgui_shaders_vk.h"
26 #include "impeller/renderer/vk/compute_shaders_vk.h"
30 static std::vector<std::shared_ptr<fml::Mapping>>
33 std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
34 impeller_entity_shaders_vk_length),
35 std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
36 impeller_modern_shaders_vk_length),
37 std::make_shared<fml::NonOwnedMapping>(
38 impeller_framebuffer_blend_shaders_vk_data,
39 impeller_framebuffer_blend_shaders_vk_length),
40 std::make_shared<fml::NonOwnedMapping>(
41 impeller_fixtures_shaders_vk_data,
42 impeller_fixtures_shaders_vk_length),
43 std::make_shared<fml::NonOwnedMapping>(
44 impeller_modern_fixtures_shaders_vk_data,
45 impeller_modern_fixtures_shaders_vk_length),
46 std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_vk_data,
47 impeller_imgui_shaders_vk_length),
48 std::make_shared<fml::NonOwnedMapping>(
49 impeller_compute_shaders_vk_data, impeller_compute_shaders_vk_length),
53 vk::UniqueInstance PlaygroundImplVK::global_instance_;
55 void PlaygroundImplVK::DestroyWindowHandle(WindowHandle handle) {
59 ::glfwDestroyWindow(
reinterpret_cast<GLFWwindow*
>(handle));
63 :
PlaygroundImpl(switches), handle_(nullptr, &DestroyWindowHandle) {
66 InitGlobalVulkanInstance();
68 ::glfwDefaultWindowHints();
69 ::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
70 ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
72 auto window = ::glfwCreateWindow(1, 1,
"Test",
nullptr,
nullptr);
80 ::glfwGetWindowSize(window, &width, &height);
81 size_ =
ISize{width, height};
83 handle_.reset(window);
87 reinterpret_cast<PFN_vkGetInstanceProcAddr
>(
88 &::glfwGetInstanceProcAddress);
97 if (!context_vk || !context_vk->IsValid()) {
98 VALIDATION_LOG <<
"Could not create Vulkan context in the playground.";
102 VkSurfaceKHR vk_surface;
103 auto res = vk::Result{::glfwCreateWindowSurface(
104 context_vk->GetInstance(),
109 if (res != vk::Result::eSuccess) {
111 << vk::to_string(res);
115 vk::UniqueSurfaceKHR surface{vk_surface, context_vk->GetInstance()};
116 auto context = context_vk->CreateSurfaceContext();
117 if (!context->SetWindowSurface(std::move(surface), size_)) {
122 context_ = std::move(context);
128 std::shared_ptr<Context> PlaygroundImplVK::GetContext()
const {
134 return handle_.get();
138 std::unique_ptr<Surface> PlaygroundImplVK::AcquireSurfaceFrame(
139 std::shared_ptr<Context> context) {
140 SurfaceContextVK* surface_context_vk =
141 reinterpret_cast<SurfaceContextVK*
>(context_.get());
145 ::glfwGetFramebufferSize(
reinterpret_cast<GLFWwindow*
>(handle_.get()), &width,
147 size_ =
ISize{width, height};
148 surface_context_vk->UpdateSurfaceSize(
ISize{width, height});
150 return surface_context_vk->AcquireNextSurface();
161 void PlaygroundImplVK::InitGlobalVulkanInstance() {
162 if (global_instance_) {
166 VULKAN_HPP_DEFAULT_DISPATCHER.init(::glfwGetInstanceProcAddress);
168 vk::ApplicationInfo application_info;
169 application_info.setApplicationVersion(VK_API_VERSION_1_0);
170 application_info.setApiVersion(VK_API_VERSION_1_1);
171 application_info.setEngineVersion(VK_API_VERSION_1_0);
172 application_info.setPEngineName(
"PlaygroundImplVK");
173 application_info.setPApplicationName(
"PlaygroundImplVK");
175 auto caps = std::shared_ptr<CapabilitiesVK>(
176 new CapabilitiesVK(
true));
177 FML_DCHECK(caps->IsValid());
179 std::optional<std::vector<std::string>> enabled_layers =
180 caps->GetEnabledLayers();
181 std::optional<std::vector<std::string>> enabled_extensions =
182 caps->GetEnabledInstanceExtensions();
183 FML_DCHECK(enabled_layers.has_value() && enabled_extensions.has_value());
185 std::vector<const char*> enabled_layers_c;
186 std::vector<const char*> enabled_extensions_c;
188 if (enabled_layers.has_value()) {
189 for (
const auto& layer : enabled_layers.value()) {
190 enabled_layers_c.push_back(layer.c_str());
194 if (enabled_extensions.has_value()) {
195 for (
const auto& ext : enabled_extensions.value()) {
196 enabled_extensions_c.push_back(ext.c_str());
200 vk::InstanceCreateFlags instance_flags = {};
201 instance_flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
202 vk::InstanceCreateInfo instance_info;
203 instance_info.setPEnabledLayerNames(enabled_layers_c);
204 instance_info.setPEnabledExtensionNames(enabled_extensions_c);
205 instance_info.setPApplicationInfo(&application_info);
206 instance_info.setFlags(instance_flags);
207 auto instance_result = vk::createInstanceUnique(instance_info);
208 FML_CHECK(instance_result.result == vk::Result::eSuccess)
209 <<
"Unable to initialize global Vulkan instance";
210 global_instance_ = std::move(instance_result.value);
214 const std::shared_ptr<Capabilities>& capabilities) {
216 fml::StatusCode::kUnimplemented,
217 "PlaygroundImplVK doesn't support setting the capabilities.");
221 if (::glfwVulkanSupported()) {
225 FML_LOG(ERROR) <<
"Attempting to initialize a Vulkan playground on macOS "
226 "where Vulkan cannot be found. It can be installed via "
227 "MoltenVK and make sure to install it globally so "
228 "dlopen can find it.";
229 #else // TARGET_OS_MAC
230 FML_LOG(ERROR) <<
"Attempting to initialize a Vulkan playground on a system "
231 "that does not support Vulkan.";
232 #endif // TARGET_OS_MAC