xref: /aosp_15_r20/external/skia/tests/graphite/UploadBufferManagerTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 
10 #include "include/gpu/graphite/Context.h"
11 #include "include/gpu/graphite/Recorder.h"
12 #include "include/gpu/graphite/Recording.h"
13 #include "src/gpu/graphite/Buffer.h"
14 #include "src/gpu/graphite/RecorderPriv.h"
15 #include "src/gpu/graphite/UploadBufferManager.h"
16 
17 namespace skgpu::graphite {
18 
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(UploadBufferManagerTest,reporter,context,CtsEnforcement::kApiLevel_V)19 DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(UploadBufferManagerTest, reporter, context,
20                                          CtsEnforcement::kApiLevel_V) {
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     };
58     REPORTER_ASSERT(reporter,
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();
120     REPORTER_ASSERT(reporter,
121                     memcmp(alBufferMap, expectedAlBufferMap0, sizeof(expectedAlBufferMap0)) == 0);
122 
123     alBufferMap = SkTAddOffset<const void>(alBufferMap, 8);
124     REPORTER_ASSERT(reporter,
125                     memcmp(alBufferMap, expectedAlBufferMap1, sizeof(expectedAlBufferMap1)) == 0);
126 }
127 
128 }  // namespace skgpu::graphite
129