| // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "base/bind.h" |
| #include "base/containers/queue.h" |
| #include "gpu/command_buffer/service/sync_point_manager.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace gpu { |
| |
| class SyncPointManagerTest : public testing::Test { |
| public: |
| SyncPointManagerTest() : sync_point_manager_(new SyncPointManager) {} |
| ~SyncPointManagerTest() override = default; |
| |
| protected: |
| // Simple static function which can be used to test callbacks. |
| static void SetIntegerFunction(int* test, int value) { *test = value; } |
| |
| std::unique_ptr<SyncPointManager> sync_point_manager_; |
| }; |
| |
| struct SyncPointStream { |
| scoped_refptr<SyncPointOrderData> order_data; |
| scoped_refptr<SyncPointClientState> client_state; |
| base::queue<uint32_t> order_numbers; |
| |
| SyncPointStream(SyncPointManager* sync_point_manager, |
| CommandBufferNamespace namespace_id, |
| CommandBufferId command_buffer_id) |
| : order_data(sync_point_manager->CreateSyncPointOrderData()), |
| client_state(sync_point_manager->CreateSyncPointClientState( |
| namespace_id, |
| command_buffer_id, |
| order_data->sequence_id())) {} |
| |
| ~SyncPointStream() { |
| if (order_data) |
| order_data->Destroy(); |
| if (client_state) |
| client_state->Destroy(); |
| } |
| |
| void AllocateOrderNum() { |
| order_numbers.push(order_data->GenerateUnprocessedOrderNumber()); |
| } |
| |
| void BeginProcessing() { |
| ASSERT_FALSE(order_numbers.empty()); |
| order_data->BeginProcessingOrderNumber(order_numbers.front()); |
| } |
| |
| void EndProcessing() { |
| ASSERT_FALSE(order_numbers.empty()); |
| order_data->FinishProcessingOrderNumber(order_numbers.front()); |
| order_numbers.pop(); |
| } |
| }; |
| |
| TEST_F(SyncPointManagerTest, BasicSyncPointOrderDataTest) { |
| scoped_refptr<SyncPointOrderData> order_data = |
| sync_point_manager_->CreateSyncPointOrderData(); |
| |
| EXPECT_EQ(0u, order_data->current_order_num()); |
| EXPECT_EQ(0u, order_data->processed_order_num()); |
| EXPECT_EQ(0u, order_data->unprocessed_order_num()); |
| |
| uint32_t order_num = order_data->GenerateUnprocessedOrderNumber(); |
| EXPECT_EQ(1u, order_num); |
| |
| EXPECT_EQ(0u, order_data->current_order_num()); |
| EXPECT_EQ(0u, order_data->processed_order_num()); |
| EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| |
| order_data->BeginProcessingOrderNumber(order_num); |
| EXPECT_EQ(order_num, order_data->current_order_num()); |
| EXPECT_EQ(0u, order_data->processed_order_num()); |
| EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| EXPECT_TRUE(order_data->IsProcessingOrderNumber()); |
| |
| order_data->PauseProcessingOrderNumber(order_num); |
| EXPECT_FALSE(order_data->IsProcessingOrderNumber()); |
| |
| order_data->BeginProcessingOrderNumber(order_num); |
| EXPECT_TRUE(order_data->IsProcessingOrderNumber()); |
| |
| order_data->FinishProcessingOrderNumber(order_num); |
| EXPECT_EQ(order_num, order_data->current_order_num()); |
| EXPECT_EQ(order_num, order_data->processed_order_num()); |
| EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| EXPECT_FALSE(order_data->IsProcessingOrderNumber()); |
| |
| order_data->Destroy(); |
| } |
| |
| TEST_F(SyncPointManagerTest, BasicFenceSyncRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kBufferId, release_count); |
| |
| // Can't wait for sync token before client is registered. |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| SyncPointStream stream(sync_point_manager_.get(), kNamespaceId, kBufferId); |
| |
| stream.AllocateOrderNum(); |
| |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| stream.order_data->BeginProcessingOrderNumber(1); |
| stream.client_state->ReleaseFenceSync(release_count); |
| stream.order_data->FinishProcessingOrderNumber(1); |
| |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, MultipleClientsPerOrderData) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId1); |
| SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId2); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token1(kNamespaceId, kCmdBufferId1, release_count); |
| stream1.AllocateOrderNum(); |
| |
| SyncToken sync_token2(kNamespaceId, kCmdBufferId2, release_count); |
| stream2.AllocateOrderNum(); |
| |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token1)); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token2)); |
| |
| stream1.order_data->BeginProcessingOrderNumber(1); |
| stream1.client_state->ReleaseFenceSync(release_count); |
| stream1.order_data->FinishProcessingOrderNumber(1); |
| |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token1)); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token2)); |
| } |
| |
| TEST_F(SyncPointManagerTest, BasicFenceSyncWaitRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| wait_stream.BeginProcessing(); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| release_stream.BeginProcessing(); |
| release_stream.client_state->ReleaseFenceSync(release_count); |
| EXPECT_EQ(123, test_num); |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, WaitOnSelfFails) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kWaitCmdBufferId, release_count); |
| |
| wait_stream.BeginProcessing(); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_FALSE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, OutOfOrderRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| // Generate wait order number first. |
| wait_stream.AllocateOrderNum(); |
| release_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| wait_stream.BeginProcessing(); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_FALSE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, HigherOrderNumberRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| // Generate wait order number first. |
| wait_stream.AllocateOrderNum(); |
| release_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| // Order number was higher but it was actually released. |
| release_stream.BeginProcessing(); |
| release_stream.client_state->ReleaseFenceSync(release_count); |
| release_stream.EndProcessing(); |
| |
| // Release stream has already released so there's no need to wait. |
| wait_stream.BeginProcessing(); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_FALSE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, DestroyedClientRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| wait_stream.BeginProcessing(); |
| |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| |
| // Destroying the client should release the wait. |
| release_stream.client_state->Destroy(); |
| release_stream.client_state = nullptr; |
| |
| EXPECT_EQ(123, test_num); |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, NonExistentRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| // Assign release stream order [1] and wait stream order [2]. |
| // This test simply tests that a wait stream of order [2] waiting on |
| // release stream of order [1] will still release the fence sync even |
| // though nothing was released. |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| wait_stream.BeginProcessing(); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| // No release but finishing the order number should automatically release. |
| release_stream.BeginProcessing(); |
| EXPECT_EQ(10, test_num); |
| release_stream.EndProcessing(); |
| EXPECT_EQ(123, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, NonExistentRelease2) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| // Assign Release stream order [1] and assign Wait stream orders [2, 3]. |
| // This test is similar to the NonExistentRelease case except |
| // we place an extra order number in between the release and wait. |
| // The wait stream [3] is waiting on release stream [1] even though |
| // order [2] was also generated. Although order [2] only exists on the |
| // wait stream so the release stream should only know about order [1]. |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| // Have wait with order [3] to wait on release. |
| wait_stream.BeginProcessing(); |
| EXPECT_EQ(2u, wait_stream.order_data->current_order_num()); |
| wait_stream.EndProcessing(); |
| wait_stream.BeginProcessing(); |
| EXPECT_EQ(3u, wait_stream.order_data->current_order_num()); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| // Even though release stream order [1] did not have a release, it |
| // should have changed test_num although the fence sync is still not released. |
| release_stream.BeginProcessing(); |
| EXPECT_EQ(1u, release_stream.order_data->current_order_num()); |
| release_stream.EndProcessing(); |
| EXPECT_EQ(123, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| |
| // Ensure that the wait callback does not get triggered again when it is |
| // actually released. |
| test_num = 1; |
| release_stream.AllocateOrderNum(); |
| release_stream.BeginProcessing(); |
| release_stream.client_state->ReleaseFenceSync(release_count); |
| release_stream.EndProcessing(); |
| EXPECT_EQ(1, test_num); |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kReleaseCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kWaitCmdBufferId = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| kReleaseCmdBufferId); |
| SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| kWaitCmdBufferId); |
| |
| // Assign Release stream orders [1, 4] and assign Wait stream orders [2, 3]. |
| // Here we are testing that wait order [3] will wait on a fence sync |
| // in either order [1] or order [2]. Order [2] was not actually assigned |
| // to the release stream so it is essentially non-existent to the release |
| // stream's point of view. Once the release stream begins processing the next |
| // order [3], it should realize order [2] didn't exist and release the fence. |
| release_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| wait_stream.AllocateOrderNum(); |
| release_stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kReleaseCmdBufferId, release_count); |
| |
| // Have wait with order [3] to wait on release order [1] or [2]. |
| wait_stream.BeginProcessing(); |
| EXPECT_EQ(2u, wait_stream.order_data->current_order_num()); |
| wait_stream.EndProcessing(); |
| wait_stream.BeginProcessing(); |
| EXPECT_EQ(3u, wait_stream.order_data->current_order_num()); |
| int test_num = 10; |
| bool valid_wait = wait_stream.client_state->Wait( |
| sync_token, base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, |
| &test_num, 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| |
| // Release stream should know it should release fence sync by order [3], but |
| // it has no unprocessed order numbers less than 3, so it runs the callback. |
| release_stream.BeginProcessing(); |
| EXPECT_EQ(1u, release_stream.order_data->current_order_num()); |
| release_stream.EndProcessing(); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| EXPECT_EQ(123, test_num); |
| |
| // Ensure that the wait callback does not get triggered again when it is |
| // actually released. |
| release_stream.BeginProcessing(); |
| test_num = 10; |
| release_stream.client_state->ReleaseFenceSync(1); |
| EXPECT_EQ(10, test_num); |
| EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, WaitOnSameSequenceFails) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kCmdBufferId = CommandBufferId::FromUnsafeValue(0x123); |
| |
| SyncPointStream stream(sync_point_manager_.get(), kNamespaceId, kCmdBufferId); |
| |
| // Dummy order number to avoid the wait_order_num <= processed_order_num + 1 |
| // check in SyncPointOrderData::ValidateReleaseOrderNum. |
| sync_point_manager_->GenerateOrderNumber(); |
| |
| // Order number for the wait. |
| stream.AllocateOrderNum(); |
| |
| uint64_t release_count = 1; |
| SyncToken sync_token(kNamespaceId, kCmdBufferId, release_count); |
| |
| int test_num = 10; |
| bool valid_wait = sync_point_manager_->Wait( |
| sync_token, stream.order_data->sequence_id(), |
| stream.order_data->unprocessed_order_num(), |
| base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num, |
| 123)); |
| EXPECT_FALSE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); |
| } |
| |
| TEST_F(SyncPointManagerTest, HandleInvalidWaitOrderNumber) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId1); |
| SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId2); |
| |
| stream1.AllocateOrderNum(); // stream 1, order num 1 |
| stream2.AllocateOrderNum(); // stream 2, order num 2 |
| stream2.AllocateOrderNum(); // stream 2, order num 3 |
| stream1.AllocateOrderNum(); // stream 1, order num 4 |
| |
| // Run stream 1, order num 1. |
| stream1.BeginProcessing(); |
| stream1.EndProcessing(); |
| |
| // Stream 2 waits on stream 1 with order num 3. This wait is invalid because |
| // there's no unprocessed order num less than 3 on stream 1. |
| int test_num = 10; |
| bool valid_wait = sync_point_manager_->Wait( |
| SyncToken(kNamespaceId, kCmdBufferId1, 1), |
| stream2.order_data->sequence_id(), 3, |
| base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num, |
| 123)); |
| EXPECT_FALSE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| } |
| |
| TEST_F(SyncPointManagerTest, RetireInvalidWaitAfterOrderNumberPasses) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId1); |
| SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId2); |
| |
| stream1.AllocateOrderNum(); // stream 1, order num 1 |
| stream1.AllocateOrderNum(); // stream 1, order num 2 |
| stream2.AllocateOrderNum(); // stream 2, order num 3 |
| |
| // Stream 2 waits on stream 1 with order num 3. |
| int test_num = 10; |
| bool valid_wait = sync_point_manager_->Wait( |
| SyncToken(kNamespaceId, kCmdBufferId1, 1), |
| stream2.order_data->sequence_id(), 3, |
| base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num, |
| 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num); |
| |
| stream1.AllocateOrderNum(); // stream 1, order num 4 |
| |
| // Run stream 1, order num 1. The wait isn't retired. |
| stream1.BeginProcessing(); |
| stream1.EndProcessing(); |
| EXPECT_EQ(10, test_num); |
| |
| // Run stream 1, order num 2. Wait is retired because we reach the last order |
| // number that was unprocessed at the time the wait was enqueued. |
| stream1.BeginProcessing(); |
| stream1.EndProcessing(); |
| EXPECT_EQ(123, test_num); |
| } |
| |
| TEST_F(SyncPointManagerTest, HandleInvalidCyclicWaits) { |
| CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; |
| CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); |
| CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); |
| |
| SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId1); |
| SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, |
| kCmdBufferId2); |
| |
| stream1.AllocateOrderNum(); // stream 1, order num 1 |
| stream2.AllocateOrderNum(); // stream 2, order num 2 |
| stream1.AllocateOrderNum(); // stream 1, order num 3 |
| stream2.AllocateOrderNum(); // stream 2, order num 4 |
| |
| // Stream 2 waits on stream 1 with order num 2. |
| int test_num1 = 10; |
| bool valid_wait = sync_point_manager_->Wait( |
| SyncToken(kNamespaceId, kCmdBufferId1, 1), |
| stream2.order_data->sequence_id(), 2, |
| base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num1, |
| 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num1); |
| |
| // Stream 1 waits on stream 2 with order num 3. |
| int test_num2 = 10; |
| valid_wait = sync_point_manager_->Wait( |
| SyncToken(kNamespaceId, kCmdBufferId2, 1), |
| stream1.order_data->sequence_id(), 3, |
| base::BindOnce(&SyncPointManagerTest::SetIntegerFunction, &test_num2, |
| 123)); |
| EXPECT_TRUE(valid_wait); |
| EXPECT_EQ(10, test_num2); |
| |
| // Run stream 1, order num 1. |
| stream1.BeginProcessing(); |
| stream1.EndProcessing(); |
| |
| // Since there's no unprocessed order num less than 2 on stream 1, the wait is |
| // released. |
| EXPECT_EQ(123, test_num1); |
| EXPECT_EQ(10, test_num2); |
| |
| // Run stream 2, order num 2. |
| stream2.BeginProcessing(); |
| stream2.EndProcessing(); |
| |
| // Since there's no unprocessed order num less than 3 on stream 2, the wait is |
| // released. |
| EXPECT_EQ(123, test_num1); |
| EXPECT_EQ(123, test_num2); |
| } |
| |
| } // namespace gpu |