reland: Allow BufferViews to have non-owning references to DeviceBuffers (flutter/engine#56286)
relands https://github.com/flutter/engine/pull/56224 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
bad046bd6e
commit
f81ed55e63
@ -136,6 +136,7 @@
|
||||
../../../flutter/impeller/compiler/shader_bundle_unittests.cc
|
||||
../../../flutter/impeller/compiler/switches_unittests.cc
|
||||
../../../flutter/impeller/core/allocator_unittests.cc
|
||||
../../../flutter/impeller/core/buffer_view_unittests.cc
|
||||
../../../flutter/impeller/display_list/aiks_dl_atlas_unittests.cc
|
||||
../../../flutter/impeller/display_list/aiks_dl_basic_unittests.cc
|
||||
../../../flutter/impeller/display_list/aiks_dl_blend_unittests.cc
|
||||
|
@ -42900,6 +42900,7 @@ ORIGIN: ../../../flutter/impeller/core/formats.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/formats.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/host_buffer.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/host_buffer.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/idle_waiter.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/platform.cc + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/platform.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/core/range.cc + ../../../flutter/LICENSE
|
||||
@ -45761,6 +45762,7 @@ FILE: ../../../flutter/impeller/core/formats.cc
|
||||
FILE: ../../../flutter/impeller/core/formats.h
|
||||
FILE: ../../../flutter/impeller/core/host_buffer.cc
|
||||
FILE: ../../../flutter/impeller/core/host_buffer.h
|
||||
FILE: ../../../flutter/impeller/core/idle_waiter.h
|
||||
FILE: ../../../flutter/impeller/core/platform.cc
|
||||
FILE: ../../../flutter/impeller/core/platform.h
|
||||
FILE: ../../../flutter/impeller/core/range.cc
|
||||
|
@ -18,6 +18,7 @@ impeller_component("core") {
|
||||
"formats.h",
|
||||
"host_buffer.cc",
|
||||
"host_buffer.h",
|
||||
"idle_waiter.h",
|
||||
"platform.cc",
|
||||
"platform.h",
|
||||
"range.cc",
|
||||
@ -50,7 +51,10 @@ impeller_component("core") {
|
||||
impeller_component("allocator_unittests") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "allocator_unittests.cc" ]
|
||||
sources = [
|
||||
"allocator_unittests.cc",
|
||||
"buffer_view_unittests.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":core",
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "impeller/base/allocation_size.h"
|
||||
#include "impeller/core/device_buffer_descriptor.h"
|
||||
#include "impeller/core/idle_waiter.h"
|
||||
#include "impeller/core/texture.h"
|
||||
#include "impeller/core/texture_descriptor.h"
|
||||
#include "impeller/geometry/size.h"
|
||||
|
@ -6,6 +6,29 @@
|
||||
|
||||
namespace impeller {
|
||||
|
||||
//
|
||||
BufferView::BufferView() : buffer_(nullptr), raw_buffer_(nullptr), range_({}) {}
|
||||
|
||||
BufferView::BufferView(DeviceBuffer* buffer, Range range)
|
||||
: buffer_(), raw_buffer_(buffer), range_(range) {}
|
||||
|
||||
BufferView::BufferView(std::shared_ptr<const DeviceBuffer> buffer, Range range)
|
||||
: buffer_(std::move(buffer)), raw_buffer_(nullptr), range_(range) {}
|
||||
|
||||
const DeviceBuffer* BufferView::GetBuffer() const {
|
||||
return raw_buffer_ ? raw_buffer_ : buffer_.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<const DeviceBuffer> BufferView::TakeBuffer() {
|
||||
if (buffer_) {
|
||||
raw_buffer_ = buffer_.get();
|
||||
return std::move(buffer_);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BufferView::operator bool() const {
|
||||
return buffer_ || raw_buffer_;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
@ -12,11 +12,34 @@ namespace impeller {
|
||||
|
||||
class DeviceBuffer;
|
||||
|
||||
/// A specific range in a DeviceBuffer.
|
||||
///
|
||||
/// BufferView can maintain ownership over the DeviceBuffer or not depending on
|
||||
/// if it is created with a std::shared_ptr or a raw pointer.
|
||||
struct BufferView {
|
||||
std::shared_ptr<const DeviceBuffer> buffer;
|
||||
Range range;
|
||||
public:
|
||||
BufferView();
|
||||
|
||||
constexpr explicit operator bool() const { return static_cast<bool>(buffer); }
|
||||
BufferView(DeviceBuffer* buffer, Range range);
|
||||
|
||||
BufferView(std::shared_ptr<const DeviceBuffer> buffer, Range range);
|
||||
|
||||
Range GetRange() const { return range_; }
|
||||
|
||||
const DeviceBuffer* GetBuffer() const;
|
||||
|
||||
std::shared_ptr<const DeviceBuffer> TakeBuffer();
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<const DeviceBuffer> buffer_;
|
||||
/// This is a non-owned DeviceBuffer. Steps should be taken to make sure this
|
||||
/// lives for the duration of the BufferView's life. Usually this is done
|
||||
/// automatically by the graphics API or in the case of Vulkan the HostBuffer
|
||||
/// or TrackedObjectsVK keeps it alive.
|
||||
const DeviceBuffer* raw_buffer_;
|
||||
Range range_;
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
26
engine/src/flutter/impeller/core/buffer_view_unittests.cc
Normal file
26
engine/src/flutter/impeller/core/buffer_view_unittests.cc
Normal file
@ -0,0 +1,26 @@
|
||||
// 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 "flutter/testing/testing.h"
|
||||
#include "impeller/core/buffer_view.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace testing {
|
||||
|
||||
TEST(BufferViewTest, Empty) {
|
||||
BufferView buffer_view;
|
||||
EXPECT_FALSE(buffer_view);
|
||||
}
|
||||
|
||||
TEST(BufferViewTest, TakeRaw) {
|
||||
DeviceBuffer* buffer = reinterpret_cast<DeviceBuffer*>(0xcafebabe);
|
||||
BufferView buffer_view(buffer, {0, 123});
|
||||
EXPECT_TRUE(buffer_view);
|
||||
std::shared_ptr<const DeviceBuffer> taken = buffer_view.TakeBuffer();
|
||||
EXPECT_FALSE(taken);
|
||||
EXPECT_EQ(buffer_view.GetBuffer(), buffer);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
@ -16,10 +16,8 @@ void DeviceBuffer::Invalidate(std::optional<Range> range) const {}
|
||||
|
||||
// static
|
||||
BufferView DeviceBuffer::AsBufferView(std::shared_ptr<DeviceBuffer> buffer) {
|
||||
BufferView view;
|
||||
view.buffer = std::move(buffer);
|
||||
view.range = {0u, view.buffer->desc_.size};
|
||||
return view;
|
||||
Range range = {0u, buffer->desc_.size};
|
||||
return BufferView(std::move(buffer), range);
|
||||
}
|
||||
|
||||
const DeviceBufferDescriptor& DeviceBuffer::GetDeviceBufferDescriptor() const {
|
||||
|
@ -19,12 +19,14 @@ namespace impeller {
|
||||
constexpr size_t kAllocatorBlockSize = 1024000; // 1024 Kb.
|
||||
|
||||
std::shared_ptr<HostBuffer> HostBuffer::Create(
|
||||
const std::shared_ptr<Allocator>& allocator) {
|
||||
return std::shared_ptr<HostBuffer>(new HostBuffer(allocator));
|
||||
const std::shared_ptr<Allocator>& allocator,
|
||||
const std::shared_ptr<const IdleWaiter>& idle_waiter) {
|
||||
return std::shared_ptr<HostBuffer>(new HostBuffer(allocator, idle_waiter));
|
||||
}
|
||||
|
||||
HostBuffer::HostBuffer(const std::shared_ptr<Allocator>& allocator)
|
||||
: allocator_(allocator) {
|
||||
HostBuffer::HostBuffer(const std::shared_ptr<Allocator>& allocator,
|
||||
const std::shared_ptr<const IdleWaiter>& idle_waiter)
|
||||
: allocator_(allocator), idle_waiter_(idle_waiter) {
|
||||
DeviceBufferDescriptor desc;
|
||||
desc.size = kAllocatorBlockSize;
|
||||
desc.storage_mode = StorageMode::kHostVisible;
|
||||
@ -35,34 +37,52 @@ HostBuffer::HostBuffer(const std::shared_ptr<Allocator>& allocator)
|
||||
}
|
||||
}
|
||||
|
||||
HostBuffer::~HostBuffer() = default;
|
||||
HostBuffer::~HostBuffer() {
|
||||
if (idle_waiter_) {
|
||||
// Since we hold on to DeviceBuffers we should make sure they aren't being
|
||||
// used while we are deleting the HostBuffer.
|
||||
idle_waiter_->WaitIdle();
|
||||
}
|
||||
};
|
||||
|
||||
BufferView HostBuffer::Emplace(const void* buffer,
|
||||
size_t length,
|
||||
size_t align) {
|
||||
auto [range, device_buffer] = EmplaceInternal(buffer, length, align);
|
||||
if (!device_buffer) {
|
||||
auto [range, device_buffer, raw_device_buffer] =
|
||||
EmplaceInternal(buffer, length, align);
|
||||
if (device_buffer) {
|
||||
return BufferView(std::move(device_buffer), range);
|
||||
} else if (raw_device_buffer) {
|
||||
return BufferView(raw_device_buffer, range);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return BufferView{std::move(device_buffer), range};
|
||||
}
|
||||
|
||||
BufferView HostBuffer::Emplace(const void* buffer, size_t length) {
|
||||
auto [range, device_buffer] = EmplaceInternal(buffer, length);
|
||||
if (!device_buffer) {
|
||||
auto [range, device_buffer, raw_device_buffer] =
|
||||
EmplaceInternal(buffer, length);
|
||||
if (device_buffer) {
|
||||
return BufferView(std::move(device_buffer), range);
|
||||
} else if (raw_device_buffer) {
|
||||
return BufferView(raw_device_buffer, range);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return BufferView{std::move(device_buffer), range};
|
||||
}
|
||||
|
||||
BufferView HostBuffer::Emplace(size_t length,
|
||||
size_t align,
|
||||
const EmplaceProc& cb) {
|
||||
auto [range, device_buffer] = EmplaceInternal(length, align, cb);
|
||||
if (!device_buffer) {
|
||||
auto [range, device_buffer, raw_device_buffer] =
|
||||
EmplaceInternal(length, align, cb);
|
||||
if (device_buffer) {
|
||||
return BufferView(std::move(device_buffer), range);
|
||||
} else if (raw_device_buffer) {
|
||||
return BufferView(raw_device_buffer, range);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return BufferView{std::move(device_buffer), range};
|
||||
}
|
||||
|
||||
HostBuffer::TestStateQuery HostBuffer::GetStateForTest() {
|
||||
@ -90,8 +110,8 @@ bool HostBuffer::MaybeCreateNewBuffer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
size_t length,
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
HostBuffer::EmplaceInternal(size_t length,
|
||||
size_t align,
|
||||
const EmplaceProc& cb) {
|
||||
if (!cb) {
|
||||
@ -113,7 +133,7 @@ std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
cb(device_buffer->OnGetContents());
|
||||
device_buffer->Flush(Range{0, length});
|
||||
}
|
||||
return std::make_tuple(Range{0, length}, std::move(device_buffer));
|
||||
return std::make_tuple(Range{0, length}, std::move(device_buffer), nullptr);
|
||||
}
|
||||
|
||||
size_t padding = 0;
|
||||
@ -135,12 +155,11 @@ std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
current_buffer->Flush(output_range);
|
||||
|
||||
offset_ += length;
|
||||
return std::make_tuple(output_range, current_buffer);
|
||||
return std::make_tuple(output_range, nullptr, current_buffer.get());
|
||||
}
|
||||
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
const void* buffer,
|
||||
size_t length) {
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
HostBuffer::EmplaceInternal(const void* buffer, size_t length) {
|
||||
// If the requested allocation is bigger than the block size, create a one-off
|
||||
// device buffer and write to that.
|
||||
if (length > kAllocatorBlockSize) {
|
||||
@ -158,7 +177,7 @@ std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return std::make_tuple(Range{0, length}, std::move(device_buffer));
|
||||
return std::make_tuple(Range{0, length}, std::move(device_buffer), nullptr);
|
||||
}
|
||||
|
||||
auto old_length = GetLength();
|
||||
@ -176,10 +195,11 @@ std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
|
||||
current_buffer->Flush(Range{old_length, length});
|
||||
}
|
||||
offset_ += length;
|
||||
return std::make_tuple(Range{old_length, length}, current_buffer);
|
||||
return std::make_tuple(Range{old_length, length}, nullptr,
|
||||
current_buffer.get());
|
||||
}
|
||||
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>>
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
HostBuffer::EmplaceInternal(const void* buffer, size_t length, size_t align) {
|
||||
if (align == 0 || (GetLength() % align) == 0) {
|
||||
return EmplaceInternal(buffer, length);
|
||||
|
@ -28,7 +28,8 @@ static const constexpr size_t kHostBufferArenaSize = 4u;
|
||||
class HostBuffer {
|
||||
public:
|
||||
static std::shared_ptr<HostBuffer> Create(
|
||||
const std::shared_ptr<Allocator>& allocator);
|
||||
const std::shared_ptr<Allocator>& allocator,
|
||||
const std::shared_ptr<const IdleWaiter>& idle_waiter);
|
||||
|
||||
~HostBuffer();
|
||||
|
||||
@ -133,13 +134,13 @@ class HostBuffer {
|
||||
TestStateQuery GetStateForTest();
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::tuple<Range, std::shared_ptr<DeviceBuffer>>
|
||||
[[nodiscard]] std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
EmplaceInternal(const void* buffer, size_t length);
|
||||
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>>
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
EmplaceInternal(size_t length, size_t align, const EmplaceProc& cb);
|
||||
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>>
|
||||
std::tuple<Range, std::shared_ptr<DeviceBuffer>, DeviceBuffer*>
|
||||
EmplaceInternal(const void* buffer, size_t length, size_t align);
|
||||
|
||||
size_t GetLength() const { return offset_; }
|
||||
@ -154,13 +155,15 @@ class HostBuffer {
|
||||
|
||||
[[nodiscard]] BufferView Emplace(const void* buffer, size_t length);
|
||||
|
||||
explicit HostBuffer(const std::shared_ptr<Allocator>& allocator);
|
||||
explicit HostBuffer(const std::shared_ptr<Allocator>& allocator,
|
||||
const std::shared_ptr<const IdleWaiter>& idle_waiter);
|
||||
|
||||
HostBuffer(const HostBuffer&) = delete;
|
||||
|
||||
HostBuffer& operator=(const HostBuffer&) = delete;
|
||||
|
||||
std::shared_ptr<Allocator> allocator_;
|
||||
std::shared_ptr<const IdleWaiter> idle_waiter_;
|
||||
std::array<std::vector<std::shared_ptr<DeviceBuffer>>, kHostBufferArenaSize>
|
||||
device_buffers_;
|
||||
size_t current_buffer_ = 0u;
|
||||
|
25
engine/src/flutter/impeller/core/idle_waiter.h
Normal file
25
engine/src/flutter/impeller/core/idle_waiter.h
Normal file
@ -0,0 +1,25 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_
|
||||
#define FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_
|
||||
|
||||
namespace impeller {
|
||||
|
||||
/// Abstraction over waiting for the GPU to be idle.
|
||||
///
|
||||
/// This is important for platforms like Vulkan where we need to make sure
|
||||
/// we aren't deleting resources while the GPU is using them.
|
||||
class IdleWaiter {
|
||||
public:
|
||||
virtual ~IdleWaiter() = default;
|
||||
|
||||
/// Wait for the GPU tasks to finish.
|
||||
/// This is a noop on some platforms, it's important for Vulkan.
|
||||
virtual void WaitIdle() const = 0;
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
#endif // FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_
|
@ -250,7 +250,8 @@ ContentContext::ContentContext(
|
||||
? std::make_shared<RenderTargetCache>(
|
||||
context_->GetResourceAllocator())
|
||||
: std::move(render_target_allocator)),
|
||||
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())) {
|
||||
host_buffer_(HostBuffer::Create(context_->GetResourceAllocator(),
|
||||
context_->GetIdleWaiter())) {
|
||||
if (!context_ || !context_->IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ TEST_P(BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4) {
|
||||
uint8_t byte = 0xff;
|
||||
BufferView buffer_view =
|
||||
renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1);
|
||||
EXPECT_EQ(buffer_view.range.offset, 4u);
|
||||
EXPECT_EQ(buffer_view.range.length, 1u);
|
||||
EXPECT_EQ(buffer_view.GetRange().offset, 4u);
|
||||
EXPECT_EQ(buffer_view.GetRange().length, 1u);
|
||||
Entity entity;
|
||||
|
||||
std::optional<Entity> result = filter_contents.GetEntity(
|
||||
|
@ -4,30 +4,48 @@
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "impeller/base/validation.h"
|
||||
#include "impeller/core/allocator.h"
|
||||
#include "impeller/core/host_buffer.h"
|
||||
#include "impeller/core/idle_waiter.h"
|
||||
#include "impeller/entity/entity_playground.h"
|
||||
|
||||
namespace impeller {
|
||||
namespace testing {
|
||||
|
||||
class MockIdleWaiter : public IdleWaiter {
|
||||
public:
|
||||
MOCK_METHOD(void, WaitIdle, (), (const, override));
|
||||
};
|
||||
|
||||
using HostBufferTest = EntityPlayground;
|
||||
INSTANTIATE_PLAYGROUND_SUITE(HostBufferTest);
|
||||
|
||||
TEST_P(HostBufferTest, IdleWaiter) {
|
||||
auto mock_idle_waiter = std::make_shared<MockIdleWaiter>();
|
||||
{
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
mock_idle_waiter);
|
||||
EXPECT_CALL(*mock_idle_waiter, WaitIdle());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, CanEmplace) {
|
||||
struct Length2 {
|
||||
uint8_t pad[2];
|
||||
};
|
||||
static_assert(sizeof(Length2) == 2u);
|
||||
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
for (size_t i = 0; i < 12500; i++) {
|
||||
auto view = buffer->Emplace(Length2{});
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u));
|
||||
ASSERT_EQ(view.GetRange(), Range(i * sizeof(Length2), 2u));
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,37 +60,39 @@ TEST_P(HostBufferTest, CanEmplaceWithAlignment) {
|
||||
static_assert(alignof(Align16) == 16);
|
||||
static_assert(sizeof(Align16) == 16);
|
||||
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
ASSERT_TRUE(buffer);
|
||||
|
||||
{
|
||||
auto view = buffer->Emplace(Length2{});
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.range, Range(0u, 2u));
|
||||
ASSERT_EQ(view.GetRange(), Range(0u, 2u));
|
||||
}
|
||||
|
||||
{
|
||||
auto view = buffer->Emplace(Align16{});
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.range.offset, 16u);
|
||||
ASSERT_EQ(view.range.length, 16u);
|
||||
ASSERT_EQ(view.GetRange().offset, 16u);
|
||||
ASSERT_EQ(view.GetRange().length, 16u);
|
||||
}
|
||||
{
|
||||
auto view = buffer->Emplace(Length2{});
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.range, Range(32u, 2u));
|
||||
ASSERT_EQ(view.GetRange(), Range(32u, 2u));
|
||||
}
|
||||
|
||||
{
|
||||
auto view = buffer->Emplace(Align16{});
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.range.offset, 48u);
|
||||
ASSERT_EQ(view.range.length, 16u);
|
||||
ASSERT_EQ(view.GetRange().offset, 48u);
|
||||
ASSERT_EQ(view.GetRange().length, 16u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, HostBufferInitialState) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
|
||||
EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
|
||||
@ -80,7 +100,8 @@ TEST_P(HostBufferTest, HostBufferInitialState) {
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, ResetIncrementsFrameCounter) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
|
||||
|
||||
@ -99,7 +120,8 @@ TEST_P(HostBufferTest, ResetIncrementsFrameCounter) {
|
||||
|
||||
TEST_P(HostBufferTest,
|
||||
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
// Emplace an amount larger than the block size, to verify that the host
|
||||
// buffer does not create a buffer.
|
||||
@ -111,7 +133,8 @@ TEST_P(HostBufferTest,
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
// Emplace an amount larger than the block size, to verify that the host
|
||||
// buffer does not create a buffer.
|
||||
@ -123,7 +146,8 @@ TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer) {
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
// Emplace two large allocations to force the allocation of a second buffer.
|
||||
auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
|
||||
@ -154,13 +178,14 @@ TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) {
|
||||
}
|
||||
|
||||
TEST_P(HostBufferTest, EmplaceWithProcIsAligned) {
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
BufferView view = buffer->Emplace(std::array<char, 21>());
|
||||
EXPECT_EQ(view.range, Range(0, 21));
|
||||
EXPECT_EQ(view.GetRange(), Range(0, 21));
|
||||
|
||||
view = buffer->Emplace(64, 16, [](uint8_t*) {});
|
||||
EXPECT_EQ(view.range, Range(32, 64));
|
||||
EXPECT_EQ(view.GetRange(), Range(32, 64));
|
||||
}
|
||||
|
||||
static constexpr const size_t kMagicFailingAllocation = 1024000 * 2;
|
||||
@ -197,13 +222,13 @@ TEST_P(HostBufferTest, EmplaceWithFailingAllocationDoesntCrash) {
|
||||
ScopedValidationDisable disable;
|
||||
std::shared_ptr<FailingAllocator> allocator =
|
||||
std::make_shared<FailingAllocator>(GetContext()->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(allocator);
|
||||
auto buffer = HostBuffer::Create(allocator, GetContext()->GetIdleWaiter());
|
||||
|
||||
auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0);
|
||||
|
||||
EXPECT_EQ(view.buffer, nullptr);
|
||||
EXPECT_EQ(view.range.offset, 0u);
|
||||
EXPECT_EQ(view.range.length, 0u);
|
||||
EXPECT_EQ(view.GetBuffer(), nullptr);
|
||||
EXPECT_EQ(view.GetRange().offset, 0u);
|
||||
EXPECT_EQ(view.GetRange().length, 0u);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
@ -1863,7 +1863,8 @@ TEST_P(EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct) {
|
||||
// 8 bytes for iResolution
|
||||
// 4 bytes for iTime
|
||||
// 4 bytes padding
|
||||
EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
|
||||
EXPECT_EQ(
|
||||
command.fragment_bindings.buffers[0].view.resource.GetRange().length,
|
||||
16u);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,8 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data,
|
||||
return; // Nothing to render.
|
||||
}
|
||||
auto host_buffer = impeller::HostBuffer::Create(
|
||||
render_pass.GetContext()->GetResourceAllocator());
|
||||
render_pass.GetContext()->GetResourceAllocator(),
|
||||
render_pass.GetContext()->GetIdleWaiter());
|
||||
|
||||
using VS = impeller::ImguiRasterVertexShader;
|
||||
using FS = impeller::ImguiRasterFragmentShader;
|
||||
@ -265,14 +266,12 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data,
|
||||
vertex_buffer_offset + pcmd->VtxOffset * sizeof(ImDrawVert);
|
||||
|
||||
impeller::VertexBuffer vertex_buffer;
|
||||
vertex_buffer.vertex_buffer = impeller::BufferView{
|
||||
.buffer = buffer,
|
||||
.range = impeller::Range(vb_start, draw_list_vtx_bytes - vb_start)};
|
||||
vertex_buffer.index_buffer = {
|
||||
.buffer = buffer,
|
||||
.range = impeller::Range(
|
||||
index_buffer_offset + pcmd->IdxOffset * sizeof(ImDrawIdx),
|
||||
pcmd->ElemCount * sizeof(ImDrawIdx))};
|
||||
vertex_buffer.vertex_buffer = impeller::BufferView(
|
||||
buffer, impeller::Range(vb_start, draw_list_vtx_bytes - vb_start));
|
||||
vertex_buffer.index_buffer = impeller::BufferView(
|
||||
buffer, impeller::Range(index_buffer_offset +
|
||||
pcmd->IdxOffset * sizeof(ImDrawIdx),
|
||||
pcmd->ElemCount * sizeof(ImDrawIdx)));
|
||||
vertex_buffer.vertex_count = pcmd->ElemCount;
|
||||
vertex_buffer.index_type = impeller::IndexType::k16bit;
|
||||
render_pass.SetVertexBuffer(std::move(vertex_buffer));
|
||||
|
@ -220,7 +220,7 @@ bool BlitCopyBufferToTextureCommandGLES::Encode(
|
||||
}
|
||||
|
||||
if (!tex_descriptor.IsValid() ||
|
||||
source.range.length !=
|
||||
source.GetRange().length !=
|
||||
BytesPerPixelForPixelFormat(tex_descriptor.format) *
|
||||
destination_region.Area()) {
|
||||
return false;
|
||||
@ -263,8 +263,8 @@ bool BlitCopyBufferToTextureCommandGLES::Encode(
|
||||
}
|
||||
const auto& gl = reactor.GetProcTable();
|
||||
gl.BindTexture(texture_type, gl_handle.value());
|
||||
const GLvoid* tex_data =
|
||||
data.buffer_view.buffer->OnGetContents() + data.buffer_view.range.offset;
|
||||
const GLvoid* tex_data = data.buffer_view.GetBuffer()->OnGetContents() +
|
||||
data.buffer_view.GetRange().offset;
|
||||
|
||||
// GL_INVALID_OPERATION if the texture array has not been
|
||||
// defined by a previous glTexImage2D operation.
|
||||
|
@ -276,14 +276,14 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl,
|
||||
Allocator& transients_allocator,
|
||||
const BufferResource& buffer) {
|
||||
const auto* metadata = buffer.GetMetadata();
|
||||
auto device_buffer = buffer.resource.buffer;
|
||||
auto device_buffer = buffer.resource.GetBuffer();
|
||||
if (!device_buffer) {
|
||||
VALIDATION_LOG << "Device buffer not found.";
|
||||
return false;
|
||||
}
|
||||
const auto& device_buffer_gles = DeviceBufferGLES::Cast(*device_buffer);
|
||||
const uint8_t* buffer_ptr =
|
||||
device_buffer_gles.GetBufferData() + buffer.resource.range.offset;
|
||||
device_buffer_gles.GetBufferData() + buffer.resource.GetRange().offset;
|
||||
|
||||
if (metadata->members.empty()) {
|
||||
VALIDATION_LOG << "Uniform buffer had no members. This is currently "
|
||||
|
@ -149,7 +149,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto vertex_buffer = vertex_buffer_view.buffer;
|
||||
const DeviceBuffer* vertex_buffer = vertex_buffer_view.GetBuffer();
|
||||
|
||||
if (!vertex_buffer) {
|
||||
return false;
|
||||
@ -165,7 +165,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl,
|
||||
/// Bind the vertex attributes associated with vertex buffer.
|
||||
///
|
||||
if (!vertex_desc_gles->BindVertexAttributes(
|
||||
gl, buffer_index, vertex_buffer_view.range.offset)) {
|
||||
gl, buffer_index, vertex_buffer_view.GetRange().offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -459,7 +459,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl,
|
||||
} else {
|
||||
// Bind the index buffer if necessary.
|
||||
auto index_buffer_view = command.index_buffer;
|
||||
auto index_buffer = index_buffer_view.buffer;
|
||||
const DeviceBuffer* index_buffer = index_buffer_view.GetBuffer();
|
||||
const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer);
|
||||
if (!index_buffer_gles.BindAndUploadDataIfNecessary(
|
||||
DeviceBufferGLES::BindingType::kElementArrayBuffer)) {
|
||||
@ -469,7 +469,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl,
|
||||
command.element_count, // count
|
||||
ToIndexType(command.index_type), // type
|
||||
reinterpret_cast<const GLvoid*>(static_cast<GLsizei>(
|
||||
index_buffer_view.range.offset)) // indices
|
||||
index_buffer_view.GetRange().offset)) // indices
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ bool BlitPassMTL::OnCopyBufferToTextureCommand(
|
||||
uint32_t mip_level,
|
||||
uint32_t slice,
|
||||
bool convert_to_read) {
|
||||
auto source_mtl = DeviceBufferMTL::Cast(*source.buffer).GetMTLBuffer();
|
||||
auto source_mtl = DeviceBufferMTL::Cast(*source.GetBuffer()).GetMTLBuffer();
|
||||
if (!source_mtl) {
|
||||
return false;
|
||||
}
|
||||
@ -221,7 +221,7 @@ bool BlitPassMTL::OnCopyBufferToTextureCommand(
|
||||
#endif // IMPELLER_DEBUG
|
||||
[encoder_
|
||||
copyFromBuffer:source_mtl
|
||||
sourceOffset:source.range.offset
|
||||
sourceOffset:source.GetRange().offset
|
||||
sourceBytesPerRow:source_bytes_per_row
|
||||
sourceBytesPerImage:
|
||||
0 // 0 for 2D textures according to
|
||||
|
@ -84,11 +84,11 @@ bool ComputePassMTL::BindResource(ShaderStage stage,
|
||||
const ShaderUniformSlot& slot,
|
||||
const ShaderMetadata& metadata,
|
||||
BufferView view) {
|
||||
if (!view.buffer) {
|
||||
if (!view.GetBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const DeviceBuffer>& device_buffer = view.buffer;
|
||||
const DeviceBuffer* device_buffer = view.GetBuffer();
|
||||
if (!device_buffer) {
|
||||
return false;
|
||||
}
|
||||
@ -99,7 +99,8 @@ bool ComputePassMTL::BindResource(ShaderStage stage,
|
||||
return false;
|
||||
}
|
||||
|
||||
pass_bindings_cache_.SetBuffer(slot.ext_res_0, view.range.offset, buffer);
|
||||
pass_bindings_cache_.SetBuffer(slot.ext_res_0, view.GetRange().offset,
|
||||
buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -189,11 +189,11 @@ static bool Bind(PassBindingsCacheMTL& pass,
|
||||
ShaderStage stage,
|
||||
size_t bind_index,
|
||||
const BufferView& view) {
|
||||
if (!view.buffer) {
|
||||
if (!view.GetBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto device_buffer = view.buffer;
|
||||
const DeviceBuffer* device_buffer = view.GetBuffer();
|
||||
if (!device_buffer) {
|
||||
return false;
|
||||
}
|
||||
@ -204,7 +204,7 @@ static bool Bind(PassBindingsCacheMTL& pass,
|
||||
return false;
|
||||
}
|
||||
|
||||
return pass.SetBuffer(stage, bind_index, view.range.offset, buffer);
|
||||
return pass.SetBuffer(stage, bind_index, view.GetRange().offset, buffer);
|
||||
}
|
||||
|
||||
static bool Bind(PassBindingsCacheMTL& pass,
|
||||
@ -346,13 +346,13 @@ fml::Status RenderPassMTL::Draw() {
|
||||
}
|
||||
} else {
|
||||
id<MTLBuffer> mtl_index_buffer =
|
||||
DeviceBufferMTL::Cast(*index_buffer_.buffer).GetMTLBuffer();
|
||||
DeviceBufferMTL::Cast(*index_buffer_.GetBuffer()).GetMTLBuffer();
|
||||
if (instance_count_ != 1u) {
|
||||
[encoder_ drawIndexedPrimitives:ToMTLPrimitiveType(primitive_type_)
|
||||
indexCount:vertex_count_
|
||||
indexType:index_type_
|
||||
indexBuffer:mtl_index_buffer
|
||||
indexBufferOffset:index_buffer_.range.offset
|
||||
indexBufferOffset:index_buffer_.GetRange().offset
|
||||
instanceCount:instance_count_
|
||||
baseVertex:base_vertex_
|
||||
baseInstance:0u];
|
||||
@ -361,7 +361,7 @@ fml::Status RenderPassMTL::Draw() {
|
||||
indexCount:vertex_count_
|
||||
indexType:index_type_
|
||||
indexBuffer:mtl_index_buffer
|
||||
indexBufferOffset:index_buffer_.range.offset];
|
||||
indexBufferOffset:index_buffer_.GetRange().offset];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,9 +248,10 @@ bool BlitPassVK::OnCopyBufferToTextureCommand(
|
||||
|
||||
// cast destination to TextureVK
|
||||
const auto& dst = TextureVK::Cast(*destination);
|
||||
const auto& src = DeviceBufferVK::Cast(*source.buffer);
|
||||
const auto& src = DeviceBufferVK::Cast(*source.GetBuffer());
|
||||
|
||||
if (!command_buffer_->Track(source.buffer) ||
|
||||
std::shared_ptr<const DeviceBuffer> source_buffer = source.TakeBuffer();
|
||||
if ((source_buffer && !command_buffer_->Track(source_buffer)) ||
|
||||
!command_buffer_->Track(destination)) {
|
||||
return false;
|
||||
}
|
||||
@ -266,7 +267,7 @@ bool BlitPassVK::OnCopyBufferToTextureCommand(
|
||||
vk::PipelineStageFlagBits::eTransfer;
|
||||
|
||||
vk::BufferImageCopy image_copy;
|
||||
image_copy.setBufferOffset(source.range.offset);
|
||||
image_copy.setBufferOffset(source.GetRange().offset);
|
||||
image_copy.setBufferRowLength(0);
|
||||
image_copy.setBufferImageHeight(0);
|
||||
image_copy.setImageSubresource(vk::ImageSubresourceLayers(
|
||||
|
@ -178,27 +178,27 @@ bool ComputePassVK::BindResource(
|
||||
|
||||
bool ComputePassVK::BindResource(size_t binding,
|
||||
DescriptorType type,
|
||||
const BufferView& view) {
|
||||
BufferView view) {
|
||||
if (bound_buffer_offset_ >= kMaxBindings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const DeviceBuffer>& device_buffer = view.buffer;
|
||||
auto buffer = DeviceBufferVK::Cast(*device_buffer).GetBuffer();
|
||||
auto buffer = DeviceBufferVK::Cast(*view.GetBuffer()).GetBuffer();
|
||||
if (!buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!command_buffer_->Track(device_buffer)) {
|
||||
std::shared_ptr<const DeviceBuffer> device_buffer = view.TakeBuffer();
|
||||
if (device_buffer && !command_buffer_->Track(device_buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = view.range.offset;
|
||||
uint32_t offset = view.GetRange().offset;
|
||||
|
||||
vk::DescriptorBufferInfo buffer_info;
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = view.range.length;
|
||||
buffer_info.range = view.GetRange().length;
|
||||
buffer_workspace_[bound_buffer_offset_++] = buffer_info;
|
||||
|
||||
vk::WriteDescriptorSet write_set;
|
||||
|
@ -82,9 +82,7 @@ class ComputePassVK final : public ComputePass {
|
||||
std::shared_ptr<const Texture> texture,
|
||||
const std::unique_ptr<const Sampler>& sampler) override;
|
||||
|
||||
bool BindResource(size_t binding,
|
||||
DescriptorType type,
|
||||
const BufferView& view);
|
||||
bool BindResource(size_t binding, DescriptorType type, BufferView view);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
@ -456,6 +456,7 @@ void ContextVK::Setup(Settings settings) {
|
||||
/// All done!
|
||||
///
|
||||
device_holder_ = std::move(device_holder);
|
||||
idle_waiter_vk_ = std::make_shared<IdleWaiterVK>(device_holder_);
|
||||
driver_info_ =
|
||||
std::make_unique<DriverInfoVK>(device_holder_->physical_device);
|
||||
debug_report_ = std::move(debug_report);
|
||||
|
@ -41,6 +41,24 @@ class DescriptorPoolRecyclerVK;
|
||||
class CommandQueueVK;
|
||||
class DescriptorPoolVK;
|
||||
|
||||
class IdleWaiterVK : public IdleWaiter {
|
||||
public:
|
||||
explicit IdleWaiterVK(std::weak_ptr<DeviceHolderVK> device_holder)
|
||||
: device_holder_(std::move(device_holder)) {}
|
||||
|
||||
void WaitIdle() const override {
|
||||
std::shared_ptr<DeviceHolderVK> strong_device_holder_ =
|
||||
device_holder_.lock();
|
||||
if (strong_device_holder_ && strong_device_holder_->GetDevice()) {
|
||||
[[maybe_unused]] auto result =
|
||||
strong_device_holder_->GetDevice().waitIdle();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::weak_ptr<DeviceHolderVK> device_holder_;
|
||||
};
|
||||
|
||||
class ContextVK final : public Context,
|
||||
public BackendCast<ContextVK, Context>,
|
||||
public std::enable_shared_from_this<ContextVK> {
|
||||
@ -211,6 +229,10 @@ class ContextVK final : public Context,
|
||||
// | Context |
|
||||
bool FlushCommandBuffers() override;
|
||||
|
||||
std::shared_ptr<const IdleWaiter> GetIdleWaiter() const override {
|
||||
return idle_waiter_vk_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DeviceHolderImpl : public DeviceHolderVK {
|
||||
// |DeviceHolder|
|
||||
@ -251,6 +273,7 @@ class ContextVK final : public Context,
|
||||
std::shared_ptr<fml::ConcurrentMessageLoop> raster_message_loop_;
|
||||
std::shared_ptr<GPUTracerVK> gpu_tracer_;
|
||||
std::shared_ptr<CommandQueue> command_queue_vk_;
|
||||
std::shared_ptr<const IdleWaiter> idle_waiter_vk_;
|
||||
|
||||
using DescriptorPoolMap =
|
||||
std::unordered_map<std::thread::id, std::shared_ptr<DescriptorPoolVK>>;
|
||||
|
@ -377,9 +377,14 @@ bool RenderPassVK::SetVertexBuffer(BufferView vertex_buffers[],
|
||||
vk::Buffer buffers[kMaxVertexBuffers];
|
||||
vk::DeviceSize vertex_buffer_offsets[kMaxVertexBuffers];
|
||||
for (size_t i = 0; i < vertex_buffer_count; i++) {
|
||||
buffers[i] = DeviceBufferVK::Cast(*vertex_buffers[i].buffer).GetBuffer();
|
||||
vertex_buffer_offsets[i] = vertex_buffers[i].range.offset;
|
||||
command_buffer_->Track(vertex_buffers[i].buffer);
|
||||
buffers[i] =
|
||||
DeviceBufferVK::Cast(*vertex_buffers[i].GetBuffer()).GetBuffer();
|
||||
vertex_buffer_offsets[i] = vertex_buffers[i].GetRange().offset;
|
||||
std::shared_ptr<const DeviceBuffer> device_buffer =
|
||||
vertex_buffers[i].TakeBuffer();
|
||||
if (device_buffer) {
|
||||
command_buffer_->Track(device_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the vertex buffers.
|
||||
@ -399,27 +404,27 @@ bool RenderPassVK::SetIndexBuffer(BufferView index_buffer,
|
||||
if (index_type != IndexType::kNone) {
|
||||
has_index_buffer_ = true;
|
||||
|
||||
const BufferView& index_buffer_view = index_buffer;
|
||||
BufferView index_buffer_view = std::move(index_buffer);
|
||||
if (!index_buffer_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const DeviceBuffer>& index_buffer =
|
||||
index_buffer_view.buffer;
|
||||
if (!index_buffer) {
|
||||
if (!index_buffer_view.GetBuffer()) {
|
||||
VALIDATION_LOG << "Failed to acquire device buffer"
|
||||
<< " for index buffer view";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!command_buffer_->Track(index_buffer)) {
|
||||
std::shared_ptr<const DeviceBuffer> index_buffer =
|
||||
index_buffer_view.TakeBuffer();
|
||||
if (index_buffer && !command_buffer_->Track(index_buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vk::Buffer index_buffer_handle =
|
||||
DeviceBufferVK::Cast(*index_buffer).GetBuffer();
|
||||
DeviceBufferVK::Cast(*index_buffer_view.GetBuffer()).GetBuffer();
|
||||
command_buffer_vk_.bindIndexBuffer(index_buffer_handle,
|
||||
index_buffer_view.range.offset,
|
||||
index_buffer_view.GetRange().offset,
|
||||
ToVKIndexType(index_type));
|
||||
} else {
|
||||
has_index_buffer_ = false;
|
||||
@ -555,27 +560,27 @@ bool RenderPassVK::BindResource(
|
||||
|
||||
bool RenderPassVK::BindResource(size_t binding,
|
||||
DescriptorType type,
|
||||
const BufferView& view) {
|
||||
BufferView view) {
|
||||
if (bound_buffer_offset_ >= kMaxBindings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const DeviceBuffer>& device_buffer = view.buffer;
|
||||
auto buffer = DeviceBufferVK::Cast(*device_buffer).GetBuffer();
|
||||
auto buffer = DeviceBufferVK::Cast(*view.GetBuffer()).GetBuffer();
|
||||
if (!buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!command_buffer_->Track(device_buffer)) {
|
||||
std::shared_ptr<const DeviceBuffer> device_buffer = view.TakeBuffer();
|
||||
if (device_buffer && !command_buffer_->Track(device_buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = view.range.offset;
|
||||
uint32_t offset = view.GetRange().offset;
|
||||
|
||||
vk::DescriptorBufferInfo buffer_info;
|
||||
buffer_info.buffer = buffer;
|
||||
buffer_info.offset = offset;
|
||||
buffer_info.range = view.range.length;
|
||||
buffer_info.range = view.GetRange().length;
|
||||
buffer_workspace_[bound_buffer_offset_++] = buffer_info;
|
||||
|
||||
vk::WriteDescriptorSet write_set;
|
||||
|
@ -117,9 +117,7 @@ class RenderPassVK final : public RenderPass {
|
||||
std::shared_ptr<const Texture> texture,
|
||||
const std::unique_ptr<const Sampler>& sampler) override;
|
||||
|
||||
bool BindResource(size_t binding,
|
||||
DescriptorType type,
|
||||
const BufferView& view);
|
||||
bool BindResource(size_t binding, DescriptorType type, BufferView view);
|
||||
|
||||
// |RenderPass|
|
||||
bool IsValid() const override;
|
||||
|
@ -58,6 +58,10 @@ const std::shared_ptr<const Capabilities>& SurfaceContextVK::GetCapabilities()
|
||||
return parent_->GetCapabilities();
|
||||
}
|
||||
|
||||
std::shared_ptr<const IdleWaiter> SurfaceContextVK::GetIdleWaiter() const {
|
||||
return parent_->GetIdleWaiter();
|
||||
}
|
||||
|
||||
void SurfaceContextVK::Shutdown() {
|
||||
parent_->Shutdown();
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ class SurfaceContextVK : public Context,
|
||||
// |Context|
|
||||
std::shared_ptr<CommandQueue> GetCommandQueue() const override;
|
||||
|
||||
std::shared_ptr<const IdleWaiter> GetIdleWaiter() const override;
|
||||
|
||||
// |Context|
|
||||
void Shutdown() override;
|
||||
|
||||
|
@ -146,7 +146,7 @@ bool BlitPass::AddCopy(BufferView source,
|
||||
BytesPerPixelForPixelFormat(destination->GetTextureDescriptor().format);
|
||||
auto bytes_per_region = destination_region_value.Area() * bytes_per_pixel;
|
||||
|
||||
if (source.range.length != bytes_per_region) {
|
||||
if (source.GetRange().length != bytes_per_region) {
|
||||
VALIDATION_LOG
|
||||
<< "Attempted to add a texture blit with out of bounds access.";
|
||||
return false;
|
||||
|
@ -30,7 +30,8 @@ TEST_P(ComputeTest, CapabilitiesReportSupport) {
|
||||
TEST_P(ComputeTest, CanCreateComputePass) {
|
||||
using CS = SampleComputeShader;
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
|
||||
@ -84,7 +85,7 @@ TEST_P(ComputeTest, CanCreateComputePass) {
|
||||
EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
|
||||
|
||||
auto view = DeviceBuffer::AsBufferView(output_buffer);
|
||||
EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
|
||||
EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
|
||||
|
||||
CS::Output<kCount>* output =
|
||||
reinterpret_cast<CS::Output<kCount>*>(
|
||||
@ -109,7 +110,8 @@ TEST_P(ComputeTest, CanCreateComputePass) {
|
||||
TEST_P(ComputeTest, CanComputePrefixSum) {
|
||||
using CS = PrefixSumTestComputeShader;
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
|
||||
@ -152,7 +154,7 @@ TEST_P(ComputeTest, CanComputePrefixSum) {
|
||||
EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
|
||||
|
||||
auto view = DeviceBuffer::AsBufferView(output_buffer);
|
||||
EXPECT_EQ(view.range.length,
|
||||
EXPECT_EQ(view.GetRange().length,
|
||||
sizeof(CS::OutputData<kCount>));
|
||||
|
||||
CS::OutputData<kCount>* output =
|
||||
@ -210,7 +212,7 @@ TEST_P(ComputeTest, 1DThreadgroupSizingIsCorrect) {
|
||||
EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
|
||||
|
||||
auto view = DeviceBuffer::AsBufferView(output_buffer);
|
||||
EXPECT_EQ(view.range.length,
|
||||
EXPECT_EQ(view.GetRange().length,
|
||||
sizeof(CS::OutputData<kCount>));
|
||||
|
||||
CS::OutputData<kCount>* output =
|
||||
@ -229,7 +231,8 @@ TEST_P(ComputeTest, CanComputePrefixSumLargeInteractive) {
|
||||
using CS = PrefixSumTestComputeShader;
|
||||
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
@ -275,7 +278,8 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) {
|
||||
using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
|
||||
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
|
||||
@ -373,7 +377,8 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) {
|
||||
TEST_P(ComputeTest, CanCompute1DimensionalData) {
|
||||
using CS = SampleComputeShader;
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
|
||||
@ -427,7 +432,7 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) {
|
||||
EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
|
||||
|
||||
auto view = DeviceBuffer::AsBufferView(output_buffer);
|
||||
EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
|
||||
EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
|
||||
|
||||
CS::Output<kCount>* output =
|
||||
reinterpret_cast<CS::Output<kCount>*>(
|
||||
@ -452,7 +457,8 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) {
|
||||
TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) {
|
||||
using CS = SampleComputeShader;
|
||||
auto context = GetContext();
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
ASSERT_TRUE(context);
|
||||
ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
|
||||
|
||||
|
@ -222,6 +222,10 @@ class Context {
|
||||
/// rendering a 2D workload.
|
||||
[[nodiscard]] virtual bool FlushCommandBuffers();
|
||||
|
||||
virtual std::shared_ptr<const IdleWaiter> GetIdleWaiter() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
Context();
|
||||
|
||||
|
@ -224,7 +224,8 @@ class RendererDartTest : public PlaygroundTest,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
|
||||
*context->GetResourceAllocator()));
|
||||
|
@ -80,7 +80,8 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) {
|
||||
context->GetSamplerLibrary()->GetSampler({});
|
||||
ASSERT_TRUE(sampler);
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
static bool wireframe;
|
||||
@ -145,7 +146,8 @@ TEST_P(RendererTest, BabysFirstTriangle) {
|
||||
auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
|
||||
|
||||
// Create a host side buffer to build the vertex and uniform information.
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
// Specify the vertex buffer information.
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
|
||||
@ -165,7 +167,8 @@ TEST_P(RendererTest, BabysFirstTriangle) {
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF();
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
|
||||
|
||||
return pass.Draw().ok();
|
||||
@ -241,7 +244,8 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) {
|
||||
ASSERT_TRUE(sampler);
|
||||
|
||||
Vector3 euler_angles;
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
static Degrees fov_y(60);
|
||||
static Scalar distance = 10;
|
||||
@ -255,17 +259,14 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) {
|
||||
pass.SetPipeline(pipeline);
|
||||
|
||||
std::array<BufferView, 2> vertex_buffers = {
|
||||
BufferView{
|
||||
.buffer = device_buffer,
|
||||
.range = Range(offsetof(Cube, positions), sizeof(Cube::positions))},
|
||||
BufferView{
|
||||
.buffer = device_buffer,
|
||||
.range = Range(offsetof(Cube, colors), sizeof(Cube::colors))},
|
||||
BufferView(device_buffer,
|
||||
Range(offsetof(Cube, positions), sizeof(Cube::positions))),
|
||||
BufferView(device_buffer,
|
||||
Range(offsetof(Cube, colors), sizeof(Cube::colors))),
|
||||
};
|
||||
|
||||
BufferView index_buffer = {
|
||||
.buffer = device_buffer,
|
||||
.range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
|
||||
BufferView index_buffer(
|
||||
device_buffer, Range(offsetof(Cube, indices), sizeof(Cube::indices)));
|
||||
pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
|
||||
pass.SetElementCount(36);
|
||||
pass.SetIndexBuffer(index_buffer, IndexType::k16bit);
|
||||
@ -324,7 +325,8 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) {
|
||||
context->GetSamplerLibrary()->GetSampler({});
|
||||
ASSERT_TRUE(sampler);
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
for (size_t i = 0; i < 1; i++) {
|
||||
for (size_t j = 0; j < 1; j++) {
|
||||
@ -377,7 +379,8 @@ TEST_P(RendererTest, CanRenderToTexture) {
|
||||
auto box_pipeline =
|
||||
context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
|
||||
ASSERT_TRUE(box_pipeline);
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
vertex_builder.SetLabel("Box");
|
||||
@ -499,7 +502,8 @@ TEST_P(RendererTest, CanRenderInstanced) {
|
||||
instances.colors[i] = Color::Random();
|
||||
}
|
||||
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
|
||||
pass.SetPipeline(pipeline);
|
||||
pass.SetCommandLabel("InstancedDraw");
|
||||
@ -570,7 +574,8 @@ TEST_P(RendererTest, CanBlitTextureToTexture) {
|
||||
vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
|
||||
ASSERT_TRUE(vertex_buffer);
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
Playground::RenderCallback callback = [&](RenderTarget& render_target) {
|
||||
auto buffer = context->CreateCommandBuffer();
|
||||
if (!buffer) {
|
||||
@ -690,7 +695,8 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) {
|
||||
vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
|
||||
ASSERT_TRUE(vertex_buffer);
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
Playground::RenderCallback callback = [&](RenderTarget& render_target) {
|
||||
{
|
||||
auto buffer = context->CreateCommandBuffer();
|
||||
@ -751,7 +757,7 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) {
|
||||
auto texture =
|
||||
context->GetResourceAllocator()->CreateTexture(texture_desc);
|
||||
if (!texture->SetContents(device_buffer->OnGetContents(),
|
||||
buffer_view.range.length)) {
|
||||
buffer_view.GetRange().length)) {
|
||||
VALIDATION_LOG << "Could not upload texture to device memory";
|
||||
return false;
|
||||
}
|
||||
@ -807,7 +813,8 @@ TEST_P(RendererTest, CanGenerateMipmaps) {
|
||||
ASSERT_TRUE(vertex_buffer);
|
||||
|
||||
bool first_frame = true;
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
Playground::RenderCallback callback = [&](RenderTarget& render_target) {
|
||||
const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
|
||||
const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
|
||||
@ -919,7 +926,8 @@ TEST_P(RendererTest, TheImpeller) {
|
||||
"table_mountain_pz.png", "table_mountain_nz.png"});
|
||||
const std::unique_ptr<const Sampler>& cube_map_sampler =
|
||||
context->GetSamplerLibrary()->GetSampler({});
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
auto size = pass.GetRenderTargetSize();
|
||||
@ -968,7 +976,8 @@ TEST_P(RendererTest, Planet) {
|
||||
context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
|
||||
ASSERT_TRUE(pipeline && pipeline->IsValid());
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
static Scalar speed = 0.1;
|
||||
@ -1034,7 +1043,8 @@ TEST_P(RendererTest, ArrayUniforms) {
|
||||
context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
|
||||
ASSERT_TRUE(pipeline && pipeline->IsValid());
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
auto size = pass.GetRenderTargetSize();
|
||||
|
||||
@ -1091,7 +1101,8 @@ TEST_P(RendererTest, InactiveUniforms) {
|
||||
context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
|
||||
ASSERT_TRUE(pipeline && pipeline->IsValid());
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
auto size = pass.GetRenderTargetSize();
|
||||
|
||||
@ -1256,7 +1267,8 @@ TEST_P(RendererTest, StencilMask) {
|
||||
static int current_back_compare =
|
||||
CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
|
||||
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
Playground::RenderCallback callback = [&](RenderTarget& render_target) {
|
||||
auto buffer = context->CreateCommandBuffer();
|
||||
if (!buffer) {
|
||||
@ -1469,7 +1481,8 @@ TEST_P(RendererTest, CanSepiaToneWithSubpasses) {
|
||||
ASSERT_TRUE(sampler);
|
||||
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
// Draw the texture.
|
||||
{
|
||||
@ -1562,7 +1575,8 @@ TEST_P(RendererTest, CanSepiaToneThenSwizzleWithSubpasses) {
|
||||
ASSERT_TRUE(sampler);
|
||||
|
||||
SinglePassCallback callback = [&](RenderPass& pass) {
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator());
|
||||
auto buffer = HostBuffer::Create(context->GetResourceAllocator(),
|
||||
context->GetIdleWaiter());
|
||||
|
||||
// Draw the texture.
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ class VertexBufferBuilder {
|
||||
if (!label_.empty()) {
|
||||
buffer->SetLabel(SPrintF("%s Vertices", label_.c_str()));
|
||||
}
|
||||
return DeviceBuffer::AsBufferView(buffer);
|
||||
return DeviceBuffer::AsBufferView(std::move(buffer));
|
||||
}
|
||||
|
||||
std::vector<IndexType> CreateIndexBuffer() const { return indices_; }
|
||||
@ -167,7 +167,7 @@ class VertexBufferBuilder {
|
||||
if (!label_.empty()) {
|
||||
buffer->SetLabel(SPrintF("%s Indices", label_.c_str()));
|
||||
}
|
||||
return DeviceBuffer::AsBufferView(buffer);
|
||||
return DeviceBuffer::AsBufferView(std::move(buffer));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,10 +47,11 @@ VertexBuffer Tessellator::TessellateConvex(const Path& path,
|
||||
|
||||
if (supports_triangle_fan) {
|
||||
FanVertexWriter writer(
|
||||
reinterpret_cast<Point*>(point_buffer.buffer->OnGetContents() +
|
||||
point_buffer.range.offset),
|
||||
reinterpret_cast<uint16_t*>(index_buffer.buffer->OnGetContents() +
|
||||
index_buffer.range.offset));
|
||||
reinterpret_cast<Point*>(point_buffer.GetBuffer()->OnGetContents() +
|
||||
point_buffer.GetRange().offset),
|
||||
reinterpret_cast<uint16_t*>(
|
||||
index_buffer.GetBuffer()->OnGetContents() +
|
||||
index_buffer.GetRange().offset));
|
||||
path.WritePolyline(tolerance, writer);
|
||||
|
||||
return VertexBuffer{
|
||||
@ -61,10 +62,11 @@ VertexBuffer Tessellator::TessellateConvex(const Path& path,
|
||||
};
|
||||
} else {
|
||||
StripVertexWriter writer(
|
||||
reinterpret_cast<Point*>(point_buffer.buffer->OnGetContents() +
|
||||
point_buffer.range.offset),
|
||||
reinterpret_cast<uint16_t*>(index_buffer.buffer->OnGetContents() +
|
||||
index_buffer.range.offset));
|
||||
reinterpret_cast<Point*>(point_buffer.GetBuffer()->OnGetContents() +
|
||||
point_buffer.GetRange().offset),
|
||||
reinterpret_cast<uint16_t*>(
|
||||
index_buffer.GetBuffer()->OnGetContents() +
|
||||
index_buffer.GetRange().offset));
|
||||
path.WritePolyline(tolerance, writer);
|
||||
|
||||
return VertexBuffer{
|
||||
|
@ -81,7 +81,8 @@ TEST_P(TypographerTest, CanCreateGlyphAtlas) {
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
ASSERT_TRUE(context && context->IsValid());
|
||||
SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
|
||||
auto blob = SkTextBlob::MakeFromString("hello", sk_font);
|
||||
@ -116,7 +117,8 @@ TEST_P(TypographerTest, CanCreateGlyphAtlas) {
|
||||
}
|
||||
|
||||
TEST_P(TypographerTest, LazyAtlasTracksColor) {
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
#if FML_OS_MACOSX
|
||||
auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
|
||||
#else
|
||||
@ -158,7 +160,8 @@ TEST_P(TypographerTest, GlyphAtlasWithOddUniqueGlyphSize) {
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
ASSERT_TRUE(context && context->IsValid());
|
||||
SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
|
||||
auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
|
||||
@ -178,7 +181,8 @@ TEST_P(TypographerTest, GlyphAtlasIsRecycledIfUnchanged) {
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
ASSERT_TRUE(context && context->IsValid());
|
||||
SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
|
||||
auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
|
||||
@ -202,7 +206,8 @@ TEST_P(TypographerTest, GlyphAtlasIsRecycledIfUnchanged) {
|
||||
}
|
||||
|
||||
TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) {
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
@ -249,7 +254,8 @@ TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) {
|
||||
}
|
||||
|
||||
TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged) {
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
@ -286,7 +292,8 @@ TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged) {
|
||||
}
|
||||
|
||||
TEST_P(TypographerTest, GlyphColorIsPartOfCacheKey) {
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
#if FML_OS_MACOSX
|
||||
auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
|
||||
#else
|
||||
@ -320,7 +327,8 @@ TEST_P(TypographerTest, GlyphColorIsPartOfCacheKey) {
|
||||
}
|
||||
|
||||
TEST_P(TypographerTest, GlyphColorIsIgnoredForNonEmojiFonts) {
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
|
||||
sk_sp<SkTypeface> typeface =
|
||||
font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
|
||||
@ -419,7 +427,8 @@ TEST_P(TypographerTest, GlyphAtlasTextureWillGrowTilMaxTextureSize) {
|
||||
GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
|
||||
}
|
||||
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
@ -495,7 +504,8 @@ TEST_P(TypographerTest, TextFrameInitialBoundsArePlaceholder) {
|
||||
auto context = TypographerContextSkia::Make();
|
||||
auto atlas_context =
|
||||
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
|
||||
auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
|
||||
GetContext()->GetIdleWaiter());
|
||||
|
||||
auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
|
||||
GlyphAtlas::Type::kAlphaBitmap, 1.0f,
|
||||
|
@ -312,10 +312,8 @@ static void BindVertexBuffer(
|
||||
int offset_in_bytes,
|
||||
int length_in_bytes,
|
||||
int vertex_count) {
|
||||
wrapper->vertex_buffer = impeller::BufferView{
|
||||
.buffer = buffer,
|
||||
.range = impeller::Range(offset_in_bytes, length_in_bytes),
|
||||
};
|
||||
wrapper->vertex_buffer = impeller::BufferView(
|
||||
buffer, impeller::Range(offset_in_bytes, length_in_bytes));
|
||||
|
||||
// If the index type is set, then the `vertex_count` becomes the index
|
||||
// count... So don't overwrite the count if it's already been set when binding
|
||||
@ -348,10 +346,8 @@ static void BindIndexBuffer(
|
||||
int index_type,
|
||||
int index_count) {
|
||||
impeller::IndexType type = flutter::gpu::ToImpellerIndexType(index_type);
|
||||
wrapper->index_buffer = impeller::BufferView{
|
||||
.buffer = buffer,
|
||||
.range = impeller::Range(offset_in_bytes, length_in_bytes),
|
||||
};
|
||||
wrapper->index_buffer = impeller::BufferView(
|
||||
buffer, impeller::Range(offset_in_bytes, length_in_bytes));
|
||||
wrapper->index_buffer_type = type;
|
||||
|
||||
bool setting_index_buffer = type != impeller::IndexType::kNone;
|
||||
@ -412,10 +408,8 @@ static bool BindUniform(
|
||||
.slot = uniform_struct->slot,
|
||||
.view = impeller::BufferResource{
|
||||
&uniform_struct->metadata,
|
||||
impeller::BufferView{
|
||||
.buffer = buffer,
|
||||
.range = impeller::Range(offset_in_bytes, length_in_bytes),
|
||||
},
|
||||
impeller::BufferView(
|
||||
buffer, impeller::Range(offset_in_bytes, length_in_bytes)),
|
||||
}});
|
||||
return true;
|
||||
}
|
||||
|
@ -130,8 +130,9 @@ def run_cmd( # pylint: disable=too-many-arguments
|
||||
|
||||
for forbidden_string in forbidden_output:
|
||||
if forbidden_string in output:
|
||||
matches = [x.group(0) for x in re.findall(f'^.*{forbidden_string}.*$', output)]
|
||||
raise RuntimeError(
|
||||
'command "%s" contained forbidden string "%s"' % (command_string, forbidden_string)
|
||||
f'command "{command_string}" contained forbidden string "{forbidden_string}": {matches}'
|
||||
)
|
||||
|
||||
print_divider('<')
|
||||
|
Loading…
x
Reference in New Issue
Block a user