Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions impeller/docs/android_validation_layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Android Vulkan Validation Layers

This is a quick guide to get Vulkan validation layers support for a Flutter application. This guide assumes that you've created the application with `flutter create`, otherwise the locations might vary.

1. Download the validation layers from https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases. Typically named `android-binaries-1.3.231.1.zip`.
2. When you unzip the file, you will see: `arm64-v8a armeabi-v7a x86 x86_64`
3. Copy these directories to `${FLUTTER_APP}/android/app/src/main/vklibs`. The layout should look similar to:

```
src/main/vklibs/
arm64-v8a/
libVkLayer_khronos_validation.so
armeabi-v7a/
libVkLayer_khronos_validation.so
x86/
libVkLayer_khronos_validation.so
x86-64/
libVkLayer_khronos_validation.so
```

4. Add the following line to `${FLUTTER_APP}/android/app/build.gradle`, `android > sourceSets` section: `main.jniLibs.srcDirs += 'src/main/vklibs'`.

5. This should enable Vulkan validation layers on your Android application.
2 changes: 1 addition & 1 deletion impeller/playground/backend/vulkan/playground_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ PlaygroundImplVK::PlaygroundImplVK()
::glfwDefaultWindowHints();
::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
::glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
// ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);

auto window =
::glfwCreateWindow(800, 600, "Test Vulkan Window", nullptr, nullptr);
Expand Down
7 changes: 5 additions & 2 deletions impeller/renderer/backend/vulkan/allocator_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
const TextureDescriptor& desc) {
auto image_create_info = vk::ImageCreateInfo{};
image_create_info.imageType = vk::ImageType::e2D;
FML_LOG(ERROR) << __PRETTY_FUNCTION__;
image_create_info.format = ToVKImageFormat(desc.format);
image_create_info.extent.width = desc.size.width;
image_create_info.extent.height = desc.size.height;
Expand Down Expand Up @@ -138,7 +139,7 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
}

vk::ImageViewCreateInfo view_create_info = {};
view_create_info.image = img;
view_create_info.image = vk::Image{img};
view_create_info.viewType = vk::ImageViewType::e2D;
view_create_info.format = image_create_info.format;
view_create_info.subresourceRange.aspectMask =
Expand All @@ -153,6 +154,8 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
return nullptr;
}

auto image_view = static_cast<vk::ImageView::NativeType>(img_view_res.value);

auto texture_info = std::make_unique<TextureInfoVK>(TextureInfoVK{
.backing_type = TextureBackingTypeVK::kAllocatedTexture,
.allocated_texture =
Expand All @@ -161,7 +164,7 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
.allocation = allocation,
.allocation_info = allocation_info,
.image = img,
.image_view = img_view_res.value,
.image_view = image_view,
},
});
return std::make_shared<TextureVK>(desc, &context_, std::move(texture_info));
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/vulkan/command_buffer_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ std::shared_ptr<RenderPass> CommandBufferVK::OnCreateRenderPass(
attachment.texture->GetTextureDescriptor();

vk::AttachmentDescription color_attachment;
FML_LOG(ERROR) << __PRETTY_FUNCTION__;
color_attachment.setFormat(ToVKImageFormat(tex_desc.format));
color_attachment.setSamples(ToVKSampleCountFlagBits(tex_desc.sample_count));
color_attachment.setLoadOp(ToVKAttachmentLoadOp(attachment.load_action));
Expand Down
66 changes: 47 additions & 19 deletions impeller/renderer/backend/vulkan/context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,33 @@
#include "impeller/renderer/backend/vulkan/surface_producer_vk.h"
#include "impeller/renderer/backend/vulkan/swapchain_details_vk.h"
#include "impeller/renderer/backend/vulkan/vk.h"
#include "vulkan/vulkan.hpp"
#include "vulkan/vulkan_core.h"
#include "vulkan/vulkan_handles.hpp"

VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE

namespace {

VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) {
const auto prefix = impeller::vk::to_string(
impeller::vk::DebugUtilsMessageSeverityFlagBitsEXT{severity});

FML_DCHECK(false) << prefix << "[" << pCallbackData->messageIdNumber << "]["
<< pCallbackData->pMessageIdName
<< "] : " << pCallbackData->pMessage;

// The return value of this callback controls whether the Vulkan call that
// caused the validation message will be aborted or not We return VK_TRUE as
// we DO want Vulkan calls that cause a validation message to abort
return VK_TRUE;
}

} // namespace

namespace impeller {

static std::set<std::string> kRequiredDeviceExtensions = {
Expand Down Expand Up @@ -335,7 +358,6 @@ ContextVK::ContextVK(

if (has_debug_utils) {
vk::DebugUtilsMessengerCreateInfoEXT debug_messenger_info;

debug_messenger_info.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
Expand All @@ -344,23 +366,7 @@ ContextVK::ContextVK(
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation;
debug_messenger_info.pUserData = nullptr;
debug_messenger_info.pfnUserCallback =
[](VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT type,
const VkDebugUtilsMessengerCallbackDataEXT* data,
void* user_data) -> VkBool32 {
if (type == VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
// do not terminate on performance warnings.
FML_LOG(ERROR)
<< vk::to_string(vk::DebugUtilsMessageSeverityFlagBitsEXT{severity})
<< ": " << data->pMessage;
} else {
FML_DCHECK(false)
<< vk::to_string(vk::DebugUtilsMessageSeverityFlagBitsEXT{severity})
<< ": " << data->pMessage;
}
return true;
};
debug_messenger_info.pfnUserCallback = DebugUtilsMessengerCallback;

auto debug_messenger_result =
instance.value->createDebugUtilsMessengerEXTUnique(
Expand Down Expand Up @@ -523,6 +529,28 @@ std::unique_ptr<Surface> ContextVK::AcquireSurface(size_t current_frame) {
return surface_producer_->AcquireSurface(current_frame);
}

#ifdef FML_OS_ANDROID

vk::UniqueSurfaceKHR ContextVK::CreateAndroidSurface(
ANativeWindow* window) const {
if (!instance_) {
return vk::UniqueSurfaceKHR{VK_NULL_HANDLE};
}

auto create_info = vk::AndroidSurfaceCreateInfoKHR().setWindow(window);
auto surface_res = instance_->createAndroidSurfaceKHRUnique(create_info);

if (surface_res.result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not create Android surface, error: "
<< vk::to_string(surface_res.result);
return vk::UniqueSurfaceKHR{VK_NULL_HANDLE};
}

return std::move(surface_res.value);
}

#endif // FML_OS_ANDROID

void ContextVK::SetupSwapchain(vk::UniqueSurfaceKHR surface) {
surface_ = std::move(surface);
auto present_queue_out = PickPresentQueue(physical_device_, *surface_);
Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/backend/vulkan/context_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class ContextVK final : public Context, public BackendCast<ContextVK, Context> {

std::string label_str = std::string(label);

if (!device_) {
FML_LOG(ERROR) << "SetDebugName called on a null device";
return false;
}

auto ret = device_->setDebugUtilsObjectNameEXT(
vk::DebugUtilsObjectNameInfoEXT()
.setObjectType(T::objectType)
Expand All @@ -66,6 +71,10 @@ class ContextVK final : public Context, public BackendCast<ContextVK, Context> {

std::shared_ptr<DescriptorPoolVK> GetDescriptorPool() const;

#ifdef FML_OS_ANDROID
vk::UniqueSurfaceKHR CreateAndroidSurface(ANativeWindow* window) const;
#endif // FML_OS_ANDROID

private:
std::shared_ptr<fml::ConcurrentTaskRunner> worker_task_runner_;
vk::UniqueInstance instance_;
Expand Down
7 changes: 7 additions & 0 deletions impeller/renderer/backend/vulkan/formats_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,25 @@ constexpr std::optional<vk::ShaderStageFlagBits> ToVKShaderStageFlagBits(
constexpr vk::Format ToVKImageFormat(PixelFormat format) {
switch (format) {
case PixelFormat::kUnknown:
FML_LOG(ERROR) << "Unknown pixel format";
return vk::Format::eUndefined;
case PixelFormat::kA8UNormInt:
FML_LOG(ERROR) << "kA8UNormInt - eA8B8G8R8UnormPack32 format";
return vk::Format::eA8B8G8R8UnormPack32;
case PixelFormat::kR8G8B8A8UNormInt:
FML_LOG(ERROR) << "kR8G8B8A8UNormInt - eR8G8B8A8Unorm format";
return vk::Format::eR8G8B8A8Unorm;
case PixelFormat::kR8G8B8A8UNormIntSRGB:
FML_LOG(ERROR) << "kR8G8B8A8UNormIntSRGB - eR8G8B8A8Srgb format";
return vk::Format::eR8G8B8A8Srgb;
case PixelFormat::kB8G8R8A8UNormInt:
FML_LOG(ERROR) << "kB8G8R8A8UNormInt - eB8G8R8A8Unorm format";
return vk::Format::eB8G8R8A8Unorm;
case PixelFormat::kB8G8R8A8UNormIntSRGB:
FML_LOG(ERROR) << "kB8G8R8A8UNormIntSRGB - eB8G8R8A8Srgb format";
return vk::Format::eB8G8R8A8Srgb;
case PixelFormat::kS8UInt:
FML_LOG(ERROR) << "kS8UInt - eS8Uint format";
return vk::Format::eS8Uint;
}
}
Expand Down
6 changes: 5 additions & 1 deletion impeller/renderer/backend/vulkan/pipeline_library_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ std::optional<vk::UniqueRenderPass> PipelineLibraryVK::CreateRenderPass(
std::vector<vk::AttachmentDescription> render_pass_attachments;
const auto sample_count = desc.GetSampleCount();
// Set the color attachment.
const auto& format = desc.GetColorAttachmentDescriptor(0)->format;
FML_LOG(ERROR) << __PRETTY_FUNCTION__;
render_pass_attachments.push_back(CreatePlaceholderAttachmentDescription(
vk::Format::eB8G8R8A8Unorm, sample_count, true));
ToVKImageFormat(format), sample_count, true));

std::vector<vk::AttachmentReference> color_attachment_references;
std::vector<vk::AttachmentReference> resolve_attachment_references;
Expand Down Expand Up @@ -390,6 +392,8 @@ std::unique_ptr<PipelineCreateInfoVK> PipelineLibraryVK::CreatePipeline(
VALIDATION_LOG << "Could not create graphics pipeline - " << desc.GetLabel()
<< ": " << vk::to_string(pipeline.result);
return nullptr;
} else {
FML_LOG(ERROR) << "Created graphics pipeline - " << desc.GetLabel();
}

return std::make_unique<PipelineCreateInfoVK>(
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/vulkan/surface_producer_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ std::unique_ptr<Surface> SurfaceProducerVK::AcquireSurface(
}

if (acuire_image_res == vk::Result::eSuboptimalKHR) {
VALIDATION_LOG << "Suboptimal image acquired.";
FML_LOG(ERROR) << "Suboptimal image acquired.";
}

SurfaceVK::SwapCallback swap_callback = [this, current_frame, image_index]() {
Expand Down
12 changes: 8 additions & 4 deletions impeller/renderer/backend/vulkan/surface_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/renderer/backend/vulkan/surface_vk.h"

#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/texture_vk.h"
#include "impeller/renderer/surface.h"

Expand All @@ -20,6 +21,10 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
TextureDescriptor color0_tex;
color0_tex.type = TextureType::kTexture2D;
color0_tex.format = swapchain_image->GetPixelFormat();

FML_LOG(ERROR) << __PRETTY_FUNCTION__;
ToVKImageFormat(color0_tex.format);

color0_tex.size = swapchain_image->GetSize();
color0_tex.usage = static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
color0_tex.sample_count = SampleCount::kCount1;
Expand Down Expand Up @@ -59,16 +64,15 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
},
});
stencil0.texture = std::make_shared<TextureVK>(
std::move(stencil0_tex), context, std::move(stencil_texture_info));
stencil0_tex, context, std::move(stencil_texture_info));
stencil0.load_action = LoadAction::kClear;
stencil0.store_action = StoreAction::kDontCare;

RenderTarget render_target_desc;
render_target_desc.SetColorAttachment(color0, 0u);

return std::unique_ptr<SurfaceVK>(new SurfaceVK(std::move(render_target_desc),
swapchain_image,
std::move(swap_callback)));
return std::unique_ptr<SurfaceVK>(new SurfaceVK(
render_target_desc, swapchain_image, std::move(swap_callback)));
}

SurfaceVK::SurfaceVK(RenderTarget target,
Expand Down
28 changes: 23 additions & 5 deletions impeller/renderer/backend/vulkan/swapchain_details_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,20 @@ std::unique_ptr<SwapchainDetailsVK> SwapchainDetailsVK::Create(
std::vector<vk::PresentModeKHR> surface_present_modes =
surface_present_modes_res.value;

return std::make_unique<SwapchainDetailsVK>(capabilities, surface_formats,
surface_present_modes);

const auto composite_alphas = capabilities.supportedCompositeAlpha;
vk::CompositeAlphaFlagBitsKHR composite_alpha;
if (composite_alphas & vk::CompositeAlphaFlagBitsKHR::eOpaque) {
composite_alpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
} else if (composite_alphas & vk::CompositeAlphaFlagBitsKHR::eInherit) {
composite_alpha = vk::CompositeAlphaFlagBitsKHR::eInherit;
} else {
VALIDATION_LOG << "No supported composite alpha found.";
return nullptr;
}

return std::make_unique<SwapchainDetailsVK>(
capabilities, surface_formats, surface_present_modes, composite_alpha);
}

vk::SurfaceFormatKHR SwapchainDetailsVK::PickSurfaceFormat() const {
Expand Down Expand Up @@ -68,6 +80,10 @@ vk::PresentModeKHR SwapchainDetailsVK::PickPresentationMode() const {
return vk::PresentModeKHR::eFifo;
}

vk::CompositeAlphaFlagBitsKHR SwapchainDetailsVK::PickCompositeAlpha() const {
return composite_alpha_;
}

vk::Extent2D SwapchainDetailsVK::PickExtent() const {
if (surface_capabilities_.currentExtent.width !=
std::numeric_limits<uint32_t>::max()) {
Expand Down Expand Up @@ -97,10 +113,12 @@ vk::SurfaceTransformFlagBitsKHR SwapchainDetailsVK::GetTransform() const {
SwapchainDetailsVK::SwapchainDetailsVK(
vk::SurfaceCapabilitiesKHR capabilities,
std::vector<vk::SurfaceFormatKHR> surface_formats,
std::vector<vk::PresentModeKHR> surface_present_modes)
std::vector<vk::PresentModeKHR> surface_present_modes,
vk::CompositeAlphaFlagBitsKHR composite_alpha)
: surface_capabilities_(capabilities),
surface_formats_(surface_formats),
present_modes_(surface_present_modes) {}
surface_formats_(std::move(surface_formats)),
present_modes_(std::move(surface_present_modes)),
composite_alpha_(composite_alpha) {}

SwapchainDetailsVK::~SwapchainDetailsVK() = default;

Expand Down
6 changes: 5 additions & 1 deletion impeller/renderer/backend/vulkan/swapchain_details_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ class SwapchainDetailsVK {

SwapchainDetailsVK(vk::SurfaceCapabilitiesKHR capabilities,
std::vector<vk::SurfaceFormatKHR> surface_formats,
std::vector<vk::PresentModeKHR> surface_present_modes);
std::vector<vk::PresentModeKHR> surface_present_modes,
vk::CompositeAlphaFlagBitsKHR composite_alpha);

~SwapchainDetailsVK();

vk::SurfaceFormatKHR PickSurfaceFormat() const;

vk::PresentModeKHR PickPresentationMode() const;

vk::CompositeAlphaFlagBitsKHR PickCompositeAlpha() const;

vk::Extent2D PickExtent() const;

uint32_t GetImageCount() const;
Expand All @@ -35,6 +38,7 @@ class SwapchainDetailsVK {
vk::SurfaceCapabilitiesKHR surface_capabilities_;
std::vector<vk::SurfaceFormatKHR> surface_formats_;
std::vector<vk::PresentModeKHR> present_modes_;
vk::CompositeAlphaFlagBitsKHR composite_alpha_;

FML_DISALLOW_COPY_AND_ASSIGN(SwapchainDetailsVK);
};
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/vulkan/swapchain_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ std::unique_ptr<SwapchainVK> SwapchainVK::Create(vk::Device device,
create_info.imageArrayLayers = 1;
create_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment;
create_info.preTransform = details.GetTransform();
create_info.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
create_info.compositeAlpha = details.PickCompositeAlpha();
create_info.clipped = VK_TRUE;

create_info.imageSharingMode = vk::SharingMode::eExclusive;
Expand Down
4 changes: 2 additions & 2 deletions impeller/renderer/backend/vulkan/texture_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ vk::ImageView TextureVK::GetImageView() const {
case TextureBackingTypeVK::kUnknownType:
return nullptr;
case TextureBackingTypeVK::kAllocatedTexture:
return texture_info_->allocated_texture.image_view;
return vk::ImageView{texture_info_->allocated_texture.image_view};
case TextureBackingTypeVK::kWrappedTexture:
return texture_info_->wrapped_texture.swapchain_image->GetImageView();
}
Expand All @@ -101,7 +101,7 @@ vk::Image TextureVK::GetImage() const {
case TextureBackingTypeVK::kUnknownType:
FML_CHECK(false) << "Unknown texture backing type";
case TextureBackingTypeVK::kAllocatedTexture:
return texture_info_->allocated_texture.image;
return vk::Image{texture_info_->allocated_texture.image};
case TextureBackingTypeVK::kWrappedTexture:
return texture_info_->wrapped_texture.swapchain_image->GetImage();
}
Expand Down
Loading