Compare commits

...

1 Commits

Author SHA1 Message Date
Kevin Granade
c5e64564a1 Use the backend test cleanup helper more extensively
BUGS=[408310509]
2025-08-15 12:44:25 -07:00
13 changed files with 303 additions and 336 deletions

View File

@@ -145,7 +145,6 @@ static void createFaces(DriverApi& dapi, Handle<HwTexture> texture, int baseWidt
TEST_F(BlitTest, ColorMagnify) {
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
constexpr int kSrcTexWidth = 256;
constexpr int kSrcTexHeight = 256;
@@ -207,7 +206,6 @@ TEST_F(BlitTest, ColorMagnify) {
TEST_F(BlitTest, ColorMinify) {
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
constexpr int kSrcTexWidth = 1024;
constexpr int kSrcTexHeight = 1024;
@@ -342,7 +340,6 @@ TEST_F(BlitTest, ColorResolve) {
TEST_F(BlitTest, Blit2DTextureArray) {
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
api.startCapture(0);
mCleanup.addPostCall([&]() { api.stopCapture(0); });
@@ -412,7 +409,6 @@ TEST_F(BlitTest, Blit2DTextureArray) {
TEST_F(BlitTest, BlitRegion) {
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
constexpr int kSrcTexWidth = 1024;
constexpr int kSrcTexHeight = 1024;
@@ -488,7 +484,6 @@ TEST_F(BlitTest, BlitRegion) {
TEST_F(BlitTest, BlitRegionToSwapChain) {
FAIL_IF(Backend::VULKAN, "Crashes due to not finding color attachment, see b/417481493");
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
constexpr int kSrcTexWidth = 1024;
constexpr int kSrcTexHeight = 1024;
@@ -541,13 +536,13 @@ TEST_F(BlitTest, BlitRegionToSwapChain) {
dstRect, srcRenderTargets[srcLevel],
srcRect, SamplerMagFilter::LINEAR);
api.commit(swapChain);
}
api.commit(swapChain);
// TODO: for some reason, this test has been disabled. It needs to be tested on all
// machines.
// EXPECT_IMAGE(dstRenderTarget,
// ScreenshotParams(kDstTexWidth, kDstTexHeight, "BlitRegionToSwapChain", 0x0));
// TODO: for some reason, this test has been disabled. It needs to be tested on all
// machines.
// EXPECT_IMAGE(dstRenderTarget,
// ScreenshotParams(kDstTexWidth, kDstTexHeight, "BlitRegionToSwapChain", 0x0));
}
}
} // namespace test

View File

@@ -91,6 +91,7 @@ TEST_F(BufferUpdatesTest, VertexBufferUpdate) {
shader.bindUniform<SimpleMaterialParams>(api, ubuffer, kBindingConfig);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
// Upload the uniform, but with an offset to accommodate the padding in the shader's
// uniform definition.
@@ -101,29 +102,42 @@ TEST_F(BufferUpdatesTest, VertexBufferUpdate) {
});
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
{
RenderFrame frame(api);
// Draw 10 triangles, updating the vertex buffer / index buffer each time.
size_t triangleIndex = 0;
for (float i = -1.0f; i < 1.0f; i += 0.2f) {
const float low = i, high = i + 0.2;
const filament::math::float2 v[3]{{ low, low },
{ high, low },
{ low, high }};
triangle.updateVertices(v);
// Draw 10 triangles, updating the vertex buffer / index buffer each time.
size_t triangleIndex = 0;
for (float i = -1.0f; i < 1.0f; i += 0.2f) {
const float low = i, high = i + 0.2;
const filament::math::float2 v[3]{{ low, low },
{ high, low },
{ low, high }};
triangle.updateVertices(v);
if (updateIndices) {
if (triangleIndex % 2 == 0) {
// Upload each index separately, to test offsets.
const TrianglePrimitive::index_type i[3]{ 0, 1, 2 };
triangle.updateIndices(i + 0, 1, 0);
triangle.updateIndices(i + 1, 1, 1);
triangle.updateIndices(i + 2, 1, 2);
} else {
// This effectively hides this triangle.
const TrianglePrimitive::index_type i[3]{ 0, 0, 0 };
triangle.updateIndices(i);
if (updateIndices) {
if (triangleIndex % 2 == 0) {
// Upload each index separately, to test offsets.
const TrianglePrimitive::index_type i[3]{ 0, 1, 2 };
triangle.updateIndices(i + 0, 1, 0);
triangle.updateIndices(i + 1, 1, 1);
triangle.updateIndices(i + 2, 1, 2);
} else {
// This effectively hides this triangle.
const TrianglePrimitive::index_type i[3]{ 0, 0, 0 };
triangle.updateIndices(i);
}
}
if (triangleIndex > 0) {
params.flags.clear = TargetBufferFlags::NONE;
params.flags.discardStart = TargetBufferFlags::NONE;
}
api.beginRenderPass(defaultRenderTarget, params);
api.draw(state, triangle.getRenderPrimitive(), 0, 3, 1);
api.endRenderPass();
triangleIndex++;
}
if (triangleIndex > 0) {
@@ -141,15 +155,7 @@ TEST_F(BufferUpdatesTest, VertexBufferUpdate) {
triangleIndex++;
}
api.flush();
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
}
executeCommands();
}
// This test renders two triangles in two separate draw calls. Between the draw calls, a uniform
@@ -241,15 +247,13 @@ TEST_F(BufferUpdatesTest, BufferObjectUpdateWithOffset) {
"BufferObjectUpdateWithOffset", 2320747245));
api.flush();
api.commit(swapChain);
api.endFrame(0);
{
RenderFrame frame(api);
api.commit(swapChain);
}
// This ensures all driver commands have finished before exiting the test.
api.finish();
executeCommands();
getDriver().purge();
}
} // namespace test

View File

@@ -29,58 +29,61 @@ TEST_F(BackendTest, FrameScheduledCallback) {
SKIP_IF(Backend::VULKAN, "Frame callbacks are unsupported in Vulkan, see b/417254479");
SKIP_IF(Backend::WEBGPU, "Frame callbacks are unsupported in WebGPU");
auto& api = getDriverApi();
Cleanup cleanup(api);
// Create a SwapChain.
// In order for the frameScheduledCallback to be called, this must be a real SwapChain (not
// headless) so we obtain a drawable.
auto swapChain = cleanup.add(createSwapChain());
Handle<HwRenderTarget> renderTarget = cleanup.add(api.createDefaultRenderTarget());
int callbackCountA = 0;
api.setFrameScheduledCallback(swapChain, nullptr, [&callbackCountA](PresentCallable callable) {
callable();
callbackCountA++;
}, 0);
// Render the first frame.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
api.endFrame(0);
// Render the next frame. The same callback should be called.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
api.endFrame(0);
// Now switch out the callback.
int callbackCountB = 0;
api.setFrameScheduledCallback(swapChain, nullptr, [&callbackCountB](PresentCallable callable) {
callable();
callbackCountB++;
}, 0);
{
auto& api = getDriverApi();
Cleanup cleanup(api);
cleanup.addPostCall([&]() { executeCommands(); });
cleanup.addPostCall([&]() { getDriver().purge(); });
// Render one final frame.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
api.endFrame(0);
// Create a SwapChain.
// In order for the frameScheduledCallback to be called, this must be a real SwapChain (not
// headless) so we obtain a drawable.
auto swapChain = cleanup.add(createSwapChain());
api.finish();
Handle<HwRenderTarget> renderTarget = cleanup.add(api.createDefaultRenderTarget());
executeCommands();
getDriver().purge();
api.setFrameScheduledCallback(swapChain, nullptr, [&callbackCountA](PresentCallable callable) {
callable();
callbackCountA++;
}, 0);
// Render the first frame.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
}
// Render the next frame. The same callback should be called.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
}
// Now switch out the callback.
api.setFrameScheduledCallback(swapChain, nullptr, [&callbackCountB](PresentCallable callable) {
callable();
callbackCountB++;
}, 0);
// Render one final frame.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.beginRenderPass(renderTarget, {});
api.endRenderPass(0);
api.commit(swapChain);
}
api.finish();
}
EXPECT_EQ(callbackCountA, 2);
EXPECT_EQ(callbackCountB, 1);
}
@@ -90,43 +93,47 @@ TEST_F(BackendTest, FrameCompletedCallback) {
SKIP_IF(Backend::VULKAN, "Frame callbacks are unsupported in Vulkan, see b/417254479");
SKIP_IF(Backend::WEBGPU, "Frame callbacks are unsupported in WebGPU");
auto& api = getDriverApi();
Cleanup cleanup(api);
// Create a SwapChain.
auto swapChain = cleanup.add(api.createSwapChainHeadless(256, 256, 0));
int callbackCountA = 0;
api.setFrameCompletedCallback(swapChain, nullptr,
[&callbackCountA]() { callbackCountA++; });
// Render the first frame.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.commit(swapChain);
api.endFrame(0);
// Render the next frame. The same callback should be called.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.commit(swapChain);
api.endFrame(0);
// Now switch out the callback.
int callbackCountB = 0;
api.setFrameCompletedCallback(swapChain, nullptr,
[&callbackCountB]() { callbackCountB++; });
{
auto& api = getDriverApi();
Cleanup cleanup(api);
cleanup.addPostCall([&]() { executeCommands(); });
cleanup.addPostCall([&]() { getDriver().purge(); });
// Render one final frame.
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
api.commit(swapChain);
api.endFrame(0);
// Create a SwapChain.
auto swapChain = cleanup.add(api.createSwapChainHeadless(256, 256, 0));
api.finish();
api.setFrameCompletedCallback(swapChain, nullptr,
[&callbackCountA]() { callbackCountA++; });
executeCommands();
getDriver().purge();
// Render the first frame.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.commit(swapChain);
}
// Render the next frame. The same callback should be called.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.commit(swapChain);
}
// Now switch out the callback.
api.setFrameCompletedCallback(swapChain, nullptr,
[&callbackCountB]() { callbackCountB++; });
// Render one final frame.
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.commit(swapChain);
}
api.finish();
}
EXPECT_EQ(callbackCountA, 2);
EXPECT_EQ(callbackCountB, 1);

View File

@@ -158,7 +158,10 @@ TEST_F(BackendTest, FeedbackLoops) {
PixelBufferDescriptor pb(buffer, size, PixelDataFormat::RGBA, PixelDataType::UBYTE, cb);
api.update3DImage(texture, 0, 0, 0, 0, kTexWidth, kTexHeight, 1, std::move(pb));
for (int frame = 0; frame < kNumFrames; frame++) {
for (int frameCount = 0; frameCount < kNumFrames; frameCount++) {
Cleanup frameCleanup(api);
frameCleanup.addPostCall([&]() { executeCommands(); });
frameCleanup.addPostCall([&]() { getDriver().purge(); });
// Prep for rendering.
PipelineState state = getColorWritePipelineState();
@@ -191,9 +194,9 @@ TEST_F(BackendTest, FeedbackLoops) {
};
shader.bindUniform<MaterialParams>(api, ubuffer, uniformBinding);
shader.uploadUniform(api, ubuffer, uniformBinding, MaterialParams{
.fbWidth = float(params.viewport.width),
.fbHeight = float(params.viewport.height),
.sourceLevel = float(sourceLevel),
.fbWidth = float(params.viewport.width),
.fbHeight = float(params.viewport.height),
.sourceLevel = float(sourceLevel),
});
api.beginRenderPass(renderTargets[targetLevel], params);
@@ -246,7 +249,7 @@ TEST_F(BackendTest, FeedbackLoops) {
//
// NOTE: Calling glReadPixels on any miplevel other than the base level
// seems to be un-reliable on some GPU's.
if (frame == kNumFrames - 1) {
if (frameCount == kNumFrames - 1) {
EXPECT_IMAGE(renderTargets[0],
ScreenshotParams(kTexWidth, kTexHeight, "FeedbackLoops", 4192780705));
}
@@ -255,8 +258,6 @@ TEST_F(BackendTest, FeedbackLoops) {
api.commit(swapChain);
api.endFrame(0);
api.finish();
executeCommands();
getDriver().purge();
}
}
}

View File

@@ -314,15 +314,19 @@ TEST_F(LoadImageTest, UpdateImage2D) {
api.startCapture();
Cleanup cleanup(api);
cleanup.addPostCall([&]() { api.finish(); });
cleanup.addPostCall([&]() { api.stopCapture(); });
// The test is executed within this block scope to force destructors to run before
// executeCommands().
for (const auto& t : testCases) {
Cleanup cleanup(api);
Cleanup caseCleanup(api);
// Create a platform-specific SwapChain and make it current.
auto swapChain = cleanup.add(createSwapChain());
auto swapChain = caseCleanup.add(createSwapChain());
api.makeCurrent(swapChain, swapChain);
auto defaultRenderTarget = cleanup.add(api.createDefaultRenderTarget(0));
auto defaultRenderTarget = caseCleanup.add(api.createDefaultRenderTarget(0));
// Create a program.
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo { "test", "tex", 0,
@@ -386,8 +390,6 @@ TEST_F(LoadImageTest, UpdateImage2D) {
api.commit(swapChain);
api.endFrame(0);
}
api.stopCapture();
}
TEST_F(LoadImageTest, UpdateImageSRGB) {
@@ -398,6 +400,7 @@ TEST_F(LoadImageTest, UpdateImageSRGB) {
auto& api = getDriverApi();
Cleanup cleanup(api);
api.startCapture();
cleanup.addPostCall([&]() { api.stopCapture(); });
PixelDataFormat const pixelFormat = PixelDataFormat::RGBA;
PixelDataType const pixelType = PixelDataType::UBYTE;
@@ -445,37 +448,36 @@ TEST_F(LoadImageTest, UpdateImageSRGB) {
api.update3DImage(texture, 0, 0, 0, 0, kTexSize, kTexSize, 1, std::move(descriptor));
api.beginFrame(0, 0, 0);
{
RenderFrame frame(api);
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
api.bindDescriptorSet(descriptorSet, 0, {});
api.bindDescriptorSet(descriptorSet, 0, {});
RenderPassParams params = getClearColorRenderPass();
params.viewport.width = kTexSize;
params.viewport.height = kTexSize;
PipelineState state = getColorWritePipelineState();
shader.addProgramToPipelineState(state);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = mTriangle.getVertexBufferInfo();
api.beginRenderPass(defaultRenderTarget, params);
api.bindPipeline(state);
api.bindRenderPrimitive(mTriangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
RenderPassParams params = getClearColorRenderPass();
params.viewport.width = kTexSize;
params.viewport.height = kTexSize;
PipelineState state = getColorWritePipelineState();
shader.addProgramToPipelineState(state);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = mTriangle.getVertexBufferInfo();
api.beginRenderPass(defaultRenderTarget, params);
api.bindPipeline(state);
api.bindRenderPrimitive(mTriangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(kTexSize, kTexSize, "UpdateImageSRGB", 3300305265));
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(kTexSize, kTexSize, "UpdateImageSRGB", 3300305265));
api.commit(swapChain);
api.endFrame(0);
api.stopCapture();
api.commit(swapChain);
}
}
TEST_F(LoadImageTest, UpdateImageMipLevel) {
@@ -486,6 +488,7 @@ TEST_F(LoadImageTest, UpdateImageMipLevel) {
auto& api = getDriverApi();
Cleanup cleanup(api);
api.startCapture();
cleanup.addPostCall([&]() { api.stopCapture(); });
PixelDataFormat pixelFormat = PixelDataFormat::RGBA;
PixelDataType pixelType = PixelDataType::HALF;
@@ -518,17 +521,7 @@ TEST_F(LoadImageTest, UpdateImageMipLevel) {
PixelBufferDescriptor descriptor = checkerboardPixelBuffer(pixelFormat, pixelType, kTexSize);
api.update3DImage(texture, /* level*/ 1, 0, 0, 0, kTexSize, kTexSize, 1, std::move(descriptor));
api.beginFrame(0, 0, 0);
// Update samplers.
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {
.filterMag = SamplerMagFilter::LINEAR,
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST
});
api.bindDescriptorSet(descriptorSet, 0, {});
RenderFrame outerFrame(api);
{
RenderFrame frame(api);
RenderPassParams params = getClearColorRenderPass();
@@ -549,9 +542,6 @@ TEST_F(LoadImageTest, UpdateImageMipLevel) {
ScreenshotParams(kTexSize, kTexSize, "UpdateImageMipLevel", 1875922935));
api.commit(swapChain);
api.endFrame(0);
api.stopCapture();
}
TEST_F(LoadImageTest, UpdateImage3D) {
@@ -564,6 +554,7 @@ TEST_F(LoadImageTest, UpdateImage3D) {
auto& api = getDriverApi();
Cleanup cleanup(api);
api.startCapture();
cleanup.addPostCall([&]() { api.stopCapture(); });
PixelDataFormat pixelFormat = PixelDataFormat::RGBA;
PixelDataType pixelType = PixelDataType::FLOAT;
@@ -634,8 +625,6 @@ TEST_F(LoadImageTest, UpdateImage3D) {
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(kTexSize, kTexSize, "UpdateImage3D", 1875922935));
}
api.stopCapture();
}
} // namespace test

View File

@@ -108,28 +108,27 @@ TEST_F(BackendTest, MRT) {
RenderPassParams params = getClearColorRenderPass();
params.viewport = getFullViewport();
Cleanup captureCleanup(api);
api.startCapture(0);
captureCleanup.addPostCall([&]() { api.stopCapture(0); });
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
{
RenderFrame frame(api);
// Draw a triangle.
api.beginRenderPass(renderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
// Draw a triangle.
api.beginRenderPass(renderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.flush();
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
api.flush();
api.commit(swapChain);
}
}
executeCommands();
}
} // namespace test

View File

@@ -56,8 +56,9 @@ using namespace filament::backend;
TEST_F(BackendTest, TextureViewLod) {
auto& api = getDriverApi();
api.startCapture(0);
Cleanup cleanup(api);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
// The test is executed within this block scope to force destructors to run before
// executeCommands().
@@ -123,7 +124,7 @@ TEST_F(BackendTest, TextureViewLod) {
TrianglePrimitive triangle(api);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
// We set the base mip to 1, and the max mip to 3
// Level 0: 128x128 (red)
@@ -211,15 +212,9 @@ TEST_F(BackendTest, TextureViewLod) {
api.endRenderPass();
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
}
api.finish();
executeCommands();
getDriver().purge();
}
} // namespace test

View File

@@ -59,10 +59,11 @@ using namespace filament::backend;
* successfully.
*/
TEST_F(BackendTest, MissingRequiredAttributes) {
DriverApi& api = getDriverApi();
// The test is executed within this block scope to force destructors to run before
// executeCommands().
{
DriverApi& api = getDriverApi();
Cleanup cleanup(api);
// Create a platform-specific SwapChain and make it current.
auto swapChain = cleanup.add(createSwapChain());
@@ -86,9 +87,10 @@ TEST_F(BackendTest, MissingRequiredAttributes) {
params.viewport = getFullViewport();
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);
@@ -101,12 +103,7 @@ TEST_F(BackendTest, MissingRequiredAttributes) {
api.flush();
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
}
executeCommands();
}
} // namespace test

View File

@@ -111,12 +111,13 @@ TEST_F(BackendTest, PushConstants) {
auto& api = getDriverApi();
api.startCapture(0);
Cleanup cleanup(api);
// The test is executed within this block scope to force destructors to run before
// executeCommands().
{
Cleanup cleanup(api);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
// Create a SwapChain and make it current.
auto swapChain = cleanup.add(createSwapChain());
api.makeCurrent(swapChain, swapChain);
@@ -141,7 +142,7 @@ TEST_F(BackendTest, PushConstants) {
ps.rasterState.depthWrite = false;
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
api.beginRenderPass(renderTarget, params);
api.bindPipeline(ps);
@@ -183,10 +184,7 @@ TEST_F(BackendTest, PushConstants) {
"pushConstants", 3575588741));
api.commit(swapChain);
api.endFrame(0);
}
api.stopCapture(0);
}
} // namespace test

View File

@@ -288,7 +288,7 @@ TEST_F(ReadPixelsTest, ReadPixels) {
params.viewport.height = t.getRenderTargetSize();
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame (api);
// Render a white triangle over blue.
api.beginRenderPass(renderTarget, params);
@@ -350,11 +350,7 @@ TEST_F(ReadPixelsTest, ReadPixels) {
api.endRenderPass();
api.commit(swapChain);
api.endFrame(0);
}
// This ensures all driver commands have finished before exiting the test.
flushAndWait();
}
TEST_F(ReadPixelsTest, ReadPixelsPerformance) {
@@ -363,6 +359,7 @@ TEST_F(ReadPixelsTest, ReadPixelsPerformance) {
DriverApi& api = getDriverApi();
Cleanup cleanup(api);
cleanup.addPostCall([&]() { executeCommands(); });
// Create a platform-specific SwapChain and make it current.
auto swapChain = cleanup.add(
@@ -416,28 +413,29 @@ TEST_F(ReadPixelsTest, ReadPixelsPerformance) {
}
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
{
RenderFrame frame(api);
// Render some content, just so we don't read back uninitialized data.
api.beginRenderPass(renderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
// Render some content, just so we don't read back uninitialized data.
api.beginRenderPass(renderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
PixelBufferDescriptor descriptor(buffer, renderTargetSize * renderTargetSize * 4,
PixelDataFormat::RGBA, PixelDataType::UBYTE, 1, 0, 0, renderTargetSize,
[](void* buffer, size_t size, void* user) {
ReadPixelsTest* test = (ReadPixelsTest*)user;
test->readPixelsFinished = true;
}, this);
PixelBufferDescriptor descriptor(buffer, renderTargetSize * renderTargetSize * 4,
PixelDataFormat::RGBA, PixelDataType::UBYTE, 1, 0, 0, renderTargetSize,
[](void* buffer, size_t size, void* user) {
ReadPixelsTest* test = (ReadPixelsTest*) user;
test->readPixelsFinished = true;
}, this);
api.readPixels(renderTarget, 0, 0, renderTargetSize, renderTargetSize,
std::move(descriptor));
api.commit(swapChain);
api.endFrame(0);
api.readPixels(renderTarget, 0, 0, renderTargetSize, renderTargetSize,
std::move(descriptor));
api.commit(swapChain);
}
flushAndWait();
getDriver().purge();
@@ -448,7 +446,6 @@ TEST_F(ReadPixelsTest, ReadPixelsPerformance) {
free(buffer);
api.finish();
executeCommands();
}
} // namespace test

View File

@@ -81,31 +81,31 @@ TEST_F(BackendTest, RenderExternalImageWithoutSet) {
DescriptorSetHandle descriptorSet = shader.createDescriptorSet(api);
api.startCapture(0);
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
{
Cleanup cleanupCapture(api);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {});
api.bindDescriptorSet(descriptorSet, 0, {});
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {});
api.bindDescriptorSet(descriptorSet, 0, {});
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.flush();
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.flush();
api.commit(swapChain);
}
}
api.finish();
executeCommands();
}
TEST_F(BackendTest, RenderExternalImage) {
@@ -180,32 +180,32 @@ TEST_F(BackendTest, RenderExternalImage) {
RenderPassParams params = getClearColorRenderPass();
params.viewport = getFullViewport();
api.startCapture(0);
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
{
Cleanup cleanupCapture(api);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
api.makeCurrent(swapChain, swapChain);
{
RenderFrame frame(api);
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {});
api.bindDescriptorSet(descriptorSet, 0, {});
api.updateDescriptorSetTexture(descriptorSet, 0, texture, {});
api.bindDescriptorSet(descriptorSet, 0, {});
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.flush();
api.commit(swapChain);
api.endFrame(0);
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(screenWidth(), screenHeight(), "RenderExternalImage", 1206264951));
api.stopCapture(0);
api.finish();
flushAndWait();
// Render a triangle.
api.beginRenderPass(defaultRenderTarget, params);
state.primitiveType = PrimitiveType::TRIANGLES;
state.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(state);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.flush();
api.commit(swapChain);
}
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(screenWidth(), screenHeight(), "RenderExternalImage", 1206264951));
}
}
} // namespace test

View File

@@ -43,8 +43,9 @@ TEST_F(BackendTest, ScissorViewportRegion) {
constexpr int kSrcRtWidth = 384;
constexpr int kSrcRtHeight = 384;
api.startCapture(0);
Cleanup cleanup(api);
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
// color texture (mip level 1) 512x512 depth texture (mip level 0) 512x512
// +----------------------------------------+ +------------------------------------------+
@@ -121,7 +122,7 @@ TEST_F(BackendTest, ScissorViewportRegion) {
shader.addProgramToPipelineState(ps);
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
api.beginRenderPass(srcRenderTarget, params);
api.scissor(scissor);
@@ -136,9 +137,6 @@ TEST_F(BackendTest, ScissorViewportRegion) {
ScreenshotParams(kSrcTexWidth >> 1, kSrcTexHeight >> 1, "scissor", 15842520));
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
}
}
@@ -146,12 +144,11 @@ TEST_F(BackendTest, ScissorViewportRegion) {
TEST_F(BackendTest, ScissorViewportEdgeCases) {
auto& api = getDriverApi();
api.startCapture(0);
Cleanup cleanup(api);
// The test is executed within this block scope to force destructors to run before
// executeCommands().
{
Cleanup cleanup(api);
api.startCapture(0);
// Create a SwapChain and make it current. We don't really use it so the res doesn't matter.
auto swapChain = cleanup.add(api.createSwapChainHeadless(256, 256, 0));
api.makeCurrent(swapChain, swapChain);
@@ -201,7 +198,7 @@ TEST_F(BackendTest, ScissorViewportEdgeCases) {
shader.addProgramToPipelineState(ps);
api.makeCurrent(swapChain, swapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
api.beginRenderPass(renderTarget, params);
api.scissor(scissor);
@@ -228,9 +225,6 @@ TEST_F(BackendTest, ScissorViewportEdgeCases) {
ScreenshotParams(512, 512, "ScissorViewportEdgeCases", 2199186852));
api.commit(swapChain);
api.endFrame(0);
api.stopCapture(0);
}
}

View File

@@ -89,7 +89,7 @@ public:
ps.stencilState.front.stencilOpDepthStencilPass = StencilOperation::INCR;
api.makeCurrent(mSwapChain, mSwapChain);
api.beginFrame(0, 0, 0);
RenderFrame frame(api);
api.beginRenderPass(renderTarget, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
@@ -117,7 +117,6 @@ public:
api.endRenderPass();
api.commit(mSwapChain);
api.endFrame(0);
}
void TearDown() override {
@@ -146,9 +145,6 @@ TEST_F(BasicStencilBufferTest, StencilBuffer) {
EXPECT_IMAGE(renderTarget,
ScreenshotParams(screenWidth(), screenHeight(), "StencilBuffer", 0x3B1AEF0F));
flushAndWait();
getDriver().purge();
}
TEST_F(BasicStencilBufferTest, DepthAndStencilBuffer) {
@@ -172,9 +168,6 @@ TEST_F(BasicStencilBufferTest, DepthAndStencilBuffer) {
EXPECT_IMAGE(renderTarget,
ScreenshotParams(screenWidth(), screenHeight(), "DepthAndStencilBuffer", 0x3B1AEF0F));
flushAndWait();
getDriver().purge();
}
TEST_F(BasicStencilBufferTest, StencilBufferMSAA) {
@@ -204,6 +197,7 @@ TEST_F(BasicStencilBufferTest, StencilBufferMSAA) {
{ depthStencilTextureMSAA }, { depthStencilTextureMSAA }));
api.startCapture(0);
cleanup.addPostCall([&]() { api.stopCapture(0); });
// We'll be using a triangle as geometry.
TrianglePrimitive smallTriangle(api);
@@ -233,44 +227,41 @@ TEST_F(BasicStencilBufferTest, StencilBufferMSAA) {
ps.stencilState.front.stencilOpDepthStencilPass = StencilOperation::INCR;
api.makeCurrent(mSwapChain, mSwapChain);
api.beginFrame(0, 0, 0);
{
RenderFrame frame(api);
api.beginRenderPass(renderTarget0, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
ps.vertexBufferInfo = smallTriangle.getVertexBufferInfo();
api.bindPipeline(ps);
api.bindRenderPrimitive(smallTriangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.beginRenderPass(renderTarget0, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
ps.vertexBufferInfo = smallTriangle.getVertexBufferInfo();
api.bindPipeline(ps);
api.bindRenderPrimitive(smallTriangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
// Step 2: Render a larger triangle with the stencil test enabled.
params.flags.clear = TargetBufferFlags::COLOR0;
params.flags.discardStart = TargetBufferFlags::COLOR0;
params.flags.discardEnd = TargetBufferFlags::STENCIL;
params.clearColor = math::float4(0.0f, 0.0f, 1.0f, 1.0f);
ps.rasterState.colorWrite = true;
ps.stencilState.stencilWrite = false;
ps.stencilState.front.stencilOpDepthStencilPass = StencilOperation::KEEP;
ps.stencilState.front.stencilFunc = StencilState::StencilFunction::E;
ps.stencilState.front.ref = 0u;
// Step 2: Render a larger triangle with the stencil test enabled.
params.flags.clear = TargetBufferFlags::COLOR0;
params.flags.discardStart = TargetBufferFlags::COLOR0;
params.flags.discardEnd = TargetBufferFlags::STENCIL;
params.clearColor = math::float4(0.0f, 0.0f, 1.0f, 1.0f);
ps.rasterState.colorWrite = true;
ps.stencilState.stencilWrite = false;
ps.stencilState.front.stencilOpDepthStencilPass = StencilOperation::KEEP;
ps.stencilState.front.stencilFunc = StencilState::StencilFunction::E;
ps.stencilState.front.ref = 0u;
api.beginRenderPass(renderTarget1, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
ps.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(ps);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.commit(mSwapChain);
api.stopCapture(0);
api.endFrame(0);
api.beginRenderPass(renderTarget1, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
ps.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(ps);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
api.commit(mSwapChain);
api.stopCapture(0);
}
EXPECT_IMAGE(renderTarget1, ScreenshotParams(screenWidth(), screenHeight(),
"StencilBufferAutoResolve", 3353562179));
flushAndWait();
getDriver().purge();
}
} // namespace test