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 defines the GLES2 command buffer commands. 6 7 #ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_ 8 #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_ 9 10 11 #include <KHR/khrplatform.h> 12 13 #include <string.h> 14 15 #include "base/safe_numerics.h" 16 #include "gpu/command_buffer/common/bitfield_helpers.h" 17 #include "gpu/command_buffer/common/cmd_buffer_common.h" 18 #include "gpu/command_buffer/common/gles2_cmd_ids.h" 19 #include "gpu/command_buffer/common/types.h" 20 21 // GL types are forward declared to avoid including the GL headers. The problem 22 // is determining which GL headers to include from code that is common to the 23 // client and service sides (GLES2 or one of several GL implementations). 24 typedef unsigned int GLenum; 25 typedef unsigned int GLbitfield; 26 typedef unsigned int GLuint; 27 typedef int GLint; 28 typedef int GLsizei; 29 typedef unsigned char GLboolean; 30 typedef signed char GLbyte; 31 typedef short GLshort; 32 typedef unsigned char GLubyte; 33 typedef unsigned short GLushort; 34 typedef unsigned long GLulong; 35 typedef float GLfloat; 36 typedef float GLclampf; 37 typedef double GLdouble; 38 typedef double GLclampd; 39 typedef void GLvoid; 40 typedef khronos_intptr_t GLintptr; 41 typedef khronos_ssize_t GLsizeiptr; 42 43 namespace gpu { 44 namespace gles2 { 45 46 #pragma pack(push, 1) 47 48 namespace id_namespaces { 49 50 // These are used when contexts share resources. 51 enum IdNamespaces { 52 kBuffers, 53 kFramebuffers, 54 kProgramsAndShaders, 55 kRenderbuffers, 56 kTextures, 57 kQueries, 58 kVertexArrays, 59 kImages, 60 kNumIdNamespaces 61 }; 62 63 // These numbers must not change 64 COMPILE_ASSERT(kBuffers == 0, kBuffers_is_not_0); 65 COMPILE_ASSERT(kFramebuffers == 1, kFramebuffers_is_not_1); 66 COMPILE_ASSERT(kProgramsAndShaders == 2, kProgramsAndShaders_is_not_2); 67 COMPILE_ASSERT(kRenderbuffers == 3, kRenderbuffers_is_not_3); 68 COMPILE_ASSERT(kTextures == 4, kTextures_is_not_4); 69 70 } // namespace id_namespaces 71 72 // Used for some glGetXXX commands that return a result through a pointer. We 73 // need to know if the command succeeded or not and the size of the result. If 74 // the command failed its result size will 0. 75 template <typename T> 76 struct SizedResult { 77 typedef T Type; 78 79 T* GetData() { 80 return static_cast<T*>(static_cast<void*>(&data)); 81 } 82 83 // Returns the total size in bytes of the SizedResult for a given number of 84 // results including the size field. 85 static size_t ComputeSize(size_t num_results) { 86 return sizeof(T) * num_results + sizeof(uint32); // NOLINT 87 } 88 89 // Returns the total size in bytes of the SizedResult for a given size of 90 // results. 91 static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) { 92 return size_of_result_in_bytes + sizeof(uint32); // NOLINT 93 } 94 95 // Returns the maximum number of results for a given buffer size. 96 static uint32 ComputeMaxResults(size_t size_of_buffer) { 97 return (size_of_buffer >= sizeof(uint32)) ? 98 ((size_of_buffer - sizeof(uint32)) / sizeof(T)) : 0; // NOLINT 99 } 100 101 // Set the size for a given number of results. 102 void SetNumResults(size_t num_results) { 103 size = sizeof(T) * num_results; // NOLINT 104 } 105 106 // Get the number of elements in the result 107 int32 GetNumResults() const { 108 return size / sizeof(T); // NOLINT 109 } 110 111 // Copy the result. 112 void CopyResult(void* dst) const { 113 memcpy(dst, &data, size); 114 } 115 116 uint32 size; // in bytes. 117 int32 data; // this is just here to get an offset. 118 }; 119 120 COMPILE_ASSERT(sizeof(SizedResult<int8>) == 8, SizedResult_size_not_8); 121 COMPILE_ASSERT(offsetof(SizedResult<int8>, size) == 0, 122 OffsetOf_SizedResult_size_not_0); 123 COMPILE_ASSERT(offsetof(SizedResult<int8>, data) == 4, 124 OffsetOf_SizedResult_data_not_4); 125 126 // The data for one attrib or uniform from GetProgramInfoCHROMIUM. 127 struct ProgramInput { 128 uint32 type; // The type (GL_VEC3, GL_MAT3, GL_SAMPLER_2D, etc. 129 int32 size; // The size (how big the array is for uniforms) 130 uint32 location_offset; // offset from ProgramInfoHeader to 'size' locations 131 // for uniforms, 1 for attribs. 132 uint32 name_offset; // offset from ProgrmaInfoHeader to start of name. 133 uint32 name_length; // length of the name. 134 }; 135 136 // The format of the bucket filled out by GetProgramInfoCHROMIUM 137 struct ProgramInfoHeader { 138 uint32 link_status; 139 uint32 num_attribs; 140 uint32 num_uniforms; 141 // ProgramInput inputs[num_attribs + num_uniforms]; 142 }; 143 144 // The format of QuerySync used by EXT_occlusion_query_boolean 145 struct QuerySync { 146 void Reset() { 147 process_count = 0; 148 result = 0; 149 } 150 151 uint32 process_count; 152 uint64 result; 153 }; 154 155 COMPILE_ASSERT(sizeof(ProgramInput) == 20, ProgramInput_size_not_20); 156 COMPILE_ASSERT(offsetof(ProgramInput, type) == 0, 157 OffsetOf_ProgramInput_type_not_0); 158 COMPILE_ASSERT(offsetof(ProgramInput, size) == 4, 159 OffsetOf_ProgramInput_size_not_4); 160 COMPILE_ASSERT(offsetof(ProgramInput, location_offset) == 8, 161 OffsetOf_ProgramInput_location_offset_not_8); 162 COMPILE_ASSERT(offsetof(ProgramInput, name_offset) == 12, 163 OffsetOf_ProgramInput_name_offset_not_12); 164 COMPILE_ASSERT(offsetof(ProgramInput, name_length) == 16, 165 OffsetOf_ProgramInput_name_length_not_16); 166 167 COMPILE_ASSERT(sizeof(ProgramInfoHeader) == 12, ProgramInfoHeader_size_not_12); 168 COMPILE_ASSERT(offsetof(ProgramInfoHeader, link_status) == 0, 169 OffsetOf_ProgramInfoHeader_link_status_not_0); 170 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_attribs) == 4, 171 OffsetOf_ProgramInfoHeader_num_attribs_not_4); 172 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_uniforms) == 8, 173 OffsetOf_ProgramInfoHeader_num_uniforms_not_8); 174 175 namespace cmds { 176 177 #include "../common/gles2_cmd_format_autogen.h" 178 179 // These are hand written commands. 180 // TODO(gman): Attempt to make these auto-generated. 181 182 struct GetAttribLocation { 183 typedef GetAttribLocation ValueType; 184 static const CommandId kCmdId = kGetAttribLocation; 185 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 186 187 typedef GLint Result; 188 189 static uint32 ComputeSize() { 190 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 191 } 192 193 void SetHeader() { 194 header.SetCmd<ValueType>(); 195 } 196 197 void Init( 198 GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, 199 uint32 _location_shm_id, uint32 _location_shm_offset, 200 uint32 _data_size) { 201 SetHeader(); 202 program = _program; 203 name_shm_id = _name_shm_id; 204 name_shm_offset = _name_shm_offset; 205 location_shm_id = _location_shm_id; 206 location_shm_offset = _location_shm_offset; 207 data_size = _data_size; 208 } 209 210 void* Set( 211 void* cmd, GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, 212 uint32 _location_shm_id, uint32 _location_shm_offset, 213 uint32 _data_size) { 214 static_cast<ValueType*>( 215 cmd)->Init( 216 _program, _name_shm_id, _name_shm_offset, _location_shm_id, 217 _location_shm_offset, _data_size); 218 return NextCmdAddress<ValueType>(cmd); 219 } 220 221 CommandHeader header; 222 uint32 program; 223 uint32 name_shm_id; 224 uint32 name_shm_offset; 225 uint32 location_shm_id; 226 uint32 location_shm_offset; 227 uint32 data_size; 228 }; 229 230 COMPILE_ASSERT(sizeof(GetAttribLocation) == 28, 231 Sizeof_GetAttribLocation_is_not_28); 232 COMPILE_ASSERT(offsetof(GetAttribLocation, header) == 0, 233 OffsetOf_GetAttribLocation_header_not_0); 234 COMPILE_ASSERT(offsetof(GetAttribLocation, program) == 4, 235 OffsetOf_GetAttribLocation_program_not_4); 236 COMPILE_ASSERT(offsetof(GetAttribLocation, name_shm_id) == 8, 237 OffsetOf_GetAttribLocation_name_shm_id_not_8); 238 COMPILE_ASSERT(offsetof(GetAttribLocation, name_shm_offset) == 12, 239 OffsetOf_GetAttribLocation_name_shm_offset_not_12); 240 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_id) == 16, 241 OffsetOf_GetAttribLocation_location_shm_id_not_16); 242 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_offset) == 20, 243 OffsetOf_GetAttribLocation_location_shm_offset_not_20); 244 COMPILE_ASSERT(offsetof(GetAttribLocation, data_size) == 24, 245 OffsetOf_GetAttribLocation_data_size_not_24); 246 247 struct GetAttribLocationImmediate { 248 typedef GetAttribLocationImmediate ValueType; 249 static const CommandId kCmdId = kGetAttribLocationImmediate; 250 static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; 251 252 typedef GLint Result; 253 254 static uint32 ComputeDataSize(const char* s) { 255 return base::checked_numeric_cast<uint32>(strlen(s)); 256 } 257 258 static uint32 ComputeSize(const char* s) { 259 return base::checked_numeric_cast<uint32>(sizeof(ValueType) + 260 ComputeDataSize(s)); 261 } 262 263 void SetHeader(const char* s) { 264 header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); 265 } 266 267 void Init( 268 GLuint _program, const char* _name, 269 uint32 _location_shm_id, uint32 _location_shm_offset) { 270 SetHeader(_name); 271 program = _program; 272 location_shm_id = _location_shm_id; 273 location_shm_offset = _location_shm_offset; 274 data_size = ComputeDataSize(_name); 275 memcpy(ImmediateDataAddress(this), _name, data_size); 276 } 277 278 void* Set( 279 void* cmd, GLuint _program, const char* _name, 280 uint32 _location_shm_id, uint32 _location_shm_offset) { 281 uint32 total_size = ComputeSize(_name); 282 static_cast<ValueType*>( 283 cmd)->Init(_program, _name, _location_shm_id, _location_shm_offset); 284 return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); 285 } 286 287 CommandHeader header; 288 uint32 program; 289 uint32 location_shm_id; 290 uint32 location_shm_offset; 291 uint32 data_size; 292 }; 293 294 COMPILE_ASSERT(sizeof(GetAttribLocationImmediate) == 20, 295 Sizeof_GetAttribLocationImmediate_is_not_20); 296 COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, header) == 0, 297 OffsetOf_GetAttribLocationImmediate_header_not_0); 298 COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, program) == 4, 299 OffsetOf_GetAttribLocationImmediate_program_not_4); 300 COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, location_shm_id) == 8, 301 OffsetOf_GetAttribLocationImmediate_location_shm_id_not_8); 302 COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, location_shm_offset) == 12, 303 OffsetOf_GetAttribLocationImmediate_location_shm_offset_not_12); 304 COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, data_size) == 16, 305 OffsetOf_GetAttribLocationImmediate_data_size_not_16); 306 307 308 struct GetAttribLocationBucket { 309 typedef GetAttribLocationBucket ValueType; 310 static const CommandId kCmdId = kGetAttribLocationBucket; 311 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 312 313 typedef GLint Result; 314 315 static uint32 ComputeSize() { 316 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 317 } 318 319 void SetHeader() { 320 header.SetCmd<ValueType>(); 321 } 322 323 void Init( 324 GLuint _program, uint32 _name_bucket_id, 325 uint32 _location_shm_id, uint32 _location_shm_offset) { 326 SetHeader(); 327 program = _program; 328 name_bucket_id = _name_bucket_id; 329 location_shm_id = _location_shm_id; 330 location_shm_offset = _location_shm_offset; 331 } 332 333 void* Set( 334 void* cmd, GLuint _program, uint32 _name_bucket_id, 335 uint32 _location_shm_id, uint32 _location_shm_offset) { 336 static_cast<ValueType*>( 337 cmd)->Init( 338 _program, _name_bucket_id, _location_shm_id, 339 _location_shm_offset); 340 return NextCmdAddress<ValueType>(cmd); 341 } 342 343 CommandHeader header; 344 uint32 program; 345 uint32 name_bucket_id; 346 uint32 location_shm_id; 347 uint32 location_shm_offset; 348 }; 349 350 COMPILE_ASSERT(sizeof(GetAttribLocationBucket) == 20, 351 Sizeof_GetAttribLocationBucket_is_not_24); 352 COMPILE_ASSERT(offsetof(GetAttribLocationBucket, header) == 0, 353 OffsetOf_GetAttribLocationBucket_header_not_0); 354 COMPILE_ASSERT(offsetof(GetAttribLocationBucket, program) == 4, 355 OffsetOf_GetAttribLocationBucket_program_not_4); 356 COMPILE_ASSERT(offsetof(GetAttribLocationBucket, name_bucket_id) == 8, 357 OffsetOf_GetAttribLocationBucket_name_bucket_id_not_8); 358 COMPILE_ASSERT(offsetof(GetAttribLocationBucket, location_shm_id) == 12, 359 OffsetOf_GetAttribLocationBucket_location_shm_id_not_12); 360 COMPILE_ASSERT(offsetof(GetAttribLocationBucket, location_shm_offset) == 16, 361 OffsetOf_GetAttribLocationBucket_location_shm_offset_not_16); 362 363 struct GetUniformLocation { 364 typedef GetUniformLocation ValueType; 365 static const CommandId kCmdId = kGetUniformLocation; 366 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 367 368 typedef GLint Result; 369 370 static uint32 ComputeSize() { 371 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 372 } 373 374 void SetHeader() { 375 header.SetCmd<ValueType>(); 376 } 377 378 void Init( 379 GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, 380 uint32 _location_shm_id, uint32 _location_shm_offset, 381 uint32 _data_size) { 382 SetHeader(); 383 program = _program; 384 name_shm_id = _name_shm_id; 385 name_shm_offset = _name_shm_offset; 386 location_shm_id = _location_shm_id; 387 location_shm_offset = _location_shm_offset; 388 data_size = _data_size; 389 } 390 391 void* Set( 392 void* cmd, GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, 393 uint32 _location_shm_id, uint32 _location_shm_offset, 394 uint32 _data_size) { 395 static_cast<ValueType*>( 396 cmd)->Init( 397 _program, _name_shm_id, _name_shm_offset, _location_shm_id, 398 _location_shm_offset, _data_size); 399 return NextCmdAddress<ValueType>(cmd); 400 } 401 402 CommandHeader header; 403 uint32 program; 404 uint32 name_shm_id; 405 uint32 name_shm_offset; 406 uint32 location_shm_id; 407 uint32 location_shm_offset; 408 uint32 data_size; 409 }; 410 411 COMPILE_ASSERT(sizeof(GetUniformLocation) == 28, 412 Sizeof_GetUniformLocation_is_not_28); 413 COMPILE_ASSERT(offsetof(GetUniformLocation, header) == 0, 414 OffsetOf_GetUniformLocation_header_not_0); 415 COMPILE_ASSERT(offsetof(GetUniformLocation, program) == 4, 416 OffsetOf_GetUniformLocation_program_not_4); 417 COMPILE_ASSERT(offsetof(GetUniformLocation, name_shm_id) == 8, 418 OffsetOf_GetUniformLocation_name_shm_id_not_8); 419 COMPILE_ASSERT(offsetof(GetUniformLocation, name_shm_offset) == 12, 420 OffsetOf_GetUniformLocation_name_shm_offset_not_12); 421 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_id) == 16, 422 OffsetOf_GetUniformLocation_location_shm_id_not_16); 423 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_offset) == 20, 424 OffsetOf_GetUniformLocation_location_shm_offset_not_20); 425 COMPILE_ASSERT(offsetof(GetUniformLocation, data_size) == 24, 426 OffsetOf_GetUniformLocation_data_size_not_24); 427 428 struct GetUniformLocationImmediate { 429 typedef GetUniformLocationImmediate ValueType; 430 static const CommandId kCmdId = kGetUniformLocationImmediate; 431 static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; 432 433 typedef GLint Result; 434 435 static uint32 ComputeDataSize(const char* s) { 436 return base::checked_numeric_cast<uint32>(strlen(s)); 437 } 438 439 static uint32 ComputeSize(const char* s) { 440 return base::checked_numeric_cast<uint32>(sizeof(ValueType) + 441 ComputeDataSize(s)); 442 } 443 444 void SetHeader(const char* s) { 445 header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); 446 } 447 448 void Init( 449 GLuint _program, const char* _name, 450 uint32 _location_shm_id, uint32 _location_shm_offset) { 451 SetHeader(_name); 452 program = _program; 453 location_shm_id = _location_shm_id; 454 location_shm_offset = _location_shm_offset; 455 data_size = ComputeDataSize(_name); 456 memcpy(ImmediateDataAddress(this), _name, data_size); 457 } 458 459 void* Set( 460 void* cmd, GLuint _program, const char* _name, 461 uint32 _location_shm_id, uint32 _location_shm_offset) { 462 uint32 total_size = ComputeSize(_name); 463 static_cast<ValueType*>( 464 cmd)->Init(_program, _name, _location_shm_id, _location_shm_offset); 465 return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); 466 } 467 468 CommandHeader header; 469 uint32 program; 470 uint32 location_shm_id; 471 uint32 location_shm_offset; 472 uint32 data_size; 473 }; 474 475 COMPILE_ASSERT(sizeof(GetUniformLocationImmediate) == 20, 476 Sizeof_GetUniformLocationImmediate_is_not_20); 477 COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, header) == 0, 478 OffsetOf_GetUniformLocationImmediate_header_not_0); 479 COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, program) == 4, 480 OffsetOf_GetUniformLocationImmediate_program_not_4); 481 COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, location_shm_id) == 8, 482 OffsetOf_GetUniformLocationImmediate_location_shm_id_not_8); 483 COMPILE_ASSERT( 484 offsetof(GetUniformLocationImmediate, location_shm_offset) == 12, 485 OffsetOf_GetUniformLocationImmediate_location_shm_offset_not_12); 486 COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, data_size) == 16, 487 OffsetOf_GetUniformLocationImmediate_data_size_not_16); 488 489 struct GetUniformLocationBucket { 490 typedef GetUniformLocationBucket ValueType; 491 static const CommandId kCmdId = kGetUniformLocationBucket; 492 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 493 494 typedef GLint Result; 495 496 static uint32 ComputeSize() { 497 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 498 } 499 500 void SetHeader() { 501 header.SetCmd<ValueType>(); 502 } 503 504 void Init( 505 GLuint _program, uint32 _name_bucket_id, 506 uint32 _location_shm_id, uint32 _location_shm_offset) { 507 SetHeader(); 508 program = _program; 509 name_bucket_id = _name_bucket_id; 510 location_shm_id = _location_shm_id; 511 location_shm_offset = _location_shm_offset; 512 } 513 514 void* Set( 515 void* cmd, GLuint _program, uint32 _name_bucket_id, 516 uint32 _location_shm_id, uint32 _location_shm_offset) { 517 static_cast<ValueType*>( 518 cmd)->Init( 519 _program, _name_bucket_id, _location_shm_id, 520 _location_shm_offset); 521 return NextCmdAddress<ValueType>(cmd); 522 } 523 524 CommandHeader header; 525 uint32 program; 526 uint32 name_bucket_id; 527 uint32 location_shm_id; 528 uint32 location_shm_offset; 529 }; 530 531 COMPILE_ASSERT(sizeof(GetUniformLocationBucket) == 20, 532 Sizeof_GetUniformLocationBucket_is_not_24); 533 COMPILE_ASSERT(offsetof(GetUniformLocationBucket, header) == 0, 534 OffsetOf_GetUniformLocationBucket_header_not_0); 535 COMPILE_ASSERT(offsetof(GetUniformLocationBucket, program) == 4, 536 OffsetOf_GetUniformLocationBucket_program_not_4); 537 COMPILE_ASSERT(offsetof(GetUniformLocationBucket, name_bucket_id) == 8, 538 OffsetOf_GetUniformLocationBucket_name_bucket_id_not_8); 539 COMPILE_ASSERT(offsetof(GetUniformLocationBucket, location_shm_id) == 12, 540 OffsetOf_GetUniformLocationBucket_location_shm_id_not_12); 541 COMPILE_ASSERT(offsetof(GetUniformLocationBucket, location_shm_offset) == 16, 542 OffsetOf_GetUniformLocationBucket_location_shm_offset_not_16); 543 544 struct InsertSyncPointCHROMIUM { 545 typedef InsertSyncPointCHROMIUM ValueType; 546 static const CommandId kCmdId = kInsertSyncPointCHROMIUM; 547 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 548 CommandHeader header; 549 }; 550 551 #pragma pack(pop) 552 553 } // namespace cmd 554 } // namespace gles2 555 } // namespace gpu 556 557 #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_ 558