1 // Copyright (c) 2012 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 "gpu/command_buffer/service/common_decoder.h" 6 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace gpu { 10 11 TEST(CommonDecoderBucket, Basic) { 12 CommonDecoder::Bucket bucket; 13 EXPECT_EQ(0u, bucket.size()); 14 EXPECT_TRUE(NULL == bucket.GetData(0, 0)); 15 } 16 17 TEST(CommonDecoderBucket, Size) { 18 CommonDecoder::Bucket bucket; 19 bucket.SetSize(24); 20 EXPECT_EQ(24u, bucket.size()); 21 bucket.SetSize(12); 22 EXPECT_EQ(12u, bucket.size()); 23 } 24 25 TEST(CommonDecoderBucket, GetData) { 26 CommonDecoder::Bucket bucket; 27 28 bucket.SetSize(24); 29 EXPECT_TRUE(NULL != bucket.GetData(0, 0)); 30 EXPECT_TRUE(NULL != bucket.GetData(24, 0)); 31 EXPECT_TRUE(NULL == bucket.GetData(25, 0)); 32 EXPECT_TRUE(NULL != bucket.GetData(0, 24)); 33 EXPECT_TRUE(NULL == bucket.GetData(0, 25)); 34 bucket.SetSize(23); 35 EXPECT_TRUE(NULL == bucket.GetData(0, 24)); 36 } 37 38 TEST(CommonDecoderBucket, SetData) { 39 CommonDecoder::Bucket bucket; 40 static const char data[] = "testing"; 41 42 bucket.SetSize(10); 43 EXPECT_TRUE(bucket.SetData(data, 0, sizeof(data))); 44 EXPECT_EQ(0, memcmp(data, bucket.GetData(0, sizeof(data)), sizeof(data))); 45 EXPECT_TRUE(bucket.SetData(data, 2, sizeof(data))); 46 EXPECT_EQ(0, memcmp(data, bucket.GetData(2, sizeof(data)), sizeof(data))); 47 EXPECT_FALSE(bucket.SetData(data, 0, sizeof(data) * 2)); 48 EXPECT_FALSE(bucket.SetData(data, 5, sizeof(data))); 49 } 50 51 class TestCommonDecoder : public CommonDecoder { 52 public: 53 // Overridden from AsyncAPIInterface 54 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE { 55 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 56 } 57 58 // Overridden from AsyncAPIInterface 59 virtual error::Error DoCommand( 60 unsigned int command, 61 unsigned int arg_count, 62 const void* cmd_data) OVERRIDE { 63 return DoCommonCommand(command, arg_count, cmd_data); 64 } 65 66 CommonDecoder::Bucket* GetBucket(uint32 id) const { 67 return CommonDecoder::GetBucket(id); 68 } 69 }; 70 71 class MockCommandBufferEngine : public CommandBufferEngine { 72 public: 73 static const int32 kStartValidShmId = 1; 74 static const int32 kValidShmId = 2; 75 static const int32 kInvalidShmId = 3; 76 static const size_t kBufferSize = 1024; 77 static const int32 kValidOffset = kBufferSize / 2; 78 static const int32 kInvalidOffset = kBufferSize; 79 80 MockCommandBufferEngine() 81 : CommandBufferEngine(), 82 token_(), 83 get_offset_(0) { 84 } 85 86 // Overridden from CommandBufferEngine. 87 virtual Buffer GetSharedMemoryBuffer(int32 shm_id) OVERRIDE { 88 Buffer buffer; 89 if (IsValidSharedMemoryId(shm_id)) { 90 buffer.ptr = buffer_; 91 buffer.size = kBufferSize; 92 } 93 return buffer; 94 } 95 96 template <typename T> 97 T GetSharedMemoryAs(uint32 offset) { 98 DCHECK_LT(offset, kBufferSize); 99 return reinterpret_cast<T>(&buffer_[offset]); 100 } 101 102 int32 GetSharedMemoryOffset(const void* memory) { 103 ptrdiff_t offset = reinterpret_cast<const int8*>(memory) - &buffer_[0]; 104 DCHECK_GE(offset, 0); 105 DCHECK_LT(static_cast<size_t>(offset), kBufferSize); 106 return static_cast<int32>(offset); 107 } 108 109 // Overridden from CommandBufferEngine. 110 virtual void set_token(int32 token) OVERRIDE { 111 token_ = token; 112 } 113 114 int32 token() const { 115 return token_; 116 } 117 118 // Overridden from CommandBufferEngine. 119 virtual bool SetGetBuffer(int32 transfer_buffer_id) OVERRIDE { 120 NOTREACHED(); 121 return false; 122 } 123 124 // Overridden from CommandBufferEngine. 125 virtual bool SetGetOffset(int32 offset) OVERRIDE { 126 if (static_cast<size_t>(offset) < kBufferSize) { 127 get_offset_ = offset; 128 return true; 129 } 130 return false; 131 } 132 133 // Overridden from CommandBufferEngine. 134 virtual int32 GetGetOffset() OVERRIDE { 135 return get_offset_; 136 } 137 138 private: 139 bool IsValidSharedMemoryId(int32 shm_id) { 140 return shm_id == kValidShmId || shm_id == kStartValidShmId; 141 } 142 143 int8 buffer_[kBufferSize]; 144 int32 token_; 145 int32 get_offset_; 146 }; 147 148 const int32 MockCommandBufferEngine::kStartValidShmId; 149 const int32 MockCommandBufferEngine::kValidShmId; 150 const int32 MockCommandBufferEngine::kInvalidShmId; 151 const size_t MockCommandBufferEngine::kBufferSize; 152 const int32 MockCommandBufferEngine::kValidOffset; 153 const int32 MockCommandBufferEngine::kInvalidOffset; 154 155 class CommonDecoderTest : public testing::Test { 156 protected: 157 virtual void SetUp() { 158 decoder_.set_engine(&engine_); 159 } 160 161 virtual void TearDown() { 162 } 163 164 template <typename T> 165 error::Error ExecuteCmd(const T& cmd) { 166 COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); 167 return decoder_.DoCommand(cmd.kCmdId, 168 ComputeNumEntries(sizeof(cmd)) - 1, 169 &cmd); 170 } 171 172 template <typename T> 173 error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { 174 COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); 175 return decoder_.DoCommand(cmd.kCmdId, 176 ComputeNumEntries(sizeof(cmd) + data_size) - 1, 177 &cmd); 178 } 179 180 MockCommandBufferEngine engine_; 181 TestCommonDecoder decoder_; 182 }; 183 184 TEST_F(CommonDecoderTest, Initialize) { 185 EXPECT_EQ(0, engine_.GetGetOffset()); 186 } 187 188 TEST_F(CommonDecoderTest, DoCommonCommandInvalidCommand) { 189 EXPECT_EQ(error::kUnknownCommand, decoder_.DoCommand(999999, 0, NULL)); 190 } 191 192 TEST_F(CommonDecoderTest, HandleNoop) { 193 cmd::Noop cmd; 194 const uint32 kSkipCount = 5; 195 cmd.Init(kSkipCount); 196 EXPECT_EQ(error::kNoError, 197 ExecuteImmediateCmd( 198 cmd, kSkipCount * kCommandBufferEntrySize)); 199 const uint32 kSkipCount2 = 1; 200 cmd.Init(kSkipCount2); 201 EXPECT_EQ(error::kNoError, 202 ExecuteImmediateCmd( 203 cmd, kSkipCount2 * kCommandBufferEntrySize)); 204 } 205 206 TEST_F(CommonDecoderTest, SetToken) { 207 cmd::SetToken cmd; 208 const int32 kTokenId = 123; 209 EXPECT_EQ(0, engine_.token()); 210 cmd.Init(kTokenId); 211 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 212 EXPECT_EQ(kTokenId, engine_.token()); 213 } 214 215 TEST_F(CommonDecoderTest, SetBucketSize) { 216 cmd::SetBucketSize cmd; 217 const uint32 kBucketId = 123; 218 const uint32 kBucketLength1 = 1234; 219 const uint32 kBucketLength2 = 78; 220 // Check the bucket does not exist. 221 EXPECT_TRUE(NULL == decoder_.GetBucket(kBucketId)); 222 // Check we can create one. 223 cmd.Init(kBucketId, kBucketLength1); 224 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 225 CommonDecoder::Bucket* bucket; 226 bucket = decoder_.GetBucket(kBucketId); 227 EXPECT_TRUE(NULL != bucket); 228 EXPECT_EQ(kBucketLength1, bucket->size()); 229 // Check we can change it. 230 cmd.Init(kBucketId, kBucketLength2); 231 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 232 bucket = decoder_.GetBucket(kBucketId); 233 EXPECT_TRUE(NULL != bucket); 234 EXPECT_EQ(kBucketLength2, bucket->size()); 235 // Check we can delete it. 236 cmd.Init(kBucketId, 0); 237 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 238 bucket = decoder_.GetBucket(kBucketId); 239 EXPECT_EQ(0u, bucket->size()); 240 } 241 242 TEST_F(CommonDecoderTest, SetBucketData) { 243 cmd::SetBucketSize size_cmd; 244 cmd::SetBucketData cmd; 245 246 static const char kData[] = "1234567890123456789"; 247 248 const uint32 kBucketId = 123; 249 const uint32 kInvalidBucketId = 124; 250 251 size_cmd.Init(kBucketId, sizeof(kData)); 252 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); 253 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId); 254 // Check the data is not there. 255 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); 256 257 // Check we can set it. 258 const uint32 kSomeOffsetInSharedMemory = 50; 259 void* memory = engine_.GetSharedMemoryAs<void*>(kSomeOffsetInSharedMemory); 260 memcpy(memory, kData, sizeof(kData)); 261 cmd.Init(kBucketId, 0, sizeof(kData), 262 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 263 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 264 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); 265 266 // Check we can set it partially. 267 static const char kData2[] = "ABCEDFG"; 268 const uint32 kSomeOffsetInBucket = 5; 269 memcpy(memory, kData2, sizeof(kData2)); 270 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2), 271 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 272 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 273 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)), 274 kData2, sizeof(kData2))); 275 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData)); 276 // Check that nothing was affected outside of updated area. 277 EXPECT_EQ(kData[kSomeOffsetInBucket - 1], 278 bucket_data[kSomeOffsetInBucket - 1]); 279 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)], 280 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]); 281 282 // Check that it fails if the bucket_id is invalid 283 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2), 284 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 285 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 286 287 // Check that it fails if the offset is out of range. 288 cmd.Init(kBucketId, bucket->size(), 1, 289 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 290 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 291 292 // Check that it fails if the size is out of range. 293 cmd.Init(kBucketId, 0, bucket->size() + 1, 294 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 295 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 296 } 297 298 TEST_F(CommonDecoderTest, SetBucketDataImmediate) { 299 cmd::SetBucketSize size_cmd; 300 int8 buffer[1024]; 301 cmd::SetBucketDataImmediate& cmd = 302 *reinterpret_cast<cmd::SetBucketDataImmediate*>(&buffer); 303 304 static const char kData[] = "1234567890123456789"; 305 306 const uint32 kBucketId = 123; 307 const uint32 kInvalidBucketId = 124; 308 309 size_cmd.Init(kBucketId, sizeof(kData)); 310 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); 311 CommonDecoder::Bucket* bucket = decoder_.GetBucket(kBucketId); 312 // Check the data is not there. 313 EXPECT_NE(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); 314 315 // Check we can set it. 316 void* memory = &buffer[0] + sizeof(cmd); 317 memcpy(memory, kData, sizeof(kData)); 318 cmd.Init(kBucketId, 0, sizeof(kData)); 319 EXPECT_EQ(error::kNoError, 320 ExecuteImmediateCmd(cmd, sizeof(kData))); 321 EXPECT_EQ(0, memcmp(bucket->GetData(0, sizeof(kData)), kData, sizeof(kData))); 322 323 // Check we can set it partially. 324 static const char kData2[] = "ABCEDFG"; 325 const uint32 kSomeOffsetInBucket = 5; 326 memcpy(memory, kData2, sizeof(kData2)); 327 cmd.Init(kBucketId, kSomeOffsetInBucket, sizeof(kData2)); 328 EXPECT_EQ(error::kNoError, 329 ExecuteImmediateCmd(cmd, sizeof(kData2))); 330 EXPECT_EQ(0, memcmp(bucket->GetData(kSomeOffsetInBucket, sizeof(kData2)), 331 kData2, sizeof(kData2))); 332 const char* bucket_data = bucket->GetDataAs<const char*>(0, sizeof(kData)); 333 // Check that nothing was affected outside of updated area. 334 EXPECT_EQ(kData[kSomeOffsetInBucket - 1], 335 bucket_data[kSomeOffsetInBucket - 1]); 336 EXPECT_EQ(kData[kSomeOffsetInBucket + sizeof(kData2)], 337 bucket_data[kSomeOffsetInBucket + sizeof(kData2)]); 338 339 // Check that it fails if the bucket_id is invalid 340 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData2)); 341 EXPECT_NE(error::kNoError, 342 ExecuteImmediateCmd(cmd, sizeof(kData2))); 343 344 // Check that it fails if the offset is out of range. 345 cmd.Init(kBucketId, bucket->size(), 1); 346 EXPECT_NE(error::kNoError, 347 ExecuteImmediateCmd(cmd, sizeof(kData2))); 348 349 // Check that it fails if the size is out of range. 350 cmd.Init(kBucketId, 0, bucket->size() + 1); 351 EXPECT_NE(error::kNoError, 352 ExecuteImmediateCmd(cmd, sizeof(kData2))); 353 } 354 355 TEST_F(CommonDecoderTest, GetBucketStart) { 356 cmd::SetBucketSize size_cmd; 357 cmd::SetBucketData set_cmd; 358 cmd::GetBucketStart cmd; 359 360 static const char kData[] = "1234567890123456789"; 361 static const char zero[sizeof(kData)] = { 0, }; 362 363 const uint32 kBucketSize = sizeof(kData); 364 const uint32 kBucketId = 123; 365 const uint32 kInvalidBucketId = 124; 366 367 // Put data in the bucket. 368 size_cmd.Init(kBucketId, sizeof(kData)); 369 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); 370 const uint32 kSomeOffsetInSharedMemory = 50; 371 uint8* start = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory); 372 memcpy(start, kData, sizeof(kData)); 373 set_cmd.Init(kBucketId, 0, sizeof(kData), 374 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 375 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd)); 376 377 // Check that the size is correct with no data buffer. 378 uint32* memory = 379 engine_.GetSharedMemoryAs<uint32*>(kSomeOffsetInSharedMemory); 380 *memory = 0x0; 381 cmd.Init(kBucketId, 382 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 383 0, 0, 0); 384 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 385 EXPECT_EQ(kBucketSize, *memory); 386 387 // Check that the data is copied with data buffer. 388 const uint32 kDataOffsetInSharedMemory = 54; 389 uint8* data = engine_.GetSharedMemoryAs<uint8*>(kDataOffsetInSharedMemory); 390 *memory = 0x0; 391 memset(data, 0, sizeof(kData)); 392 cmd.Init(kBucketId, 393 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 394 kBucketSize, MockCommandBufferEngine::kValidShmId, 395 kDataOffsetInSharedMemory); 396 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 397 EXPECT_EQ(kBucketSize, *memory); 398 EXPECT_EQ(0, memcmp(data, kData, kBucketSize)); 399 400 // Check that we can get a piece. 401 *memory = 0x0; 402 memset(data, 0, sizeof(kData)); 403 const uint32 kPieceSize = kBucketSize / 2; 404 cmd.Init(kBucketId, 405 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 406 kPieceSize, MockCommandBufferEngine::kValidShmId, 407 kDataOffsetInSharedMemory); 408 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 409 EXPECT_EQ(kBucketSize, *memory); 410 EXPECT_EQ(0, memcmp(data, kData, kPieceSize)); 411 EXPECT_EQ(0, memcmp(data + kPieceSize, zero, sizeof(kData) - kPieceSize)); 412 413 // Check that it fails if the result_id is invalid 414 cmd.Init(kInvalidBucketId, 415 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 416 0, 0, 0); 417 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 418 419 // Check that it fails if the data_id is invalid 420 cmd.Init(kBucketId, 421 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 422 1, MockCommandBufferEngine::kInvalidShmId, 0); 423 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 424 425 // Check that it fails if the data_size is invalid 426 cmd.Init(kBucketId, 427 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 428 1, 0, 0); 429 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 430 cmd.Init(kBucketId, 431 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 432 MockCommandBufferEngine::kBufferSize + 1, 433 MockCommandBufferEngine::kValidShmId, 0); 434 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 435 436 // Check that it fails if the data_offset is invalid 437 cmd.Init(kBucketId, 438 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 439 0, 0, 1); 440 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 441 cmd.Init(kBucketId, 442 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 443 MockCommandBufferEngine::kBufferSize, 444 MockCommandBufferEngine::kValidShmId, 1); 445 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 446 447 // Check that it fails if the result size is not set to zero 448 *memory = 0x1; 449 cmd.Init(kBucketId, 450 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory, 451 0, 0, 0); 452 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 453 } 454 455 TEST_F(CommonDecoderTest, GetBucketData) { 456 cmd::SetBucketSize size_cmd; 457 cmd::SetBucketData set_cmd; 458 cmd::GetBucketData cmd; 459 460 static const char kData[] = "1234567890123456789"; 461 static const char zero[sizeof(kData)] = { 0, }; 462 463 const uint32 kBucketId = 123; 464 const uint32 kInvalidBucketId = 124; 465 466 size_cmd.Init(kBucketId, sizeof(kData)); 467 EXPECT_EQ(error::kNoError, ExecuteCmd(size_cmd)); 468 const uint32 kSomeOffsetInSharedMemory = 50; 469 uint8* memory = engine_.GetSharedMemoryAs<uint8*>(kSomeOffsetInSharedMemory); 470 memcpy(memory, kData, sizeof(kData)); 471 set_cmd.Init(kBucketId, 0, sizeof(kData), 472 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 473 EXPECT_EQ(error::kNoError, ExecuteCmd(set_cmd)); 474 475 // Check we can get the whole thing. 476 memset(memory, 0, sizeof(kData)); 477 cmd.Init(kBucketId, 0, sizeof(kData), 478 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 479 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 480 EXPECT_EQ(0, memcmp(memory, kData, sizeof(kData))); 481 482 // Check we can get a piece. 483 const uint32 kSomeOffsetInBucket = 5; 484 const uint32 kLengthOfPiece = 6; 485 const uint8 kSentinel = 0xff; 486 memset(memory, 0, sizeof(kData)); 487 memory[-1] = kSentinel; 488 cmd.Init(kBucketId, kSomeOffsetInBucket, kLengthOfPiece, 489 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 490 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 491 EXPECT_EQ(0, memcmp(memory, kData + kSomeOffsetInBucket, kLengthOfPiece)); 492 EXPECT_EQ(0, memcmp(memory + kLengthOfPiece, zero, 493 sizeof(kData) - kLengthOfPiece)); 494 EXPECT_EQ(kSentinel, memory[-1]); 495 496 // Check that it fails if the bucket_id is invalid 497 cmd.Init(kInvalidBucketId, kSomeOffsetInBucket, sizeof(kData), 498 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 499 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 500 501 // Check that it fails if the offset is invalid 502 cmd.Init(kBucketId, sizeof(kData) + 1, 1, 503 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 504 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 505 506 // Check that it fails if the size is invalid 507 cmd.Init(kBucketId, 0, sizeof(kData) + 1, 508 MockCommandBufferEngine::kValidShmId, kSomeOffsetInSharedMemory); 509 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 510 } 511 512 } // namespace gpu 513