Avoid calling glCopyImageSubData on Qualcomm as some drivers have bugs

This commit is contained in:
baldurk
2019-05-10 17:56:07 +01:00
parent ca2307e34c
commit 4582056de0
3 changed files with 44 additions and 5 deletions
+13 -1
View File
@@ -479,11 +479,12 @@ void FetchEnabledExtensions()
void DoVendorChecks(GLPlatform &platform, GLWindowingData context)
{
const char *vendor = "";
const char *renderer = "";
if(GL.glGetString)
{
vendor = (const char *)GL.glGetString(eGL_VENDOR);
const char *renderer = (const char *)GL.glGetString(eGL_RENDERER);
renderer = (const char *)GL.glGetString(eGL_RENDERER);
const char *version = (const char *)GL.glGetString(eGL_VERSION);
RDCLOG("Vendor checks for %u (%s / %s / %s)", GLCoreVersion, vendor, renderer, version);
@@ -769,6 +770,17 @@ void DoVendorChecks(GLPlatform &platform, GLWindowingData context)
// avoiding use of the DSA function and always doing our emulated version.
VendorCheck[VendorCheck_AMD_vertex_array_elem_buffer_query] = true;
// Qualcomm's implementation of glCopyImageSubData is buggy on some drivers and can cause GPU
// crashes or corrupted data. We force the initial state copies to happen via our emulation which
// uses framebuffer blits.
if(strstr(vendor, "Qualcomm") || strstr(vendor, "Adreno") || strstr(renderer, "Qualcomm") ||
strstr(vendor, "Adreno"))
{
RDCWARN("Using hack to avoid glCopyImageSubData on Qualcomm");
VendorCheck[VendorCheck_Qualcomm_avoid_glCopyImageSubData] = true;
}
if(IsGLES)
{
// Check whether reading from the depth, stencil and depth-stencil buffers using glReadPixels is
+1
View File
@@ -821,6 +821,7 @@ enum VendorCheckEnum
VendorCheck_NV_ClearNamedFramebufferfiBugs,
VendorCheck_AMD_copy_compressed_cubemaps,
VendorCheck_AMD_vertex_array_elem_buffer_query,
VendorCheck_Qualcomm_avoid_glCopyImageSubData,
VendorCheck_Count,
};
extern bool VendorCheck[VendorCheck_Count];
+30 -4
View File
@@ -26,6 +26,16 @@
#include "gl_driver.h"
#include "gl_manager.h"
// declare emulated glCopyImageSubData in case we need to force its use when the driver's version is
// buggy
namespace glEmulate
{
void APIENTRY _glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX,
GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget,
GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ,
GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
};
const GLenum FramebufferInitialData::attachmentNames[10] = {
eGL_COLOR_ATTACHMENT0, eGL_COLOR_ATTACHMENT1, eGL_COLOR_ATTACHMENT2, eGL_COLOR_ATTACHMENT3,
eGL_COLOR_ATTACHMENT4, eGL_COLOR_ATTACHMENT5, eGL_COLOR_ATTACHMENT6, eGL_COLOR_ATTACHMENT7,
@@ -951,10 +961,18 @@ void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, Resourc
// it might require would be depth-only formatted).
if(details.internalFormat == eGL_DEPTH32F_STENCIL8 &&
VendorCheck[VendorCheck_NV_avoid_D32S8_copy])
{
RDCDEBUG("Not fetching initial contents of D32F_S8 texture");
}
else
GL.glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex, details.curType, i, 0,
0, 0, w, h, d);
{
if(VendorCheck[VendorCheck_Qualcomm_avoid_glCopyImageSubData])
glEmulate::_glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex,
details.curType, i, 0, 0, 0, w, h, d);
else
GL.glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex, details.curType, i,
0, 0, 0, w, h, d);
}
}
}
@@ -1971,10 +1989,18 @@ void GLResourceManager::Apply_InitialState(GLResource live, GLInitialContents in
// (shadow maps that it might require would be depth-only formatted).
if(details.internalFormat == eGL_DEPTH32F_STENCIL8 &&
VendorCheck[VendorCheck_NV_avoid_D32S8_copy])
{
RDCDEBUG("Not fetching initial contents of D32F_S8 texture");
}
else
GL.glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name, details.curType, i,
0, 0, 0, w, h, d);
{
if(VendorCheck[VendorCheck_Qualcomm_avoid_glCopyImageSubData])
glEmulate::_glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name,
details.curType, i, 0, 0, 0, w, h, d);
else
GL.glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name, details.curType,
i, 0, 0, 0, w, h, d);
}
}
}