Skip to content
This repository was archived by the owner on Jun 28, 2023. It is now read-only.

Commit bb34fb1

Browse files
committed
Fix CommandWork moving
1 parent 2310110 commit bb34fb1

22 files changed

+234
-93
lines changed

docs/tests/allocator.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,68 @@ TEST(memory) {
5757
EXPECT(alloc.memories()[0].totalFree(), 1024u * 3);
5858
}
5959
}
60+
61+
62+
TEST(custom) {
63+
auto& dev = *globals.device;
64+
auto alloc = vpp::DeviceMemoryAllocator(dev);
65+
EXPECT(alloc.memories().empty(), true);
66+
67+
// allocate some stuff
68+
{
69+
vk::BufferCreateInfo bufInfo;
70+
bufInfo.size = 1024;
71+
bufInfo.usage = vk::BufferUsageBits::storageBuffer;
72+
auto buffer = vpp::Buffer(vpp::defer, dev, bufInfo, ~0u, &alloc);
73+
vpp::Buffer buffer1(vpp::defer, dev, bufInfo, ~0u, &alloc);
74+
vpp::Buffer buffer2(vpp::defer, dev, bufInfo, ~0u, &alloc);
75+
vpp::Buffer buffer3(vpp::defer, dev, bufInfo, ~0u, &alloc);
76+
EXPECT(buffer3.memoryEntry().allocator(), &alloc);
77+
78+
auto alloc2 = std::move(alloc);
79+
80+
vpp::Buffer buffer4(vpp::defer, dev, bufInfo, ~0u, &alloc2);
81+
EXPECT(alloc2.memories().empty(), true);
82+
EXPECT(buffer1.memoryEntry().allocated(), false);
83+
EXPECT(buffer2.memoryEntry().allocator(), &alloc2);
84+
EXPECT(buffer3.memoryEntry().allocator(), &alloc2);
85+
86+
alloc = std::move(alloc2);
87+
alloc.allocate();
88+
EXPECT(alloc.memories().size(), 1u);
89+
90+
EXPECT(buffer2.memoryEntry().allocated(), true);
91+
EXPECT(buffer3.memoryEntry().allocated(), true);
92+
EXPECT(buffer3.memoryEntry().memory(), &alloc.memories()[0]);
93+
94+
EXPECT(buffer1.memorySize(), 1024u);
95+
EXPECT(buffer2.memorySize(), 1024u);
96+
EXPECT(buffer3.memorySize(), 1024u);
97+
EXPECT(buffer4.memorySize(), 1024u);
98+
}
99+
100+
EXPECT(alloc.memories().size(), 1u);
101+
102+
// XXX: might fail due to alignment requirements etc (allocater
103+
// allocated larger memory)
104+
EXPECT(alloc.memories()[0].totalFree(), 1024u * 5);
105+
106+
// make sure same memory is used again
107+
{
108+
vk::BufferCreateInfo bufInfo;
109+
bufInfo.size = 1024;
110+
bufInfo.usage = vk::BufferUsageBits::storageBuffer;
111+
auto buffer = vpp::Buffer(dev, bufInfo, ~0u, &alloc);
112+
EXPECT(alloc.memories().size(), 1u);
113+
EXPECT(alloc.memories()[0].totalFree(), 1024u * 4);
114+
115+
vpp::Buffer buffer1(vpp::defer, dev, bufInfo, ~0u, &alloc);
116+
EXPECT(alloc.memories()[0].totalFree(), 1024u * 4);
117+
118+
auto alloc2 = std::move(alloc);
119+
buffer1.init();
120+
EXPECT(alloc2.memories()[0].totalFree(), 1024u * 3);
121+
122+
alloc = std::move(alloc2);
123+
}
124+
}

docs/tests/bufferOps.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,19 @@ vpp::BufferRange readWrite(bool mappable, vk::BufferUsageFlags usage,
210210
std::int32_t c {};
211211

212212
if(!direct && !mappable) {
213-
vpp::writeStaging140(buf, 42.f, Vec3f {1.f, 2.f, 3.f}, (std::int32_t) -420);
213+
auto work = vpp::writeStaging140(buf, 42.f, Vec3f {1.f, 2.f, 3.f}, (std::int32_t) -420);
214+
auto work2 = std::move(work);
215+
work2.finish();
216+
214217
vpp::readStaging140(buf, a, b, c);
215218
} else if(!direct && mappable) {
216219
vpp::writeMap140(buf, 42.f, Vec3f {1.f, 2.f, 3.f}, (std::int32_t) -420);
217220
vpp::readMap140(buf, a, b, c);
218221
} else {
219-
vpp::writeDirect140(buf, 42.f, Vec3f {1.f, 2.f, 3.f}, (std::int32_t) -420);
222+
auto work = vpp::writeDirect140(buf, 42.f, Vec3f {1.f, 2.f, 3.f}, (std::int32_t) -420);
223+
auto work2 = std::move(work);
224+
work2.finish();
225+
220226
vpp::readStaging140(buf, a, b, c);
221227
}
222228

@@ -243,7 +249,9 @@ TEST(buffer_range) {
243249
auto buf6 = readWrite(false, usage, true);
244250

245251
for(auto i = 0u; i < 100u; ++i) {
246-
readWrite(true, usage);
252+
auto range = readWrite(true, usage);
253+
auto range2 = std::move(range);
254+
247255
readWrite(false, usage);
248256
readWrite(true, usage, true);
249257
readWrite(false, usage, true);

docs/tests/framebuffer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ TEST(framebuffer) {
6161
{}, renderPass, 2, fbAttachments.begin(), size.width, size.height, 1
6262
};
6363
auto fb = vpp::Framebuffer(dev, info);
64+
auto moved = std::move(fb);
6465
}

docs/tests/image.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ TEST(image) {
2121
};
2222

2323
vpp::Image img1 = {dev, imgInfo};
24+
auto moved = std::move(img1);
25+
img1 = std::move(moved);
2426

2527
imgInfo.usage = vk::ImageUsageBits::sampled;
2628
imgInfo.format = vk::Format::r8Uint;
@@ -43,26 +45,33 @@ TEST(image) {
4345
vk::AccessBits::transferWrite,
4446
{vk::ImageAspectBits::color, 0, 1, 0, 1}, dev.queueSubmitter());
4547

46-
vpp::fillStaging(img1, vk::Format::r8g8b8a8Unorm,
48+
auto work = vpp::fillStaging(img1, vk::Format::r8g8b8a8Unorm,
4749
vk::ImageLayout::transferDstOptimal, size, data,
4850
{vk::ImageAspectBits::color});
51+
auto workm = std::move(work);
52+
workm.wait();
53+
workm.submit();
54+
workm.finish();
4955

5056
vpp::fillMap(img2, vk::Format::r8Unorm, size,
5157
{data.data(), size.width * size.height},
5258
{vk::ImageAspectBits::color});
5359

54-
vpp::changeLayout(img1,
60+
auto work1 = vpp::changeLayout(img1,
5561
vk::ImageLayout::transferDstOptimal, vk::PipelineStageBits::transfer,
5662
vk::AccessBits::transferWrite,
5763
vk::ImageLayout::transferSrcOptimal, vk::PipelineStageBits::transfer,
5864
vk::AccessBits::transferRead,
5965
{vk::ImageAspectBits::color, 0, 1, 0, 1}, dev.queueSubmitter());
66+
auto work2 = std::move(work1);
67+
work2.finish();
6068

61-
auto dataWork = vpp::retrieveStaging(img1,
69+
auto dataWork1 = vpp::retrieveStaging(img1,
6270
vk::Format::r8g8b8a8Unorm, vk::ImageLayout::transferSrcOptimal,
6371
size, {vk::ImageAspectBits::color, 0, 0});
72+
auto dataWork2 = std::move(dataWork1);
6473

65-
auto data1 = dataWork.data();
74+
auto data1 = dataWork2.data();
6675
EXPECT(data1.size(), size.width * size.height * 4u);
6776
EXPECT((unsigned int) data1[0], 0x00u);
6877
EXPECT((unsigned int) data1[1], 0x01u);

docs/tests/memory.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,17 @@ TEST(map) {
6161

6262
EXPECT(memory.mappable(), true);
6363
auto map = memory.map({0u, 1024u});
64+
auto map2 = std::move(map);
65+
map = std::move(map2);
66+
6467
EXPECT(map.offset(), 0u);
6568
EXPECT(map.size(), 1024u);
6669
EXPECT(&map.memory(), &memory);
6770
EXPECT(map.ptr() != nullptr, true);
6871
EXPECT(memory.mapped() != nullptr, true);
6972

7073
// this will have no effect, just return another view
71-
auto map2 = memory.map({0, 256});
74+
map2 = memory.map({0, 256});
7275
EXPECT(map2.offset(), 0u);
7376
EXPECT(map2.size(), 256u);
7477
EXPECT(map2.ptr(), map.ptr());
@@ -77,6 +80,8 @@ TEST(map) {
7780
// just another view
7881
auto map3 = memory.map({256, 256});
7982
EXPECT(map3.ptr(), map.ptr() + 256);
83+
84+
map = std::move(map3);
8085
}
8186

8287
TEST(remap) {

docs/tests/objects.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ TEST(mem) {
2020
auto rawMem = vk::allocateMemory(dev, {2048, 0u});
2121
auto memHandle1 = vpp::DeviceMemoryHandle(dev, {256u, 0u});
2222
auto memHandle2 = vpp::DeviceMemoryHandle(dev, rawMem);
23+
auto memHandle3 = std::move(memHandle2);
2324

2425
auto rawMem2 = vk::allocateMemory(dev, {14u, 0u});
2526
auto mem1 = vpp::DeviceMemory(dev, {256u, 0u});
2627
auto mem2 = vpp::DeviceMemory(dev, rawMem2, 14u, 0u);
2728

2829
auto allocator = vpp::DeviceMemoryAllocator(dev);
2930
auto memEntry = vpp::MemoryEntry(mem1, mem1.alloc(10u, 0u, vpp::AllocationType::linear));
31+
auto memEntry2 = std::move(memEntry);
3032
}
3133

3234
TEST(cmd) {
@@ -44,6 +46,7 @@ TEST(cmd) {
4446
auto cmdAllocator = vpp::CommandAllocator(dev);
4547
auto cmdBuf5 = cmdAllocator.get(0);
4648
auto cmdBufs6 = cmdAllocator.get(0, 3);
49+
auto cmdBuf7 = std::move(cmdBuf5);
4750
}
4851

4952
// returns the index of the first set bit of an uint
@@ -100,6 +103,7 @@ TEST(buf) {
100103
vpp::Buffer buf8(dev, rawBuf3, std::move(entry));
101104

102105
vpp::Buffer buf9(dev, info, mem);
106+
auto buf10 = std::move(buf9);
103107
}
104108

105109
TEST(sync) {

docs/tests/sharedBuffer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ TEST(sharedBuf) {
3939
EXPECT(bufRange.size(), 100u);
4040
EXPECT(bufRange.offset(), 0u);
4141

42+
auto bufRange2 = std::move(bufRange);
43+
EXPECT(&bufRange2.buffer(), &buf);
44+
EXPECT(bufRange2.size(), 100u);
45+
EXPECT(bufRange2.offset(), 0u);
46+
4247
ERROR(vpp::BufferRange(buf, 1000u), std::runtime_error);
4348

4449
// allocator
@@ -119,6 +124,8 @@ TEST(nonCoherentAtomAlign) {
119124
vpp::BufferRange range3(buf, buf.alloc(100u));
120125
offset = vpp::align<vk::DeviceSize>(range2.allocation().end(), atomAlign);
121126
EXPECT(range3.allocation(), (Alloc{offset, 100u}));
127+
128+
auto range4 = std::move(range3);
122129
}
123130

124131
TEST(mappable) {
@@ -148,6 +155,10 @@ TEST(mappable) {
148155
EXPECT((coherentBits & (1 << type)) != 0, true);
149156
EXPECT(buf2.buffer().nonCoherentAtomAlign, false);
150157

158+
auto mapView1 = buf2.memoryMap();
159+
auto mapView2 = buf2.memoryMap();
160+
auto mapView3 = buf2.memoryMap();
161+
151162
// allocate mappable buffer on non-coherent memory
152163
// there might be vulkan implementations where are all hostVisible
153164
// types are also hostCoherent, we cannot do this test there

docs/todo.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ Todo list vor vpp
2222
- image constructors (simply copy from buffer constructors in objects.cpp)
2323
- etc...
2424
- also test coherent atom handling in SharedBuffer
25-
- fix config for vkpp
25+
- fix config.hpp for vkpp (messed up atm)
26+
- memoryMap: remap when MemoryMapView is destroyed? for guarantees?
2627
- imageOps: really allow extent with depth == 0? also handle it for height == 0?
2728
- make codestyle consistent everywhere
2829
- device: cache supported extensions (see e.g. defaults.cpp: could change
@@ -35,6 +36,7 @@ Todo list vor vpp
3536
- implement BufferAllocator optimize/shrink
3637
- add more assertions everywhere where things are assumed
3738
- don't overdo, only if potentially useful when debugging
39+
- see work.inl (something like tryFinish probably best)
3840

3941
low prio / general / ideas
4042
--------------------------

include/vpp/bits/work.inl

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44

55
#pragma once
66

7+
void commandWork_assert(bool, const char* msg);
8+
void commandWork_updateMoved(QueueSubmitter*, uint64_t, unsigned int,
9+
const vk::CommandBuffer&);
10+
711
template<typename R>
812
CommandWork<R>::CommandWork(QueueSubmitter& submitter, CommandBuffer&& cmd) :
913
cmdBuffer_(std::move(cmd))
1014
{
15+
commandWork_assert(cmdBuffer_, "invalid commandBuffer passed");
1116
init(submitter, {{}, {}, {}, 1, &cmdBuffer_.vkHandle(), {}, {}});
1217
}
1318

1419
template<typename R>
15-
CommandWork<R>::CommandWork(QueueSubmitter& submitter,
16-
const vk::SubmitInfo& info, CommandBuffer&& cmd) :
17-
cmdBuffer_(std::move(cmd))
20+
CommandWork<R>::CommandWork(QueueSubmitter& submitter, const vk::SubmitInfo& info)
1821
{
1922
init(submitter, info);
2023
}
@@ -30,30 +33,44 @@ CommandWork<R>::~CommandWork()
3033
template<typename R>
3134
void CommandWork<R>::init(QueueSubmitter& submitter, const vk::SubmitInfo& info)
3235
{
36+
commandWork_assert(state_ == WorkBase::State::none,
37+
"already initialized");
38+
3339
submitter_ = &submitter;
34-
submitID_ = submitter.add(info);
40+
submitID_ = submitter.add(info, &infoID_);
3541
state_ = WorkBase::State::pending;
3642
}
3743

3844
template<typename R>
3945
void CommandWork<R>::submit()
4046
{
41-
// dlg_assert(state_ != WorkBase::State::none);
42-
// dlg_assert(submitter_ && submitID_);
47+
commandWork_assert(state_ != WorkBase::State::none && submitter_ && submitID_,
48+
"submit: invalid");
4349

44-
submitter_->submit(submitID_);
45-
state_ = WorkBase::State::submitted;
50+
if(this->pending()) {
51+
submitter_->submit(submitID_);
52+
state_ = WorkBase::State::submitted;
53+
}
4654
}
4755

4856
template<typename R>
4957
void CommandWork<R>::wait()
5058
{
51-
// dlg_assert(state_ != WorkBase::State::none);
52-
// dlg_assert(submitter_ && submitID_);
59+
commandWork_assert(state_ != WorkBase::State::none && submitter_ && submitID_,
60+
"wait: invalid");
61+
62+
if(!this->executed()) {
63+
submitter_->wait(submitID_); // will automatically submit if needed
64+
}
5365

54-
submitter_->wait(submitID_); // will automatically submit if needed
5566
cmdBuffer_ = {}; // free the commandBuffer it is no longer needed
56-
state_ = WorkBase::State::executed;
67+
state_ = WorkBase::State::finished;
68+
}
69+
70+
template<typename R>
71+
void CommandWork<R>::finish()
72+
{
73+
wait();
5774
}
5875

5976
template<typename R>
@@ -64,15 +81,12 @@ WorkBase::State CommandWork<R>::state()
6481
}
6582

6683
// query state
67-
// dlg_assert(submitID_);
68-
// dlg_assert(submitter_);
69-
7084
if(state_ == WorkBase::State::pending && submitter_->submitted(submitID_)) {
7185
state_ = WorkBase::State::submitted;
7286
}
7387

7488
if(state_ == WorkBase::State::submitted && submitter_->completed(submitID_)) {
75-
state_ = WorkBase::State::executed;
89+
state_ = WorkBase::State::finished;
7690
}
7791

7892
return state_;
@@ -81,11 +95,14 @@ WorkBase::State CommandWork<R>::state()
8195
template<typename R>
8296
CommandWork<R>::CommandWork(CommandWork&& rhs) noexcept :
8397
cmdBuffer_(std::move(rhs.cmdBuffer_)), submitter_(rhs.submitter_),
84-
submitID_(rhs.submitID_), state_(rhs.state_)
98+
submitID_(rhs.submitID_), infoID_(rhs.infoID_), state_(rhs.state_)
8599
{
86100
rhs.submitter_ = {};
87101
rhs.submitID_ = {};
88102
rhs.state_ = WorkBase::State::none;
103+
rhs.infoID_ = {};
104+
105+
commandWork_updateMoved(submitter_, submitID_, infoID_, cmdBuffer_.vkHandle());
89106
}
90107

91108
template<typename R>
@@ -98,11 +115,15 @@ CommandWork<R>& CommandWork<R>::operator=(CommandWork&& rhs) noexcept
98115
cmdBuffer_ = std::move(rhs.cmdBuffer_);
99116
submitter_ = rhs.submitter_;
100117
submitID_ = rhs.submitID_;
118+
infoID_ = rhs.infoID_;
101119
state_ = rhs.state_;
102120

103121
rhs.submitter_ = {};
104122
rhs.submitID_ = {};
123+
rhs.infoID_ = {};
105124
rhs.state_ = WorkBase::State::none;
106125

126+
commandWork_updateMoved(submitter_, submitID_, infoID_, cmdBuffer_.vkHandle());
127+
107128
return *this;
108129
}

0 commit comments

Comments
 (0)