Skip to content

Commit

Permalink
Add basic GrGpuBufferUpdateDataTest to test current functionality
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bsalomon authored and SkCQ committed Jun 24, 2022
1 parent a3983b6 commit b5ea901
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 6 deletions.
14 changes: 12 additions & 2 deletions src/gpu/ganesh/dawn/GrDawnBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ sk_sp<GrDawnBuffer> GrDawnBuffer::Make(GrDawnGpu* gpu,
mappable = Mappable::kWriteOnly;
}

if (mappable == Mappable::kNot) {
// onMap can still succeed by using a staging buffer that gets transferred to the real
// buffer. updateData will use this same mechanism ("map", copy to staging buffer, "unmap").
// The transfer must be 4 byte aligned. So ensure the real size of the buffer is 4 byte
// aligned.
bufferDesc.size = SkAlign4(bufferDesc.size);
SkASSERT(gpu->caps()->transferFromBufferToBufferAlignment() == 4);
}

wgpu::Buffer buffer;
void* mapPtr = nullptr;
if (mappable == Mappable::kNot || mappable == Mappable::kReadOnly) {
Expand Down Expand Up @@ -102,7 +111,7 @@ void GrDawnBuffer::onMap() {
if (fMappable == Mappable::kNot) {
GrStagingBufferManager::Slice slice =
this->getDawnGpu()->stagingBufferManager()->allocateStagingBufferSlice(
this->size());
this->size(), /*requiredAlignment=*/4);
fStagingBuffer = static_cast<GrDawnBuffer*>(slice.fBuffer)->get();
fStagingOffset = slice.fOffset;
fMapPtr = slice.fOffsetMapPtr;
Expand All @@ -120,8 +129,9 @@ void GrDawnBuffer::onUnmap() {
}

if (fMappable == Mappable::kNot) {
size_t actualSize = SkAlign4(this->size());
this->getDawnGpu()->getCopyEncoder().CopyBufferToBuffer(fStagingBuffer, fStagingOffset,
fBuffer, 0, this->size());
fBuffer, 0, actualSize);
} else {
fBuffer.Unmap();
fUnmapped = true;
Expand Down
4 changes: 4 additions & 0 deletions src/gpu/ganesh/dawn/GrDawnCaps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(conte
fShaderCaps->fMaxFragmentSamplers = 6;
fShaderCaps->fShaderDerivativeSupport = true;

// We haven't yet implemented GrGpu::transferFromBufferToBuffer for Dawn but GrDawnBuffer uses
// transfers to implement buffer mapping and updates and transfers must be 4 byte aligned.
fTransferFromBufferToBufferAlignment = 4;

this->finishInitialization(contextOptions);
}

Expand Down
66 changes: 62 additions & 4 deletions tests/GrGpuBufferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferTransferTest, reporter, ctxInfo) {

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

for (bool byteAtATime : {false, true}) {
for (bool minSizedTransfers : {false, true}) {
for (int srcBaseVertex : {0, 5}) {
auto src = create_cpu_to_gpu_buffer(srcBaseVertex);
if (!src) {
ERRORF(reporter, "Could not create src buffer");
return;
}
for (int vbBaseVertex : {0, 2}) {
auto vb = create_vertex_buffer(src, srcBaseVertex, vbBaseVertex, byteAtATime);
auto vb = create_vertex_buffer(src, srcBaseVertex, vbBaseVertex, minSizedTransfers);
if (!vb) {
ERRORF(reporter, "Could not create vertex buffer");
return;
Expand Down Expand Up @@ -289,11 +289,69 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferTransferTest, reporter, ctxInfo) {

REPORTER_ASSERT(reporter, *color == kGreen, "src base vertex: %d, "
"vb base vertex: %d, "
"byteAtATime: %d",
"minSizedTransfers: %d",
srcBaseVertex,
vbBaseVertex,
byteAtATime);
minSizedTransfers);
}
}
}
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrGpuBufferUpdateDataTest, reporter, ctxInfo) {
GrDirectContext* dc = ctxInfo.directContext();

GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();

static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
{1, 0}, {0, 1}, {1, 1}};

auto sdc = skgpu::v1::SurfaceDrawContext::Make(dc,
GrColorType::kRGBA_8888,
nullptr,
SkBackingFit::kExact,
{1, 1},
SkSurfaceProps{},
std::string_view{});
if (!sdc) {
ERRORF(reporter, "Could not create draw context");
return;
}

for (bool oversizedBuffer : {false, true}) {
auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));

// Go direct to GrGpu to avoid caching/size adjustments at GrResourceProvider level.
auto vb = gpu->createBuffer(sizeof(kUnitQuad) + (oversizedBuffer ? 7 : 0),
GrGpuBufferType::kVertex,
kDynamic_GrAccessPattern);
if (!vb) {
ERRORF(reporter, "Could not create vertex buffer");
return;
}

if (!vb->updateData(kUnitQuad, sizeof(kUnitQuad))) {
ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
return;
}

static constexpr SkColor4f kRed{1, 0, 0, 1};

static constexpr SkRect kBounds{0, 0, 1, 1};

sdc->clear(kRed);

sdc->addDrawOp(nullptr, TestVertexOp::Make(dc, vb, 0, std::size(kUnitQuad), kBounds));

auto color = static_cast<SkPMColor4f*>(pm.addr());
*color = kRed.premul();
if (!sdc->readPixels(dc, pm, {0, 0})) {
ERRORF(reporter, "Read back failed.");
return;
}

static constexpr SkPMColor4f kGreen{0, 1, 0, 1};

REPORTER_ASSERT(reporter, *color == kGreen);
}
}

0 comments on commit b5ea901

Please sign in to comment.