Flutter Engine
The Flutter Engine
UploadBufferManagerTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "tests/Test.h"
9
16
17namespace skgpu::graphite {
18
19DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(UploadBufferManagerTest, reporter, context,
21 std::unique_ptr<Recorder> recorder = context->makeRecorder();
22 UploadBufferManager* bufferManager = recorder->priv().uploadBufferManager();
23
24 // The test source data.
25 char src[8] = {
26 1, 2, 3, 4,
27 5, 6, 7, 8,
28 };
29
30 // Test multiple small writes to a reused buffer.
31 auto [smWriter0, smBufferInfo0] = bufferManager->getTextureUploadWriter(10, 1);
32 smWriter0.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/3, /*trimRowBytes=*/3,
33 /*rowCount=*/2);
34 smWriter0.write(/*offset=*/6, src, /*srcRowBytes=*/4, /*dstRowBytes=*/2, /*trimRowBytes=*/2,
35 /*rowCount=*/2);
36
37 auto [smWriter1, smBufferInfo1] = bufferManager->getTextureUploadWriter(4, 1);
38 smWriter1.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/2, /*trimRowBytes=*/2,
39 /*rowCount=*/2);
40
41 REPORTER_ASSERT(reporter, smBufferInfo0.fBuffer == smBufferInfo1.fBuffer);
42 REPORTER_ASSERT(reporter, smBufferInfo0.fOffset == 0);
43 REPORTER_ASSERT(reporter, smBufferInfo1.fOffset >= 10);
44
45 // Test a large write, which should get its own dedicated buffer.
46 auto [lgWriter, lgBufferInfo] = bufferManager->getTextureUploadWriter((64 << 10) + 1, 1);
47 lgWriter.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/2, /*trimRowBytes=*/2,
48 /*rowCount=*/2);
49
50 REPORTER_ASSERT(reporter, lgBufferInfo.fBuffer != smBufferInfo0.fBuffer);
51 REPORTER_ASSERT(reporter, lgBufferInfo.fOffset == 0);
52 REPORTER_ASSERT(reporter, lgBufferInfo.fBuffer->isMapped());
53 const void* lgBufferMap = const_cast<Buffer*>(lgBufferInfo.fBuffer)->map();
54 const char expectedLgBufferMap[4] = {
55 1, 2,
56 5, 6,
57 };
59 memcmp(lgBufferMap, expectedLgBufferMap, sizeof(expectedLgBufferMap)) == 0);
60
61 // Test another small write after the large write.
62 auto [smWriter2, smBufferInfo2] = bufferManager->getTextureUploadWriter(2, 1);
63 smWriter2.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/2, /*trimRowBytes=*/2,
64 /*rowCount=*/1);
65
66 REPORTER_ASSERT(reporter, smBufferInfo2.fBuffer == smBufferInfo0.fBuffer);
67 REPORTER_ASSERT(reporter, smBufferInfo2.fOffset >= 4 + smBufferInfo1.fOffset);
68
69 REPORTER_ASSERT(reporter, smBufferInfo0.fBuffer->isMapped());
70 const char* smBufferMap =
71 reinterpret_cast<const char*>(const_cast<Buffer*>(smBufferInfo0.fBuffer)->map());
72 // Each section of written data could be offset and aligned by GPU-required rules, so we can't
73 // easily validate the contents of the buffer in one go, and instead test at each of the three
74 // reported offsets.
75 const char expectedSmBuffer0[10] = { 1, 2, 3, 5, 6, 7, 1, 2, 5, 6 };
76 const char expectedSmBuffer1[4] = { 1, 2, 5, 6 };
77 const char expectedSmBuffer2[2] = { 1, 2};
78 REPORTER_ASSERT(reporter, memcmp(smBufferMap + smBufferInfo0.fOffset,
79 expectedSmBuffer0,
80 sizeof(expectedSmBuffer0)) == 0);
81 REPORTER_ASSERT(reporter, memcmp(smBufferMap + smBufferInfo1.fOffset,
82 expectedSmBuffer1,
83 sizeof(expectedSmBuffer1)) == 0);
84 REPORTER_ASSERT(reporter, memcmp(smBufferMap + smBufferInfo2.fOffset,
85 expectedSmBuffer1,
86 sizeof(expectedSmBuffer2)) == 0);
87
88 // Snap a Recording from the Recorder. This will transfer resources from the UploadBufferManager
89 // to the Recording.
90 auto recording = recorder->snap();
91
92 // Test writes with a required alignment.
93 auto [alWriter0, alBufferInfo0] = bufferManager->getTextureUploadWriter(6, 4);
94 alWriter0.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/3, /*trimRowBytes=*/3,
95 /*rowCount=*/2);
96
97 auto [alWriter1, alBufferInfo1] = bufferManager->getTextureUploadWriter(2, 4);
98 alWriter1.write(/*offset=*/0, src, /*srcRowBytes=*/4, /*dstRowBytes=*/2, /*trimRowBytes=*/2,
99 /*rowCount=*/1);
100
101 // Should not share a buffer with earlier small writes, since we've transferred previously-
102 // allocated resources to the command buffer.
103 REPORTER_ASSERT(reporter, alBufferInfo0.fBuffer != smBufferInfo0.fBuffer);
104 REPORTER_ASSERT(reporter, alBufferInfo0.fBuffer == alBufferInfo1.fBuffer);
105 REPORTER_ASSERT(reporter, alBufferInfo0.fOffset == 0);
106 REPORTER_ASSERT(reporter, alBufferInfo1.fOffset == 8);
107
108 // From alWriter0.
109 const char expectedAlBufferMap0[6] = {
110 1, 2, 3,
111 5, 6, 7,
112 };
113 // From alWriter1.
114 const char expectedAlBufferMap1[2] = {
115 1, 2,
116 };
117
118 REPORTER_ASSERT(reporter, alBufferInfo0.fBuffer->isMapped());
119 const void* alBufferMap = const_cast<Buffer*>(alBufferInfo0.fBuffer)->map();
121 memcmp(alBufferMap, expectedAlBufferMap0, sizeof(expectedAlBufferMap0)) == 0);
122
123 alBufferMap = SkTAddOffset<const void>(alBufferMap, 8);
125 memcmp(alBufferMap, expectedAlBufferMap1, sizeof(expectedAlBufferMap1)) == 0);
126}
127
128} // namespace skgpu::graphite
reporter
Definition: FontMgrTest.cpp:39
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
std::tuple< TextureUploadWriter, BindBufferInfo > getTextureUploadWriter(size_t requiredBytes, size_t requiredAlignment)
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(BufferManagerGpuOnlyBufferTest, reporter, context, CtsEnforcement::kNextRelease)
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition: SkVx.h:680