blob: 5ecc73347a9c692d072b802f001afeca32146d39 [file] [log] [blame]
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tests/Test.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/TextureProxy.h"
using namespace skgpu::graphite;
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(PipelineDataCacheTest, reporter, context,
CtsEnforcement::kApiLevel_202404) {
const Caps* caps = context->priv().caps();
ResourceProvider* resourceProvider = context->priv().resourceProvider();
// Setup caches
UniformDataCache uCache;
TextureDataCache tCache;
REPORTER_ASSERT(reporter, uCache.count() == 0);
REPORTER_ASSERT(reporter, tCache.bindingCount() == 0);
// Create testing textures and uniforms
[[maybe_unused]] static constexpr Uniform kUniforms[] = {{"data", SkSLType::kFloat4}};
TextureInfo info = caps->getDefaultSampledTextureInfo(kAlpha_8_SkColorType,
skgpu::Mipmapped::kNo,
skgpu::Protected::kNo,
skgpu::Renderable::kYes);
REPORTER_ASSERT(reporter, info.isValid());
sk_sp<TextureProxy> proxyA = TextureProxy::Make(caps,
resourceProvider,
SkISize::Make(32, 32),
info,
"TestDataProxyA",
skgpu::Budgeted::kYes);
sk_sp<TextureProxy> proxyB = TextureProxy::Make(caps,
resourceProvider,
SkISize::Make(32, 32),
info,
"TestDataProxyB",
skgpu::Budgeted::kYes);
REPORTER_ASSERT(reporter, proxyA && proxyB);
// Block A: Add a new, unique set of uniforms and textures for a render step
UniformDataCache::Index uID1;
TextureDataCache::Index tID1;
{
PipelineDataGatherer gatherer{Layout::kStd430};
gatherer.setRenderStepManagerActive(); // Set active manager for render step data
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{1.f, 2.f, 3.f, 4.f});
gatherer.add(proxyA, {});
auto [udb, tdb] = gatherer.endRenderStepData(/*performsShading=*/true);
uID1 = uCache.insert(udb);
tID1 = tCache.insert(tdb);
REPORTER_ASSERT(reporter, uCache.count() == 1);
REPORTER_ASSERT(reporter, tCache.bindingCount() == 1);
REPORTER_ASSERT(reporter, tCache.uniqueTextureCount() == 1);
// Verify lookup
REPORTER_ASSERT(reporter, uCache.lookup(uID1).fCpuData == udb);
REPORTER_ASSERT(reporter, tCache.lookup(tID1) == tdb);
}
// Block B: Add the exact same render step data to test de-duplication
{
PipelineDataGatherer gatherer{Layout::kStd430};
gatherer.setRenderStepManagerActive();
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{1.f, 2.f, 3.f, 4.f}); // Same uniform data
gatherer.add(proxyA, {}); // Same texture
auto [udb, tdb] = gatherer.endRenderStepData(/*performsShading=*/true);
UniformDataCache::Index uID2 = uCache.insert(udb);
TextureDataCache::Index tID2 = tCache.insert(tdb);
REPORTER_ASSERT(reporter, uID2 == uID1); // Index should be the same
REPORTER_ASSERT(reporter, tID2 == tID1); // Index should be the same
REPORTER_ASSERT(reporter, uCache.count() == 1); // Count should NOT increase
REPORTER_ASSERT(reporter, tCache.bindingCount() == 1); // Count should NOT increase
}
// Block C: Add new unique render step uniforms but the same texture
UniformDataCache::Index uID3;
{
PipelineDataGatherer gatherer{Layout::kStd430};
gatherer.setRenderStepManagerActive();
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{5.f, 6.f, 7.f, 8.f}); // Different uniform data
gatherer.add(proxyA, {}); // Same texture
auto [udb, tdb] = gatherer.endRenderStepData(/*performsShading=*/true);
uID3 = uCache.insert(udb);
TextureDataCache::Index tID3 = tCache.insert(tdb);
REPORTER_ASSERT(reporter, uID3 != uID1); // New unique uniform index
REPORTER_ASSERT(reporter, tID3 == tID1); // Same texture binding index
REPORTER_ASSERT(reporter, uCache.count() == 2); // Uniform count increases
REPORTER_ASSERT(reporter, tCache.bindingCount() == 1); // Texture count does not
}
// Block D: Add the same render step uniforms but a new unique texture
{
PipelineDataGatherer gatherer{Layout::kStd430};
gatherer.setRenderStepManagerActive();
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{1.f, 2.f, 3.f, 4.f}); // Same uniform data as Block A
gatherer.add(proxyB, {}); // Different texture
auto [udb, tdb] = gatherer.endRenderStepData(/*performsShading=*/true);
UniformDataCache::Index uID4 = uCache.insert(udb);
TextureDataCache::Index tID4 = tCache.insert(tdb);
REPORTER_ASSERT(reporter, uID4 == uID1); // Same uniform index
REPORTER_ASSERT(reporter, tID4 != tID1); // New unique texture index
REPORTER_ASSERT(reporter, uCache.count() == 2); // Uniform count does not increase
REPORTER_ASSERT(reporter, tCache.bindingCount() == 2); // Texture count increases
REPORTER_ASSERT(reporter, tCache.uniqueTextureCount() == 2);
}
// Block E: Add a unique paint uniform.
UniformDataCache::Index uID5;
{
PipelineDataGatherer gatherer{Layout::kStd430};
// Starts in paint mode by default, no state change needed.
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{10.f, 20.f, 30.f, 40.f}); // New unique paint uniform data
UniformDataBlock udb = gatherer.endPaintData();
uID5 = uCache.insert(udb);
REPORTER_ASSERT(reporter, uID5 != uID1 && uID5 != uID3); // New unique uniform index
REPORTER_ASSERT(reporter, uCache.count() == 3); // Uniform count increases
}
// Block F: Add the same paint uniform to test de-duplication.
{
PipelineDataGatherer gatherer{Layout::kStd430};
SkDEBUGCODE(UniformExpectationsValidator uev(&gatherer, kUniforms);)
gatherer.write(SkV4{10.f, 20.f, 30.f, 40.f}); // Same paint uniform data as Block E
UniformDataBlock udb = gatherer.endPaintData();
UniformDataCache::Index uID6 = uCache.insert(udb);
REPORTER_ASSERT(reporter, uID6 == uID5); // Index should be the same
REPORTER_ASSERT(reporter, uCache.count() == 3); // Count should NOT increase
}
// Block G: Test paint and render step uniforms together.
{
PipelineDataGatherer gatherer{Layout::kStd430};
// 1. Add paint data
{
SkDEBUGCODE(UniformExpectationsValidator paintUev(&gatherer, kUniforms);)
gatherer.write(SkV4{10.f, 20.f, 30.f, 40.f}); // Same paint uniform as Block E
gatherer.add(proxyA, {});
UniformDataBlock paintUdb = gatherer.endPaintData();
UniformDataCache::Index paintUID = uCache.insert(paintUdb);
REPORTER_ASSERT(reporter, paintUID == uID5); // Should de-duplicate with Block E
REPORTER_ASSERT(reporter, uCache.count() == 3); // Count should NOT increase
}
// 2. Add render step data
{
gatherer.setRenderStepManagerActive(); // Switch to render step mode
SkDEBUGCODE(UniformExpectationsValidator rsUev(&gatherer, kUniforms);)
gatherer.write(SkV4{1.f, 2.f, 3.f, 4.f}); // Same render step uniform as Block A
gatherer.add(proxyB, {});
auto [rsUdb, combinedTdb] = gatherer.endRenderStepData(/*performsShading=*/true);
UniformDataCache::Index rsUID = uCache.insert(rsUdb);
REPORTER_ASSERT(reporter, rsUID == uID1); // Should de-duplicate with Block A
REPORTER_ASSERT(reporter, uCache.count() == 3); // Count should NOT increase
// 3. Check combined texture data
REPORTER_ASSERT(reporter, combinedTdb.numTextures() == 2);
TextureDataCache::Index combinedTID = tCache.insert(combinedTdb);
REPORTER_ASSERT(reporter, combinedTID != tID1); // New binding
REPORTER_ASSERT(reporter, tCache.bindingCount() == 3); // Count increases
REPORTER_ASSERT(reporter, tCache.uniqueTextureCount() == 2); // Still 2 unique proxies
}
}
}