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 7 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 @@ -400,7 +400,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

@jonahwilliams jonahwilliams May 3, 2023

Copy link
Copy Markdown
Contributor Author

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
20 changes: 20 additions & 0 deletions impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ TEST(BlitCommandVkTest, BlitCopyTextureToBufferCommandVK) {
EXPECT_TRUE(encoder.IsTracking(cmd.destination));
}

TEST(BlitCommandVkTest, BlitCopyBufferToTextureCommandVK) {
auto context = CreateMockVulkanContext();
auto pool = CommandPoolVK::GetThreadLocal(context.get());
CommandEncoderVK encoder(context, 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 @@ -315,7 +315,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 @@ -51,14 +51,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 @@ -88,7 +88,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 @@ -185,7 +185,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 @@ -194,7 +194,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 @@ -20,11 +20,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 @@ -40,9 +42,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 @@ -69,6 +71,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
16 changes: 8 additions & 8 deletions lib/ui/painting/image_decoder_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,14 @@ void ImageDecoderImpeller::Decode(fml::RefPtr<ImageDescriptor> descriptor,
auto upload_texture_and_invoke_result = [result, context,
bitmap_result =
bitmap_result.value()]() {
// TODO(jonahwilliams): remove ifdef once blit from buffer to texture is
// implemented on other platforms.
#ifdef FML_OS_IOS
result(UploadTextureToPrivate(context, bitmap_result.device_buffer,
bitmap_result.image_info));
#else
result(UploadTextureToShared(context, bitmap_result.sk_bitmap));
#endif
// TODO(jonahwilliams): remove ifdef once blit from buffer to texture
// is implemented on other platforms.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove todo? There's no longer an ifdef.

if (context->GetCapabilities()->SupportsBufferToTextureBlits()) {
result(UploadTextureToPrivate(context, bitmap_result.device_buffer,
bitmap_result.image_info));
} else {
result(UploadTextureToShared(context, bitmap_result.sk_bitmap));
}
};
// TODO(jonahwilliams): https://github.com/flutter/flutter/issues/123058
// Technically we don't need to post tasks to the io runner, but without
Expand Down