Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Namespaces | Functions
GrGpuBufferTest.cpp File Reference
#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAlign.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrGpuBuffer.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPipeline.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include <algorithm>
#include <cstring>
#include <initializer_list>
#include <memory>
#include <string_view>
#include <utility>

Go to the source code of this file.

Classes

class  TestVertexOp
 

Namespaces

namespace  skgpu
 

Functions

 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (GrGpuBufferTransferTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_U)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (GrGpuBufferUpdateDataTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_U)
 

Function Documentation

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( GrGpuBufferTransferTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_U   
)

Definition at line 219 of file GrGpuBufferTest.cpp.

222 {
223 if (!ctxInfo.directContext()->priv().caps()->transferFromBufferToBufferSupport()) {
224 return;
225 }
226
227 GrDirectContext* dc = ctxInfo.directContext();
228
230
231 GrResourceProvider* rp = ctxInfo.directContext()->priv().resourceProvider();
232
233 GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();
234
235 auto create_cpu_to_gpu_buffer = [&](int baseVertex) {
236 // Ensure any extra vertices are offscreen
237 int totalVertices = baseVertex + 6;
238 auto points = std::make_unique<SkPoint[]>(totalVertices);
239 SkPoint offscreenPt{-10000, -10000};
240 std::fill_n(points.get(), totalVertices, offscreenPt);
241
242 // set the quad at the desired base vertex
243 static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
244 {1, 0}, {0, 1}, {1, 1}};
245 std::copy_n(kUnitQuad, 6, points.get() + baseVertex);
246
247 return rp->createBuffer(points.get(),
248 totalVertices*sizeof(SkPoint),
251 };
252
253 auto create_vertex_buffer = [&](sk_sp<GrGpuBuffer> srcBuffer,
254 int srcBaseVertex,
255 int vbBaseVertex,
256 bool useTask,
257 bool minSizedTransfers) {
258 // make initialization data of offscreen points.
259 int dstVertexCount = vbBaseVertex + 6;
260 auto points = std::make_unique<SkPoint[]>(dstVertexCount);
261 SkPoint offscreenPt{-10000, -10000};
262 std::fill_n(points.get(), dstVertexCount, offscreenPt);
263
265 dstVertexCount*sizeof(SkPoint),
268
269 // copy actual quad data from the source buffer to our new vb.
270
271 static constexpr size_t kTotalSize = 6*sizeof(SkPoint);
272
273 size_t srcOffset = srcBaseVertex*sizeof(SkPoint);
274 size_t vbOffset = vbBaseVertex*sizeof(SkPoint);
275
276 size_t alignment = gpu->caps()->transferFromBufferToBufferAlignment();
277 SkASSERT(kTotalSize % alignment == 0);
278 SkASSERT(sizeof(SkPoint) % alignment == 0);
279
280 if (minSizedTransfers) {
281 for (size_t n = kTotalSize/alignment, i = 0; i < n; ++i) {
282 if (useTask) {
283 dm->newBufferTransferTask(srcBuffer,
284 srcOffset + i*alignment,
285 vb,
286 vbOffset + i*alignment,
287 alignment);
288 } else {
289 gpu->transferFromBufferToBuffer(srcBuffer,
290 srcOffset + i*alignment,
291 vb,
292 vbOffset + i*alignment,
293 alignment);
294 }
295 }
296 } else if (useTask) {
297 dm->newBufferTransferTask(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
298 } else {
299 gpu->transferFromBufferToBuffer(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
300 }
301 return vb;
302 };
303
306 nullptr,
308 {1, 1},
310 std::string_view{});
311 if (!sdc) {
312 ERRORF(reporter, "Could not create draw context");
313 return;
314 }
315
316 auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
317
318 for (bool useTask : {false, true}) {
319 for (bool minSizedTransfers : {false, true}) {
320 for (int srcBaseVertex : {0, 5}) {
321 auto src = create_cpu_to_gpu_buffer(srcBaseVertex);
322 if (!src) {
323 ERRORF(reporter, "Could not create src buffer");
324 return;
325 }
326 for (int vbBaseVertex : {0, 2}) {
327 auto vb = create_vertex_buffer(src,
328 srcBaseVertex,
329 vbBaseVertex,
330 useTask,
331 minSizedTransfers);
332 if (!vb) {
333 ERRORF(reporter, "Could not create vertex buffer");
334 return;
335 }
336
337 static constexpr SkColor4f kRed{1, 0, 0, 1};
338
339 static constexpr SkRect kBounds{0, 0, 1, 1};
340
341 sdc->clear(kRed);
342
343 sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
344 vb,
345 vbBaseVertex,
346 /*vertexCount=*/6,
347 kBounds));
348
349 auto color = static_cast<SkPMColor4f*>(pm.addr());
350 *color = kRed.premul();
351 if (!sdc->readPixels(dc, pm, {0, 0})) {
352 ERRORF(reporter, "Read back failed.");
353 return;
354 }
355
356 static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
357
358 REPORTER_ASSERT(reporter, *color == kGreen, "src base vertex: %d, "
359 "vb base vertex: %d, "
360 "use task: %d, "
361 "minSizedTransfers: %d",
362 srcBaseVertex,
363 vbBaseVertex,
364 useTask,
365 minSizedTransfers);
366 }
367 }
368 }
369 }
370}
reporter
@ kDynamic_GrAccessPattern
static const int points[]
SkColor4f color
static const uint64_t kGreen
static const uint64_t kRed
#define SkASSERT(cond)
Definition SkAssert.h:116
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
size_t transferFromBufferToBufferAlignment() const
Definition GrCaps.h:244
GrDirectContextPriv priv()
void newBufferTransferTask(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size)
Definition GrGpu.h:62
const GrCaps * caps() const
Definition GrGpu.h:73
bool transferFromBufferToBuffer(sk_sp< GrGpuBuffer > src, size_t srcOffset, sk_sp< GrGpuBuffer > dst, size_t dstOffset, size_t size)
Definition GrGpu.cpp:511
static GrPixmap Allocate(const GrImageInfo &info)
Definition GrPixmap.h:101
GrDrawingManager * drawingManager()
sk_sp< GrGpuBuffer > createBuffer(size_t size, GrGpuBufferType, GrAccessPattern, ZeroInit)
GrResourceProviderPriv priv()
static GrOp::Owner Make(GrRecordingContext *context, sk_sp< GrGpuBuffer > buffer, int baseVertex, int vertexCount, const SkRect &bounds)
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( GrGpuBufferUpdateDataTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_U   
)

Definition at line 372 of file GrGpuBufferTest.cpp.

375 {
376 GrDirectContext* dc = ctxInfo.directContext();
377
378 GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();
379
380 static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
381 {1, 0}, {0, 1}, {1, 1}};
382
385 nullptr,
387 {1, 1},
389 std::string_view{});
390 if (!sdc) {
391 ERRORF(reporter, "Could not create draw context");
392 return;
393 }
394
395 auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));
396
397 for (bool piecewise : {false, true}) {
398 size_t alignment = piecewise ? gpu->caps()->bufferUpdateDataPreserveAlignment() : 1;
399 for (size_t offset : {size_t{0}, 4*sizeof(SkPoint), size_t{1}, size_t{27}}) {
400 // For non-discarding updates we may not be able to actually put the data at an
401 // arbitrary offset.
402 if (alignment > 1) {
403 offset = SkAlignTo(offset, alignment);
404 }
405 for (auto accessPattern : {kStatic_GrAccessPattern,
406 // kStream_GrAccessPattern, GrVkGpu asserts on this for VBs.
408 // Go direct to GrGpu to avoid caching/size adjustments at GrResourceProvider level.
409 // We add an extra size(SkPoint) to ensure that everything fits when we align the
410 // first point's location in the vb below.
411 auto vb = gpu->createBuffer(sizeof(kUnitQuad) + offset + sizeof(SkPoint),
413 accessPattern);
414 if (!vb) {
415 ERRORF(reporter, "Could not create vertex buffer");
416 return;
417 }
418
419 const void* src = kUnitQuad;
420 size_t updateSize = sizeof(kUnitQuad);
421 // The vertices in the VB must be aligned to the size of a vertex (because our draw
422 // call takes a base vertex index rather than a byte offset). So if we want our
423 // upload to begin at a non-aligned byte we shift the data in the src buffer so that
424 // it falls at a vertex alignment in the vb.
425 std::unique_ptr<char[]> tempSrc;
426 size_t baseVertex = offset/sizeof(SkPoint);
427 if (size_t r = offset%sizeof(SkPoint); r != 0) {
428 size_t pad = sizeof(SkPoint) - r;
429 updateSize += pad;
430 if (alignment > 1) {
431 updateSize = SkAlignTo(updateSize, alignment);
432 }
433 ++baseVertex;
434 tempSrc.reset(new char[updateSize]);
435 std::memcpy(tempSrc.get() + pad, kUnitQuad, sizeof(kUnitQuad));
436 src = tempSrc.get();
437 }
438 if (piecewise) {
439 // This is the minimum size we can transfer at once.
440 size_t pieceSize = alignment;
441
442 // Upload each piece from a buffer where the byte before and after the uploaded
443 // bytes are not the same values as want adjacent to the piece in the buffer.
444 // Thus, if updateData() transfers extra bytes around the source we should get a
445 // bad buffer.
446 auto piece = std::make_unique<unsigned char[]>(pieceSize + 2);
447 piece[0] = piece[pieceSize + 1] = 0xFF;
448
449 for (size_t o = 0; o < updateSize; o += pieceSize) {
450 memcpy(&piece[1], SkTAddOffset<const void>(src, o), pieceSize);
451 if (!vb->updateData(&piece[1], offset + o, pieceSize, /*preserve=*/true)) {
452 ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
453 return;
454 }
455 }
456 } else if (!vb->updateData(src, offset, updateSize, /*preserve=*/false)) {
457 ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
458 return;
459 }
460
461 static constexpr SkColor4f kRed{1, 0, 0, 1};
462
463 static constexpr SkRect kBounds{0, 0, 1, 1};
464
465 sdc->clear(kRed);
466
467 sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
468 vb,
469 baseVertex,
470 std::size(kUnitQuad),
471 kBounds));
472
473 auto color = static_cast<SkPMColor4f*>(pm.addr());
474 *color = kRed.premul();
475 if (!sdc->readPixels(dc, pm, {0, 0})) {
476 ERRORF(reporter, "Read back failed.");
477 return;
478 }
479
480 static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
481
482 REPORTER_ASSERT(reporter, *color == kGreen, "piecewise: %d, offset: %zu",
483 piecewise, offset);
484 }
485 }
486 }
487}
@ kStatic_GrAccessPattern
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
Definition SkAlign.h:33
size_t bufferUpdateDataPreserveAlignment() const
Definition GrCaps.h:250
sk_sp< GrGpuBuffer > createBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern accessPattern)
Definition GrGpu.cpp:393
Point offset