Stefan Dösinger : wined3d: Detect and work around the MacOS Geforce 8 PBO brokeness.
Alexandre Julliard
julliard at winehq.org
Mon Feb 18 08:50:46 CST 2008
Module: wine
Branch: master
Commit: 989d283000e5d75b67ad5550e6b97e75c7c67929
URL: http://source.winehq.org/git/wine.git/?a=commit;h=989d283000e5d75b67ad5550e6b97e75c7c67929
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Mon Feb 11 01:55:11 2008 +0100
wined3d: Detect and work around the MacOS Geforce 8 PBO brokeness.
---
dlls/wined3d/directx.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 011620d..2438f54 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2874,6 +2874,68 @@ static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
}
}
+#define GLINFO_LOCATION (*gl_info)
+static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
+ /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
+ * but glTexSubImage from a PBO fails miserably, with the first line repeated over
+ * all the texture. This function detects this bug by its symptom and disables PBOs
+ * if the test fails.
+ *
+ * The test uplaods a 4x4 texture via the PBO in the "native" format GL_BGRA,
+ * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
+ * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
+ * read back is compared to the original. If they are equal PBOs are assumed to work,
+ * otherwise the PBO extension is disabled.
+ */
+ GLuint texture, pbo;
+ static const unsigned int pattern[] = {
+ 0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
+ 0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
+ 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
+ 0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
+ };
+ unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
+
+ if(!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) {
+ /* No PBO -> No point in testing them */
+ return;
+ }
+
+ while(glGetError());
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
+ checkGLcall("Specifying the PBO test texture\n");
+
+ GL_EXTCALL(glGenBuffersARB(1, &pbo));
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
+ GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
+ checkGLcall("Specifying the PBO test pbo\n");
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
+ checkGLcall("Loading the PBO test texture\n");
+
+ GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
+ glFinish(); /* just to be sure */
+
+ memset(check, 0, sizeof(check));
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
+ checkGLcall("Reading back the PBO test texture\n");
+
+ glDeleteTextures(1, &texture);
+ GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
+ checkGLcall("PBO test cleanup\n");
+
+ if(memcmp(check, pattern, sizeof(check)) != 0) {
+ WARN_(d3d_caps)("PBO test failed, read back data doesn't match original\n");
+ WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance\n");
+ gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
+ } else {
+ TRACE_(d3d_caps)("PBO test successfull\n");
+ }
+}
+#undef GLINFO_LOCATION
+
/* Certain applications(Steam) complain if we report an outdated driver version. In general,
* reporting a driver version is moot because we are not the Windows driver, and we have different
* bugs, features, etc.
@@ -2965,6 +3027,9 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
}
}
+ /* Find out if PBOs work as they are supposed to */
+ test_pbo_functionality(gl_info);
+
/* Fixup the driver version */
for(i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++) {
if(gl_info->gl_vendor == driver_version_table[i].vendor &&
More information about the wine-cvs
mailing list