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