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