OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <queue> |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "gpu/command_buffer/service/sync_point_manager.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 namespace gpu { |
| 12 |
| 13 class SyncPointManagerTest : public testing::Test { |
| 14 public: |
| 15 SyncPointManagerTest() {} |
| 16 |
| 17 ~SyncPointManagerTest() override {} |
| 18 |
| 19 protected: |
| 20 void SetUp() override { |
| 21 sync_point_manager_.reset(new SyncPointManager(false)); |
| 22 } |
| 23 |
| 24 void TearDown() override { sync_point_manager_.reset(); } |
| 25 |
| 26 // Simple static function which can be used to test callbacks. |
| 27 static void SetIntegerFunction(int* test, int value) { *test = value; } |
| 28 |
| 29 scoped_ptr<SyncPointManager> sync_point_manager_; |
| 30 }; |
| 31 |
| 32 struct SyncPointStream { |
| 33 scoped_refptr<SyncPointOrderData> order_data; |
| 34 scoped_ptr<SyncPointClient> client; |
| 35 std::queue<uint32_t> order_numbers; |
| 36 |
| 37 SyncPointStream(SyncPointManager* sync_point_manager, |
| 38 CommandBufferNamespace namespace_id, |
| 39 uint64_t command_buffer_id) |
| 40 : order_data(SyncPointOrderData::Create()), |
| 41 client(sync_point_manager->CreateSyncPointClient(order_data, |
| 42 namespace_id, |
| 43 command_buffer_id)) {} |
| 44 |
| 45 ~SyncPointStream() { |
| 46 order_data->Destroy(); |
| 47 order_data = nullptr; |
| 48 } |
| 49 |
| 50 void AllocateOrderNum(SyncPointManager* sync_point_manager) { |
| 51 order_numbers.push( |
| 52 order_data->GenerateUnprocessedOrderNumber(sync_point_manager)); |
| 53 } |
| 54 |
| 55 void BeginProcessing() { |
| 56 ASSERT_FALSE(order_numbers.empty()); |
| 57 order_data->BeginProcessingOrderNumber(order_numbers.front()); |
| 58 } |
| 59 |
| 60 void EndProcessing() { |
| 61 ASSERT_FALSE(order_numbers.empty()); |
| 62 order_data->FinishProcessingOrderNumber(order_numbers.front()); |
| 63 order_numbers.pop(); |
| 64 } |
| 65 }; |
| 66 |
| 67 TEST_F(SyncPointManagerTest, BasicSyncPointOrderDataTest) { |
| 68 scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
| 69 |
| 70 EXPECT_EQ(0u, order_data->current_order_num()); |
| 71 EXPECT_EQ(0u, order_data->processed_order_num()); |
| 72 EXPECT_EQ(0u, order_data->unprocessed_order_num()); |
| 73 |
| 74 const uint32_t order_num = |
| 75 order_data->GenerateUnprocessedOrderNumber(sync_point_manager_.get()); |
| 76 EXPECT_EQ(1u, order_num); |
| 77 |
| 78 EXPECT_EQ(0u, order_data->current_order_num()); |
| 79 EXPECT_EQ(0u, order_data->processed_order_num()); |
| 80 EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| 81 |
| 82 order_data->BeginProcessingOrderNumber(order_num); |
| 83 EXPECT_EQ(order_num, order_data->current_order_num()); |
| 84 EXPECT_EQ(0u, order_data->processed_order_num()); |
| 85 EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| 86 |
| 87 order_data->FinishProcessingOrderNumber(order_num); |
| 88 EXPECT_EQ(order_num, order_data->current_order_num()); |
| 89 EXPECT_EQ(order_num, order_data->processed_order_num()); |
| 90 EXPECT_EQ(order_num, order_data->unprocessed_order_num()); |
| 91 } |
| 92 |
| 93 TEST_F(SyncPointManagerTest, SyncPointClientRegistration) { |
| 94 const CommandBufferNamespace kNamespaceId = |
| 95 gpu::CommandBufferNamespace::GPU_IO; |
| 96 const uint64_t kBufferId = 0x123; |
| 97 |
| 98 scoped_refptr<SyncPointClientState> empty_state = |
| 99 sync_point_manager_->GetSyncPointClientState(kNamespaceId, kBufferId); |
| 100 EXPECT_FALSE(empty_state); |
| 101 |
| 102 scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
| 103 |
| 104 scoped_ptr<SyncPointClient> client = |
| 105 sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, |
| 106 kBufferId); |
| 107 |
| 108 EXPECT_EQ(order_data, client->client_state()->order_data()); |
| 109 EXPECT_EQ( |
| 110 client->client_state(), |
| 111 sync_point_manager_->GetSyncPointClientState(kNamespaceId, kBufferId)); |
| 112 } |
| 113 |
| 114 TEST_F(SyncPointManagerTest, BasicFenceSyncRelease) { |
| 115 const CommandBufferNamespace kNamespaceId = |
| 116 gpu::CommandBufferNamespace::GPU_IO; |
| 117 const uint64_t kBufferId = 0x123; |
| 118 |
| 119 scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
| 120 scoped_ptr<SyncPointClient> client = |
| 121 sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, |
| 122 kBufferId); |
| 123 scoped_refptr<SyncPointClientState> client_state = client->client_state(); |
| 124 |
| 125 EXPECT_EQ(0u, client_state->fence_sync_release()); |
| 126 EXPECT_FALSE(client_state->IsFenceSyncReleased(1)); |
| 127 |
| 128 client->ReleaseFenceSync(1); |
| 129 |
| 130 EXPECT_EQ(1u, client_state->fence_sync_release()); |
| 131 EXPECT_TRUE(client_state->IsFenceSyncReleased(1)); |
| 132 } |
| 133 |
| 134 TEST_F(SyncPointManagerTest, MultipleClientsPerOrderData) { |
| 135 const CommandBufferNamespace kNamespaceId = |
| 136 gpu::CommandBufferNamespace::GPU_IO; |
| 137 const uint64_t kBufferId1 = 0x123; |
| 138 const uint64_t kBufferId2 = 0x234; |
| 139 |
| 140 scoped_refptr<SyncPointOrderData> order_data = SyncPointOrderData::Create(); |
| 141 scoped_ptr<SyncPointClient> client1 = |
| 142 sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, |
| 143 kBufferId1); |
| 144 scoped_ptr<SyncPointClient> client2 = |
| 145 sync_point_manager_->CreateSyncPointClient(order_data, kNamespaceId, |
| 146 kBufferId2); |
| 147 |
| 148 scoped_refptr<SyncPointClientState> client_state1 = client1->client_state(); |
| 149 scoped_refptr<SyncPointClientState> client_state2 = client2->client_state(); |
| 150 |
| 151 client1->ReleaseFenceSync(1); |
| 152 |
| 153 EXPECT_TRUE(client_state1->IsFenceSyncReleased(1)); |
| 154 EXPECT_FALSE(client_state2->IsFenceSyncReleased(1)); |
| 155 } |
| 156 |
| 157 TEST_F(SyncPointManagerTest, BasicFenceSyncWaitRelease) { |
| 158 const CommandBufferNamespace kNamespaceId = |
| 159 gpu::CommandBufferNamespace::GPU_IO; |
| 160 const uint64_t kBufferId1 = 0x123; |
| 161 const uint64_t kBufferId2 = 0x234; |
| 162 |
| 163 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 164 kBufferId1); |
| 165 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 166 kBufferId2); |
| 167 |
| 168 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 169 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 170 |
| 171 wait_stream.BeginProcessing(); |
| 172 int test_num = 10; |
| 173 const bool valid_wait = wait_stream.client->Wait( |
| 174 release_stream.client->client_state().get(), 1, |
| 175 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 176 ASSERT_TRUE(valid_wait); |
| 177 EXPECT_EQ(10, test_num); |
| 178 |
| 179 release_stream.BeginProcessing(); |
| 180 release_stream.client->ReleaseFenceSync(1); |
| 181 EXPECT_EQ(123, test_num); |
| 182 } |
| 183 |
| 184 TEST_F(SyncPointManagerTest, WaitOnSelfFails) { |
| 185 const CommandBufferNamespace kNamespaceId = |
| 186 gpu::CommandBufferNamespace::GPU_IO; |
| 187 const uint64_t kBufferId1 = 0x123; |
| 188 const uint64_t kBufferId2 = 0x234; |
| 189 |
| 190 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 191 kBufferId1); |
| 192 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 193 kBufferId2); |
| 194 |
| 195 // Generate wait order number first. |
| 196 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 197 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 198 |
| 199 wait_stream.BeginProcessing(); |
| 200 int test_num = 10; |
| 201 const bool valid_wait = wait_stream.client->Wait( |
| 202 wait_stream.client->client_state().get(), 1, |
| 203 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 204 EXPECT_FALSE(valid_wait); |
| 205 EXPECT_EQ(123, test_num); |
| 206 } |
| 207 |
| 208 TEST_F(SyncPointManagerTest, OutOfOrderRelease) { |
| 209 const CommandBufferNamespace kNamespaceId = |
| 210 gpu::CommandBufferNamespace::GPU_IO; |
| 211 const uint64_t kBufferId1 = 0x123; |
| 212 const uint64_t kBufferId2 = 0x234; |
| 213 |
| 214 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 215 kBufferId1); |
| 216 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 217 kBufferId2); |
| 218 |
| 219 // Generate wait order number first. |
| 220 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 221 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 222 |
| 223 wait_stream.BeginProcessing(); |
| 224 int test_num = 10; |
| 225 const bool valid_wait = wait_stream.client->Wait( |
| 226 release_stream.client->client_state().get(), 1, |
| 227 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 228 EXPECT_FALSE(valid_wait); |
| 229 EXPECT_EQ(123, test_num); |
| 230 } |
| 231 |
| 232 TEST_F(SyncPointManagerTest, HigherOrderNumberRelease) { |
| 233 const CommandBufferNamespace kNamespaceId = |
| 234 gpu::CommandBufferNamespace::GPU_IO; |
| 235 const uint64_t kBufferId1 = 0x123; |
| 236 const uint64_t kBufferId2 = 0x234; |
| 237 |
| 238 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 239 kBufferId1); |
| 240 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 241 kBufferId2); |
| 242 |
| 243 // Generate wait order number first. |
| 244 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 245 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 246 |
| 247 // Order number was higher but it was actually released. |
| 248 release_stream.BeginProcessing(); |
| 249 release_stream.client->ReleaseFenceSync(1); |
| 250 release_stream.EndProcessing(); |
| 251 |
| 252 wait_stream.BeginProcessing(); |
| 253 int test_num = 10; |
| 254 const bool valid_wait = wait_stream.client->Wait( |
| 255 release_stream.client->client_state().get(), 1, |
| 256 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 257 EXPECT_TRUE(valid_wait); |
| 258 EXPECT_EQ(123, test_num); |
| 259 } |
| 260 |
| 261 TEST_F(SyncPointManagerTest, DestroyedClientRelease) { |
| 262 const CommandBufferNamespace kNamespaceId = |
| 263 gpu::CommandBufferNamespace::GPU_IO; |
| 264 const uint64_t kBufferId1 = 0x123; |
| 265 const uint64_t kBufferId2 = 0x234; |
| 266 |
| 267 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 268 kBufferId1); |
| 269 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 270 kBufferId2); |
| 271 |
| 272 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 273 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 274 |
| 275 wait_stream.BeginProcessing(); |
| 276 int test_num = 10; |
| 277 const bool valid_wait = wait_stream.client->Wait( |
| 278 release_stream.client->client_state().get(), 1, |
| 279 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 280 EXPECT_TRUE(valid_wait); |
| 281 EXPECT_EQ(10, test_num); |
| 282 |
| 283 // Destroying the client should release the wait. |
| 284 release_stream.client.reset(); |
| 285 EXPECT_EQ(123, test_num); |
| 286 } |
| 287 |
| 288 TEST_F(SyncPointManagerTest, NonExistentRelease) { |
| 289 const CommandBufferNamespace kNamespaceId = |
| 290 gpu::CommandBufferNamespace::GPU_IO; |
| 291 const uint64_t kBufferId1 = 0x123; |
| 292 const uint64_t kBufferId2 = 0x234; |
| 293 |
| 294 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 295 kBufferId1); |
| 296 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 297 kBufferId2); |
| 298 |
| 299 // Assign release stream order [1] and wait stream order [2]. |
| 300 // This test simply tests that a wait stream of order [2] waiting on |
| 301 // release stream of order [1] will still release the fence sync even |
| 302 // though nothing was released. |
| 303 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 304 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 305 |
| 306 wait_stream.BeginProcessing(); |
| 307 int test_num = 10; |
| 308 const bool valid_wait = wait_stream.client->Wait( |
| 309 release_stream.client->client_state().get(), 1, |
| 310 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 311 EXPECT_TRUE(valid_wait); |
| 312 EXPECT_EQ(10, test_num); |
| 313 |
| 314 // No release but finishing the order number should automatically release. |
| 315 release_stream.BeginProcessing(); |
| 316 EXPECT_EQ(10, test_num); |
| 317 release_stream.EndProcessing(); |
| 318 EXPECT_EQ(123, test_num); |
| 319 } |
| 320 |
| 321 TEST_F(SyncPointManagerTest, NonExistentRelease2) { |
| 322 const CommandBufferNamespace kNamespaceId = |
| 323 gpu::CommandBufferNamespace::GPU_IO; |
| 324 const uint64_t kBufferId1 = 0x123; |
| 325 const uint64_t kBufferId2 = 0x234; |
| 326 |
| 327 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 328 kBufferId1); |
| 329 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 330 kBufferId2); |
| 331 |
| 332 // Assign Release stream order [1] and assign Wait stream orders [2, 3]. |
| 333 // This test is similar to the NonExistentRelease case except |
| 334 // we place an extra order number in between the release and wait. |
| 335 // The wait stream [3] is waiting on release stream [1] even though |
| 336 // order [2] was also generated. Although order [2] only exists on the |
| 337 // wait stream so the release stream should only know about order [1]. |
| 338 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 339 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 340 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 341 |
| 342 // Have wait with order [3] to wait on release. |
| 343 wait_stream.BeginProcessing(); |
| 344 ASSERT_EQ(2u, wait_stream.order_data->current_order_num()); |
| 345 wait_stream.EndProcessing(); |
| 346 wait_stream.BeginProcessing(); |
| 347 ASSERT_EQ(3u, wait_stream.order_data->current_order_num()); |
| 348 int test_num = 10; |
| 349 const bool valid_wait = wait_stream.client->Wait( |
| 350 release_stream.client->client_state().get(), 1, |
| 351 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 352 EXPECT_TRUE(valid_wait); |
| 353 EXPECT_EQ(10, test_num); |
| 354 |
| 355 // Even though release stream order [1] did not have a release, it |
| 356 // should still release the fence when finish processing since the wait |
| 357 // stream had expected on to exist there. |
| 358 release_stream.BeginProcessing(); |
| 359 ASSERT_EQ(1u, release_stream.order_data->current_order_num()); |
| 360 release_stream.EndProcessing(); |
| 361 EXPECT_TRUE(release_stream.client->client_state()->IsFenceSyncReleased(1)); |
| 362 EXPECT_EQ(123, test_num); |
| 363 } |
| 364 |
| 365 TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) { |
| 366 const CommandBufferNamespace kNamespaceId = |
| 367 gpu::CommandBufferNamespace::GPU_IO; |
| 368 const uint64_t kBufferId1 = 0x123; |
| 369 const uint64_t kBufferId2 = 0x234; |
| 370 |
| 371 SyncPointStream release_stream(sync_point_manager_.get(), kNamespaceId, |
| 372 kBufferId1); |
| 373 SyncPointStream wait_stream(sync_point_manager_.get(), kNamespaceId, |
| 374 kBufferId2); |
| 375 |
| 376 // Assign Release stream orders [1, 4] and assign Wait stream orders [2, 3]. |
| 377 // Here we are testing that wait order [3] will wait on a fence sync |
| 378 // in either order [1] or order [2]. Order [2] was not actually assigned |
| 379 // to the release stream so it is essentially non-existent to the release |
| 380 // stream's point of view. Once the release stream begins processing the next |
| 381 // order [3], it should realize order [2] didn't exist and release the fence. |
| 382 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 383 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 384 wait_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 385 release_stream.AllocateOrderNum(sync_point_manager_.get()); |
| 386 |
| 387 // Have wait with order [3] to wait on release order [1] or [2]. |
| 388 wait_stream.BeginProcessing(); |
| 389 ASSERT_EQ(2u, wait_stream.order_data->current_order_num()); |
| 390 wait_stream.EndProcessing(); |
| 391 wait_stream.BeginProcessing(); |
| 392 ASSERT_EQ(3u, wait_stream.order_data->current_order_num()); |
| 393 int test_num = 10; |
| 394 const bool valid_wait = wait_stream.client->Wait( |
| 395 release_stream.client->client_state().get(), 1, |
| 396 base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); |
| 397 EXPECT_TRUE(valid_wait); |
| 398 EXPECT_EQ(10, test_num); |
| 399 |
| 400 // Release stream should know it should release fence sync by order [3], |
| 401 // so going through order [1] should not release it yet. |
| 402 release_stream.BeginProcessing(); |
| 403 ASSERT_EQ(1u, release_stream.order_data->current_order_num()); |
| 404 release_stream.EndProcessing(); |
| 405 EXPECT_FALSE(release_stream.client->client_state()->IsFenceSyncReleased(1)); |
| 406 EXPECT_EQ(10, test_num); |
| 407 |
| 408 // Beginning order [4] should immediately trigger the release. |
| 409 release_stream.BeginProcessing(); |
| 410 ASSERT_EQ(4u, release_stream.order_data->current_order_num()); |
| 411 EXPECT_TRUE(release_stream.client->client_state()->IsFenceSyncReleased(1)); |
| 412 EXPECT_EQ(123, test_num); |
| 413 } |
| 414 |
| 415 } // namespace gpu |
OLD | NEW |