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 <stdint.h> 14 #include <string.h> 15 16 #include "base/atomicops.h" 17 #include "base/logging.h" 18 #include "base/macros.h" 19 #include "gpu/command_buffer/common/bitfield_helpers.h" 20 #include "gpu/command_buffer/common/cmd_buffer_common.h" 21 #include "gpu/command_buffer/common/gles2_cmd_ids.h" 22 23 // GL types are forward declared to avoid including the GL headers. The problem 24 // is determining which GL headers to include from code that is common to the 25 // client and service sides (GLES2 or one of several GL implementations). 26 typedef unsigned int GLenum; 27 typedef unsigned int GLbitfield; 28 typedef unsigned int GLuint; 29 typedef int GLint; 30 typedef int GLsizei; 31 typedef unsigned char GLboolean; 32 typedef signed char GLbyte; 33 typedef short GLshort; 34 typedef unsigned char GLubyte; 35 typedef unsigned short GLushort; 36 typedef unsigned long GLulong; 37 typedef float GLfloat; 38 typedef float GLclampf; 39 typedef double GLdouble; 40 typedef double GLclampd; 41 typedef void GLvoid; 42 typedef khronos_intptr_t GLintptr; 43 typedef khronos_ssize_t GLsizeiptr; 44 45 namespace gpu { 46 namespace gles2 { 47 48 // Command buffer is GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT byte aligned. 49 #pragma pack(push, GPU_COMMAND_BUFFER_ENTRY_ALIGNMENT) 50 51 namespace id_namespaces { 52 53 // These are used when contexts share resources. 54 enum IdNamespaces { 55 kBuffers, 56 kFramebuffers, 57 kProgramsAndShaders, 58 kRenderbuffers, 59 kTextures, 60 kQueries, 61 kVertexArrays, 62 kNumIdNamespaces 63 }; 64 65 // These numbers must not change 66 COMPILE_ASSERT(kBuffers == 0, kBuffers_is_not_0); 67 COMPILE_ASSERT(kFramebuffers == 1, kFramebuffers_is_not_1); 68 COMPILE_ASSERT(kProgramsAndShaders == 2, kProgramsAndShaders_is_not_2); 69 COMPILE_ASSERT(kRenderbuffers == 3, kRenderbuffers_is_not_3); 70 COMPILE_ASSERT(kTextures == 4, kTextures_is_not_4); 71 72 } // namespace id_namespaces 73 74 // Used for some glGetXXX commands that return a result through a pointer. We 75 // need to know if the command succeeded or not and the size of the result. If 76 // the command failed its result size will 0. 77 template <typename T> 78 struct SizedResult { 79 typedef T Type; 80 81 T* GetData() { 82 return static_cast<T*>(static_cast<void*>(&data)); 83 } 84 85 // Returns the total size in bytes of the SizedResult for a given number of 86 // results including the size field. 87 static size_t ComputeSize(size_t num_results) { 88 return sizeof(T) * num_results + sizeof(uint32_t); // NOLINT 89 } 90 91 // Returns the total size in bytes of the SizedResult for a given size of 92 // results. 93 static size_t ComputeSizeFromBytes(size_t size_of_result_in_bytes) { 94 return size_of_result_in_bytes + sizeof(uint32_t); // NOLINT 95 } 96 97 // Returns the maximum number of results for a given buffer size. 98 static uint32_t ComputeMaxResults(size_t size_of_buffer) { 99 return (size_of_buffer >= sizeof(uint32_t)) ? 100 ((size_of_buffer - sizeof(uint32_t)) / sizeof(T)) : 0; // NOLINT 101 } 102 103 // Set the size for a given number of results. 104 void SetNumResults(size_t num_results) { 105 size = sizeof(T) * num_results; // NOLINT 106 } 107 108 // Get the number of elements in the result 109 int32_t GetNumResults() const { 110 return size / sizeof(T); // NOLINT 111 } 112 113 // Copy the result. 114 void CopyResult(void* dst) const { 115 memcpy(dst, &data, size); 116 } 117 118 uint32_t size; // in bytes. 119 int32_t data; // this is just here to get an offset. 120 }; 121 122 COMPILE_ASSERT(sizeof(SizedResult<int8_t>) == 8, SizedResult_size_not_8); 123 COMPILE_ASSERT(offsetof(SizedResult<int8_t>, size) == 0, 124 OffsetOf_SizedResult_size_not_0); 125 COMPILE_ASSERT(offsetof(SizedResult<int8_t>, data) == 4, 126 OffsetOf_SizedResult_data_not_4); 127 128 // The data for one attrib or uniform from GetProgramInfoCHROMIUM. 129 struct ProgramInput { 130 uint32_t type; // The type (GL_VEC3, GL_MAT3, GL_SAMPLER_2D, etc. 131 int32_t size; // The size (how big the array is for uniforms) 132 uint32_t location_offset; // offset from ProgramInfoHeader to 'size' 133 // locations for uniforms, 1 for attribs. 134 uint32_t name_offset; // offset from ProgrmaInfoHeader to start of name. 135 uint32_t name_length; // length of the name. 136 }; 137 138 // The format of the bucket filled out by GetProgramInfoCHROMIUM 139 struct ProgramInfoHeader { 140 uint32_t link_status; 141 uint32_t num_attribs; 142 uint32_t num_uniforms; 143 // ProgramInput inputs[num_attribs + num_uniforms]; 144 }; 145 146 // The format of QuerySync used by EXT_occlusion_query_boolean 147 struct QuerySync { 148 void Reset() { 149 process_count = 0; 150 result = 0; 151 } 152 153 base::subtle::Atomic32 process_count; 154 uint64_t result; 155 }; 156 157 struct AsyncUploadSync { 158 void Reset() { 159 base::subtle::Release_Store(&async_upload_token, 0); 160 } 161 162 void SetAsyncUploadToken(uint32_t token) { 163 DCHECK_NE(token, 0u); 164 base::subtle::Release_Store(&async_upload_token, token); 165 } 166 167 bool HasAsyncUploadTokenPassed(uint32_t token) { 168 DCHECK_NE(token, 0u); 169 uint32_t current_token = base::subtle::Acquire_Load(&async_upload_token); 170 return (current_token - token < 0x80000000); 171 } 172 173 base::subtle::Atomic32 async_upload_token; 174 }; 175 176 COMPILE_ASSERT(sizeof(ProgramInput) == 20, ProgramInput_size_not_20); 177 COMPILE_ASSERT(offsetof(ProgramInput, type) == 0, 178 OffsetOf_ProgramInput_type_not_0); 179 COMPILE_ASSERT(offsetof(ProgramInput, size) == 4, 180 OffsetOf_ProgramInput_size_not_4); 181 COMPILE_ASSERT(offsetof(ProgramInput, location_offset) == 8, 182 OffsetOf_ProgramInput_location_offset_not_8); 183 COMPILE_ASSERT(offsetof(ProgramInput, name_offset) == 12, 184 OffsetOf_ProgramInput_name_offset_not_12); 185 COMPILE_ASSERT(offsetof(ProgramInput, name_length) == 16, 186 OffsetOf_ProgramInput_name_length_not_16); 187 188 COMPILE_ASSERT(sizeof(ProgramInfoHeader) == 12, ProgramInfoHeader_size_not_12); 189 COMPILE_ASSERT(offsetof(ProgramInfoHeader, link_status) == 0, 190 OffsetOf_ProgramInfoHeader_link_status_not_0); 191 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_attribs) == 4, 192 OffsetOf_ProgramInfoHeader_num_attribs_not_4); 193 COMPILE_ASSERT(offsetof(ProgramInfoHeader, num_uniforms) == 8, 194 OffsetOf_ProgramInfoHeader_num_uniforms_not_8); 195 196 namespace cmds { 197 198 #include "../common/gles2_cmd_format_autogen.h" 199 200 // These are hand written commands. 201 // TODO(gman): Attempt to make these auto-generated. 202 struct GetAttribLocation { 203 typedef GetAttribLocation ValueType; 204 static const CommandId kCmdId = kGetAttribLocation; 205 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 206 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 207 208 typedef GLint Result; 209 210 static uint32 ComputeSize() { 211 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 212 } 213 214 void SetHeader() { 215 header.SetCmd<ValueType>(); 216 } 217 218 void Init( 219 GLuint _program, uint32 _name_bucket_id, 220 uint32 _location_shm_id, uint32 _location_shm_offset) { 221 SetHeader(); 222 program = _program; 223 name_bucket_id = _name_bucket_id; 224 location_shm_id = _location_shm_id; 225 location_shm_offset = _location_shm_offset; 226 } 227 228 void* Set( 229 void* cmd, GLuint _program, uint32 _name_bucket_id, 230 uint32 _location_shm_id, uint32 _location_shm_offset) { 231 static_cast<ValueType*>( 232 cmd)->Init( 233 _program, _name_bucket_id, _location_shm_id, 234 _location_shm_offset); 235 return NextCmdAddress<ValueType>(cmd); 236 } 237 238 CommandHeader header; 239 uint32 program; 240 uint32 name_bucket_id; 241 uint32 location_shm_id; 242 uint32 location_shm_offset; 243 }; 244 245 COMPILE_ASSERT(sizeof(GetAttribLocation) == 20, 246 Sizeof_GetAttribLocation_is_not_24); 247 COMPILE_ASSERT(offsetof(GetAttribLocation, header) == 0, 248 OffsetOf_GetAttribLocation_header_not_0); 249 COMPILE_ASSERT(offsetof(GetAttribLocation, program) == 4, 250 OffsetOf_GetAttribLocation_program_not_4); 251 COMPILE_ASSERT(offsetof(GetAttribLocation, name_bucket_id) == 8, 252 OffsetOf_GetAttribLocation_name_bucket_id_not_8); 253 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_id) == 12, 254 OffsetOf_GetAttribLocation_location_shm_id_not_12); 255 COMPILE_ASSERT(offsetof(GetAttribLocation, location_shm_offset) == 16, 256 OffsetOf_GetAttribLocation_location_shm_offset_not_16); 257 258 struct GetUniformLocation { 259 typedef GetUniformLocation ValueType; 260 static const CommandId kCmdId = kGetUniformLocation; 261 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 262 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 263 264 typedef GLint Result; 265 266 static uint32 ComputeSize() { 267 return static_cast<uint32>(sizeof(ValueType)); // NOLINT 268 } 269 270 void SetHeader() { 271 header.SetCmd<ValueType>(); 272 } 273 274 void Init( 275 GLuint _program, uint32 _name_bucket_id, 276 uint32 _location_shm_id, uint32 _location_shm_offset) { 277 SetHeader(); 278 program = _program; 279 name_bucket_id = _name_bucket_id; 280 location_shm_id = _location_shm_id; 281 location_shm_offset = _location_shm_offset; 282 } 283 284 void* Set( 285 void* cmd, GLuint _program, uint32 _name_bucket_id, 286 uint32 _location_shm_id, uint32 _location_shm_offset) { 287 static_cast<ValueType*>( 288 cmd)->Init( 289 _program, _name_bucket_id, _location_shm_id, 290 _location_shm_offset); 291 return NextCmdAddress<ValueType>(cmd); 292 } 293 294 CommandHeader header; 295 uint32 program; 296 uint32 name_bucket_id; 297 uint32 location_shm_id; 298 uint32 location_shm_offset; 299 }; 300 301 COMPILE_ASSERT(sizeof(GetUniformLocation) == 20, 302 Sizeof_GetUniformLocation_is_not_24); 303 COMPILE_ASSERT(offsetof(GetUniformLocation, header) == 0, 304 OffsetOf_GetUniformLocation_header_not_0); 305 COMPILE_ASSERT(offsetof(GetUniformLocation, program) == 4, 306 OffsetOf_GetUniformLocation_program_not_4); 307 COMPILE_ASSERT(offsetof(GetUniformLocation, name_bucket_id) == 8, 308 OffsetOf_GetUniformLocation_name_bucket_id_not_8); 309 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_id) == 12, 310 OffsetOf_GetUniformLocation_location_shm_id_not_12); 311 COMPILE_ASSERT(offsetof(GetUniformLocation, location_shm_offset) == 16, 312 OffsetOf_GetUniformLocation_location_shm_offset_not_16); 313 314 struct GenMailboxCHROMIUM { 315 typedef GenMailboxCHROMIUM ValueType; 316 static const CommandId kCmdId = kGenMailboxCHROMIUM; 317 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 318 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 319 CommandHeader header; 320 }; 321 322 struct InsertSyncPointCHROMIUM { 323 typedef InsertSyncPointCHROMIUM ValueType; 324 static const CommandId kCmdId = kInsertSyncPointCHROMIUM; 325 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 326 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 327 CommandHeader header; 328 }; 329 330 struct CreateAndConsumeTextureCHROMIUMImmediate { 331 typedef CreateAndConsumeTextureCHROMIUMImmediate ValueType; 332 static const CommandId kCmdId = kCreateAndConsumeTextureCHROMIUMImmediate; 333 static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; 334 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); 335 336 static uint32_t ComputeDataSize() { 337 return static_cast<uint32_t>(sizeof(GLbyte) * 64); // NOLINT 338 } 339 340 static uint32_t ComputeSize() { 341 return static_cast<uint32_t>(sizeof(ValueType) + 342 ComputeDataSize()); // NOLINT 343 } 344 345 void SetHeader(uint32_t size_in_bytes) { 346 header.SetCmdByTotalSize<ValueType>(size_in_bytes); 347 } 348 349 void Init(GLenum _target, uint32_t _client_id, const GLbyte* _mailbox) { 350 SetHeader(ComputeSize()); 351 target = _target; 352 client_id = _client_id; 353 memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize()); 354 } 355 356 void* Set(void* cmd, 357 GLenum _target, 358 uint32_t _client_id, 359 const GLbyte* _mailbox) { 360 static_cast<ValueType*>(cmd)->Init(_target, _client_id, _mailbox); 361 const uint32_t size = ComputeSize(); 362 return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); 363 } 364 365 gpu::CommandHeader header; 366 uint32_t target; 367 uint32_t client_id; 368 }; 369 370 COMPILE_ASSERT(sizeof(CreateAndConsumeTextureCHROMIUMImmediate) == 12, 371 Sizeof_CreateAndConsumeTextureCHROMIUMImmediate_is_not_12); 372 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, header) == 0, 373 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_header_not_0); 374 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, target) == 4, 375 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_target_not_4); 376 COMPILE_ASSERT( 377 offsetof(CreateAndConsumeTextureCHROMIUMImmediate, client_id) == 8, 378 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_client_id_not_8); 379 380 381 #pragma pack(pop) 382 383 } // namespace cmd 384 } // namespace gles2 385 } // namespace gpu 386 387 #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_ 388