forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Impeller] Support blit passes on Vulkan. (flutter#39438)
fixes: flutter/flutter#112649
- Loading branch information
1 parent
e50569b
commit 9a40a38
Showing
10 changed files
with
456 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
// Copyright 2013 The Flutter 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 "impeller/renderer/backend/vulkan/blit_command_vk.h" | ||
|
||
#include "impeller/renderer/backend/vulkan/commands_vk.h" | ||
#include "impeller/renderer/backend/vulkan/texture_vk.h" | ||
|
||
namespace impeller { | ||
|
||
BlitEncodeVK::~BlitEncodeVK() = default; | ||
|
||
//------------------------------------------------------------------------------ | ||
/// BlitCopyTextureToTextureCommandVK | ||
/// | ||
|
||
BlitCopyTextureToTextureCommandVK::~BlitCopyTextureToTextureCommandVK() = | ||
default; | ||
|
||
std::string BlitCopyTextureToTextureCommandVK::GetLabel() const { | ||
return label; | ||
} | ||
|
||
[[nodiscard]] bool BlitCopyTextureToTextureCommandVK::Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const { | ||
// cast source and destination to TextureVK | ||
const auto& source_tex_vk = TextureVK::Cast(*source); | ||
const auto& dest_tex_vk = TextureVK::Cast(*destination); | ||
|
||
// get the vulkan image and image view | ||
const auto source_image = source_tex_vk.GetImage(); | ||
const auto dest_image = dest_tex_vk.GetImage(); | ||
|
||
// copy the source image to the destination image, from source_region to | ||
// destination_origin. | ||
vk::ImageCopy image_copy; | ||
image_copy.setSrcSubresource( | ||
vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1)); | ||
image_copy.setDstSubresource( | ||
vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1)); | ||
|
||
image_copy.srcOffset = | ||
vk::Offset3D(source_region.origin.x, source_region.origin.y, 0); | ||
image_copy.dstOffset = | ||
vk::Offset3D(destination_origin.x, destination_origin.y, 0); | ||
image_copy.extent = | ||
vk::Extent3D(source_region.size.width, source_region.size.height, 1); | ||
|
||
// get single use command buffer | ||
auto copy_cmd = fenced_command_buffer->GetSingleUseChild(); | ||
|
||
vk::CommandBufferBeginInfo begin_info; | ||
begin_info.setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); | ||
auto res = copy_cmd.begin(begin_info); | ||
|
||
if (res != vk::Result::eSuccess) { | ||
VALIDATION_LOG << "Failed to begin command buffer: " << vk::to_string(res); | ||
return false; | ||
} | ||
|
||
// transition the source image to transfer source optimal | ||
TransitionImageLayoutCommandVK transition_source_cmd = | ||
TransitionImageLayoutCommandVK(source_image, vk::ImageLayout::eUndefined, | ||
vk::ImageLayout::eTransferSrcOptimal); | ||
bool success = transition_source_cmd.Submit(fenced_command_buffer); | ||
if (!success) { | ||
VALIDATION_LOG << "Failed to transition source image layout"; | ||
return false; | ||
} | ||
|
||
// transition the destination image to transfer destination optimal | ||
TransitionImageLayoutCommandVK transition_dest_cmd = | ||
TransitionImageLayoutCommandVK(dest_image, vk::ImageLayout::eUndefined, | ||
vk::ImageLayout::eTransferDstOptimal); | ||
success = transition_dest_cmd.Submit(fenced_command_buffer); | ||
if (!success) { | ||
VALIDATION_LOG << "Failed to transition destination image layout"; | ||
return false; | ||
} | ||
|
||
// issue the copy command | ||
copy_cmd.copyImage(source_image, vk::ImageLayout::eTransferSrcOptimal, | ||
dest_image, vk::ImageLayout::eTransferDstOptimal, | ||
image_copy); | ||
res = copy_cmd.end(); | ||
if (res != vk::Result::eSuccess) { | ||
VALIDATION_LOG << "Failed to end command buffer: " << vk::to_string(res); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
/// BlitCopyTextureToBufferCommandVK | ||
/// | ||
|
||
BlitCopyTextureToBufferCommandVK::~BlitCopyTextureToBufferCommandVK() = default; | ||
|
||
std::string BlitCopyTextureToBufferCommandVK::GetLabel() const { | ||
return label; | ||
} | ||
|
||
[[nodiscard]] bool BlitCopyTextureToBufferCommandVK::Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const { | ||
// cast source and destination to TextureVK | ||
const auto& source_tex_vk = TextureVK::Cast(*source); | ||
const auto& dest_buf_vk = DeviceBufferVK::Cast(*destination); | ||
|
||
// get the vulkan image and image view | ||
const auto source_image = source_tex_vk.GetImage(); | ||
|
||
// get buffer image handle | ||
const auto dest_buffer = dest_buf_vk.GetVKBufferHandle(); | ||
|
||
// copy the source image to the destination buffer, from source_region to | ||
// destination_origin. | ||
vk::BufferImageCopy image_copy{}; | ||
image_copy.setBufferOffset(destination_offset); | ||
image_copy.setBufferRowLength(0); | ||
image_copy.setBufferImageHeight(0); | ||
image_copy.setImageSubresource( | ||
vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1)); | ||
image_copy.setImageOffset( | ||
vk::Offset3D(source_region.origin.x, source_region.origin.y, 0)); | ||
image_copy.setImageExtent( | ||
vk::Extent3D(source_region.size.width, source_region.size.height, 1)); | ||
|
||
// transition the source image to transfer source optimal | ||
TransitionImageLayoutCommandVK transition_source_cmd = | ||
TransitionImageLayoutCommandVK(source_image, vk::ImageLayout::eUndefined, | ||
vk::ImageLayout::eTransferSrcOptimal); | ||
bool success = transition_source_cmd.Submit(fenced_command_buffer); | ||
if (!success) { | ||
return false; | ||
} | ||
|
||
// get single use command buffer | ||
auto copy_cmd = fenced_command_buffer->GetSingleUseChild(); | ||
|
||
vk::CommandBufferBeginInfo begin_info; | ||
begin_info.setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); | ||
auto res = copy_cmd.begin(begin_info); | ||
|
||
if (res != vk::Result::eSuccess) { | ||
VALIDATION_LOG << "Failed to begin command buffer: " << vk::to_string(res); | ||
return false; | ||
} | ||
|
||
// issue the copy command | ||
copy_cmd.copyImageToBuffer(source_image, vk::ImageLayout::eTransferSrcOptimal, | ||
dest_buffer, image_copy); | ||
res = copy_cmd.end(); | ||
if (res != vk::Result::eSuccess) { | ||
VALIDATION_LOG << "Failed to end command buffer: " << vk::to_string(res); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
/// BlitGenerateMipmapCommandVK | ||
/// | ||
|
||
BlitGenerateMipmapCommandVK::~BlitGenerateMipmapCommandVK() = default; | ||
|
||
std::string BlitGenerateMipmapCommandVK::GetLabel() const { | ||
return label; | ||
} | ||
|
||
[[nodiscard]] bool BlitGenerateMipmapCommandVK::Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const { | ||
// TODO(https://github.com/flutter/flutter/issues/120134): Support generating | ||
// mipmaps on Vulkan. | ||
IMPELLER_UNIMPLEMENTED; | ||
return true; | ||
} | ||
|
||
// END: BlitGenerateMipmapCommandVK | ||
|
||
} // namespace impeller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include "impeller/base/backend_cast.h" | ||
#include "impeller/renderer/backend/vulkan/context_vk.h" | ||
#include "impeller/renderer/backend/vulkan/fenced_command_buffer_vk.h" | ||
#include "impeller/renderer/blit_command.h" | ||
#include "impeller/renderer/context.h" | ||
|
||
namespace impeller { | ||
|
||
/// Mixin for dispatching Vulkan commands. | ||
struct BlitEncodeVK : BackendCast<BlitEncodeVK, BlitCommand> { | ||
virtual ~BlitEncodeVK(); | ||
|
||
virtual std::string GetLabel() const = 0; | ||
|
||
[[nodiscard]] virtual bool Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const = 0; | ||
}; | ||
|
||
struct BlitCopyTextureToTextureCommandVK | ||
: public BlitCopyTextureToTextureCommand, | ||
public BlitEncodeVK { | ||
~BlitCopyTextureToTextureCommandVK() override; | ||
|
||
std::string GetLabel() const override; | ||
|
||
[[nodiscard]] bool Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const override; | ||
}; | ||
|
||
struct BlitCopyTextureToBufferCommandVK : public BlitCopyTextureToBufferCommand, | ||
public BlitEncodeVK { | ||
~BlitCopyTextureToBufferCommandVK() override; | ||
|
||
std::string GetLabel() const override; | ||
|
||
[[nodiscard]] bool Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const override; | ||
}; | ||
|
||
struct BlitGenerateMipmapCommandVK : public BlitGenerateMipmapCommand, | ||
public BlitEncodeVK { | ||
~BlitGenerateMipmapCommandVK() override; | ||
|
||
std::string GetLabel() const override; | ||
|
||
[[nodiscard]] bool Encode( | ||
FencedCommandBufferVK* fenced_command_buffer) const override; | ||
}; | ||
|
||
} // namespace impeller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.