Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
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
2 changes: 1 addition & 1 deletion impeller/playground/playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static std::shared_ptr<Texture> CreateTextureForDecompressedImage(
DecompressedImage& decompressed_image,
bool enable_mipmapping) {
// TODO(https://github.com/flutter/flutter/issues/123468): copying buffers to
// textures is not implemented for GLES/Vulkan.
// textures is not implemented for GLES.
if (context->GetCapabilities()->SupportsBufferToTextureBlits()) {
impeller::TextureDescriptor texture_descriptor;
texture_descriptor.storage_mode = impeller::StorageMode::kDevicePrivate;
Expand Down
56 changes: 56 additions & 0 deletions impeller/renderer/backend/vulkan/blit_command_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,62 @@ bool BlitCopyTextureToBufferCommandVK::Encode(CommandEncoderVK& encoder) const {
return true;
}

//------------------------------------------------------------------------------
/// BlitCopyBufferToTextureCommandVK
///

BlitCopyBufferToTextureCommandVK::~BlitCopyBufferToTextureCommandVK() = default;

std::string BlitCopyBufferToTextureCommandVK::GetLabel() const {
return label;
}

bool BlitCopyBufferToTextureCommandVK::Encode(CommandEncoderVK& encoder) const {
const auto& cmd_buffer = encoder.GetCommandBuffer();

// cast destination to TextureVK
const auto& dst = TextureVK::Cast(*destination);
const auto& src = DeviceBufferVK::Cast(*source.buffer);

if (!encoder.Track(source.buffer) || !encoder.Track(destination)) {
return false;
}

LayoutTransition dst_tran;
dst_tran.cmd_buffer = cmd_buffer;
dst_tran.new_layout = vk::ImageLayout::eTransferDstOptimal;
dst_tran.src_access = {};
dst_tran.src_stage = vk::PipelineStageFlagBits::eTopOfPipe;
dst_tran.dst_access =
vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eTransferWrite;
dst_tran.dst_stage = vk::PipelineStageFlagBits::eFragmentShader |
vk::PipelineStageFlagBits::eTransfer;
Comment on lines +174 to +176
Copy link
Contributor Author

@jonahwilliams jonahwilliams May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to update the dst access and stage to incude transfer.


vk::BufferImageCopy image_copy;
image_copy.setBufferOffset(source.range.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(destination_origin.x, destination_origin.y, 0));
image_copy.setImageExtent(vk::Extent3D(destination->GetSize().width,
destination->GetSize().height, 1));

if (!dst.SetLayout(dst_tran)) {
VALIDATION_LOG << "Could not encode layout transition.";
return false;
}

cmd_buffer.copyBufferToImage(src.GetBuffer(), //
dst.GetImage(), //
dst_tran.new_layout, //
image_copy //
);

return true;
}

//------------------------------------------------------------------------------
/// BlitGenerateMipmapCommandVK
///
Expand Down
9 changes: 9 additions & 0 deletions impeller/renderer/backend/vulkan/blit_command_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ struct BlitCopyTextureToBufferCommandVK : public BlitCopyTextureToBufferCommand,
[[nodiscard]] bool Encode(CommandEncoderVK& encoder) const override;
};

struct BlitCopyBufferToTextureCommandVK : public BlitCopyBufferToTextureCommand,
public BlitEncodeVK {
~BlitCopyBufferToTextureCommandVK() override;

std::string GetLabel() const override;

[[nodiscard]] bool Encode(CommandEncoderVK& encoder) const override;
};

struct BlitGenerateMipmapCommandVK : public BlitGenerateMipmapCommand,
public BlitEncodeVK {
~BlitGenerateMipmapCommandVK() override;
Expand Down
21 changes: 21 additions & 0 deletions impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ TEST(BlitCommandVkTest, BlitCopyTextureToBufferCommandVK) {
EXPECT_TRUE(encoder.IsTracking(cmd.destination));
}

TEST(BlitCommandVkTest, BlitCopyBufferToTextureCommandVK) {
auto context = CreateMockVulkanContext();
auto pool = CommandPoolVK::GetThreadLocal(context.get());
CommandEncoderVK encoder(context->GetDeviceHolder(),
context->GetGraphicsQueue(), pool,
context->GetFenceWaiter());
BlitCopyBufferToTextureCommandVK cmd;
cmd.destination = context->GetResourceAllocator()->CreateTexture({
.size = ISize(100, 100),
});
cmd.source = context->GetResourceAllocator()
->CreateBuffer({
.size = 1,
})
->AsBufferView();
bool result = cmd.Encode(encoder);
EXPECT_TRUE(result);
EXPECT_TRUE(encoder.IsTracking(cmd.source.buffer));
EXPECT_TRUE(encoder.IsTracking(cmd.destination));
}

TEST(BlitCommandVkTest, BlitGenerateMipmapCommandVK) {
auto context = CreateMockVulkanContext();
auto pool = CommandPoolVK::GetThreadLocal(context.get());
Expand Down
17 changes: 17 additions & 0 deletions impeller/renderer/backend/vulkan/blit_pass_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ bool BlitPassVK::OnCopyTextureToBufferCommand(
return true;
}

// |BlitPass|
bool BlitPassVK::OnCopyBufferToTextureCommand(
BufferView source,
std::shared_ptr<Texture> destination,
IPoint destination_origin,
std::string label) {
auto command = std::make_unique<BlitCopyBufferToTextureCommandVK>();

command->source = std::move(source);
command->destination = std::move(destination);
command->destination_origin = destination_origin;
command->label = std::move(label);

commands_.push_back(std::move(command));
return true;
}

// |BlitPass|
bool BlitPassVK::OnGenerateMipmapCommand(std::shared_ptr<Texture> texture,
std::string label) {
Expand Down
6 changes: 1 addition & 5 deletions impeller/renderer/backend/vulkan/blit_pass_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ class BlitPassVK final : public BlitPass {
bool OnCopyBufferToTextureCommand(BufferView source,
std::shared_ptr<Texture> destination,
IPoint destination_origin,
std::string label) override {
IMPELLER_UNIMPLEMENTED;
return false;
}

std::string label) override;
// |BlitPass|
bool OnGenerateMipmapCommand(std::shared_ptr<Texture> texture,
std::string label) override;
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/vulkan/capabilities_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ bool CapabilitiesVK::SupportsSSBO() const {

// |Capabilities|
bool CapabilitiesVK::SupportsBufferToTextureBlits() const {
return false;
return true;
}

// |Capabilities|
Expand Down
10 changes: 5 additions & 5 deletions impeller/renderer/backend/vulkan/command_encoder_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ class TrackedObjectsVK {
tracked_objects_.insert(std::move(object));
}

void Track(std::shared_ptr<const DeviceBuffer> buffer) {
void Track(std::shared_ptr<const Buffer> buffer) {
if (!buffer) {
return;
}
tracked_buffers_.insert(std::move(buffer));
}

bool IsTracking(const std::shared_ptr<const DeviceBuffer>& buffer) const {
bool IsTracking(const std::shared_ptr<const Buffer>& buffer) const {
if (!buffer) {
return false;
}
Expand Down Expand Up @@ -89,7 +89,7 @@ class TrackedObjectsVK {
std::weak_ptr<CommandPoolVK> pool_;
vk::UniqueCommandBuffer buffer_;
std::set<std::shared_ptr<SharedObjectVK>> tracked_objects_;
std::set<std::shared_ptr<const DeviceBuffer>> tracked_buffers_;
std::set<std::shared_ptr<const Buffer>> tracked_buffers_;
std::set<std::shared_ptr<const TextureSourceVK>> tracked_textures_;
bool is_valid_ = false;

Expand Down Expand Up @@ -202,7 +202,7 @@ bool CommandEncoderVK::Track(std::shared_ptr<SharedObjectVK> object) {
return true;
}

bool CommandEncoderVK::Track(std::shared_ptr<const DeviceBuffer> buffer) {
bool CommandEncoderVK::Track(std::shared_ptr<const Buffer> buffer) {
if (!IsValid()) {
return false;
}
Expand All @@ -211,7 +211,7 @@ bool CommandEncoderVK::Track(std::shared_ptr<const DeviceBuffer> buffer) {
}

bool CommandEncoderVK::IsTracking(
const std::shared_ptr<const DeviceBuffer>& buffer) const {
const std::shared_ptr<const Buffer>& buffer) const {
if (!IsValid()) {
return false;
}
Expand Down
8 changes: 6 additions & 2 deletions impeller/renderer/backend/vulkan/command_encoder_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ namespace impeller {
namespace testing {
class BlitCommandVkTest_BlitCopyTextureToTextureCommandVK_Test;
class BlitCommandVkTest_BlitCopyTextureToBufferCommandVK_Test;
class BlitCommandVkTest_BlitCopyBufferToTextureCommandVK_Test;
class BlitCommandVkTest_BlitGenerateMipmapCommandVK_Test;
} // namespace testing

class ContextVK;
class DeviceBuffer;
class Buffer;
class Texture;
class TextureSourceVK;
class TrackedObjectsVK;
Expand All @@ -43,9 +45,9 @@ class CommandEncoderVK {

bool Track(std::shared_ptr<SharedObjectVK> object);

bool Track(std::shared_ptr<const DeviceBuffer> buffer);
bool Track(std::shared_ptr<const Buffer> buffer);

bool IsTracking(const std::shared_ptr<const DeviceBuffer>& texture) const;
bool IsTracking(const std::shared_ptr<const Buffer>& texture) const;

bool Track(const std::shared_ptr<const Texture>& texture);

Expand All @@ -72,6 +74,8 @@ class CommandEncoderVK {
BlitCommandVkTest_BlitCopyTextureToBufferCommandVK_Test;
friend class ::impeller::testing::
BlitCommandVkTest_BlitGenerateMipmapCommandVK_Test;
friend class ::impeller::testing::
BlitCommandVkTest_BlitCopyBufferToTextureCommandVK_Test;

std::weak_ptr<const DeviceHolder> device_holder_;
std::shared_ptr<QueueVK> queue_;
Expand Down
2 changes: 1 addition & 1 deletion impeller/renderer/backend/vulkan/device_buffer_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace impeller {

class DeviceBufferVK final : public DeviceBuffer,
public BackendCast<DeviceBufferVK, DeviceBuffer> {
public BackendCast<DeviceBufferVK, Buffer> {
public:
DeviceBufferVK(DeviceBufferDescriptor desc,
std::weak_ptr<Context> context,
Expand Down
24 changes: 11 additions & 13 deletions lib/ui/painting/image_decoder_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -481,21 +481,19 @@ void ImageDecoderImpeller::Decode(fml::RefPtr<ImageDescriptor> descriptor,
}
auto upload_texture_and_invoke_result = [result, context, bitmap_result,
gpu_disabled_switch]() {
// TODO(jonahwilliams): remove ifdef once blit from buffer
// to texture is implemented on other platforms.
sk_sp<DlImage> image;
std::string decode_error;

#ifdef FML_OS_IOS
std::tie(image, decode_error) = UploadTextureToPrivate(
context, bitmap_result.device_buffer, bitmap_result.image_info,
bitmap_result.sk_bitmap, gpu_disabled_switch);
#else
std::tie(image, decode_error) =
UploadTextureToShared(context, bitmap_result.sk_bitmap,
gpu_disabled_switch, /*create_mips=*/true);
#endif // FML_OS_IOS
result(image, decode_error);
if (context->GetCapabilities()->SupportsBufferToTextureBlits()) {
std::tie(image, decode_error) = UploadTextureToPrivate(
context, bitmap_result.device_buffer, bitmap_result.image_info,
bitmap_result.sk_bitmap, gpu_disabled_switch);
result(image, decode_error);
} else {
std::tie(image, decode_error) = UploadTextureToShared(
context, bitmap_result.sk_bitmap, gpu_disabled_switch,
/*create_mips=*/true);
result(image, decode_error);
}
};
// TODO(jonahwilliams):
// https://github.com/flutter/flutter/issues/123058 Technically we
Expand Down