1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef _GL_CLIENT_STATE_H_ 17 #define _GL_CLIENT_STATE_H_ 18 19 #define GL_API 20 #ifndef ANDROID 21 #define GL_APIENTRY 22 #define GL_APIENTRYP 23 #endif 24 25 #include "StateTrackingSupport.h" 26 27 #include "TextureSharedData.h" 28 29 #include <GLES/gl.h> 30 #include <GLES/glext.h> 31 #include <GLES2/gl2.h> 32 #include <GLES2/gl2ext.h> 33 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include "ErrorLog.h" 37 #include "codec_defs.h" 38 39 #include <vector> 40 #include <map> 41 #include <memory> 42 #include <set> 43 #include <string> 44 45 46 namespace gfxstream { 47 namespace guest { 48 49 // Caps of host driver that make it easy to validate stuff 50 struct HostDriverCaps { 51 // ES 2 52 int max_vertex_attribs; 53 int max_combined_texture_image_units; 54 int max_color_attachments; 55 56 int max_texture_size; 57 int max_texture_size_cube_map; 58 int max_renderbuffer_size; 59 60 // ES 3.0 61 int max_draw_buffers; 62 63 int ubo_offset_alignment; 64 int max_uniform_buffer_bindings; 65 int max_transform_feedback_separate_attribs; 66 67 int max_texture_size_3d; 68 int max_array_texture_layers; 69 70 // ES 3.1 71 int max_atomic_counter_buffer_bindings; 72 int max_shader_storage_buffer_bindings; 73 int max_vertex_attrib_bindings; 74 int max_vertex_attrib_stride; 75 int ssbo_offset_alignment; 76 }; 77 78 // Tracking framebuffer objects: 79 // which framebuffer is bound, 80 // and which texture names 81 // are currently bound to which attachment points. 82 struct FboProps { 83 GLuint name; 84 bool previouslyBound; 85 bool completenessDirty; 86 GLenum cachedCompleteness; 87 std::vector<std::shared_ptr<TextureRec>> colorAttachmenti_textures; 88 std::vector<GLint> colorAttachmenti_texture_levels; 89 std::vector<GLint> colorAttachmenti_texture_layers; 90 91 GLint depthAttachment_texture_level; 92 GLint depthAttachment_texture_layer; 93 GLint stencilAttachment_texture_level; 94 GLint stencilAttachment_texture_layer; 95 96 std::shared_ptr<TextureRec> depthAttachment_texture; 97 std::shared_ptr<TextureRec> stencilAttachment_texture; 98 std::shared_ptr<TextureRec> depthstencilAttachment_texture; 99 100 std::vector<bool> colorAttachmenti_hasTex; 101 bool depthAttachment_hasTexObj; 102 bool stencilAttachment_hasTexObj; 103 bool depthstencilAttachment_hasTexObj; 104 105 std::vector<std::shared_ptr<RboProps>> colorAttachmenti_rbos; 106 std::shared_ptr<RboProps> depthAttachment_rbo = 0; 107 std::shared_ptr<RboProps> stencilAttachment_rbo = 0; 108 std::shared_ptr<RboProps> depthstencilAttachment_rbo = 0; 109 110 std::vector<bool> colorAttachmenti_hasRbo; 111 bool depthAttachment_hasRbo = false; 112 bool stencilAttachment_hasRbo = false; 113 bool depthstencilAttachment_hasRbo = false; 114 115 GLuint defaultWidth; 116 GLuint defaultHeight; 117 }; 118 119 // Enum for describing whether a framebuffer attachment 120 // is a texture or renderbuffer. 121 enum FboAttachmentType { 122 FBO_ATTACHMENT_RENDERBUFFER = 0, 123 FBO_ATTACHMENT_TEXTURE = 1, 124 FBO_ATTACHMENT_NONE = 2 125 }; 126 127 // Tracking FBO format 128 struct FboFormatInfo { 129 FboAttachmentType type; 130 GLenum rb_format; 131 GLsizei rb_multisamples; 132 bool rb_external; 133 134 GLint tex_internalformat; 135 GLenum tex_format; 136 GLenum tex_type; 137 GLsizei tex_multisamples; 138 GLint tex_level; 139 GLint tex_layer; 140 bool tex_external; 141 }; 142 143 class GLClientState { 144 public: 145 // TODO: Unify everything in here 146 typedef enum { 147 Buffer, 148 TransformFeedback, 149 Sampler, 150 Query, 151 } ObjectType; 152 153 typedef enum { 154 VERTEX_LOCATION = 0, 155 NORMAL_LOCATION = 1, 156 COLOR_LOCATION = 2, 157 POINTSIZE_LOCATION = 3, 158 TEXCOORD0_LOCATION = 4, 159 TEXCOORD1_LOCATION = 5, 160 TEXCOORD2_LOCATION = 6, 161 TEXCOORD3_LOCATION = 7, 162 TEXCOORD4_LOCATION = 8, 163 TEXCOORD5_LOCATION = 9, 164 TEXCOORD6_LOCATION = 10, 165 TEXCOORD7_LOCATION = 11, 166 MATRIXINDEX_LOCATION = 12, 167 WEIGHT_LOCATION = 13, 168 LAST_LOCATION = 14 169 } StateLocation; 170 171 typedef struct { 172 GLint enabled; 173 GLint size; 174 GLenum type; 175 GLsizei stride; 176 void *data; 177 GLuint reloffset; 178 GLuint bufferObject; 179 GLenum glConst; 180 unsigned int elementSize; 181 bool enableDirty; // true if any enable state has changed since last draw 182 bool normalized; 183 GLuint divisor; 184 bool isInt; 185 int bindingindex; 186 } VertexAttribState; 187 188 struct BufferBinding { 189 GLintptr offset; 190 GLintptr stride; 191 GLintptr effectiveStride; 192 GLsizeiptr size; 193 GLuint buffer; 194 GLuint divisor; 195 GLint vertexAttribLoc; 196 }; 197 198 typedef std::vector<VertexAttribState> VertexAttribStateVector; 199 typedef std::vector<BufferBinding> VertexAttribBindingVector; 200 201 struct VAOState { VAOStateVAOState202 VAOState(GLuint ibo, int nLoc, int nBindings) : 203 attribState(nLoc), 204 bindingState(nBindings), 205 element_array_buffer_binding(ibo), 206 element_array_buffer_binding_lastEncode(ibo) { } 207 VertexAttribStateVector attribState; 208 VertexAttribBindingVector bindingState; 209 GLuint element_array_buffer_binding; 210 GLuint element_array_buffer_binding_lastEncode; 211 int attributesNeedingUpdateForDraw[CODEC_MAX_VERTEX_ATTRIBUTES]; 212 int numAttributesNeedingUpdateForDraw; 213 }; 214 215 typedef std::map<GLuint, VAOState> VAOStateMap; 216 struct VAOStateRef { VAOStateRefVAOStateRef217 VAOStateRef() { } VAOStateRefVAOStateRef218 VAOStateRef( 219 VAOStateMap::iterator iter) : it(iter) { } vaoStateVAOStateRef220 VAOState& vaoState() { return it->second; } 221 VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; } bufferBindingVAOStateRef222 BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; } bufferBindingsVAOStateRef223 VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; } bufferBindings_constVAOStateRef224 const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; } vaoIdVAOStateRef225 GLuint vaoId() const { return it->first; } iboIdVAOStateRef226 GLuint& iboId() { return it->second.element_array_buffer_binding; } iboIdLastEncodeVAOStateRef227 GLuint& iboIdLastEncode() { return it->second.element_array_buffer_binding_lastEncode; } 228 VAOStateMap::iterator it; 229 }; 230 231 typedef struct { 232 int unpack_alignment; 233 234 int unpack_row_length; 235 int unpack_image_height; 236 int unpack_skip_pixels; 237 int unpack_skip_rows; 238 int unpack_skip_images; 239 240 int pack_alignment; 241 242 int pack_row_length; 243 int pack_skip_pixels; 244 int pack_skip_rows; 245 } PixelStoreState; 246 247 enum { 248 MAX_TEXTURE_UNITS = 256, 249 }; 250 251 public: 252 GLClientState(); 253 GLClientState(int majorVersion, int minorVersion); 254 ~GLClientState(); nLocations()255 int nLocations() { return CODEC_MAX_VERTEX_ATTRIBUTES; } pixelStoreState()256 const PixelStoreState *pixelStoreState() { return &m_pixelStore; } 257 int setPixelStore(GLenum param, GLint value); currentVertexArrayObject()258 GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); } currentVertexBufferBindings()259 const VertexAttribBindingVector& currentVertexBufferBindings() const { 260 return m_currVaoState.bufferBindings_const(); 261 } 262 currentArrayVbo()263 GLuint currentArrayVbo() { return m_arrayBuffer; } currentIndexVbo()264 GLuint currentIndexVbo() { return m_currVaoState.iboId(); } 265 void enable(int location, int state); 266 // Vertex array objects and vertex attributes 267 void addVertexArrayObjects(GLsizei n, GLuint* arrays); 268 void removeVertexArrayObjects(GLsizei n, const GLuint* arrays); 269 void addVertexArrayObject(GLuint name); 270 void removeVertexArrayObject(GLuint name); 271 void setVertexArrayObject(GLuint vao); 272 bool isVertexArrayObject(GLuint vao) const; 273 void setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt = false); 274 void setVertexBindingDivisor(int bindingindex, GLuint divisor); 275 const BufferBinding& getCurrAttributeBindingInfo(int attribindex); 276 void setVertexAttribBinding(int attribindex, int bindingindex); 277 void setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt = false); 278 void getVBOUsage(bool* hasClientArrays, bool* hasVBOs); 279 const VertexAttribState& getState(int location); 280 const VertexAttribState& getStateAndEnableDirty(int location, bool *enableChanged); 281 void updateEnableDirtyArrayForDraw(); 282 VAOState& currentVaoState(); 283 int getLocation(GLenum loc); setActiveTexture(int texUnit)284 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; }; getActiveTexture()285 int getActiveTexture() const { return m_activeTexture; } 286 287 void addBuffer(GLuint id); 288 void removeBuffer(GLuint id); 289 bool bufferIdExists(GLuint id) const; 290 void unBindBuffer(GLuint id); 291 292 void setBufferHostMapDirty(GLuint id, bool dirty); 293 bool isBufferHostMapDirty(GLuint id) const; 294 295 void setExistence(ObjectType type, bool exists, GLsizei count, const GLuint* ids); 296 bool queryExistence(ObjectType type, GLuint id) const; 297 bool samplerExists(GLuint id) const; 298 bool tryBind(GLenum target, GLuint id); 299 bool isBoundTargetValid(GLenum target); 300 bool isQueryBound(GLenum target); 301 bool isQueryObjectActive(GLuint id); 302 void setLastQueryTarget(GLenum target, GLuint id); 303 GLenum getLastQueryTarget(GLuint id); 304 305 static void onFenceCreated(GLsync sync); 306 static void onFenceDestroyed(GLsync sync); 307 static bool fenceExists(GLsync sync); 308 309 void setBoundPixelPackBufferDirtyForHostMap(); 310 void setBoundTransformFeedbackBuffersDirtyForHostMap(); 311 void setBoundShaderStorageBuffersDirtyForHostMap(); 312 void setBoundAtomicCounterBuffersDirtyForHostMap(); 313 314 int bindBuffer(GLenum target, GLuint id); 315 void bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride); 316 int getMaxIndexedBufferBindings(GLenum target) const; 317 bool isNonIndexedBindNoOp(GLenum target, GLuint buffer); 318 bool isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride); 319 320 int getMaxTextureSize() const; 321 int getMaxTextureSize3D() const; 322 int getMaxTextureSizeCubeMap() const; 323 int getLog2MaxTextureSize() const; 324 325 void postDraw(); 326 void postReadPixels(); 327 void postDispatchCompute(); 328 329 bool shouldSkipHostMapBuffer(GLenum target); 330 void onHostMappedBuffer(GLenum target); 331 332 int getBuffer(GLenum target); 333 GLuint getLastEncodedBufferBind(GLenum target); 334 void setLastEncodedBufferBind(GLenum target, GLuint id); 335 336 size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const; 337 size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack, int ignoreTrailing = 0) const; 338 size_t clearBufferNumElts(GLenum buffer) const; 339 void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; 340 void getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const; 341 void getUnpackingOffsets3D(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* pixelImageSize, int* totalImageSize, int* skipRows, int* skipImages) const; 342 setCurrentProgram(GLint program)343 void setCurrentProgram(GLint program) { m_currentProgram = program; } setCurrentShaderProgram(GLint program)344 void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; } currentProgram()345 GLint currentProgram() const { return m_currentProgram; } currentShaderProgram()346 GLint currentShaderProgram() const { return m_currentShaderProgram; } 347 348 struct UniformBlockInfoKey { 349 GLuint program; 350 GLuint uniformBlockIndex; 351 }; 352 struct UniformBlockInfoKeyCompare { operatorUniformBlockInfoKeyCompare353 bool operator() (const UniformBlockInfoKey& a, 354 const UniformBlockInfoKey& b) const { 355 if (a.program != b.program) return a.program < b.program; 356 if (a.uniformBlockIndex != b.uniformBlockIndex) return a.uniformBlockIndex < b.uniformBlockIndex; 357 return false; 358 } 359 }; 360 struct UniformBlockUniformInfo { 361 size_t numActiveUniforms; 362 }; 363 364 typedef std::map<UniformBlockInfoKey, UniformBlockUniformInfo, UniformBlockInfoKeyCompare> UniformBlockInfoMap; 365 UniformBlockInfoMap m_uniformBlockInfoMap; 366 367 void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms); 368 size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const; 369 370 typedef std::map<GLuint, GLuint> ProgramPipelineMap; 371 typedef ProgramPipelineMap::iterator ProgramPipelineIterator; 372 void associateProgramWithPipeline(GLuint program, GLuint pipeline); 373 ProgramPipelineIterator programPipelineBegin(); 374 ProgramPipelineIterator programPipelineEnd(); 375 376 /* OES_EGL_image_external 377 * 378 * These functions manipulate GL state which interacts with the 379 * OES_EGL_image_external extension, to support client-side emulation on 380 * top of host implementations that don't have it. 381 * 382 * Most of these calls should only be used with TEXTURE_2D or 383 * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension 384 * targets should bypass this. An exception is bindTexture(), which should 385 * see all glBindTexture() calls for any target. 386 */ 387 388 // glActiveTexture(GL_TEXTURE0 + i) 389 // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported. 390 GLenum setActiveTextureUnit(GLenum texture); 391 GLenum getActiveTextureUnit() const; 392 393 // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES)) 394 void enableTextureTarget(GLenum target); 395 396 // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES)) 397 void disableTextureTarget(GLenum target); 398 399 bool bindSampler(GLuint unit, GLuint sampler); 400 bool isSamplerBindNoOp(GLuint unit, GLuint sampler); 401 void onDeleteSamplers(GLsizei n, const GLuint* samplers); 402 403 // Implements the target priority logic: 404 // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else 405 // * Return GL_TEXTURE_2D if enabled, else 406 // * Return the allDisabled value. 407 // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code 408 // simpler; for other cases passing a recognizable enum like GL_ZERO or 409 // GL_INVALID_ENUM is appropriate. 410 GLenum getPriorityEnabledTarget(GLenum allDisabled) const; 411 412 // glBindTexture(GL_TEXTURE_*, ...) 413 // Set the target binding of the active texture unit to texture. Returns 414 // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has 415 // previously been bound to a different target. If firstUse is not NULL, 416 // it is set to indicate whether this is the first use of the texture. 417 // For accurate error detection, bindTexture should be called for *all* 418 // targets, not just 2D and EXTERNAL_OES. 419 GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse); 420 void setBoundEGLImage(GLenum target, GLeglImageOES image, int width, int height); 421 422 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES). 423 GLuint getBoundTexture(GLenum target) const; 424 // Return bound framebuffer for target 425 GLuint getBoundFramebuffer(GLenum target) const; 426 427 // Check framebuffer completeness 428 GLenum checkFramebufferCompleteness(GLenum target); 429 // |currentSamples|: threads through the current sample count of attachments so far, 430 // for validating consistent number of samples across attachments 431 GLenum checkFramebufferAttachmentCompleteness(GLenum target, GLenum attachment, int* currentSamples) const; 432 433 // Other publicly-visible texture queries 434 GLenum queryTexLastBoundTarget(GLuint name) const; 435 GLenum queryTexFormat(GLuint name) const; 436 GLint queryTexInternalFormat(GLuint name) const; 437 GLsizei queryTexWidth(GLsizei level, GLuint name) const; 438 GLsizei queryTexHeight(GLsizei level, GLuint name) const; 439 GLsizei queryTexDepth(GLsizei level, GLuint name) const; 440 bool queryTexEGLImageBacked(GLuint name) const; 441 442 // For AMD GPUs, it is easy for the emulator to segfault 443 // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D 444 // and uses GL_LUMINANCE as internal format. 445 // In particular, the segfault happens when negative components of 446 // cube maps are defined before positive ones, 447 // This procedure checks internal state to see if we have defined 448 // the positive component of a cube map already. If not, it returns 449 // which positive component needs to be defined first. 450 // If there is no need for the extra definition, 0 is returned. 451 GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level, 452 GLenum internalformat); 453 454 // Tracks the format of the currently bound texture. 455 // This is to pass dEQP tests for fbo completeness. 456 void setBoundTextureInternalFormat(GLenum target, GLint format); 457 void setBoundTextureFormat(GLenum target, GLenum format); 458 void setBoundTextureType(GLenum target, GLenum type); 459 void setBoundTextureDims(GLenum target, GLenum cubetarget, GLsizei level, GLsizei width, GLsizei height, GLsizei depth); 460 void setBoundTextureSamples(GLenum target, GLsizei samples); 461 void addTextureCubeMapImage(GLenum stateTarget, GLenum cubeTarget); 462 463 // glTexStorage2D disallows any change in texture format after it is set for a particular texture. 464 void setBoundTextureImmutableFormat(GLenum target); 465 bool isBoundTextureImmutableFormat(GLenum target) const; 466 bool isBoundTextureComplete(GLenum target) const; 467 468 // glDeleteTextures(...) 469 // Remove references to the to-be-deleted textures. 470 void deleteTextures(GLsizei n, const GLuint* textures); 471 472 // Render buffer objects 473 void addRenderbuffers(GLsizei n, GLuint* renderbuffers); 474 void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers); 475 bool usedRenderbufferName(GLuint name) const; 476 void bindRenderbuffer(GLenum target, GLuint name); 477 GLuint boundRenderbuffer() const; 478 void setBoundRenderbufferFormat(GLenum format); 479 void setBoundRenderbufferSamples(GLsizei samples); 480 void setBoundRenderbufferDimensions(GLsizei width, GLsizei height); 481 void setBoundRenderbufferEGLImageBacked(); 482 483 // Frame buffer objects 484 void addFramebuffers(GLsizei n, GLuint* framebuffers); 485 void removeFramebuffers(GLsizei n, const GLuint* framebuffers); 486 bool usedFramebufferName(GLuint name) const; 487 void bindFramebuffer(GLenum target, GLuint name); 488 void setCheckFramebufferStatus(GLenum target, GLenum status); 489 void setFramebufferParameter(GLenum target, GLenum pname, GLint param); 490 GLenum getCheckFramebufferStatus(GLenum target) const; 491 GLuint boundFramebuffer(GLenum target) const; 492 493 // Texture object -> FBO 494 void attachTextureObject(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); 495 std::shared_ptr<TextureRec> getFboAttachmentTexture(GLenum target, GLenum attachment) const; 496 497 // RBO -> FBO 498 void detachRbo(GLuint renderbuffer); 499 void detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer); 500 void attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer); 501 std::shared_ptr<RboProps> getFboAttachmentRbo(GLenum target, GLenum attachment) const; 502 503 // FBO attachments in general 504 bool attachmentHasObject(GLenum target, GLenum attachment) const; 505 bool depthStencilHasSameObject(GLenum target) const; 506 507 // Dirty FBO completeness 508 void setFboCompletenessDirtyForTexture(GLuint texture); 509 void setFboCompletenessDirtyForRbo(std::shared_ptr<RboProps> rbo); 510 511 // Transform feedback state 512 void setTransformFeedbackActive(bool active); 513 void setTransformFeedbackUnpaused(bool unpaused); 514 void setTransformFeedbackVaryingsCountForLinking(uint32_t count); 515 bool getTransformFeedbackActive() const; 516 bool getTransformFeedbackUnpaused() const; 517 bool getTransformFeedbackActiveUnpaused() const; 518 uint32_t getTransformFeedbackVaryingsCountForLinking() const; 519 520 // Stencil state 521 void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); 522 void stencilMaskSeparate(GLenum face, GLuint mask); 523 void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); 524 525 void setTextureData(SharedTextureDataMap* sharedTexData); 526 void setRenderbufferInfo(RenderbufferInfo* rbInfo); 527 void setSamplerInfo(SamplerInfo* samplerInfo); 528 529 bool compressedTexImageSizeCompatible(GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize); 530 // set eglsurface property on default framebuffer 531 // if coming from eglMakeCurrent 532 void fromMakeCurrent(); 533 // set indexed buffer state. 534 // We need to query the underlying OpenGL to get 535 // accurate values for indexed buffers 536 // and # render targets. 537 void initFromCaps( 538 const HostDriverCaps& caps); 539 bool needsInitFromCaps() const; 540 void setExtensions(const std::string& extensions); 541 bool hasExtension(const char* ext) const; 542 543 // Queries the format backing the current framebuffer. 544 // Type differs depending on whether the attachment 545 // is a texture or renderbuffer. 546 void getBoundFramebufferFormat( 547 GLenum target, 548 GLenum attachment, 549 FboFormatInfo* res_info) const; 550 FboAttachmentType getBoundFramebufferAttachmentType( 551 GLenum target, 552 GLenum attachment) const; 553 int getMaxColorAttachments() const; 554 int getMaxDrawBuffers() const; 555 556 // Uniform/attribute validation info 557 UniformValidationInfo currentUniformValidationInfo; 558 AttribValidationInfo currentAttribValidationInfo;; 559 560 // Uniform validation api 561 void validateUniform(bool isFloat, bool isUnsigned, GLint columns, GLint rows, GLint location, GLsizei count, GLenum* err); 562 // Attrib validation 563 bool isAttribIndexUsedByProgram(int attribIndex); 564 565 // Fast access to some enables and stencil related glGet's 566 bool state_GL_STENCIL_TEST; 567 GLenum state_GL_STENCIL_FUNC; 568 unsigned int state_GL_STENCIL_VALUE_MASK; 569 int state_GL_STENCIL_REF; 570 GLenum state_GL_STENCIL_FAIL; 571 GLenum state_GL_STENCIL_PASS_DEPTH_FAIL; 572 GLenum state_GL_STENCIL_PASS_DEPTH_PASS; 573 GLenum state_GL_STENCIL_BACK_FUNC; 574 unsigned int state_GL_STENCIL_BACK_VALUE_MASK; 575 int state_GL_STENCIL_BACK_REF; 576 GLenum state_GL_STENCIL_BACK_FAIL; 577 GLenum state_GL_STENCIL_BACK_PASS_DEPTH_FAIL; 578 GLenum state_GL_STENCIL_BACK_PASS_DEPTH_PASS; 579 unsigned int state_GL_STENCIL_WRITEMASK; 580 unsigned int state_GL_STENCIL_BACK_WRITEMASK; 581 int state_GL_STENCIL_CLEAR_VALUE; 582 private: 583 void init(); 584 bool m_initialized; 585 PixelStoreState m_pixelStore; 586 587 using DirtyMap = PredicateMap<uint32_t, true>; 588 589 ExistenceMap mBufferIds; 590 ExistenceMap mTransformFeedbackIds; 591 SamplerInfo* mSamplerInfo; 592 ExistenceMap mQueryIds; 593 LastQueryTargetInfo mLastQueryTargets; 594 595 // Bound query target validity and tracking 596 struct BoundTargetInfo { 597 GLuint id; 598 bool valid; 599 }; 600 601 // Transform feedback 602 BoundTargetInfo mBoundTransformFeedbackValidity; 603 604 // Queries 605 // GL_ANY_SAMPLES_PASSED 606 BoundTargetInfo mBoundQueryValidity_AnySamplesPassed; 607 // GL_ANY_SAMPLES_PASSED_CONSERVATIVE 608 BoundTargetInfo mBoundQueryValidity_AnySamplesPassedConservative; 609 // GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 610 BoundTargetInfo mBoundQueryValidity_TransformFeedbackPrimitivesWritten; 611 612 // Dirty maps 613 DirtyMap mHostMappedBufferDirty; 614 615 // GL_ARRAY_BUFFER_BINDING is separate from VAO state 616 GLuint m_arrayBuffer; 617 GLuint m_arrayBuffer_lastEncode; 618 VAOStateMap m_vaoMap; 619 VAOStateRef m_currVaoState; 620 621 uint16_t m_attribEnableCache; 622 uint16_t m_vaoAttribBindingCacheInvalid; 623 uint16_t m_vaoAttribBindingHasClientArrayCache; 624 uint16_t m_vaoAttribBindingHasVboCache; 625 uint8_t m_noClientArraysCache; 626 627 // Other buffer id's, other targets 628 GLuint m_copyReadBuffer; 629 GLuint m_copyWriteBuffer; 630 631 GLuint m_pixelPackBuffer; 632 GLuint m_pixelUnpackBuffer; 633 634 GLuint m_transformFeedbackBuffer; 635 GLuint m_uniformBuffer; 636 637 GLuint m_atomicCounterBuffer; 638 GLuint m_dispatchIndirectBuffer; 639 GLuint m_drawIndirectBuffer; 640 GLuint m_shaderStorageBuffer; 641 GLuint m_textureBuffer; 642 643 bool m_transformFeedbackActive; 644 bool m_transformFeedbackUnpaused; 645 uint32_t m_transformFeedbackVaryingsCountForLinking; 646 647 HostDriverCaps m_hostDriverCaps; 648 bool m_extensions_set; 649 std::string m_extensions; 650 bool m_has_color_buffer_float_extension; 651 bool m_has_color_buffer_half_float_extension; 652 std::vector<BufferBinding> m_indexedTransformFeedbackBuffers; 653 std::vector<BufferBinding> m_indexedUniformBuffers; 654 std::vector<BufferBinding> m_indexedAtomicCounterBuffers; 655 std::vector<BufferBinding> m_indexedShaderStorageBuffers; 656 int m_log2MaxTextureSize; 657 658 int m_glesMajorVersion; 659 int m_glesMinorVersion; 660 int m_activeTexture; 661 GLint m_currentProgram; 662 GLint m_currentShaderProgram; 663 ProgramPipelineMap m_programPipelines; 664 665 enum TextureTarget { 666 TEXTURE_2D = 0, 667 TEXTURE_EXTERNAL = 1, 668 TEXTURE_CUBE_MAP = 2, 669 TEXTURE_2D_ARRAY = 3, 670 TEXTURE_3D = 4, 671 TEXTURE_2D_MULTISAMPLE = 5, 672 TEXTURE_BUFFER = 6, 673 TEXTURE_TARGET_COUNT 674 }; 675 struct TextureUnit { 676 unsigned int enables; 677 GLuint texture[TEXTURE_TARGET_COUNT]; 678 GLuint boundSampler; 679 }; 680 struct TextureState { 681 TextureUnit unit[MAX_TEXTURE_UNITS]; 682 TextureUnit* activeUnit; 683 // Initialized from shared group. 684 SharedTextureDataMap* textureRecs; 685 }; 686 TextureState m_tex; 687 688 // State tracking of cube map definitions. 689 // Currently used only for driver workarounds 690 // when using GL_LUMINANCE and defining cube maps with 691 // glCopyTexImage2D. 692 struct CubeMapDef { 693 GLuint id; 694 GLenum target; 695 GLint level; 696 GLenum internalformat; 697 }; 698 struct CubeMapDefCompare { operatorCubeMapDefCompare699 bool operator() (const CubeMapDef& a, 700 const CubeMapDef& b) const { 701 if (a.id != b.id) return a.id < b.id; 702 if (a.target != b.target) return a.target < b.target; 703 if (a.level != b.level) return a.level < b.level; 704 if (a.internalformat != b.internalformat) 705 return a.internalformat < b.internalformat; 706 return false; 707 } 708 }; 709 std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs; 710 void writeCopyTexImageState(GLenum target, GLint level, 711 GLenum internalformat); 712 GLenum copyTexImageNeededTarget(GLenum target, GLint level, 713 GLenum internalformat); 714 715 struct RboState { 716 std::shared_ptr<RboProps> boundRenderbuffer; 717 // Connects to share group. 718 // Expected that share group lifetime outlives this context. 719 RenderbufferInfo* rboData; 720 }; 721 RboState mRboState; 722 void addFreshRenderbuffer(GLuint name); 723 724 struct FboState { 725 GLuint boundDrawFramebuffer; 726 GLuint boundReadFramebuffer; 727 size_t boundFramebufferIndex; 728 std::map<GLuint, FboProps> fboData; 729 GLenum drawFboCheckStatus; 730 GLenum readFboCheckStatus; 731 }; 732 FboState mFboState; 733 void addFreshFramebuffer(GLuint name); 734 FboProps& boundFboProps(GLenum target); 735 const FboProps& boundFboProps_const(GLenum target) const; 736 737 // Querying framebuffer format 738 GLenum queryTexType(GLuint name) const; 739 GLsizei queryTexSamples(GLuint name) const; 740 741 static int compareTexId(const void* pid, const void* prec); 742 TextureRec* addTextureRec(GLuint id, GLenum target); 743 std::shared_ptr<TextureRec> getTextureRec(GLuint id) const; 744 TextureRec* getTextureRecPtr(GLuint id) const; 745 TextureRec* getTextureRecPtrLocked(GLuint id) const; 746 747 public: 748 bool isTexture(GLuint name) const; 749 bool isTextureWithStorage(GLuint name) const; 750 bool isTextureWithTarget(GLuint name) const; 751 bool isTextureCubeMap(GLuint name) const; 752 bool isRenderbuffer(GLuint name) const; 753 bool isRenderbufferThatWasBound(GLuint name) const; 754 755 void getClientStatePointer(GLenum pname, GLvoid** params); 756 757 template <class T> getVertexAttribParameter(GLuint index,GLenum param,T * ptr)758 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr) 759 { 760 bool handled = true; 761 const VertexAttribState& vertexAttrib = getState(index); 762 const BufferBinding& vertexAttribBufferBinding = 763 m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex]; 764 765 switch(param) { 766 #define GL_VERTEX_ATTRIB_BINDING 0x82D4 767 case GL_VERTEX_ATTRIB_BINDING: 768 *ptr = (T)vertexAttrib.bindingindex; 769 break; 770 #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 771 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: 772 *ptr = (T)vertexAttrib.reloffset; 773 break; 774 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 775 *ptr = (T)(vertexAttribBufferBinding.buffer); 776 break; 777 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 778 *ptr = (T)(vertexAttrib.enabled); 779 break; 780 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD 781 case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 782 *ptr = (T)(vertexAttrib.isInt); 783 break; 784 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 785 *ptr = (T)(vertexAttrib.size); 786 break; 787 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 788 *ptr = (T)(vertexAttribBufferBinding.stride); 789 break; 790 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 791 *ptr = (T)(vertexAttrib.type); 792 break; 793 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 794 *ptr = (T)(vertexAttrib.normalized); 795 break; 796 case GL_CURRENT_VERTEX_ATTRIB: 797 handled = false; 798 break; 799 default: 800 handled = false; 801 ERR("unknown vertex-attrib parameter param %d\n", param); 802 } 803 return handled; 804 } 805 806 template <class T> getClientStateParameter(GLenum param,T * out)807 bool getClientStateParameter(GLenum param, T* out) 808 { 809 bool isClientStateParam = false; 810 switch (param) { 811 case GL_CLIENT_ACTIVE_TEXTURE: { 812 GLint tex = getActiveTexture() + GL_TEXTURE0; 813 *out = tex; 814 isClientStateParam = true; 815 break; 816 } 817 case GL_VERTEX_ARRAY_SIZE: { 818 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 819 *out = state.size; 820 isClientStateParam = true; 821 break; 822 } 823 case GL_VERTEX_ARRAY_TYPE: { 824 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 825 *out = state.type; 826 isClientStateParam = true; 827 break; 828 } 829 case GL_VERTEX_ARRAY_STRIDE: { 830 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 831 *out = state.stride; 832 isClientStateParam = true; 833 break; 834 } 835 case GL_COLOR_ARRAY_SIZE: { 836 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 837 *out = state.size; 838 isClientStateParam = true; 839 break; 840 } 841 case GL_COLOR_ARRAY_TYPE: { 842 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 843 *out = state.type; 844 isClientStateParam = true; 845 break; 846 } 847 case GL_COLOR_ARRAY_STRIDE: { 848 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 849 *out = state.stride; 850 isClientStateParam = true; 851 break; 852 } 853 case GL_NORMAL_ARRAY_TYPE: { 854 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 855 *out = state.type; 856 isClientStateParam = true; 857 break; 858 } 859 case GL_NORMAL_ARRAY_STRIDE: { 860 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 861 *out = state.stride; 862 isClientStateParam = true; 863 break; 864 } 865 case GL_TEXTURE_COORD_ARRAY_SIZE: { 866 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 867 *out = state.size; 868 isClientStateParam = true; 869 break; 870 } 871 case GL_TEXTURE_COORD_ARRAY_TYPE: { 872 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 873 *out = state.type; 874 isClientStateParam = true; 875 break; 876 } 877 case GL_TEXTURE_COORD_ARRAY_STRIDE: { 878 const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 879 *out = state.stride; 880 isClientStateParam = true; 881 break; 882 } 883 case GL_POINT_SIZE_ARRAY_TYPE_OES: { 884 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 885 *out = state.type; 886 isClientStateParam = true; 887 break; 888 } 889 case GL_POINT_SIZE_ARRAY_STRIDE_OES: { 890 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 891 *out = state.stride; 892 isClientStateParam = true; 893 break; 894 } 895 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: { 896 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 897 *out = state.size; 898 isClientStateParam = true; 899 break; 900 } 901 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: { 902 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 903 *out = state.type; 904 isClientStateParam = true; 905 break; 906 } 907 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: { 908 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 909 *out = state.stride; 910 isClientStateParam = true; 911 break; 912 } 913 case GL_WEIGHT_ARRAY_SIZE_OES: { 914 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 915 *out = state.size; 916 isClientStateParam = true; 917 break; 918 } 919 case GL_WEIGHT_ARRAY_TYPE_OES: { 920 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 921 *out = state.type; 922 isClientStateParam = true; 923 break; 924 } 925 case GL_WEIGHT_ARRAY_STRIDE_OES: { 926 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 927 *out = state.stride; 928 isClientStateParam = true; 929 break; 930 } 931 case GL_VERTEX_ARRAY_BUFFER_BINDING: { 932 const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION); 933 *out = state.bufferObject; 934 isClientStateParam = true; 935 break; 936 } 937 case GL_NORMAL_ARRAY_BUFFER_BINDING: { 938 const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION); 939 *out = state.bufferObject; 940 isClientStateParam = true; 941 break; 942 } 943 case GL_COLOR_ARRAY_BUFFER_BINDING: { 944 const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION); 945 *out = state.bufferObject; 946 isClientStateParam = true; 947 break; 948 } 949 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: { 950 const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION); 951 *out = state.bufferObject; 952 isClientStateParam = true; 953 break; 954 } 955 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: { 956 const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION); 957 *out = state.bufferObject; 958 isClientStateParam = true; 959 break; 960 } 961 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: { 962 const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION); 963 *out = state.bufferObject; 964 isClientStateParam = true; 965 break; 966 } 967 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: { 968 const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION); 969 *out = state.bufferObject; 970 isClientStateParam = true; 971 break; 972 } 973 case GL_ARRAY_BUFFER_BINDING: { 974 int buffer = getBuffer(GL_ARRAY_BUFFER); 975 *out = buffer; 976 isClientStateParam = true; 977 break; 978 } 979 case GL_ELEMENT_ARRAY_BUFFER_BINDING: { 980 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER); 981 *out = buffer; 982 isClientStateParam = true; 983 break; 984 } 985 case GL_MAX_VERTEX_ATTRIBS: { 986 *out = CODEC_MAX_VERTEX_ATTRIBUTES; 987 isClientStateParam = true; 988 break; 989 } 990 case GL_FRAMEBUFFER_BINDING: 991 // also case GL_DRAW_FRAMEBUFFER_BINDING: 992 *out = (T)mFboState.boundDrawFramebuffer; 993 isClientStateParam = true; 994 break; 995 case 0x8CAA: // GL_READ_FRAMEBUFFER_BINDING 996 *out = (T)mFboState.boundReadFramebuffer; 997 isClientStateParam = true; 998 break; 999 case GL_STENCIL_TEST: 1000 *out = (T)state_GL_STENCIL_TEST; 1001 isClientStateParam = true; 1002 break; 1003 case GL_STENCIL_FUNC: 1004 *out = (T)state_GL_STENCIL_FUNC; 1005 isClientStateParam = true; 1006 break; 1007 case GL_STENCIL_VALUE_MASK: 1008 *out = (T)state_GL_STENCIL_VALUE_MASK; 1009 isClientStateParam = true; 1010 break; 1011 case GL_STENCIL_REF: 1012 *out = (T)state_GL_STENCIL_REF; 1013 isClientStateParam = true; 1014 break; 1015 case GL_STENCIL_FAIL: 1016 *out = (T)state_GL_STENCIL_FAIL; 1017 isClientStateParam = true; 1018 break; 1019 case GL_STENCIL_PASS_DEPTH_FAIL: 1020 *out = (T)state_GL_STENCIL_PASS_DEPTH_FAIL; 1021 isClientStateParam = true; 1022 break; 1023 case GL_STENCIL_PASS_DEPTH_PASS: 1024 *out = (T)state_GL_STENCIL_PASS_DEPTH_PASS; 1025 isClientStateParam = true; 1026 break; 1027 case GL_STENCIL_BACK_FUNC: 1028 *out = (T)state_GL_STENCIL_BACK_FUNC; 1029 isClientStateParam = true; 1030 break; 1031 case GL_STENCIL_BACK_VALUE_MASK: 1032 *out = (T)state_GL_STENCIL_BACK_VALUE_MASK; 1033 isClientStateParam = true; 1034 break; 1035 case GL_STENCIL_BACK_REF: 1036 *out = (T)state_GL_STENCIL_BACK_REF; 1037 isClientStateParam = true; 1038 break; 1039 case GL_STENCIL_BACK_FAIL: 1040 *out = (T)state_GL_STENCIL_BACK_FAIL; 1041 isClientStateParam = true; 1042 break; 1043 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 1044 *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_FAIL; 1045 isClientStateParam = true; 1046 break; 1047 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 1048 *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_PASS; 1049 isClientStateParam = true; 1050 break; 1051 case GL_STENCIL_WRITEMASK: 1052 *out = (T)state_GL_STENCIL_WRITEMASK; 1053 isClientStateParam = true; 1054 break; 1055 case GL_STENCIL_BACK_WRITEMASK: 1056 *out = (T)state_GL_STENCIL_BACK_WRITEMASK; 1057 isClientStateParam = true; 1058 break; 1059 case GL_STENCIL_CLEAR_VALUE: 1060 *out = (T)state_GL_STENCIL_CLEAR_VALUE; 1061 isClientStateParam = true; 1062 break; 1063 } 1064 return isClientStateParam; 1065 } 1066 1067 }; 1068 1069 } // namespace guest 1070 } // namespace gfxstream 1071 1072 #endif 1073