Skip to content

Commit b5ea901

Browse files
bsalomonSkCQ
authored andcommitted
Add basic GrGpuBufferUpdateDataTest to test current functionality
Bug: skia:13427 Change-Id: I49b879dfd6f25a591144bd950cf00e15fa71dc01 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/551887 Commit-Queue: Brian Salomon <[email protected]> Reviewed-by: Greg Daniel <[email protected]>
1 parent a3983b6 commit b5ea901

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-6
lines changed

src/gpu/ganesh/dawn/GrDawnBuffer.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ sk_sp<GrDawnBuffer> GrDawnBuffer::Make(GrDawnGpu* gpu,
4646
mappable = Mappable::kWriteOnly;
4747
}
4848

49+
if (mappable == Mappable::kNot) {
50+
// onMap can still succeed by using a staging buffer that gets transferred to the real
51+
// buffer. updateData will use this same mechanism ("map", copy to staging buffer, "unmap").
52+
// The transfer must be 4 byte aligned. So ensure the real size of the buffer is 4 byte
53+
// aligned.
54+
bufferDesc.size = SkAlign4(bufferDesc.size);
55+
SkASSERT(gpu->caps()->transferFromBufferToBufferAlignment() == 4);
56+
}
57+
4958
wgpu::Buffer buffer;
5059
void* mapPtr = nullptr;
5160
if (mappable == Mappable::kNot || mappable == Mappable::kReadOnly) {
@@ -102,7 +111,7 @@ void GrDawnBuffer::onMap() {
102111
if (fMappable == Mappable::kNot) {
103112
GrStagingBufferManager::Slice slice =
104113
this->getDawnGpu()->stagingBufferManager()->allocateStagingBufferSlice(
105-
this->size());
114+
this->size(), /*requiredAlignment=*/4);
106115
fStagingBuffer = static_cast<GrDawnBuffer*>(slice.fBuffer)->get();
107116
fStagingOffset = slice.fOffset;
108117
fMapPtr = slice.fOffsetMapPtr;
@@ -120,8 +129,9 @@ void GrDawnBuffer::onUnmap() {
120129
}
121130

122131
if (fMappable == Mappable::kNot) {
132+
size_t actualSize = SkAlign4(this->size());
123133
this->getDawnGpu()->getCopyEncoder().CopyBufferToBuffer(fStagingBuffer, fStagingOffset,
124-
fBuffer, 0, this->size());
134+
fBuffer, 0, actualSize);
125135
} else {
126136
fBuffer.Unmap();
127137
fUnmapped = true;

src/gpu/ganesh/dawn/GrDawnCaps.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(conte
3333
fShaderCaps->fMaxFragmentSamplers = 6;
3434
fShaderCaps->fShaderDerivativeSupport = true;
3535

36+
// We haven't yet implemented GrGpu::transferFromBufferToBuffer for Dawn but GrDawnBuffer uses
37+
// transfers to implement buffer mapping and updates and transfers must be 4 byte aligned.
38+
fTransferFromBufferToBufferAlignment = 4;
39+
3640
this->finishInitialization(contextOptions);
3741
}
3842

tests/GrGpuBufferTest.cpp

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferTransferTest, reporter, ctxInfo) {
252252

253253
auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
254254

255-
for (bool byteAtATime : {false, true}) {
255+
for (bool minSizedTransfers : {false, true}) {
256256
for (int srcBaseVertex : {0, 5}) {
257257
auto src = create_cpu_to_gpu_buffer(srcBaseVertex);
258258
if (!src) {
259259
ERRORF(reporter, "Could not create src buffer");
260260
return;
261261
}
262262
for (int vbBaseVertex : {0, 2}) {
263-
auto vb = create_vertex_buffer(src, srcBaseVertex, vbBaseVertex, byteAtATime);
263+
auto vb = create_vertex_buffer(src, srcBaseVertex, vbBaseVertex, minSizedTransfers);
264264
if (!vb) {
265265
ERRORF(reporter, "Could not create vertex buffer");
266266
return;
@@ -289,11 +289,69 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferTransferTest, reporter, ctxInfo) {
289289

290290
REPORTER_ASSERT(reporter, *color == kGreen, "src base vertex: %d, "
291291
"vb base vertex: %d, "
292-
"byteAtATime: %d",
292+
"minSizedTransfers: %d",
293293
srcBaseVertex,
294294
vbBaseVertex,
295-
byteAtATime);
295+
minSizedTransfers);
296296
}
297297
}
298298
}
299299
}
300+
301+
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferUpdateDataTest, reporter, ctxInfo) {
302+
GrDirectContext* dc = ctxInfo.directContext();
303+
304+
GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();
305+
306+
static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
307+
{1, 0}, {0, 1}, {1, 1}};
308+
309+
auto sdc = skgpu::v1::SurfaceDrawContext::Make(dc,
310+
GrColorType::kRGBA_8888,
311+
nullptr,
312+
SkBackingFit::kExact,
313+
{1, 1},
314+
SkSurfaceProps{},
315+
std::string_view{});
316+
if (!sdc) {
317+
ERRORF(reporter, "Could not create draw context");
318+
return;
319+
}
320+
321+
for (bool oversizedBuffer : {false, true}) {
322+
auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
323+
324+
// Go direct to GrGpu to avoid caching/size adjustments at GrResourceProvider level.
325+
auto vb = gpu->createBuffer(sizeof(kUnitQuad) + (oversizedBuffer ? 7 : 0),
326+
GrGpuBufferType::kVertex,
327+
kDynamic_GrAccessPattern);
328+
if (!vb) {
329+
ERRORF(reporter, "Could not create vertex buffer");
330+
return;
331+
}
332+
333+
if (!vb->updateData(kUnitQuad, sizeof(kUnitQuad))) {
334+
ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
335+
return;
336+
}
337+
338+
static constexpr SkColor4f kRed{1, 0, 0, 1};
339+
340+
static constexpr SkRect kBounds{0, 0, 1, 1};
341+
342+
sdc->clear(kRed);
343+
344+
sdc->addDrawOp(nullptr, TestVertexOp::Make(dc, vb, 0, std::size(kUnitQuad), kBounds));
345+
346+
auto color = static_cast<SkPMColor4f*>(pm.addr());
347+
*color = kRed.premul();
348+
if (!sdc->readPixels(dc, pm, {0, 0})) {
349+
ERRORF(reporter, "Read back failed.");
350+
return;
351+
}
352+
353+
static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
354+
355+
REPORTER_ASSERT(reporter, *color == kGreen);
356+
}
357+
}

0 commit comments

Comments
 (0)