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