wined3d: Check the alignment of mapped buffer pointers.
authorStefan Dösinger <stefan@codeweavers.com>
Thu, 11 Mar 2010 12:20:32 +0000 (13:20 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 16 Mar 2010 16:03:13 +0000 (17:03 +0100)
Windows returns 32 byte aligned pointers when locking vertex and index
buffers, and some applications(Half Life 2, Alpha Prime, possibly others)
rely on this. Check the alignment and fall back to double buffered
buffers with HeapAlloced and aligned pointers if the alignment doesn't
fit.

dlls/wined3d/buffer.c

index 08d3097707b445f4087abc9c8ad1d54016c92739..46131afc5410e8e501904f16c767b3d916f73c09 100644 (file)
@@ -1186,6 +1186,21 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
                     This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
                 }
                 LEAVE_GL();
+
+                if (((DWORD_PTR) This->resource.allocatedMemory) & (RESOURCE_ALIGNMENT - 1))
+                {
+                    WARN("Pointer %p is not %u byte aligned, falling back to double buffered operation\n",
+                        This->resource.allocatedMemory, RESOURCE_ALIGNMENT);
+
+                    ENTER_GL();
+                    GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+                    checkGLcall("glUnmapBufferARB");
+                    LEAVE_GL();
+                    This->resource.allocatedMemory = NULL;
+
+                    buffer_get_sysmem(This);
+                    TRACE("New pointer is %p\n", This->resource.allocatedMemory);
+                }
                 context_release(context);
             }
         }