When GL_ARB_vertex_buffer_object is enabled, all of the text messages in World of Warcraft disappear. Originally, all of the text used to appear but be "stretched" to the bottom-lefthand corner of the screen. However, as of this commit: d8c6719f95b1543296ac954f95d13b048ae48634 is first bad commit commit d8c6719f95b1543296ac954f95d13b048ae48634 Author: Brian <brian.paul@tungstengraphics.com> Date: Mon Aug 20 13:12:20 2007 +0100 refactor bounds checking code the text disappeared instead.
Created attachment 11661 [details] Warcraft with stretched-text corruption.
Created attachment 11662 [details] Warcraft with missing-text corruption
Warcraft seems to be tripping on this check in _mesa_validate_DrawRangeElements(): /* make sure count doesn't go outside buffer bounds */ if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); return GL_FALSE; } Interestingly, it looks as if ctx->Array.ElementArrayBufferObj->Size is always equal to "12" when this check fails. Why 12?
'Size' is the user-provided VBO size, set when the app calls glBufferData(). With gdb, please run: print *ctx->Array.ElementArrayBufferObj print indexBytes where
(In reply to comment #4) > 'Size' is the user-provided VBO size, set when the app calls glBufferData(). > > With gdb, please run: > print *ctx->Array.ElementArrayBufferObj > print indexBytes > where I'm running WoW via wine; can I still use gdb? I'm currently putting a lot of fprintfs into main/bufferobj.c and am seeing the following: _mesa_BufferDataARB: size=12 ** target=GL_ELEMENT_ARRAY_BUFFER_ARB ** Calling BufferData(12) _mesa_buffer_data: Size=12 MapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_BufferDataARB: size=144 ** target=GL_ARRAY_BUFFER_ARB ** Calling BufferData(144) _mesa_buffer_data: Size=144 MapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_BufferDataARB: size=12 ** target=GL_ELEMENT_ARRAY_BUFFER_ARB ** Calling BufferData(12) _mesa_buffer_data: Size=12 MapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_BufferDataARB: size=49152 ** target=GL_ARRAY_BUFFER_ARB ** Calling BufferData(49152) _mesa_buffer_data: Size=49152 MapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_BindBufferARB: bind_buffer_object: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB glDrawRangeElements index out of buffer bounds: 192 12 ... etc. So it *looks* as if the most recent call to _mesa_BufferDataARB with target=GL_ELEMENT_ARRAY_BUFFER_ARB really was for 12 bytes. However, this doesn't explain how presumably the fglrx driver used to cope with the same program. Having said all this, I've noticed that the text doesn't always disappear immediately, and during the time that it is working OK I see stretches of DEBUG statements like: _mesa_BufferDataARB: size=576 ** target=GL_ELEMENT_ARRAY_BUFFER_ARB ** Calling BufferData(576) _mesa_buffer_data: Size=576 MapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB _mesa_BufferDataARB: size=49152 ** target=GL_ARRAY_BUFFER_ARB ** Calling BufferData(49152) _mesa_buffer_data: Size=49152 MapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_UnmapBufferARB: ** target=GL_ARRAY_BUFFER_ARB _mesa_BindBufferARB: bind_buffer_object: ** target=GL_ELEMENT_ARRAY_BUFFER_ARB i.e. calls to populate ElementArrayBufferObj with 576 bytes. BTW, the _mesa_warning message in _mesa_validate_DrawRangeElements() incorrectly mentions glDrawElements instead of glDrawRangeElements.
(In reply to comment #4) > 'Size' is the user-provided VBO size, set when the app calls glBufferData(). > > With gdb, please run: > print *ctx->Array.ElementArrayBufferObj > print indexBytes > where I'm having trouble using gdb with Wine, so I've resorted to fprintf() instead. In this example, indexBytes = 192, although it looks like it can take other "random" even values up to 5064. The contents of ElementArrayBufferObj do not change. glDrawRangeElements index out of buffer bounds: indexBytes=192 Size=12 ElementArrayBufferObj: - RefCount: 2 - Name: 5 - Usage: 35040 - Access: 35002 - Pointer: (nil) - Size: 12 - Data: 0x68ff29f0 - OnCard: 0
What are the parameters to glDrawRangeElements when you get the warning? What happens if you disable the indexBytes check? Why do you say ""In this example, indexBytes = 192, although it looks like it can take other "random" even values up to 5064.""? Where does 5064 come from? What's random about it?
(In reply to comment #7) > What are the parameters to glDrawRangeElements when you get the warning? Here are a few examples: glDrawRangeElements index out of buffer bounds: indexBytes=408 Size=12 ElementArrayBufferObj: - RefCount: 2 - Name: 5 - Usage: 35040 - Access: 35002 - Pointer: (nil) - Size: 12 - Data: 0x691840b0 - OnCard: 0 Mode=4, Start=0, End=135, Count=204, Type=5123 glDrawRangeElements index out of buffer bounds: indexBytes=3648 Size=12 ElementArrayBufferObj: - RefCount: 2 - Name: 5 - Usage: 35040 - Access: 35002 - Pointer: (nil) - Size: 12 - Data: 0x691840b0 - OnCard: 0 Mode=4, Start=0, End=1215, Count=1824, Type=5123 glDrawRangeElements index out of buffer bounds: indexBytes=192 Size=12 ElementArrayBufferObj: - RefCount: 2 - Name: 5 - Usage: 35040 - Access: 35002 - Pointer: (nil) - Size: 12 - Data: 0x691840b0 - OnCard: 0 Mode=4, Start=0, End=63, Count=96, Type=5123 > Why do you say ""In this example, indexBytes = 192, although it looks like it > can take other "random" even values up to 5064.""? Where does 5064 come from? > What's random about it? This error message appears many times, with a variety of different values of indexBytes. 5064 is simply the largest example value. > What happens if you disable the indexBytes check? I'm sure that I had an "access violation" the last time I tried this. However, this time I just saw the return of the "stretched text" corruption instead.
I don't see any indications of a bug in Mesa so far. The parameters and indexBytes look OK. I guess one experiment to try would be to force disabling of GL_ARB_vertex_buffer. You can do that by going into src/mesa/main/extensions.c and changing "GL_ARB_vertex_buffer" in some trivial way, like inserting "foo" in the middle. If the app is checking the GL_EXTENSIONS string (like it should) it won't use VBOs.
(In reply to comment #9) > I don't see any indications of a bug in Mesa so far. The parameters and > indexBytes look OK. The problem is the way that the writing disappears after an undetermined interval. It's not as if the writing *never* works with GL_ARB_vertex_buffer_object disabled. But once it does stop working, you need to restart the game to get it back. > I guess one experiment to try would be to force disabling of > GL_ARB_vertex_buffer. Wine has a way of doing this (you mean GL_ARB_vertex_buffer_object?) already, and this is how I usually play WoW. However, I would rather help fix the problem than simply avoid it. Neither fglrx nor nvidia needs this workaround. Can Mesa have only one ElementArrayBufferObj at any one time? Because WoW *seems* to be expecting the one with the text information to be loaded once at start up, and then it keeps trying to use it. However, Mesa seems to drop it after a while.
(In reply to comment #10) > It's not as if the writing *never* works with GL_ARB_vertex_buffer_object disabled. Oops - I meant "enabled", not "disabled" there. Enabling GL_ARB_vertex_buffer_object makes all the text disappear after a short yet undetermined period.
OK, I wasn't clear on that. My only guess at this point is that maybe the vertex element buffer is not getting unbound at some point so the glDrawRangeElements() is inadvertantly using a VBO. Maybe try: 1. Insert a printf in _mesa_BindBufferARB(), printing the arguments. 2. When you print the parameters to glDrawRangeElements, also print the 'indices' pointer value. If it looks like a real pointer address (and not a small integer) that's a good sign that we're using a VBO when we're not supposed to.
(In reply to comment #12) > 1. Insert a printf in _mesa_BindBufferARB(), printing the arguments. _mesa_BindBufferARB(target=34962, buffer=14) _mesa_BindBufferARB(target=34962, buffer=2) and _mesa_BindBufferARB(target=34963, buffer=1) _mesa_BindBufferARB(target=34963, buffer=3) _mesa_BindBufferARB(target=34963, buffer=4) _mesa_BindBufferARB(target=34963, buffer=5) > 2. When you print the parameters to glDrawRangeElements, also print the > 'indices' pointer value. When glDrawRangeElements() fails, indices is always NULL.
Mass version move, cvs -> git
Amazingly, this bug is now fixed with Mesa 7.9-git as well. VBOs are enabled, and the text remains readable. And the minimap in the top-right corner of the screen isn't a large, blank white circle any more either: I actually now see a corrupted version of what is supposed to appear there.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.