diff --git a/src/dawn_native/CommandValidation.cpp b/src/dawn_native/CommandValidation.cpp index 78f8949c1e..75101f031c 100644 --- a/src/dawn_native/CommandValidation.cpp +++ b/src/dawn_native/CommandValidation.cpp @@ -192,6 +192,7 @@ namespace dawn_native { "Command disallowed inside a render bundle")); } + DAWN_TRY(ValidateDebugGroups(debugGroupStackSize)); DAWN_TRY(usageTracker.ValidateRenderPassUsages()); ASSERT(resourceUsage != nullptr); *resourceUsage = usageTracker.AcquireResourceUsage(); diff --git a/src/tests/unittests/validation/RenderBundleValidationTests.cpp b/src/tests/unittests/validation/RenderBundleValidationTests.cpp index daac454384..6c38506691 100644 --- a/src/tests/unittests/validation/RenderBundleValidationTests.cpp +++ b/src/tests/unittests/validation/RenderBundleValidationTests.cpp @@ -173,6 +173,65 @@ TEST_F(RenderBundleValidationTest, SimpleSuccess) { commandEncoder.Finish(); } +// Test that render bundle debug groups must be well nested. +TEST_F(RenderBundleValidationTest, DebugGroups) { + DummyRenderPass renderPass(device); + + utils::ComboRenderBundleEncoderDescriptor desc = {}; + desc.colorFormatsCount = 1; + desc.cColorFormats[0] = renderPass.attachmentFormat; + + // Test a single debug group works. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PushDebugGroup("group"); + renderBundleEncoder.PopDebugGroup(); + renderBundleEncoder.Finish(); + } + + // Test nested debug groups work. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PushDebugGroup("group"); + renderBundleEncoder.PushDebugGroup("group2"); + renderBundleEncoder.PopDebugGroup(); + renderBundleEncoder.PopDebugGroup(); + renderBundleEncoder.Finish(); + } + + // Test popping when no group is pushed is invalid. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PopDebugGroup(); + ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish()); + } + + // Test popping too many times is invalid. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PushDebugGroup("group"); + renderBundleEncoder.PopDebugGroup(); + renderBundleEncoder.PopDebugGroup(); + ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish()); + } + + // Test that a single debug group must be popped. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PushDebugGroup("group"); + ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish()); + } + + // Test that all debug groups must be popped. + { + dawn::RenderBundleEncoder renderBundleEncoder = device.CreateRenderBundleEncoder(&desc); + renderBundleEncoder.PushDebugGroup("group"); + renderBundleEncoder.PushDebugGroup("group2"); + renderBundleEncoder.PopDebugGroup(); + ASSERT_DEVICE_ERROR(renderBundleEncoder.Finish()); + } +} + // Test render bundles do not inherit command buffer state TEST_F(RenderBundleValidationTest, StateInheritance) { DummyRenderPass renderPass(device);