Home | History | Annotate | Download | only in common
      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 // This file contains the common parts of command buffer formats.
      6 
      7 #ifndef GPU_COMMAND_BUFFER_COMMON_CMD_BUFFER_COMMON_H_
      8 #define GPU_COMMAND_BUFFER_COMMON_CMD_BUFFER_COMMON_H_
      9 
     10 #include <stddef.h>
     11 #include <stdint.h>
     12 
     13 #include "base/logging.h"
     14 #include "base/macros.h"
     15 #include "gpu/command_buffer/common/bitfield_helpers.h"
     16 #include "gpu/gpu_export.h"
     17 
     18 namespace gpu {
     19 
     20 namespace cmd {
     21   enum ArgFlags {
     22     kFixed = 0x0,
     23     kAtLeastN = 0x1
     24   };
     25 }  // namespace cmd
     26 
     27 // Pack & unpack Command cmd_flags
     28 #define CMD_FLAG_SET_TRACE_LEVEL(level)     ((level & 3) << 0)
     29 #define CMD_FLAG_GET_TRACE_LEVEL(cmd_flags) ((cmd_flags >> 0) & 3)
     30 
     31 // Computes the number of command buffer entries needed for a certain size. In
     32 // other words it rounds up to a multiple of entries.
     33 inline uint32_t ComputeNumEntries(size_t size_in_bytes) {
     34   return static_cast<uint32_t>(
     35       (size_in_bytes + sizeof(uint32_t) - 1) / sizeof(uint32_t));  // NOLINT
     36 }
     37 
     38 // Rounds up to a multiple of entries in bytes.
     39 inline size_t RoundSizeToMultipleOfEntries(size_t size_in_bytes) {
     40   return ComputeNumEntries(size_in_bytes) * sizeof(uint32_t);  // NOLINT
     41 }
     42 
     43 // Struct that defines the command header in the command buffer.
     44 struct CommandHeader {
     45   uint32_t size:21;
     46   uint32_t command:11;
     47 
     48   GPU_EXPORT static const int32_t kMaxSize = (1 << 21) - 1;
     49 
     50   void Init(uint32_t _command, int32_t _size) {
     51     DCHECK_LE(_size, kMaxSize);
     52     command = _command;
     53     size = _size;
     54   }
     55 
     56   // Sets the header based on the passed in command. Can not be used for
     57   // variable sized commands like immediate commands or Noop.
     58   template <typename T>
     59   void SetCmd() {
     60     COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
     61     Init(T::kCmdId, ComputeNumEntries(sizeof(T)));  // NOLINT
     62   }
     63 
     64   // Sets the header by a size in bytes of the immediate data after the command.
     65   template <typename T>
     66   void SetCmdBySize(uint32_t size_of_data_in_bytes) {
     67     COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
     68     Init(T::kCmdId,
     69          ComputeNumEntries(sizeof(T) + size_of_data_in_bytes));  // NOLINT
     70   }
     71 
     72   // Sets the header by a size in bytes.
     73   template <typename T>
     74   void SetCmdByTotalSize(uint32_t size_in_bytes) {
     75     COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
     76     DCHECK_GE(size_in_bytes, sizeof(T));  // NOLINT
     77     Init(T::kCmdId, ComputeNumEntries(size_in_bytes));
     78   }
     79 };
     80 
     81 COMPILE_ASSERT(sizeof(CommandHeader) == 4, Sizeof_CommandHeader_is_not_4);
     82 
     83 // Union that defines possible command buffer entries.
     84 union CommandBufferEntry {
     85   CommandHeader value_header;
     86   uint32_t value_uint32;
     87   int32_t value_int32;
     88   float value_float;
     89 };
     90 
     91 #define GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT 4
     92 const size_t kCommandBufferEntrySize = GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT;
     93 
     94 COMPILE_ASSERT(sizeof(CommandBufferEntry) == kCommandBufferEntrySize,
     95                Sizeof_CommandBufferEntry_is_not_4);
     96 
     97 // Command buffer is GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT byte aligned.
     98 #pragma pack(push, GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT)
     99 
    100 // Gets the address of memory just after a structure in a typesafe way. This is
    101 // used for IMMEDIATE commands to get the address of the place to put the data.
    102 // Immediate command put their data direclty in the command buffer.
    103 // Parameters:
    104 //   cmd: Address of command.
    105 template <typename T>
    106 void* ImmediateDataAddress(T* cmd) {
    107   COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
    108   return reinterpret_cast<char*>(cmd) + sizeof(*cmd);
    109 }
    110 
    111 // Gets the address of the place to put the next command in a typesafe way.
    112 // This can only be used for fixed sized commands.
    113 template <typename T>
    114 // Parameters:
    115 //   cmd: Address of command.
    116 void* NextCmdAddress(void* cmd) {
    117   COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
    118   return reinterpret_cast<char*>(cmd) + sizeof(T);
    119 }
    120 
    121 // Gets the address of the place to put the next command in a typesafe way.
    122 // This can only be used for variable sized command like IMMEDIATE commands.
    123 // Parameters:
    124 //   cmd: Address of command.
    125 //   size_of_data_in_bytes: Size of the data for the command.
    126 template <typename T>
    127 void* NextImmediateCmdAddress(void* cmd, uint32_t size_of_data_in_bytes) {
    128   COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
    129   return reinterpret_cast<char*>(cmd) + sizeof(T) +   // NOLINT
    130       RoundSizeToMultipleOfEntries(size_of_data_in_bytes);
    131 }
    132 
    133 // Gets the address of the place to put the next command in a typesafe way.
    134 // This can only be used for variable sized command like IMMEDIATE commands.
    135 // Parameters:
    136 //   cmd: Address of command.
    137 //   size_of_cmd_in_bytes: Size of the cmd and data.
    138 template <typename T>
    139 void* NextImmediateCmdAddressTotalSize(void* cmd,
    140                                        uint32_t total_size_in_bytes) {
    141   COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
    142   DCHECK_GE(total_size_in_bytes, sizeof(T));  // NOLINT
    143   return reinterpret_cast<char*>(cmd) +
    144       RoundSizeToMultipleOfEntries(total_size_in_bytes);
    145 }
    146 
    147 namespace cmd {
    148 
    149 // This macro is used to safely and convienently expand the list of commnad
    150 // buffer commands in to various lists and never have them get out of sync. To
    151 // add a new command, add it this list, create the corresponding structure below
    152 // and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where
    153 // COMMAND_NAME is the name of your command structure.
    154 //
    155 // NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order)
    156 #define COMMON_COMMAND_BUFFER_CMDS(OP) \
    157   OP(Noop)                          /*  0 */ \
    158   OP(SetToken)                      /*  1 */ \
    159   OP(SetBucketSize)                 /*  2 */ \
    160   OP(SetBucketData)                 /*  3 */ \
    161   OP(SetBucketDataImmediate)        /*  4 */ \
    162   OP(GetBucketStart)                /*  5 */ \
    163   OP(GetBucketData)                 /*  6 */ \
    164 
    165 // Common commands.
    166 enum CommandId {
    167   #define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name,
    168 
    169   COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
    170 
    171   #undef COMMON_COMMAND_BUFFER_CMD_OP
    172 
    173   kNumCommands,
    174   kLastCommonId = 255  // reserve 256 spaces for common commands.
    175 };
    176 
    177 COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands);
    178 
    179 const char* GetCommandName(CommandId id);
    180 
    181 // A Noop command.
    182 struct Noop {
    183   typedef Noop ValueType;
    184   static const CommandId kCmdId = kNoop;
    185   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
    186   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    187 
    188   void SetHeader(uint32_t skip_count) {
    189     DCHECK_GT(skip_count, 0u);
    190     header.Init(kCmdId, skip_count);
    191   }
    192 
    193   void Init(uint32_t skip_count) {
    194     SetHeader(skip_count);
    195   }
    196 
    197   static void* Set(void* cmd, uint32_t skip_count) {
    198     static_cast<ValueType*>(cmd)->Init(skip_count);
    199     return NextImmediateCmdAddress<ValueType>(
    200         cmd, skip_count * sizeof(CommandBufferEntry));  // NOLINT
    201   }
    202 
    203   CommandHeader header;
    204 };
    205 
    206 COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4);
    207 COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0);
    208 
    209 // The SetToken command puts a token in the command stream that you can
    210 // use to check if that token has been passed in the command stream.
    211 struct SetToken {
    212   typedef SetToken ValueType;
    213   static const CommandId kCmdId = kSetToken;
    214   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    215   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    216 
    217   void SetHeader() {
    218     header.SetCmd<ValueType>();
    219   }
    220 
    221   void Init(uint32_t _token) {
    222     SetHeader();
    223     token = _token;
    224   }
    225   static void* Set(void* cmd, uint32_t token) {
    226     static_cast<ValueType*>(cmd)->Init(token);
    227     return NextCmdAddress<ValueType>(cmd);
    228   }
    229 
    230   CommandHeader header;
    231   uint32_t token;
    232 };
    233 
    234 COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8);
    235 COMPILE_ASSERT(offsetof(SetToken, header) == 0,
    236                Offsetof_SetToken_header_not_0);
    237 COMPILE_ASSERT(offsetof(SetToken, token) == 4,
    238                Offsetof_SetToken_token_not_4);
    239 
    240 // Sets the size of a bucket for collecting data on the service side.
    241 // This is a utility for gathering data on the service side so it can be used
    242 // all at once when some service side API is called. It removes the need to add
    243 // special commands just to support a particular API. For example, any API
    244 // command that needs a string needs a way to send that string to the API over
    245 // the command buffers. While you can require that the command buffer or
    246 // transfer buffer be large enough to hold the largest string you can send,
    247 // using this command removes that restriction by letting you send smaller
    248 // pieces over and build up the data on the service side.
    249 //
    250 // You can clear a bucket on the service side and thereby free memory by sending
    251 // a size of 0.
    252 struct SetBucketSize {
    253   typedef SetBucketSize ValueType;
    254   static const CommandId kCmdId = kSetBucketSize;
    255   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    256   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    257 
    258   void SetHeader() {
    259     header.SetCmd<ValueType>();
    260   }
    261 
    262   void Init(uint32_t _bucket_id, uint32_t _size) {
    263     SetHeader();
    264     bucket_id = _bucket_id;
    265     size = _size;
    266   }
    267   static void* Set(void* cmd, uint32_t _bucket_id, uint32_t _size) {
    268     static_cast<ValueType*>(cmd)->Init(_bucket_id, _size);
    269     return NextCmdAddress<ValueType>(cmd);
    270   }
    271 
    272   CommandHeader header;
    273   uint32_t bucket_id;
    274   uint32_t size;
    275 };
    276 
    277 COMPILE_ASSERT(sizeof(SetBucketSize) == 12, Sizeof_SetBucketSize_is_not_8);
    278 COMPILE_ASSERT(offsetof(SetBucketSize, header) == 0,
    279                Offsetof_SetBucketSize_header_not_0);
    280 COMPILE_ASSERT(offsetof(SetBucketSize, bucket_id) == 4,
    281                Offsetof_SetBucketSize_bucket_id_4);
    282 COMPILE_ASSERT(offsetof(SetBucketSize, size) == 8,
    283                Offsetof_SetBucketSize_size_8);
    284 
    285 // Sets the contents of a portion of a bucket on the service side from data in
    286 // shared memory.
    287 // See SetBucketSize.
    288 struct SetBucketData {
    289   typedef SetBucketData ValueType;
    290   static const CommandId kCmdId = kSetBucketData;
    291   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    292   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    293 
    294   void SetHeader() {
    295     header.SetCmd<ValueType>();
    296   }
    297 
    298   void Init(uint32_t _bucket_id,
    299             uint32_t _offset,
    300             uint32_t _size,
    301             uint32_t _shared_memory_id,
    302             uint32_t _shared_memory_offset) {
    303     SetHeader();
    304     bucket_id = _bucket_id;
    305     offset = _offset;
    306     size = _size;
    307     shared_memory_id = _shared_memory_id;
    308     shared_memory_offset = _shared_memory_offset;
    309   }
    310   static void* Set(void* cmd,
    311                    uint32_t _bucket_id,
    312                    uint32_t _offset,
    313                    uint32_t _size,
    314                    uint32_t _shared_memory_id,
    315                    uint32_t _shared_memory_offset) {
    316     static_cast<ValueType*>(cmd)->Init(
    317         _bucket_id,
    318         _offset,
    319         _size,
    320         _shared_memory_id,
    321         _shared_memory_offset);
    322     return NextCmdAddress<ValueType>(cmd);
    323   }
    324 
    325   CommandHeader header;
    326   uint32_t bucket_id;
    327   uint32_t offset;
    328   uint32_t size;
    329   uint32_t shared_memory_id;
    330   uint32_t shared_memory_offset;
    331 };
    332 
    333 COMPILE_ASSERT(sizeof(SetBucketData) == 24, Sizeof_SetBucketData_is_not_24);
    334 COMPILE_ASSERT(offsetof(SetBucketData, header) == 0,
    335                Offsetof_SetBucketData_header_not_0);
    336 COMPILE_ASSERT(offsetof(SetBucketData, bucket_id) == 4,
    337                Offsetof_SetBucketData_bucket_id_not_4);
    338 COMPILE_ASSERT(offsetof(SetBucketData, offset) == 8,
    339                Offsetof_SetBucketData_offset_not_8);
    340 COMPILE_ASSERT(offsetof(SetBucketData, size) == 12,
    341                Offsetof_SetBucketData_size_not_12);
    342 COMPILE_ASSERT(offsetof(SetBucketData, shared_memory_id) == 16,
    343                Offsetof_SetBucketData_shared_memory_id_not_16);
    344 COMPILE_ASSERT(offsetof(SetBucketData, shared_memory_offset) == 20,
    345                Offsetof_SetBucketData_shared_memory_offset_not_20);
    346 
    347 // Sets the contents of a portion of a bucket on the service side from data in
    348 // the command buffer.
    349 // See SetBucketSize.
    350 struct SetBucketDataImmediate {
    351   typedef SetBucketDataImmediate ValueType;
    352   static const CommandId kCmdId = kSetBucketDataImmediate;
    353   static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
    354   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    355 
    356   void SetHeader(uint32_t size) {
    357     header.SetCmdBySize<ValueType>(size);
    358   }
    359 
    360   void Init(uint32_t _bucket_id,
    361             uint32_t _offset,
    362             uint32_t _size) {
    363     SetHeader(_size);
    364     bucket_id = _bucket_id;
    365     offset = _offset;
    366     size = _size;
    367   }
    368   static void* Set(void* cmd,
    369                    uint32_t _bucket_id,
    370                    uint32_t _offset,
    371                    uint32_t _size) {
    372     static_cast<ValueType*>(cmd)->Init(
    373         _bucket_id,
    374         _offset,
    375         _size);
    376     return NextImmediateCmdAddress<ValueType>(cmd, _size);
    377   }
    378 
    379   CommandHeader header;
    380   uint32_t bucket_id;
    381   uint32_t offset;
    382   uint32_t size;
    383 };
    384 
    385 COMPILE_ASSERT(sizeof(SetBucketDataImmediate) == 16,
    386                Sizeof_SetBucketDataImmediate_is_not_24);
    387 COMPILE_ASSERT(offsetof(SetBucketDataImmediate, header) == 0,
    388                Offsetof_SetBucketDataImmediate_header_not_0);
    389 COMPILE_ASSERT(offsetof(SetBucketDataImmediate, bucket_id) == 4,
    390                Offsetof_SetBucketDataImmediate_bucket_id_not_4);
    391 COMPILE_ASSERT(offsetof(SetBucketDataImmediate, offset) == 8,
    392                Offsetof_SetBucketDataImmediate_offset_not_8);
    393 COMPILE_ASSERT(offsetof(SetBucketDataImmediate, size) == 12,
    394                Offsetof_SetBucketDataImmediate_size_not_12);
    395 
    396 // Gets the start of a bucket the service has available. Sending a variable size
    397 // result back to the client and the portion of that result that fits in the
    398 // supplied shared memory. If the size of the result is larger than the supplied
    399 // shared memory the rest of the bucket's contents can be retrieved with
    400 // GetBucketData.
    401 //
    402 // This is used for example for any API that returns a string. The problem is
    403 // the largest thing you can send back in 1 command is the size of your shared
    404 // memory. This command along with GetBucketData implements a way to get a
    405 // result a piece at a time to help solve that problem in a generic way.
    406 struct GetBucketStart {
    407   typedef GetBucketStart ValueType;
    408   static const CommandId kCmdId = kGetBucketStart;
    409   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    410   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    411 
    412   typedef uint32_t Result;
    413 
    414   void SetHeader() {
    415     header.SetCmd<ValueType>();
    416   }
    417 
    418   void Init(uint32_t _bucket_id,
    419             uint32_t _result_memory_id,
    420             uint32_t _result_memory_offset,
    421             uint32_t _data_memory_size,
    422             uint32_t _data_memory_id,
    423             uint32_t _data_memory_offset) {
    424     SetHeader();
    425     bucket_id = _bucket_id;
    426     result_memory_id = _result_memory_id;
    427     result_memory_offset = _result_memory_offset;
    428     data_memory_size = _data_memory_size;
    429     data_memory_id = _data_memory_id;
    430     data_memory_offset = _data_memory_offset;
    431   }
    432   static void* Set(void* cmd,
    433                    uint32_t _bucket_id,
    434                    uint32_t _result_memory_id,
    435                    uint32_t _result_memory_offset,
    436                    uint32_t _data_memory_size,
    437                    uint32_t _data_memory_id,
    438                    uint32_t _data_memory_offset) {
    439     static_cast<ValueType*>(cmd)->Init(
    440         _bucket_id,
    441         _result_memory_id,
    442         _result_memory_offset,
    443         _data_memory_size,
    444         _data_memory_id,
    445         _data_memory_offset);
    446     return NextCmdAddress<ValueType>(cmd);
    447   }
    448 
    449   CommandHeader header;
    450   uint32_t bucket_id;
    451   uint32_t result_memory_id;
    452   uint32_t result_memory_offset;
    453   uint32_t data_memory_size;
    454   uint32_t data_memory_id;
    455   uint32_t data_memory_offset;
    456 };
    457 
    458 COMPILE_ASSERT(sizeof(GetBucketStart) == 28, Sizeof_GetBucketStart_is_not_28);
    459 COMPILE_ASSERT(offsetof(GetBucketStart, header) == 0,
    460                Offsetof_GetBucketStart_header_not_0);
    461 COMPILE_ASSERT(offsetof(GetBucketStart, bucket_id) == 4,
    462                Offsetof_GetBucketStart_bucket_id_not_4);
    463 COMPILE_ASSERT(offsetof(GetBucketStart, result_memory_id) == 8,
    464                Offsetof_GetBucketStart_result_memory_id_not_8);
    465 COMPILE_ASSERT(offsetof(GetBucketStart, result_memory_offset) == 12,
    466                Offsetof_GetBucketStart_result_memory_offset_not_12);
    467 COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_size) == 16,
    468                Offsetof_GetBucketStart_data_memory_size_not_16);
    469 COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_id) == 20,
    470                Offsetof_GetBucketStart_data_memory_id_not_20);
    471 COMPILE_ASSERT(offsetof(GetBucketStart, data_memory_offset) == 24,
    472                Offsetof_GetBucketStart_data_memory_offset_not_24);
    473 
    474 // Gets a piece of a result the service as available.
    475 // See GetBucketSize.
    476 struct GetBucketData {
    477   typedef GetBucketData ValueType;
    478   static const CommandId kCmdId = kGetBucketData;
    479   static const cmd::ArgFlags kArgFlags = cmd::kFixed;
    480   static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
    481 
    482   void SetHeader() {
    483     header.SetCmd<ValueType>();
    484   }
    485 
    486   void Init(uint32_t _bucket_id,
    487             uint32_t _offset,
    488             uint32_t _size,
    489             uint32_t _shared_memory_id,
    490             uint32_t _shared_memory_offset) {
    491     SetHeader();
    492     bucket_id = _bucket_id;
    493     offset = _offset;
    494     size = _size;
    495     shared_memory_id = _shared_memory_id;
    496     shared_memory_offset = _shared_memory_offset;
    497   }
    498   static void* Set(void* cmd,
    499                    uint32_t _bucket_id,
    500                    uint32_t _offset,
    501                    uint32_t _size,
    502                    uint32_t _shared_memory_id,
    503                    uint32_t _shared_memory_offset) {
    504     static_cast<ValueType*>(cmd)->Init(
    505         _bucket_id,
    506         _offset,
    507         _size,
    508         _shared_memory_id,
    509         _shared_memory_offset);
    510     return NextCmdAddress<ValueType>(cmd);
    511   }
    512 
    513   CommandHeader header;
    514   uint32_t bucket_id;
    515   uint32_t offset;
    516   uint32_t size;
    517   uint32_t shared_memory_id;
    518   uint32_t shared_memory_offset;
    519 };
    520 
    521 COMPILE_ASSERT(sizeof(GetBucketData) == 24, Sizeof_GetBucketData_is_not_20);
    522 COMPILE_ASSERT(offsetof(GetBucketData, header) == 0,
    523                Offsetof_GetBucketData_header_not_0);
    524 COMPILE_ASSERT(offsetof(GetBucketData, bucket_id) == 4,
    525                Offsetof_GetBucketData_bucket_id_not_4);
    526 COMPILE_ASSERT(offsetof(GetBucketData, offset) == 8,
    527                Offsetof_GetBucketData_offset_not_8);
    528 COMPILE_ASSERT(offsetof(GetBucketData, size) == 12,
    529                Offsetof_GetBucketData_size_not_12);
    530 COMPILE_ASSERT(offsetof(GetBucketData, shared_memory_id) == 16,
    531                Offsetof_GetBucketData_shared_memory_id_not_16);
    532 COMPILE_ASSERT(offsetof(GetBucketData, shared_memory_offset) == 20,
    533                Offsetof_GetBucketData_shared_memory_offset_not_20);
    534 
    535 }  // namespace cmd
    536 
    537 #pragma pack(pop)
    538 
    539 }  // namespace gpu
    540 
    541 #endif  // GPU_COMMAND_BUFFER_COMMON_CMD_BUFFER_COMMON_H_
    542 
    543