Commit ad692f2a authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

wined3d: Add PBO support for dynamically locked surfaces.

parent 7226f88f
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* Copyright 2005 Oliver Stieber * Copyright 2005 Oliver Stieber
* Copyright 2006 Stefan Dsinger for CodeWeavers * Copyright 2006 Stefan Dsinger for CodeWeavers
* Copyright 2007 Henri Verbeet * Copyright 2007 Henri Verbeet
* Copyright 2006-2007 Roderick Colenbrander
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -71,9 +72,21 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) { ...@@ -71,9 +72,21 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level, TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level,
This->glDescription.glFormat, This->glDescription.glType, mem); This->glDescription.glFormat, This->glDescription.glType, mem);
glGetTexImage(This->glDescription.target, This->glDescription.level, This->glDescription.glFormat, if(This->Flags & SFLAG_PBO) {
This->glDescription.glType, mem); GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
checkGLcall("glGetTexImage()"); checkGLcall("glBindBufferARB");
glGetTexImage(This->glDescription.target, This->glDescription.level, This->glDescription.glFormat,
This->glDescription.glType, NULL);
checkGLcall("glGetTexImage()");
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
} else {
glGetTexImage(This->glDescription.target, This->glDescription.level, This->glDescription.glFormat,
This->glDescription.glType, mem);
checkGLcall("glGetTexImage()");
}
if (This->Flags & SFLAG_NONPOW2) { if (This->Flags & SFLAG_NONPOW2) {
LPBYTE src_data, dst_data; LPBYTE src_data, dst_data;
...@@ -171,8 +184,23 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi ...@@ -171,8 +184,23 @@ static void surface_upload_data(IWineD3DSurfaceImpl *This, GLenum internal, GLsi
} else { } else {
TRACE("(%p) : Calling glTexSubImage2D w %d, h %d, data, %p\n", This, width, height, data); TRACE("(%p) : Calling glTexSubImage2D w %d, h %d, data, %p\n", This, width, height, data);
ENTER_GL(); ENTER_GL();
glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, data);
checkGLcall("glTexSubImage2D"); if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
TRACE("(%p) pbo: %#x, data: %p\n", This, This->pbo, data);
glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, NULL);
checkGLcall("glTexSubImage2D");
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
}
else {
glTexSubImage2D(This->glDescription.target, This->glDescription.level, 0, 0, width, height, format, type, data);
checkGLcall("glTexSubImage2D");
}
LEAVE_GL(); LEAVE_GL();
} }
} }
...@@ -376,6 +404,11 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) { ...@@ -376,6 +404,11 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
LEAVE_GL(); LEAVE_GL();
} }
if(This->Flags & SFLAG_PBO) {
/* Delete the PBO */
GL_EXTCALL(glDeleteBuffersARB(1, &This->pbo));
}
if(This->Flags & SFLAG_DIBSECTION) { if(This->Flags & SFLAG_DIBSECTION) {
/* Release the DC */ /* Release the DC */
SelectObject(This->hDC, This->dib.holdbitmap); SelectObject(This->hDC, This->dib.holdbitmap);
...@@ -600,14 +633,35 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v ...@@ -600,14 +633,35 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
bpp = This->bytesPerPixel; bpp = This->bytesPerPixel;
} }
if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
}
glReadPixels(rect->left, rect->top, glReadPixels(rect->left, rect->top,
rect->right - rect->left, rect->right - rect->left,
rect->bottom - rect->top, rect->bottom - rect->top,
fmt, type, mem); fmt, type, mem);
vcheckGLcall("glReadPixels"); vcheckGLcall("glReadPixels");
/* TODO: Merge this with the palettization loop below for P8 targets */ if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
/* Check if we need to flip the image. If we need to flip use glMapBufferARB
* to get a pointer to it and perform the flipping in software. This is a lot
* faster than calling glReadPixels for each line. In case we want more speed
* we should rerender it flipped in a FBO and read the data back from the FBO. */
if(!srcUpsideDown) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
mem = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
checkGLcall("glMapBufferARB");
}
}
/* TODO: Merge this with the palettization loop below for P8 targets */
if(!srcUpsideDown) { if(!srcUpsideDown) {
UINT len, off; UINT len, off;
/* glReadPixels returns the image upside down, and there is no way to prevent this. /* glReadPixels returns the image upside down, and there is no way to prevent this.
...@@ -632,6 +686,12 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v ...@@ -632,6 +686,12 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
bottom -= pitch; bottom -= pitch;
} }
HeapFree(GetProcessHeap(), 0, row); HeapFree(GetProcessHeap(), 0, row);
/* Unmap the temp PBO buffer */
if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
}
} }
if(This->resource.format == WINED3DFMT_P8) { if(This->resource.format == WINED3DFMT_P8) {
...@@ -692,11 +752,44 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED ...@@ -692,11 +752,44 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
/* Whatever surface we have, make sure that there is memory allocated for the downloaded copy */ /* Whatever surface we have, make sure that there is memory allocated for the downloaded copy */
if(!This->resource.allocatedMemory) { if(!This->resource.allocatedMemory) {
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + 4); /* In case of PBOs allocatedMemory should be zero. */
if(!(This->Flags & SFLAG_PBO))
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + 4);
This->Flags &= ~SFLAG_INSYSMEM; /* This is the marker that surface data has to be downloaded */ This->Flags &= ~SFLAG_INSYSMEM; /* This is the marker that surface data has to be downloaded */
} }
/* Calculate the dimensions of the locked rect */ /* Create a PBO for dynamicly locked surfaces but don't do it for converted or non-pow2 surfaces */
if(GL_SUPPORT(ARB_PIXEL_BUFFER_OBJECT) && (This->Flags & SFLAG_DYNLOCK) && !(This->Flags & (SFLAG_PBO | SFLAG_CONVERTED | SFLAG_NONPOW2))) {
GLenum error;
ENTER_GL();
GL_EXTCALL(glGenBuffersARB(1, &This->pbo));
error = glGetError();
if(This->pbo == 0 || error != GL_NO_ERROR) {
ERR("Failed to bind the PBO with error %s (%#x)\n", debug_glerror(error), error);
}
TRACE("Attaching pbo=%#x to (%p)\n", This->pbo, This);
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->resource.size + 4, This->resource.allocatedMemory, GL_STREAM_DRAW_ARB));
checkGLcall("glBufferDataARB");
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
/* We don't need the system memory anymore and we can't even use it for PBOs */
if(This->resource.allocatedMemory) HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
This->resource.allocatedMemory = NULL;
This->Flags |= SFLAG_PBO;
LEAVE_GL();
}
/* Calculate the correct start address to report */
if (NULL == pRect) { if (NULL == pRect) {
This->lockedRect.left = 0; This->lockedRect.left = 0;
This->lockedRect.top = 0; This->lockedRect.top = 0;
...@@ -799,6 +892,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED ...@@ -799,6 +892,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
FIXME("Reading from render target with a texture isn't implemented yet, falling back to framebuffer reading\n"); FIXME("Reading from render target with a texture isn't implemented yet, falling back to framebuffer reading\n");
break; break;
} }
LEAVE_GL(); LEAVE_GL();
/* Mark the local copy up to date if a full download was done */ /* Mark the local copy up to date if a full download was done */
...@@ -855,6 +949,27 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED ...@@ -855,6 +949,27 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
} }
lock_end: lock_end:
if(This->Flags & SFLAG_PBO) {
ActivateContext(myDevice, myDevice->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
/* This shouldn't happen but could occur if some other function didn't handle the PBO properly */
if(This->resource.allocatedMemory) {
ERR("The surface already has PBO memory allocated!\n");
}
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_READ_WRITE_ARB));
checkGLcall("glMapBufferARB");
/* Make sure the pbo isn't set anymore in order not to break non-pbo calls */
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
LEAVE_GL();
}
/* Calculate the correct start address to report */ /* Calculate the correct start address to report */
if (NULL == pRect) { if (NULL == pRect) {
pLockedRect->pBits = This->resource.allocatedMemory; pLockedRect->pBits = This->resource.allocatedMemory;
...@@ -941,7 +1056,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) { ...@@ -941,7 +1056,7 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
* be any interfering gdi accesses, because UnlockRect is called from * be any interfering gdi accesses, because UnlockRect is called from
* ReleaseDC, and the app won't use the dc any more afterwards. * ReleaseDC, and the app won't use the dc any more afterwards.
*/ */
if(This->Flags & SFLAG_DIBSECTION) { if((This->Flags & SFLAG_DIBSECTION) && !(This->Flags & SFLAG_PBO)) {
volatile BYTE read; volatile BYTE read;
read = This->resource.allocatedMemory[0]; read = This->resource.allocatedMemory[0];
} }
...@@ -1069,11 +1184,22 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) { ...@@ -1069,11 +1184,22 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This) {
bpp = This->bytesPerPixel; bpp = This->bytesPerPixel;
} }
if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
checkGLcall("glBindBufferARB");
}
glDrawPixels(This->lockedRect.right - This->lockedRect.left, glDrawPixels(This->lockedRect.right - This->lockedRect.left,
(This->lockedRect.bottom - This->lockedRect.top)-1, (This->lockedRect.bottom - This->lockedRect.top)-1,
fmt, type, fmt, type,
mem + bpp * This->lockedRect.left + pitch * This->lockedRect.top); mem + bpp * This->lockedRect.left + pitch * This->lockedRect.top);
checkGLcall("glDrawPixels"); checkGLcall("glDrawPixels");
if(This->Flags & SFLAG_PBO) {
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glBindBufferARB");
}
glPixelZoom(1.0,1.0); glPixelZoom(1.0,1.0);
vcheckGLcall("glPixelZoom"); vcheckGLcall("glPixelZoom");
...@@ -1155,6 +1281,18 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { ...@@ -1155,6 +1281,18 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) {
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (This->Flags & SFLAG_PBO) {
TRACE("Freeing PBO memory\n");
ActivateContext(myDevice, myDevice->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, This->pbo));
GL_EXTCALL(glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB));
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
checkGLcall("glUnmapBufferARB");
LEAVE_GL();
This->resource.allocatedMemory = NULL;
}
TRACE("(%p) : dirtyfied(%d)\n", This, This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1); TRACE("(%p) : dirtyfied(%d)\n", This, This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE) ? 0 : 1);
if (This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE)) { if (This->Flags & (SFLAG_INDRAWABLE | SFLAG_INTEXTURE)) {
...@@ -1376,20 +1514,23 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) { ...@@ -1376,20 +1514,23 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
} }
TRACE("DIBSection at : %p\n", This->dib.bitmap_data); TRACE("DIBSection at : %p\n", This->dib.bitmap_data);
/* copy the existing surface to the dib section */ /* copy the existing surface to the dib section */
if(This->resource.allocatedMemory) { if(This->resource.allocatedMemory) {
memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, b_info->bmiHeader.biSizeImage); /* In case of a PBO, allocatedMemory=NULL, it isn't NULL between a LockRect and a UnlockRect */
if(!(This->Flags & SFLAG_PBO))
memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, b_info->bmiHeader.biSizeImage);
/* We won't need that any more */ /* We won't need that any more */
} else { } else {
/* This is to make LockRect read the gl Texture although memory is allocated */ /* This is to make LockRect read the gl Texture although memory is allocated */
This->Flags &= ~SFLAG_INSYSMEM; This->Flags &= ~SFLAG_INSYSMEM;
} }
This->dib.bitmap_size = b_info->bmiHeader.biSizeImage;
HeapFree(GetProcessHeap(), 0, b_info); HeapFree(GetProcessHeap(), 0, b_info);
/* Use the dib section from now on */ /* Use the dib section from now on if we are not using a PBO */
This->resource.allocatedMemory = This->dib.bitmap_data; if(!(This->Flags & SFLAG_PBO))
This->resource.allocatedMemory = This->dib.bitmap_data;
/* Now allocate a HDC */ /* Now allocate a HDC */
This->hDC = CreateCompatibleDC(0); This->hDC = CreateCompatibleDC(0);
...@@ -1412,6 +1553,12 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) { ...@@ -1412,6 +1553,12 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
&lock, &lock,
NULL, NULL,
0); 0);
if(This->Flags & SFLAG_PBO) {
/* Sync the DIB with the PBO. This can't be done earlier because LockRect activates the allocatedMemory */
memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, This->dib.bitmap_size);
}
if(FAILED(hr)) { if(FAILED(hr)) {
ERR("IWineD3DSurface_LockRect failed with hr = %08x\n", hr); ERR("IWineD3DSurface_LockRect failed with hr = %08x\n", hr);
/* keep the dib section */ /* keep the dib section */
...@@ -1465,6 +1612,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) { ...@@ -1465,6 +1612,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) {
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if((This->Flags & SFLAG_PBO) && This->resource.allocatedMemory) {
/* Copy the contents of the DIB over to the PBO */
memcpy(This->resource.allocatedMemory, This->dib.bitmap_data, This->dib.bitmap_size);
}
/* we locked first, so unlock now */ /* we locked first, so unlock now */
IWineD3DSurface_UnlockRect(iface); IWineD3DSurface_UnlockRect(iface);
...@@ -2226,7 +2378,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO ...@@ -2226,7 +2378,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
if(!(This->Flags & SFLAG_ALLOCATED)) { if(!(This->Flags & SFLAG_ALLOCATED)) {
surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type); surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type);
} }
if (mem) { if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem); surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
} }
} else { } else {
...@@ -2236,7 +2388,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO ...@@ -2236,7 +2388,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
if(!(This->Flags & SFLAG_ALLOCATED)) { if(!(This->Flags & SFLAG_ALLOCATED)) {
surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type); surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
} }
if (mem) { if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem); surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem);
} }
} }
...@@ -2244,7 +2396,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO ...@@ -2244,7 +2396,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
/* Restore the default pitch */ /* Restore the default pitch */
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
if (mem != This->resource.allocatedMemory) /* Don't delete PBO memory */
if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO))
HeapFree(GetProcessHeap(), 0, mem); HeapFree(GetProcessHeap(), 0, mem);
#if 0 #if 0
......
...@@ -321,6 +321,25 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO ...@@ -321,6 +321,25 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
back->resource.allocatedMemory = tmp; back->resource.allocatedMemory = tmp;
} }
/* Flip the PBO */
{
DWORD tmp_flags = front->Flags;
GLuint tmp_pbo = front->pbo;
front->pbo = back->pbo;
back->pbo = tmp_pbo;
if(back->Flags & SFLAG_PBO)
front->Flags |= SFLAG_PBO;
else
front->Flags &= ~SFLAG_PBO;
if(tmp_flags & SFLAG_PBO)
back->Flags |= SFLAG_PBO;
else
back->Flags &= ~SFLAG_PBO;
}
/* client_memory should not be different, but just in case */ /* client_memory should not be different, but just in case */
{ {
BOOL tmp; BOOL tmp;
......
...@@ -1045,6 +1045,7 @@ typedef struct _WINED3DSURFACET_DESC ...@@ -1045,6 +1045,7 @@ typedef struct _WINED3DSURFACET_DESC
typedef struct wineD3DSurface_DIB { typedef struct wineD3DSurface_DIB {
HBITMAP DIBsection; HBITMAP DIBsection;
void* bitmap_data; void* bitmap_data;
UINT bitmap_size;
HGDIOBJ holdbitmap; HGDIOBJ holdbitmap;
BOOL client_memory; BOOL client_memory;
} wineD3DSurface_DIB; } wineD3DSurface_DIB;
...@@ -1095,6 +1096,9 @@ struct IWineD3DSurfaceImpl ...@@ -1095,6 +1096,9 @@ struct IWineD3DSurfaceImpl
/* Oversized texture */ /* Oversized texture */
RECT glRect; RECT glRect;
/* PBO */
GLuint pbo;
#if 0 #if 0
/* precalculated x and y scalings for texture coords */ /* precalculated x and y scalings for texture coords */
float pow2scalingFactorX; /* = (Width / pow2Width ) */ float pow2scalingFactorX; /* = (Width / pow2Width ) */
...@@ -1195,6 +1199,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl ...@@ -1195,6 +1199,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
#define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */ #define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */
#define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */ #define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */
#define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */ #define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */
#define SFLAG_PBO 0x00040000 /* Has a PBO attached for speeding data transfer for dynamicly locked surfaces */
/* In some conditions the surface memory must not be freed: /* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL * SFLAG_OVERSIZE: Not all data can be kept in GL
...@@ -1203,6 +1208,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl ...@@ -1203,6 +1208,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
* SFLAG_LOCKED: The app requires access to the surface data * SFLAG_LOCKED: The app requires access to the surface data
* SFLAG_DYNLOCK: Avoid freeing the data for performance * SFLAG_DYNLOCK: Avoid freeing the data for performance
* SFLAG_DYNCHANGE: Same reason as DYNLOCK * SFLAG_DYNCHANGE: Same reason as DYNLOCK
* SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup * SFLAG_CLIENT: OpenGL uses our memory as backup
*/ */
#define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \ #define SFLAG_DONOTFREE (SFLAG_OVERSIZE | \
...@@ -1212,6 +1218,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl ...@@ -1212,6 +1218,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetClipper(IWineD3DSurface *iface, IWineD3DCl
SFLAG_DYNLOCK | \ SFLAG_DYNLOCK | \
SFLAG_DYNCHANGE | \ SFLAG_DYNCHANGE | \
SFLAG_USERPTR | \ SFLAG_USERPTR | \
SFLAG_PBO | \
SFLAG_CLIENT) SFLAG_CLIENT)
BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]); BOOL CalculateTexRect(IWineD3DSurfaceImpl *This, RECT *Rect, float glTexCoord[4]);
......
...@@ -2353,6 +2353,13 @@ typedef GLhandleARB (WINE_GLAPI * WINED3D_PFNGLGETHANDLEARBPROC) (GLenum pname); ...@@ -2353,6 +2353,13 @@ typedef GLhandleARB (WINE_GLAPI * WINED3D_PFNGLGETHANDLEARBPROC) (GLenum pname);
typedef void (WINE_GLAPI * WINED3D_PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); typedef void (WINE_GLAPI * WINED3D_PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
typedef void (WINE_GLAPI * WINED3D_PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (WINE_GLAPI * WINED3D_PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
typedef GLint (WINE_GLAPI * WINED3D_PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef GLint (WINE_GLAPI * WINED3D_PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
/* GL_ARB_pixel_buffer_object */
#ifndef GL_ARB_pixel_buffer_object
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
#endif
/* GL_EXT_texture */ /* GL_EXT_texture */
#ifndef GL_EXT_texture #ifndef GL_EXT_texture
#define GL_EXT_texture 1 #define GL_EXT_texture 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment