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 GetDataSizedResult81 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. ComputeSizeSizedResult87 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. ComputeSizeFromBytesSizedResult93 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. ComputeMaxResultsSizedResult98 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. SetNumResultsSizedResult104 void SetNumResults(size_t num_results) { 105 size = sizeof(T) * num_results; // NOLINT 106 } 107 108 // Get the number of elements in the result GetNumResultsSizedResult109 int32_t GetNumResults() const { 110 return size / sizeof(T); // NOLINT 111 } 112 113 // Copy the result. CopyResultSizedResult114 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 { ResetQuerySync148 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 { ResetAsyncUploadSync158 void Reset() { 159 base::subtle::Release_Store(&async_upload_token, 0); 160 } 161 SetAsyncUploadTokenAsyncUploadSync162 void SetAsyncUploadToken(uint32_t token) { 163 DCHECK_NE(token, 0u); 164 base::subtle::Release_Store(&async_upload_token, token); 165 } 166 HasAsyncUploadTokenPassedAsyncUploadSync167 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 203 struct GenMailboxCHROMIUM { 204 typedef GenMailboxCHROMIUM ValueType; 205 static const CommandId kCmdId = kGenMailboxCHROMIUM; 206 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 207 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 208 CommandHeader header; 209 }; 210 211 struct InsertSyncPointCHROMIUM { 212 typedef InsertSyncPointCHROMIUM ValueType; 213 static const CommandId kCmdId = kInsertSyncPointCHROMIUM; 214 static const cmd::ArgFlags kArgFlags = cmd::kFixed; 215 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); 216 CommandHeader header; 217 }; 218 219 struct CreateAndConsumeTextureCHROMIUMImmediate { 220 typedef CreateAndConsumeTextureCHROMIUMImmediate ValueType; 221 static const CommandId kCmdId = kCreateAndConsumeTextureCHROMIUMImmediate; 222 static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; 223 static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); 224 ComputeDataSizeCreateAndConsumeTextureCHROMIUMImmediate225 static uint32_t ComputeDataSize() { 226 return static_cast<uint32_t>(sizeof(GLbyte) * 64); // NOLINT 227 } 228 ComputeSizeCreateAndConsumeTextureCHROMIUMImmediate229 static uint32_t ComputeSize() { 230 return static_cast<uint32_t>(sizeof(ValueType) + 231 ComputeDataSize()); // NOLINT 232 } 233 SetHeaderCreateAndConsumeTextureCHROMIUMImmediate234 void SetHeader(uint32_t size_in_bytes) { 235 header.SetCmdByTotalSize<ValueType>(size_in_bytes); 236 } 237 InitCreateAndConsumeTextureCHROMIUMImmediate238 void Init(GLenum _target, uint32_t _client_id, const GLbyte* _mailbox) { 239 SetHeader(ComputeSize()); 240 target = _target; 241 client_id = _client_id; 242 memcpy(ImmediateDataAddress(this), _mailbox, ComputeDataSize()); 243 } 244 SetCreateAndConsumeTextureCHROMIUMImmediate245 void* Set(void* cmd, 246 GLenum _target, 247 uint32_t _client_id, 248 const GLbyte* _mailbox) { 249 static_cast<ValueType*>(cmd)->Init(_target, _client_id, _mailbox); 250 const uint32_t size = ComputeSize(); 251 return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); 252 } 253 254 gpu::CommandHeader header; 255 uint32_t target; 256 uint32_t client_id; 257 }; 258 259 COMPILE_ASSERT(sizeof(CreateAndConsumeTextureCHROMIUMImmediate) == 12, 260 Sizeof_CreateAndConsumeTextureCHROMIUMImmediate_is_not_12); 261 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, header) == 0, 262 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_header_not_0); 263 COMPILE_ASSERT(offsetof(CreateAndConsumeTextureCHROMIUMImmediate, target) == 4, 264 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_target_not_4); 265 COMPILE_ASSERT( 266 offsetof(CreateAndConsumeTextureCHROMIUMImmediate, client_id) == 8, 267 OffsetOf_CreateAndConsumeTextureCHROMIUMImmediate_client_id_not_8); 268 269 270 #pragma pack(pop) 271 272 } // namespace cmd 273 } // namespace gles2 274 } // namespace gpu 275 276 #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_ 277