From 0672905ef1b8f6ca219341e7252044dd727753dd Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 7 Dec 2016 22:30:55 -0800 Subject: [PATCH] OpenGL2: Detect Intel graphics and avoid/use certain operations there. Also use qglCopyTextureSubImage2DEXT instead of qglCopyTextureImage2DEXT. --- code/renderercommon/qgl.h | 2 +- code/renderergl2/tr_backend.c | 8 +++++--- code/renderergl2/tr_dsa.c | 6 +++--- code/renderergl2/tr_dsa.h | 4 ++-- code/renderergl2/tr_extensions.c | 5 +++++ code/renderergl2/tr_fbo.c | 2 +- code/renderergl2/tr_image.c | 2 +- code/renderergl2/tr_local.h | 2 ++ code/renderergl2/tr_vbo.c | 4 ++-- 9 files changed, 22 insertions(+), 13 deletions(-) diff --git a/code/renderercommon/qgl.h b/code/renderercommon/qgl.h index 6d8629f6..8b7367af 100644 --- a/code/renderercommon/qgl.h +++ b/code/renderercommon/qgl.h @@ -622,7 +622,7 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void); GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \ GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \ GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \ - GLE(GLvoid, CopyTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) \ + GLE(GLvoid, CopyTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) \ GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \ GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \ GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \ diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 00b31e42..bc0d5e74 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -971,7 +971,9 @@ const void *RB_DrawSurfs( const void *data ) { else if (tr.renderFbo == NULL && tr.renderDepthImage) { // If we're rendering directly to the screen, copy the depth to a texture - qglCopyTextureImage2DEXT(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0); + // This is incredibly slow on Intel Graphics, so just skip it on there + if (!glRefConfig.intelGraphics) + qglCopyTextureSubImage2DEXT(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight); } if (tr.hdrDepthFbo) @@ -1475,14 +1477,14 @@ const void *RB_CapShadowMap(const void *data) { if (tr.shadowCubemaps[cmd->map]) { - qglCopyTextureImage2DEXT(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureSubImage2DEXT(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, 0, 0, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE); } } else { if (tr.pshadowMaps[cmd->map]) { - qglCopyTextureImage2DEXT(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureSubImage2DEXT(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, 0, 0, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE); } } } diff --git a/code/renderergl2/tr_dsa.c b/code/renderergl2/tr_dsa.c index f738a5d5..8fde8419 100644 --- a/code/renderergl2/tr_dsa.c +++ b/code/renderergl2/tr_dsa.c @@ -113,11 +113,11 @@ GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } -GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +GLvoid APIENTRY GLDSA_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { GL_BindMultiTexture(glDsaState.texunit, target, texture); - qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + qglCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, diff --git a/code/renderergl2/tr_dsa.h b/code/renderergl2/tr_dsa.h index 44f32303..84e35f56 100644 --- a/code/renderergl2/tr_dsa.h +++ b/code/renderergl2/tr_dsa.h @@ -33,8 +33,8 @@ GLvoid APIENTRY GLDSA_TextureImage2DEXT(GLuint texture, GLenum target, GLint lev GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); GLvoid APIENTRY GLDSA_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -GLvoid APIENTRY GLDSA_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid APIENTRY GLDSA_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); GLvoid APIENTRY GLDSA_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); GLvoid APIENTRY GLDSA_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index 135af76f..10ae3b85 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -63,6 +63,11 @@ void GLimp_InitExtraExtensions() ri.Error(ERR_FATAL, "OpenGL 2.0 required!"); ri.Printf(PRINT_ALL, "...using OpenGL %s\n", glConfig.version_string); + // Check if we need Intel graphics specific fixes. + glRefConfig.intelGraphics = qfalse; + if (strstr((char *)qglGetString(GL_RENDERER), "Intel")) + glRefConfig.intelGraphics = qtrue; + // set DSA fallbacks #define GLE(ret, name, ...) qgl##name = GLDSA_##name; QGL_EXT_direct_state_access_PROCS; diff --git a/code/renderergl2/tr_fbo.c b/code/renderergl2/tr_fbo.c index aa5148c8..6b7ab01a 100644 --- a/code/renderergl2/tr_fbo.c +++ b/code/renderergl2/tr_fbo.c @@ -271,7 +271,7 @@ void FBO_Init(void) R_IssuePendingRenderCommands(); hdrFormat = GL_RGBA8; - if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) + if (r_hdr->integer && glRefConfig.textureFloat) hdrFormat = GL_RGBA16F_ARB; if (glRefConfig.framebufferMultisample) diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index 81e32684..42038339 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2761,7 +2761,7 @@ void R_CreateBuiltinImages( void ) { height = glConfig.vidHeight; hdrFormat = GL_RGBA8; - if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) + if (r_hdr->integer && glRefConfig.textureFloat) hdrFormat = GL_RGBA16F_ARB; rgbFormat = GL_RGBA8; diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 5a7c1799..e6781b73 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1373,6 +1373,8 @@ typedef struct { int openglMajorVersion; int openglMinorVersion; + qboolean intelGraphics; + qboolean drawRangeElements; qboolean multiDrawArrays; qboolean occlusionQuery; diff --git a/code/renderergl2/tr_vbo.c b/code/renderergl2/tr_vbo.c index 7b68f43f..0ac63a40 100644 --- a/code/renderergl2/tr_vbo.c +++ b/code/renderergl2/tr_vbo.c @@ -360,8 +360,8 @@ void R_BindVao(vao_t * vao) { qglBindVertexArray(vao->vao); - // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel? - if (1) + // Intel Graphics doesn't save GL_ELEMENT_ARRAY_BUFFER binding with VAO binding. + if (glRefConfig.intelGraphics || vao == tess.vao) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); // tess VAO always has buffers bound