d3d8: Move d3d8 surface over to wined3d (based on the work of Oliver Stieber).

This commit is contained in:
Roderick Colenbrander 2006-02-14 17:13:19 +01:00 committed by Alexandre Julliard
parent bc2b9e3feb
commit 4e4fc93645
6 changed files with 443 additions and 600 deletions

View File

@ -143,27 +143,27 @@ void WINAPI IDirect3DCubeTexture8Impl_PreLoad(LPDIRECT3DCUBETEXTURE8
ENTER_GL(); ENTER_GL();
for (i = 0; i < This->levels; i++) { for (i = 0; i < This->levels; i++) {
if (i == 0 && This->surfaces[0][0]->textureName != 0 && This->Dirty == FALSE) { if (i == 0 && D3D8_SURFACE(This->surfaces[0][0])->textureName != 0 && This->Dirty == FALSE) {
glEnable(GL_TEXTURE_CUBE_MAP_ARB); glEnable(GL_TEXTURE_CUBE_MAP_ARB);
#if defined(GL_VERSION_1_3) #if defined(GL_VERSION_1_3)
glBindTexture(GL_TEXTURE_CUBE_MAP, This->surfaces[0][0]->textureName); glBindTexture(GL_TEXTURE_CUBE_MAP, D3D8_SURFACE(This->surfaces[0][0])->textureName);
#else #else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->surfaces[0][0]->textureName); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, D3D8_SURFACE(This->surfaces[0][0])->textureName);
#endif #endif
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][0], i, This->surfaces[0][0]->textureName); TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][0], i, D3D8_SURFACE(This->surfaces[0][0])->textureName);
/* No need to walk through all mip-map levels, since already all assigned */ /* No need to walk through all mip-map levels, since already all assigned */
i = This->levels; i = This->levels;
} else { } else {
if (i == 0) { if (i == 0) {
if (This->surfaces[0][0]->textureName == 0) { if (D3D8_SURFACE(This->surfaces[0][0])->textureName == 0) {
glGenTextures(1, &This->surfaces[0][0]->textureName); glGenTextures(1, &(D3D8_SURFACE(This->surfaces[0][0]))->textureName);
checkGLcall("glGenTextures"); checkGLcall("glGenTextures");
TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][i], i, This->surfaces[0][0]->textureName); TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][i], i, D3D8_SURFACE(This->surfaces[0][0])->textureName);
} }
#if defined(GL_VERSION_1_3) #if defined(GL_VERSION_1_3)
glBindTexture(GL_TEXTURE_CUBE_MAP, This->surfaces[0][0]->textureName); glBindTexture(GL_TEXTURE_CUBE_MAP, D3D8_SURFACE(This->surfaces[0][0])->textureName);
#else #else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->surfaces[0][0]->textureName); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->surfaces[0][0]->textureName);
#endif #endif
@ -275,7 +275,7 @@ HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(LPDIRECT3DCUBETEXT
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface; IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
This->Dirty = TRUE; This->Dirty = TRUE;
TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType); TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
return IDirect3DSurface8Impl_AddDirtyRect((LPDIRECT3DSURFACE8) This->surfaces[FaceType][0], pDirtyRect); return IWineD3DSurface_AddDirtyRect( (IWineD3DSurface*)(This->surfaces[FaceType][0])->wineD3DSurface, pDirtyRect);
} }

View File

@ -64,8 +64,13 @@ extern int num_lock;
#include <stdarg.h> #include <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wingdi.h"
#include "wine/debug.h"
#include "d3d8.h" #include "d3d8.h"
#include "wine/wined3d_interface.h" #include "wine/wined3d_interface.h"
@ -674,6 +679,92 @@ extern ULONG WINAPI IDirect3DSwapChain8Impl_Release(LPDIRECT3DSWAPCHAIN8 iface
extern HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion); extern HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
extern HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer); extern HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8 iface, UINT BackBuffer, D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer);
/* Below follow the definitions of some WineD3D structures which are needed during the D3D8->WineD3D transition. */
typedef struct IWineD3DSurfaceImpl IWineD3DSurfaceImpl;
typedef struct PrivateData
{
struct PrivateData* next;
GUID tag;
DWORD flags; /* DDSPD_* */
DWORD uniqueness_value;
union
{
LPVOID data;
LPUNKNOWN object;
} ptr;
DWORD size;
} PrivateData;
typedef struct IWineD3DResourceClass
{
/* IUnknown fields */
LONG ref; /* Note: Ref counting not required */
/* WineD3DResource Information */
IUnknown *parent;
D3DRESOURCETYPE resourceType;
void *wineD3DDevice;
D3DPOOL pool;
UINT size;
DWORD usage;
WINED3DFORMAT format;
BYTE *allocatedMemory;
PrivateData *privateData;
} IWineD3DResourceClass;
typedef struct _WINED3DSURFACET_DESC
{
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
UINT Width;
UINT Height;
} WINED3DSURFACET_DESC;
struct IWineD3DSurfaceImpl
{
/* IUnknown & IWineD3DResource Information */
const IWineD3DSurfaceVtbl *lpVtbl;
IWineD3DResourceClass resource;
/* IWineD3DSurface fields */
IUnknown *container;
WINED3DSURFACET_DESC currentDesc;
UINT textureName;
UINT bytesPerPixel;
/* TODO: move this off into a management class(maybe!) */
BOOL nonpow2;
UINT pow2Width;
UINT pow2Height;
UINT pow2Size;
#if 0
/* precalculated x and y scalings for texture coords */
float pow2scalingFactorX; /* = (Width / pow2Width ) */
float pow2scalingFactorY; /* = (Height / pow2Height) */
#endif
BOOL lockable;
BOOL discard;
BOOL locked;
BOOL activeLock;
RECT lockedRect;
RECT dirtyRect;
BOOL Dirty;
BOOL inTexture;
BOOL inPBuffer;
glDescriptor glDescription;
};
/* ----------------- */ /* ----------------- */
/* IDirect3DSurface8 */ /* IDirect3DSurface8 */
@ -691,28 +782,12 @@ struct IDirect3DSurface8Impl
{ {
/* IUnknown fields */ /* IUnknown fields */
const IDirect3DSurface8Vtbl *lpVtbl; const IDirect3DSurface8Vtbl *lpVtbl;
LONG ref; LONG ref;
/* IDirect3DSurface8 fields */ /* IDirect3DSurface8 fields */
IDirect3DDevice8Impl *Device; IWineD3DSurface *wineD3DSurface;
D3DRESOURCETYPE ResourceType;
IUnknown *Container;
D3DSURFACE_DESC myDesc;
BYTE *allocatedMemory;
UINT textureName;
UINT bytesPerPixel;
BOOL lockable;
BOOL locked;
RECT lockedRect;
RECT dirtyRect;
BOOL Dirty;
BOOL inTexture;
BOOL inPBuffer;
IWineD3DSurface *wineD3DSurface;
}; };
#define D3D8_SURFACE(a) ((IWineD3DSurfaceImpl*)(a->wineD3DSurface))
/* IUnknown: */ /* IUnknown: */
extern HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface,REFIID refiid,LPVOID *obj); extern HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface,REFIID refiid,LPVOID *obj);

View File

@ -304,6 +304,45 @@ ULONG WINAPI IDirect3DDevice8Impl_AddRef(LPDIRECT3DDEVICE8 iface) {
return ref; return ref;
} }
/* The function below is needed during the D3D8->WineD3D transition
in order to release various surfaces like the front- and backBuffer.
When the transition is complete code similar to this will be executed
by IWineD3DDevice_Release.
*/
void IDirect3DDevice8_CleanUp(IDirect3DDevice8Impl *This)
{
LPDIRECT3DSURFACE8 stencilBufferParent;
/* Release the buffers (with sanity checks)*/
if(This->stencilBufferTarget != NULL && (IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->stencilBufferTarget) >0)){
if(This->depthStencilBuffer != This->stencilBufferTarget)
TRACE("(%p) Something's still holding the depthStencilBuffer\n",This);
}
This->stencilBufferTarget = NULL;
if(This->renderTarget != NULL) {
IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->renderTarget);
This->renderTarget = NULL;
}
if(This->depthStencilBuffer != NULL) {
stencilBufferParent = (LPDIRECT3DSURFACE8)D3D8_SURFACE(This->depthStencilBuffer)->resource.parent;
if(stencilBufferParent != NULL) {
IDirect3DSurface8_Release(stencilBufferParent);
This->depthStencilBuffer = NULL;
}
}
if(This->backBuffer != NULL) {
IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->backBuffer);
This->backBuffer = NULL;
}
if(This->frontBuffer != NULL) {
IDirect3DSurface8Impl_Release((LPDIRECT3DSURFACE8)This->frontBuffer);
This->frontBuffer = NULL;
}
}
ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) { ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
@ -313,8 +352,8 @@ ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
if (ref == 0) { if (ref == 0) {
IDirect3DDevice8Impl_CleanRender(iface); IDirect3DDevice8Impl_CleanRender(iface);
IDirect3D8_Release((LPDIRECT3D8) This->direct3d8); IDirect3D8_Release((LPDIRECT3D8) This->direct3d8);
IDirect3DDevice8_CleanUp(This);
IWineD3DDevice_Release(This->WineD3DDevice); IWineD3DDevice_Release(This->WineD3DDevice);
if (glXGetCurrentContext() == This->glCtx) { if (glXGetCurrentContext() == This->glCtx) {
glXMakeCurrent(This->display, None, NULL); glXMakeCurrent(This->display, None, NULL);
} }
@ -401,11 +440,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 ifac
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot); TRACE("(%p) : Spot Pos(%u,%u)\n", This, XHotSpot, YHotSpot);
if (D3DFMT_A8R8G8B8 != pSur->myDesc.Format) { if (D3DFMT_A8R8G8B8 != D3D8_SURFACE(pSur)->resource.format) {
ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap); ERR("(%p) : surface(%p) has an invalid format\n", This, pCursorBitmap);
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
if (32 != pSur->myDesc.Height || 32 != pSur->myDesc.Width) { if (32 != D3D8_SURFACE(pSur)->currentDesc.Height || 32 != D3D8_SURFACE(pSur)->currentDesc.Width) {
ERR("(%p) : surface(%p) has an invalid size\n", This, pCursorBitmap); ERR("(%p) : surface(%p) has an invalid size\n", This, pCursorBitmap);
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
@ -655,18 +694,18 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UIN
for (i = 0; i < object->levels; i++) for (i = 0; i < object->levels; i++)
{ {
IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]); IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
object->surfaces[i]->Container = (IUnknown*) object; D3D8_SURFACE(object->surfaces[i])->container = (IUnknown*) object;
object->surfaces[i]->myDesc.Usage = Usage; D3D8_SURFACE(object->surfaces[i])->resource.usage = Usage;
object->surfaces[i]->myDesc.Pool = Pool; D3D8_SURFACE(object->surfaces[i])->resource.pool = Pool;
/** /**
* As written in msdn in IDirect3DTexture8::LockRect * As written in msdn in IDirect3DTexture8::LockRect
* Textures created in D3DPOOL_DEFAULT are not lockable. * Textures created in D3DPOOL_DEFAULT are not lockable.
*/ */
if (D3DPOOL_DEFAULT == Pool) { if (D3DPOOL_DEFAULT == Pool) {
object->surfaces[i]->lockable = FALSE; D3D8_SURFACE(object->surfaces[i])->lockable = FALSE;
} }
TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], object->surfaces[i]->allocatedMemory); TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[i], D3D8_SURFACE(object->surfaces[i])->resource.allocatedMemory);
tmpW = max(1, tmpW / 2); tmpW = max(1, tmpW / 2);
tmpH = max(1, tmpH / 2); tmpH = max(1, tmpH / 2);
} }
@ -805,22 +844,21 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface,
/* Create the 6 faces */ /* Create the 6 faces */
for (j = 0; j < 6; j++) { for (j = 0; j < 6; j++) {
IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]); IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
object->surfaces[j][i]->Container = (IUnknown*) object; D3D8_SURFACE(object->surfaces[j][i])->container = (IUnknown*) object;
object->surfaces[j][i]->myDesc.Usage = Usage; D3D8_SURFACE(object->surfaces[j][i])->resource.usage = Usage;
object->surfaces[j][i]->myDesc.Pool = Pool; D3D8_SURFACE(object->surfaces[j][i])->resource.pool = Pool;
/** /**
* As written in msdn in IDirect3DCubeTexture8::LockRect * As written in msdn in IDirect3DCubeTexture8::LockRect
* Textures created in D3DPOOL_DEFAULT are not lockable. * Textures created in D3DPOOL_DEFAULT are not lockable.
*/ */
if (D3DPOOL_DEFAULT == Pool) { if (D3DPOOL_DEFAULT == Pool) {
object->surfaces[j][i]->lockable = FALSE; D3D8_SURFACE(object->surfaces[j][i])->lockable = FALSE;
} }
TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], object->surfaces[j][i]->allocatedMemory); TRACE("Created surface level %d @ %p, memory at %p\n", i, object->surfaces[j][i], D3D8_SURFACE(object->surfaces[j][i])->resource.allocatedMemory);
} }
tmpW = max(1, tmpW / 2); tmpW = max(1, tmpW / 2);
} }
TRACE("(%p) : Iface@%p\n", This, object); TRACE("(%p) : Iface@%p\n", This, object);
*ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object; *ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
return D3D_OK; return D3D_OK;
@ -875,233 +913,81 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface,
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
HRESULT WINAPI IDirect3DDevice8Impl_CreateSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface8 **ppSurface,D3DRESOURCETYPE Type, UINT Usage,D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality) {
HRESULT hrc;
IDirect3DSurface8Impl *object; IDirect3DSurface8Impl *object;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) Relay\n", This);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl)); if(MultisampleQuality < 0) {
FIXME("MultisampleQuality out of range %ld, substituting 0 \n", MultisampleQuality);
/*FIXME: Find out what windows does with a MultisampleQuality < 0 */
MultisampleQuality=0;
}
if(MultisampleQuality > 0){
FIXME("MultisampleQuality set to %ld, bstituting 0 \n" , MultisampleQuality);
/*
MultisampleQuality
[in] Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D8::CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces, and the MultiSample type must all match.
*/
MultisampleQuality=0;
}
/*FIXME: Check MAX bounds of MultisampleQuality*/
/* Allocate the storage for the device */
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
if (NULL == object) { if (NULL == object) {
*ppSurface = NULL; FIXME("Allocation of memory failed\n");
return D3DERR_OUTOFVIDEOMEMORY; *ppSurface = NULL;
return D3DERR_OUTOFVIDEOMEMORY;
} }
*ppSurface = (LPDIRECT3DSURFACE8) object;
object->lpVtbl = &Direct3DSurface8_Vtbl; object->lpVtbl = &Direct3DSurface8_Vtbl;
object->Device = This;
object->ResourceType = D3DRTYPE_SURFACE;
object->Container = (IUnknown*) This;
object->ref = 1; object->ref = 1;
object->myDesc.Width = Width;
object->myDesc.Height = Height;
object->myDesc.Format = Format;
object->myDesc.Type = D3DRTYPE_SURFACE;
object->myDesc.Usage = D3DUSAGE_RENDERTARGET;
object->myDesc.Pool = D3DPOOL_DEFAULT;
object->myDesc.MultiSampleType = MultiSample;
object->bytesPerPixel = D3DFmtGetBpp(This, Format);
if (Format == D3DFMT_DXT1) {
object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */
} else {
object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
}
object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
object->lockable = Lockable;
object->locked = FALSE;
memset(&object->lockedRect, 0, sizeof(RECT));
IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) lockable(%d) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), Lockable, *ppSurface, object->allocatedMemory, object->myDesc.Size); TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
return D3D_OK;
hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, Format, Lockable, Discard, Level, &object->wineD3DSurface, Type, Usage, Pool,MultiSample,MultisampleQuality, NULL,(IUnknown *)object);
if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
/* free up object */
FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
HeapFree(GetProcessHeap(), 0, object);
*ppSurface = NULL;
} else {
*ppSurface = (LPDIRECT3DSURFACE8) object;
}
return hrc;
}
HRESULT WINAPI IDirect3DDevice8Impl_CreateRenderTarget(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, BOOL Lockable, IDirect3DSurface8** ppSurface) {
TRACE("Relay\n");
return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */, 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, 0);
} }
HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) { HRESULT WINAPI IDirect3DDevice8Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) {
IDirect3DSurface8Impl *object; TRACE("Relay\n");
/* TODO: Verify that Discard is false */
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl)); D3DPOOL_DEFAULT, MultiSample, 0);
if (NULL == object) {
*ppSurface = NULL;
return D3DERR_OUTOFVIDEOMEMORY;
}
*ppSurface = (LPDIRECT3DSURFACE8) object;
object->lpVtbl = &Direct3DSurface8_Vtbl;
object->Device = This;
object->ResourceType = D3DRTYPE_SURFACE;
object->Container = (IUnknown*) This;
object->ref = 1;
object->myDesc.Width = Width;
object->myDesc.Height = Height;
object->myDesc.Format = Format;
object->myDesc.Type = D3DRTYPE_SURFACE;
object->myDesc.Usage = D3DUSAGE_DEPTHSTENCIL;
object->myDesc.Pool = D3DPOOL_DEFAULT;
object->myDesc.MultiSampleType = MultiSample;
object->bytesPerPixel = D3DFmtGetBpp(This, Format);
if (Format == D3DFMT_DXT1) {
object->myDesc.Size = (Width * object->bytesPerPixel)/2 * Height; /* DXT1 is half byte per pixel */
} else {
object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
}
object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
object->lockable = (D3DFMT_D16_LOCKABLE == Format) ? TRUE : FALSE;
object->locked = FALSE;
memset(&object->lockedRect, 0, sizeof(RECT));
IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
return D3D_OK;
} }
HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) { HRESULT WINAPI IDirect3DDevice8Impl_CreateImageSurface(LPDIRECT3DDEVICE8 iface, UINT Width, UINT Height, D3DFORMAT Format, IDirect3DSurface8** ppSurface) {
IDirect3DSurface8Impl *object; TRACE("Relay\n");
return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Loackable */ , FALSE /*Discard*/ , 0 /* Level */ , ppSurface, D3DRTYPE_SURFACE, 0 /* Usage (undefined/none) */ , D3DPOOL_SCRATCH, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
}
HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface, IDirect3DSurface8 *pSourceSurface, CONST RECT *pSourceRects, UINT cRects, IDirect3DSurface8 *pDestinationSurface, CONST POINT *pDestPoints) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl)); TRACE("(%p) Relay\n" , This);
*ppSurface = (LPDIRECT3DSURFACE8) object;
object->lpVtbl = &Direct3DSurface8_Vtbl;
object->Device = This;
object->ResourceType = D3DRTYPE_SURFACE;
object->Container = (IUnknown*) This;
object->ref = 1; return IWineD3DDevice_CopyRects(This->WineD3DDevice, pSourceSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pSourceSurface)->wineD3DSurface,
object->myDesc.Width = Width; pSourceRects, cRects, pDestinationSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pDestinationSurface)->wineD3DSurface, pDestPoints);
object->myDesc.Height = Height;
object->myDesc.Format = Format;
object->myDesc.Type = D3DRTYPE_SURFACE;
object->myDesc.Usage = 0;
object->myDesc.Pool = D3DPOOL_SYSTEMMEM;
object->bytesPerPixel = D3DFmtGetBpp(This, Format);
/* DXTn mipmaps use the same number of 'levels' down to eg. 8x1, but since
it is based around 4x4 pixel blocks it requires padding, so allocate enough
space! */
if (Format == D3DFMT_DXT1) {
object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4)) / 2; /* DXT1 is half byte per pixel */
} else if (Format == D3DFMT_DXT2 || Format == D3DFMT_DXT3 ||
Format == D3DFMT_DXT4 || Format == D3DFMT_DXT5) {
object->myDesc.Size = ((max(Width,4) * object->bytesPerPixel) * max(Height,4));
} else {
object->myDesc.Size = (Width * object->bytesPerPixel) * Height;
}
object->allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->myDesc.Size);
object->lockable = TRUE;
object->locked = FALSE;
memset(&object->lockedRect, 0, sizeof(RECT));
IDirect3DSurface8Impl_CleanDirtyRect((LPDIRECT3DSURFACE8) object);
TRACE("(%p) : w(%d) h(%d) fmt(%d,%s) surf@%p, surfmem@%p, %d bytes\n", This, Width, Height, Format, debug_d3dformat(Format), *ppSurface, object->allocatedMemory, object->myDesc.Size);
return D3D_OK;
} }
HRESULT WINAPI IDirect3DDevice8Impl_CopyRects(LPDIRECT3DDEVICE8 iface,
IDirect3DSurface8* pSourceSurface, CONST RECT* pSourceRectsArray, UINT cRects,
IDirect3DSurface8* pDestinationSurface, CONST POINT* pDestPointsArray) {
HRESULT rc = D3D_OK;
IDirect3DBaseTexture8* texture = NULL;
IDirect3DSurface8Impl* src = (IDirect3DSurface8Impl*) pSourceSurface;
IDirect3DSurface8Impl* dst = (IDirect3DSurface8Impl*) pDestinationSurface;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
/* Note: Not sure about the d3dfmt_unknown bit, but seems to avoid a problem inside
a sample and doesn't seem to break anything as far as I can tell */
if (src->myDesc.Format != dst->myDesc.Format && (dst->myDesc.Format != D3DFMT_UNKNOWN)) {
TRACE("Formats do not match (%x,%s) / (%x,%s)\n",
src->myDesc.Format, debug_d3dformat(src->myDesc.Format),
dst->myDesc.Format, debug_d3dformat(dst->myDesc.Format));
rc = D3DERR_INVALIDCALL;
} else if (dst->myDesc.Format == D3DFMT_UNKNOWN) {
TRACE("Converting dest to same format as source, since dest was unknown\n");
dst->myDesc.Format = src->myDesc.Format;
/* Convert container as well */
rc = IDirect3DSurface8Impl_GetContainer((LPDIRECT3DSURFACE8) dst, &IID_IDirect3DBaseTexture8, (void**) &texture); /* FIXME: Which refid? */
if (SUCCEEDED(rc) && NULL != texture) {
((IDirect3DBaseTexture8Impl*) texture)->format = src->myDesc.Format;
/** Releasing texture after GetContainer */
IDirect3DBaseTexture8_Release(texture);
texture = NULL;
}
}
/* Quick if complete copy ... */
if (SUCCEEDED(rc)) {
if (cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
if (src->myDesc.Width == dst->myDesc.Width && src->myDesc.Height == dst->myDesc.Height) {
D3DLOCKED_RECT lrSrc;
D3DLOCKED_RECT lrDst;
IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, NULL, D3DLOCK_READONLY);
IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, NULL, 0L);
TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", dst->myDesc.Width, dst->myDesc.Height);
memcpy(lrDst.pBits, lrSrc.pBits, src->myDesc.Size);
IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
TRACE("Unlocked src and dst\n");
} else {
FIXME("Wanted to copy all surfaces but size not compatible\n");
rc = D3DERR_INVALIDCALL;
}
} else {
if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
int bytesPerPixel = ((IDirect3DSurface8Impl*) pSourceSurface)->bytesPerPixel;
unsigned int i;
/* Copy rect by rect */
for (i = 0; i < cRects; i++) {
CONST RECT* r = &pSourceRectsArray[i];
CONST POINT* p = &pDestPointsArray[i];
int copyperline;
int j;
D3DLOCKED_RECT lrSrc;
D3DLOCKED_RECT lrDst;
RECT dest_rect;
TRACE("Copying rect %d (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
if (src->myDesc.Format == D3DFMT_DXT1) {
copyperline = ((r->right - r->left) * bytesPerPixel)/2; /* DXT1 is half byte per pixel */
} else {
copyperline = ((r->right - r->left) * bytesPerPixel);
}
IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) src, &lrSrc, r, D3DLOCK_READONLY);
dest_rect.left = p->x;
dest_rect.top = p->y;
dest_rect.right = p->x + (r->right - r->left);
dest_rect.bottom= p->y + (r->bottom - r->top);
IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) dst, &lrDst, &dest_rect, 0L);
TRACE("Locked src and dst\n");
/* Find where to start */
for (j = 0; j < (r->bottom - r->top - 1); j++) {
memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
}
IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) src);
rc = IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) dst);
TRACE("Unlocked src and dst\n");
}
} else {
FIXME("Wanted to copy partial surfaces not implemented\n");
rc = D3DERR_INVALIDCALL;
}
}
}
return rc;
}
HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) { HRESULT WINAPI IDirect3DDevice8Impl_UpdateTexture(LPDIRECT3DDEVICE8 iface, IDirect3DBaseTexture8* pSourceTexture, IDirect3DBaseTexture8* pDestinationTexture) {
IDirect3DBaseTexture8Impl* src = (IDirect3DBaseTexture8Impl*) pSourceTexture; IDirect3DBaseTexture8Impl* src = (IDirect3DBaseTexture8Impl*) pSourceTexture;
IDirect3DBaseTexture8Impl* dst = (IDirect3DBaseTexture8Impl*) pDestinationTexture; IDirect3DBaseTexture8Impl* dst = (IDirect3DBaseTexture8Impl*) pDestinationTexture;
@ -1189,7 +1075,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetFrontBuffer(LPDIRECT3DDEVICE8 iface, ID
FIXME("(%p) : Should return whole screen, only returns GL context window in top left corner\n", This); FIXME("(%p) : Should return whole screen, only returns GL context window in top left corner\n", This);
if (D3DFMT_A8R8G8B8 != ((IDirect3DSurface8Impl*) pDestSurface)->myDesc.Format) { if (D3DFMT_A8R8G8B8 != D3D8_SURFACE(((IDirect3DSurface8Impl*)pDestSurface))->resource.format) {
ERR("(%p) : surface(%p) has an invalid format\n", This, pDestSurface); ERR("(%p) : surface(%p) has an invalid format\n", This, pDestSurface);
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
@ -1263,8 +1149,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, I
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
/* Finally, reset the viewport as the MSDN states. */ /* Finally, reset the viewport as the MSDN states. */
viewport.Height = ((IDirect3DSurface8Impl*)pRenderTarget)->myDesc.Height; viewport.Height = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Height;
viewport.Width = ((IDirect3DSurface8Impl*)pRenderTarget)->myDesc.Width; viewport.Width = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Width;
viewport.X = 0; viewport.X = 0;
viewport.Y = 0; viewport.Y = 0;
viewport.MaxZ = 1.0f; viewport.MaxZ = 1.0f;
@ -1318,7 +1204,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
printf("Hit Enter ...\n"); printf("Hit Enter ...\n");
getchar(); getchar();
#endif #endif
if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) { if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) {
#if 0 #if 0
GLenum prev_read; GLenum prev_read;
@ -1351,11 +1236,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont); hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont);
if (SUCCEEDED(hr) && NULL != cont) { if (SUCCEEDED(hr) && NULL != cont) {
/** always dirtify for now. we must find a better way to see that surface have been modified */ /** always dirtify for now. we must find a better way to see that surface have been modified */
This->renderTarget->inPBuffer = TRUE; D3D8_SURFACE(This->renderTarget)->inPBuffer = TRUE;
This->renderTarget->inTexture = FALSE; D3D8_SURFACE(This->renderTarget)->inTexture = FALSE;
IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE); IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE);
IDirect3DBaseTexture8_PreLoad(cont); IDirect3DBaseTexture8_PreLoad(cont);
This->renderTarget->inPBuffer = FALSE; D3D8_SURFACE(This->renderTarget)->inPBuffer = FALSE;
IDirect3DBaseTexture8Impl_Release(cont); IDirect3DBaseTexture8Impl_Release(cont);
cont = NULL; cont = NULL;
} }
@ -1429,14 +1314,14 @@ HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count
/* Note gl uses lower left, width/height */ /* Note gl uses lower left, width/height */
TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect, TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect,
curRect->x1, curRect->y1, curRect->x2, curRect->y2, curRect->x1, curRect->y1, curRect->x2, curRect->y2,
curRect->x1, (This->renderTarget->myDesc.Height - curRect->y2), curRect->x1, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - curRect->y2),
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
glScissor(curRect->x1, (This->renderTarget->myDesc.Height - curRect->y2), glScissor(curRect->x1, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - curRect->y2),
curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); curRect->x2 - curRect->x1, curRect->y2 - curRect->y1);
checkGLcall("glScissor"); checkGLcall("glScissor");
} else { } else {
glScissor(This->StateBlock->viewport.X, glScissor(This->StateBlock->viewport.X,
(This->renderTarget->myDesc.Height - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)), (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - (This->StateBlock->viewport.Y + This->StateBlock->viewport.Height)),
This->StateBlock->viewport.Width, This->StateBlock->viewport.Width,
This->StateBlock->viewport.Height); This->StateBlock->viewport.Height);
checkGLcall("glScissor"); checkGLcall("glScissor");
@ -1662,7 +1547,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST
glDepthRange(pViewport->MinZ, pViewport->MaxZ); glDepthRange(pViewport->MinZ, pViewport->MaxZ);
checkGLcall("glDepthRange"); checkGLcall("glDepthRange");
/* Note: GL requires lower left, DirectX supplies upper left */ /* Note: GL requires lower left, DirectX supplies upper left */
glViewport(pViewport->X, (This->renderTarget->myDesc.Height - (pViewport->Y + pViewport->Height)), glViewport(pViewport->X, (D3D8_SURFACE(This->renderTarget)->currentDesc.Height - (pViewport->Y + pViewport->Height)),
pViewport->Width, pViewport->Height); pViewport->Width, pViewport->Height);
checkGLcall("glViewport"); checkGLcall("glViewport");
@ -4577,10 +4462,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
int nCfgs = 0; int nCfgs = 0;
int attribs[256]; int attribs[256];
int nAttribs = 0; int nAttribs = 0;
D3DFORMAT BackBufferFormat = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Format; D3DFORMAT BackBufferFormat = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->resource.format;
D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IDirect3DSurface8Impl*) StencilSurface)->myDesc.Format : 0; D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? D3D8_SURFACE(((IDirect3DSurface8Impl*) StencilSurface))->resource.format : 0;
UINT Width = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Width; UINT Width = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Width;
UINT Height = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Height; UINT Height = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Height;
IDirect3DSurface8Impl* tmp; IDirect3DSurface8Impl* tmp;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
@ -4727,8 +4612,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
#endif #endif
} }
if (BackBufferFormat != This->renderTarget->myDesc.Format && if (BackBufferFormat != D3D8_SURFACE(This->renderTarget)->resource.format &&
StencilBufferFormat != This->stencilBufferTarget->myDesc.Format) { StencilBufferFormat != D3D8_SURFACE(This->stencilBufferTarget)->resource.format) {
nAttribs = 0; nAttribs = 0;
PUSH2(GLX_PBUFFER_WIDTH, Width); PUSH2(GLX_PBUFFER_WIDTH, Width);
PUSH2(GLX_PBUFFER_HEIGHT, Height); PUSH2(GLX_PBUFFER_HEIGHT, Height);

View File

@ -113,15 +113,15 @@ D3DPOOL WINAPI IDirect3DResource8Impl_GetPool(LPDIRECT3DRESOURCE8 iface) {
switch (This->ResourceType) { switch (This->ResourceType) {
case D3DRTYPE_SURFACE: case D3DRTYPE_SURFACE:
return ((IDirect3DSurface8Impl*) This)->myDesc.Pool; return D3D8_SURFACE(((IDirect3DSurface8Impl*) This))->resource.pool;
case D3DRTYPE_TEXTURE: case D3DRTYPE_TEXTURE:
return ((IDirect3DTexture8Impl*) This)->surfaces[0]->myDesc.Pool; return D3D8_SURFACE(((IDirect3DTexture8Impl*) This)->surfaces[0])->resource.pool;
case D3DRTYPE_VOLUME: case D3DRTYPE_VOLUME:
return ((IDirect3DVolume8Impl*) This)->myDesc.Pool; return ((IDirect3DVolume8Impl*) This)->myDesc.Pool;
case D3DRTYPE_VOLUMETEXTURE: case D3DRTYPE_VOLUMETEXTURE:
return ((IDirect3DVolumeTexture8Impl*) This)->volumes[0]->myDesc.Pool; return ((IDirect3DVolumeTexture8Impl*) This)->volumes[0]->myDesc.Pool;
case D3DRTYPE_CUBETEXTURE: case D3DRTYPE_CUBETEXTURE:
return ((IDirect3DCubeTexture8Impl*) This)->surfaces[0][0]->myDesc.Pool; return D3D8_SURFACE(((IDirect3DCubeTexture8Impl*) This)->surfaces[0][0])->resource.pool;
case D3DRTYPE_VERTEXBUFFER: case D3DRTYPE_VERTEXBUFFER:
return ((IDirect3DVertexBuffer8Impl*) This)->currentDesc.Pool; return ((IDirect3DVertexBuffer8Impl*) This)->currentDesc.Pool;
case D3DRTYPE_INDEXBUFFER: case D3DRTYPE_INDEXBUFFER:

View File

@ -1,9 +1,7 @@
/* /*
* IDirect3DSurface8 implementation * IDirect3DSurface8 implementation
* *
* Copyright 2002-2004 Jason Edmeades * Copyright 2005 Oliver Stieber
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2004 Christian Costa
* *
* 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
@ -21,44 +19,30 @@
*/ */
#include "config.h" #include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "wine/debug.h"
#include "d3d8_private.h" #include "d3d8_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
/* IDirect3DVolume IUnknown parts follow: */ /* IDirect3DSurface8 IUnknown parts follow: */
HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface,REFIID riid,LPVOID *ppobj) HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface, REFIID riid, LPVOID *ppobj) {
{
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (IsEqualGUID(riid, &IID_IUnknown) if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|| IsEqualGUID(riid, &IID_IDirect3DSurface8)) { || IsEqualGUID(riid, &IID_IDirect3DSurface8)) {
IDirect3DSurface8Impl_AddRef(iface); IUnknown_AddRef(iface);
*ppobj = This; *ppobj = This;
return D3D_OK; return D3D_OK;
} }
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
return E_NOINTERFACE; return E_NOINTERFACE;
} }
ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) { ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
ULONG ref = InterlockedIncrement(&This->ref); ULONG ref = InterlockedIncrement(&This->ref);
InterlockedIncrement(&D3D8_SURFACE(This)->resource.ref);
TRACE("(%p) : AddRef from %ld\n", This, ref - 1); TRACE("(%p) : AddRef from %ld\n", This, ref - 1);
@ -72,54 +56,51 @@ ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
TRACE("(%p) : ReleaseRef to %ld\n", This, ref); TRACE("(%p) : ReleaseRef to %ld\n", This, ref);
if (ref == 0) { if (ref == 0) {
HeapFree(GetProcessHeap(), 0, This->allocatedMemory); IWineD3DSurface_Release(This->wineD3DSurface);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
else
InterlockedDecrement(&D3D8_SURFACE(This)->resource.ref);
return ref; return ref;
} }
/* IDirect3DSurface8: */ /* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8** ppDevice) { HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8 **ppDevice) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
TRACE("(%p) : returning %p\n", This, This->Device); return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
*ppDevice = (LPDIRECT3DDEVICE8) This->Device;
/**
* Note Calling this method will increase the internal reference count
* on the IDirect3DDevice8 interface.
*/
IDirect3DDevice8Impl_AddRef(*ppDevice);
return D3D_OK;
} }
HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
FIXME("(%p) : stub\n", This); TRACE("(%p) Relay\n", This);
return D3D_OK; return IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
} }
HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
FIXME("(%p) : stub\n", This); TRACE("(%p) Relay\n", This);
return D3D_OK; return IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
} }
HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid) { HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
FIXME("(%p) : stub\n", This); TRACE("(%p) Relay\n", This);
return D3D_OK; return IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
} }
HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(LPDIRECT3DSURFACE8 iface, REFIID riid, void** ppContainer) { /* IDirect3DSurface8 Interface follow: */
HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(LPDIRECT3DSURFACE8 iface, REFIID riid, void **ppContainer) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
HRESULT res; HRESULT res;
res = IUnknown_QueryInterface(This->Container, riid, ppContainer); res = IUnknown_QueryInterface(D3D8_SURFACE(This)->container, riid, ppContainer);
if (E_NOINTERFACE == res) { if (E_NOINTERFACE == res) {
/** /**
* If the surface is created using CreateImageSurface, CreateRenderTarget, * If the surface is created using CreateImageSurface, CreateRenderTarget,
* or CreateDepthStencilSurface, the surface is considered stand alone. In this case, * or CreateDepthStencilSurface, the surface is considered stand alone. In this case,
* GetContainer will return the Direct3D device used to create the surface. * GetContainer will return the Direct3D device used to create the surface.
*/ */
res = IUnknown_QueryInterface(This->Container, &IID_IDirect3DDevice8, ppContainer); res = IUnknown_QueryInterface(D3D8_SURFACE(This)->container, &IID_IDirect3DDevice8, ppContainer);
} }
TRACE("(%p) : returning %p\n", This, *ppContainer); TRACE("(%p) : returning %p\n", This, *ppContainer);
return res; return res;
@ -127,24 +108,37 @@ HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(LPDIRECT3DSURFACE8 iface, REFI
HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3DSURFACE_DESC *pDesc) { HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3DSURFACE_DESC *pDesc) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
WINED3DSURFACE_DESC wined3ddesc;
UINT tmpInt = -1;
TRACE("(%p) Relay\n", This);
TRACE("(%p) : copying into %p\n", This, pDesc); /* As d3d8 and d3d8 structures differ, pass in ptrs to where data needs to go */
memcpy(pDesc, &This->myDesc, sizeof(D3DSURFACE_DESC)); memset(&wined3ddesc, 0, sizeof(wined3ddesc));
return D3D_OK; wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
wined3ddesc.Type = &pDesc->Type;
wined3ddesc.Usage = &pDesc->Usage;
wined3ddesc.Pool = &pDesc->Pool;
wined3ddesc.Size = &tmpInt;
wined3ddesc.MultiSampleType = &pDesc->MultiSampleType;
wined3ddesc.Width = &pDesc->Width;
wined3ddesc.Height = &pDesc->Height;
return IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
} }
#define D3D8_SURFACE_GET_DEVICE(a) ((IDirect3DDevice8Impl*)((IDirect3DTexture8Impl*)(D3D8_SURFACE(a)->container))->Device)
HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
HRESULT hr; HRESULT hr;
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
/* fixme: should we really lock as such? */ /* fixme: should we really lock as such? */
if (This->inTexture && This->inPBuffer) { if (D3D8_SURFACE(This)->inTexture && D3D8_SURFACE(This)->inPBuffer) {
FIXME("Warning: Surface is in texture memory or pbuffer\n"); FIXME("Warning: Surface is in texture memory or pbuffer\n");
This->inTexture = 0; D3D8_SURFACE(This)->inTexture = 0;
This->inPBuffer = 0; D3D8_SURFACE(This)->inPBuffer = 0;
} }
if (FALSE == This->lockable) { if (FALSE == D3D8_SURFACE(This)->lockable) {
/* Note: UpdateTextures calls CopyRects which calls this routine to populate the /* Note: UpdateTextures calls CopyRects which calls this routine to populate the
texture regions, and since the destination is an unlockable region we need texture regions, and since the destination is an unlockable region we need
to tolerate this */ to tolerate this */
@ -152,60 +146,60 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
/*return D3DERR_INVALIDCALL; */ /*return D3DERR_INVALIDCALL; */
} }
if (This == This->Device->backBuffer || This == This->Device->renderTarget || This == This->Device->frontBuffer || This->Device->depthStencilBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget || This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer || D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
if (This == This->Device->backBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
} else if (This == This->Device->frontBuffer) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer) {
TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
} else if (This == This->Device->renderTarget) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
TRACE("(%p, renderTarget) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); TRACE("(%p, renderTarget) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
} else if (This == This->Device->depthStencilBuffer) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
} }
} else { } else {
TRACE("(%p) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); TRACE("(%p) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
} }
/* DXTn formats don't have exact pitches as they are to the new row of blocks, /* DXTn formats don't have exact pitches as they are to the new row of blocks,
where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5) where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5)
ie pitch = (width/4) * bytes per block */ ie pitch = (width/4) * bytes per block */
if (This->myDesc.Format == D3DFMT_DXT1) /* DXT1 is 8 bytes per block */ if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1) /* DXT1 is 8 bytes per block */
pLockedRect->Pitch = (This->myDesc.Width/4) * 8; pLockedRect->Pitch = (D3D8_SURFACE(This)->currentDesc.Width/4) * 8;
else if (This->myDesc.Format == D3DFMT_DXT2 || This->myDesc.Format == D3DFMT_DXT3 || else if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 ||
This->myDesc.Format == D3DFMT_DXT4 || This->myDesc.Format == D3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */ D3D8_SURFACE(This)->resource.format == D3DFMT_DXT4 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */
pLockedRect->Pitch = (This->myDesc.Width/4) * 16; pLockedRect->Pitch = (D3D8_SURFACE(This)->currentDesc.Width/4) * 16;
else else
pLockedRect->Pitch = This->bytesPerPixel * This->myDesc.Width; /* Bytes / row */ pLockedRect->Pitch = D3D8_SURFACE(This)->bytesPerPixel * D3D8_SURFACE(This)->currentDesc.Width; /* Bytes / row */
if (NULL == pRect) { if (NULL == pRect) {
pLockedRect->pBits = This->allocatedMemory; pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory;
This->lockedRect.left = 0; D3D8_SURFACE(This)->lockedRect.left = 0;
This->lockedRect.top = 0; D3D8_SURFACE(This)->lockedRect.top = 0;
This->lockedRect.right = This->myDesc.Width; D3D8_SURFACE(This)->lockedRect.right = D3D8_SURFACE(This)->currentDesc.Width;
This->lockedRect.bottom = This->myDesc.Height; D3D8_SURFACE(This)->lockedRect.bottom = D3D8_SURFACE(This)->currentDesc.Height;
TRACE("Locked Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", &This->lockedRect, This->lockedRect.left, This->lockedRect.top, This->lockedRect.right, This->lockedRect.bottom); TRACE("Locked Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", &D3D8_SURFACE(This)->lockedRect, D3D8_SURFACE(This)->lockedRect.left, D3D8_SURFACE(This)->lockedRect.top, D3D8_SURFACE(This)->lockedRect.right, D3D8_SURFACE(This)->lockedRect.bottom);
} else { } else {
TRACE("Lock Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom); TRACE("Lock Rect (%p) = l %ld, t %ld, r %ld, b %ld\n", pRect, pRect->left, pRect->top, pRect->right, pRect->bottom);
if (This->myDesc.Format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */ if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */
pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel/2)); pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * D3D8_SURFACE(This)->bytesPerPixel/2));
} else { } else {
pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * This->bytesPerPixel); pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + (pRect->left * D3D8_SURFACE(This)->bytesPerPixel);
} }
This->lockedRect.left = pRect->left; D3D8_SURFACE(This)->lockedRect.left = pRect->left;
This->lockedRect.top = pRect->top; D3D8_SURFACE(This)->lockedRect.top = pRect->top;
This->lockedRect.right = pRect->right; D3D8_SURFACE(This)->lockedRect.right = pRect->right;
This->lockedRect.bottom = pRect->bottom; D3D8_SURFACE(This)->lockedRect.bottom = pRect->bottom;
} }
if (0 == This->myDesc.Usage) { /* classic surface */ if (0 == D3D8_SURFACE(This)->resource.usage) { /* classic surface */
/* Nothing to do ;) */ /* Nothing to do ;) */
} else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */ } else if (D3DUSAGE_RENDERTARGET & D3D8_SURFACE(This)->resource.usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */
if (This == This->Device->backBuffer || This == This->Device->renderTarget || This == This->Device->frontBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget || This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer) {
GLint prev_store; GLint prev_store;
GLint prev_read; GLint prev_read;
@ -215,7 +209,7 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
* for render->surface copy begin to begin of allocatedMemory * for render->surface copy begin to begin of allocatedMemory
* unlock can be more easy * unlock can be more easy
*/ */
pLockedRect->pBits = This->allocatedMemory; pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory;
glFlush(); glFlush();
vcheckGLcall("glFlush"); vcheckGLcall("glFlush");
@ -224,27 +218,27 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store); glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
vcheckGLcall("glIntegerv"); vcheckGLcall("glIntegerv");
if (This == This->Device->backBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
glReadBuffer(GL_BACK); glReadBuffer(GL_BACK);
} else if (This == This->Device->frontBuffer || This == This->Device->renderTarget) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
glReadBuffer(GL_FRONT); glReadBuffer(GL_FRONT);
} else if (This == This->Device->depthStencilBuffer) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
ERR("Stencil Buffer lock unsupported for now\n"); ERR("Stencil Buffer lock unsupported for now\n");
} }
vcheckGLcall("glReadBuffer"); vcheckGLcall("glReadBuffer");
{ {
long j; long j;
GLenum format = D3DFmt2GLFmt(This->Device, This->myDesc.Format); GLenum format = D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format);
GLenum type = D3DFmt2GLType(This->Device, This->myDesc.Format); GLenum type = D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format);
for (j = This->lockedRect.top; j < This->lockedRect.bottom - This->lockedRect.top; ++j) { for (j = D3D8_SURFACE(This)->lockedRect.top; j < D3D8_SURFACE(This)->lockedRect.bottom - D3D8_SURFACE(This)->lockedRect.top; ++j) {
glReadPixels(This->lockedRect.left, glReadPixels(D3D8_SURFACE(This)->lockedRect.left,
This->lockedRect.bottom - j - 1, D3D8_SURFACE(This)->lockedRect.bottom - j - 1,
This->lockedRect.right - This->lockedRect.left, D3D8_SURFACE(This)->lockedRect.right - D3D8_SURFACE(This)->lockedRect.left,
1, 1,
format, format,
type, type,
(char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top))); (char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-D3D8_SURFACE(This)->lockedRect.top)));
vcheckGLcall("glReadPixels"); vcheckGLcall("glReadPixels");
} }
} }
@ -255,15 +249,15 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
LEAVE_GL(); LEAVE_GL();
} else { } else {
FIXME("unsupported locking to Rendering surface surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("unsupported locking to Rendering surface surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} }
} else if (D3DUSAGE_DEPTHSTENCIL & This->myDesc.Usage) { /* stencil surfaces */ } else if (D3DUSAGE_DEPTHSTENCIL & D3D8_SURFACE(This)->resource.usage) { /* stencil surfaces */
FIXME("TODO stencil depth surface locking surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("TODO stencil depth surface locking surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} else { } else {
FIXME("unsupported locking to surface surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("unsupported locking to surface surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} }
if (Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY)) { if (Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY)) {
@ -273,12 +267,12 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
* Dirtify on lock * Dirtify on lock
* as seen in msdn docs * as seen in msdn docs
*/ */
IDirect3DSurface8Impl_AddDirtyRect(iface, &This->lockedRect); IWineD3DSurface_AddDirtyRect(This->wineD3DSurface, &D3D8_SURFACE(This)->lockedRect);
/** Dirtify Container if needed */ /** Dirtify Container if needed */
if (NULL != This->Container) { if (NULL != D3D8_SURFACE(This)->container) {
IDirect3DBaseTexture8* cont = NULL; IDirect3DBaseTexture8* cont = NULL;
hr = IUnknown_QueryInterface(This->Container, &IID_IDirect3DBaseTexture8, (void**) &cont); hr = IUnknown_QueryInterface(D3D8_SURFACE(This)->container, &IID_IDirect3DBaseTexture8, (void**) &cont);
if (SUCCEEDED(hr) && NULL != cont) { if (SUCCEEDED(hr) && NULL != cont) {
IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE); IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE);
@ -288,9 +282,9 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
} }
} }
TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch, This->Dirty); TRACE("returning memory@%p, pitch(%d) dirtyfied(%d)\n", pLockedRect->pBits, pLockedRect->Pitch, D3D8_SURFACE(This)->Dirty);
This->locked = TRUE; D3D8_SURFACE(This)->locked = TRUE;
return D3D_OK; return D3D_OK;
} }
@ -298,38 +292,38 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
GLint skipBytes = 0; GLint skipBytes = 0;
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (FALSE == This->locked) { if (FALSE == D3D8_SURFACE(This)->locked) {
ERR("trying to Unlock an unlocked surf@%p\n", This); ERR("trying to Unlock an unlocked surf@%p\n", This);
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This->Device->depthStencilBuffer || This == This->Device->renderTarget) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer || D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
if (This == This->Device->backBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == This->Device->frontBuffer) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer) {
TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == This->Device->depthStencilBuffer) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == This->Device->renderTarget) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} }
} else { } else {
TRACE("(%p) : dirtyfied(%d)\n", This, This->Dirty); TRACE("(%p) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} }
if (FALSE == This->Dirty) { if (FALSE == D3D8_SURFACE(This)->Dirty) {
TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This); TRACE("(%p) : Not Dirtified so nothing to do, return now\n", This);
goto unlock_end; goto unlock_end;
} }
if (0 == This->myDesc.Usage) { /* classic surface */ if (0 == D3D8_SURFACE(This)->resource.usage) { /* classic surface */
/** /**
* nothing to do * nothing to do
* waiting to reload the surface via IDirect3DDevice8::UpdateTexture * waiting to reload the surface via IDirect3DDevice8::UpdateTexture
*/ */
} else if (D3DUSAGE_RENDERTARGET & This->myDesc.Usage) { /* render surfaces */ } else if (D3DUSAGE_RENDERTARGET & D3D8_SURFACE(This)->resource.usage) { /* render surfaces */
if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This == This->Device->renderTarget) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
GLint prev_store; GLint prev_store;
GLint prev_draw; GLint prev_draw;
GLint prev_rasterpos[4]; GLint prev_rasterpos[4];
@ -350,10 +344,10 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
/* glDrawPixels transforms the raster position as though it was a vertex - /* glDrawPixels transforms the raster position as though it was a vertex -
we want to draw at screen position 0,0 - Set up ortho (rhw) mode as we want to draw at screen position 0,0 - Set up ortho (rhw) mode as
per drawprim (and leave set - it will sort itself out due to last_was_rhw */ per drawprim (and leave set - it will sort itself out due to last_was_rhw */
if (!This->Device->last_was_rhw) { if (!D3D8_SURFACE_GET_DEVICE(This)->last_was_rhw) {
double X, Y, height, width, minZ, maxZ; double X, Y, height, width, minZ, maxZ;
This->Device->last_was_rhw = TRUE; D3D8_SURFACE_GET_DEVICE(This)->last_was_rhw = TRUE;
/* Transformed already into viewport coordinates, so we do not need transform /* Transformed already into viewport coordinates, so we do not need transform
matrices. Reset all matrices to identity and leave the default matrix in world matrices. Reset all matrices to identity and leave the default matrix in world
@ -369,12 +363,12 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
checkGLcall("glLoadIdentity"); checkGLcall("glLoadIdentity");
/* Set up the viewport to be full viewport */ /* Set up the viewport to be full viewport */
X = This->Device->StateBlock->viewport.X; X = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.X;
Y = This->Device->StateBlock->viewport.Y; Y = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Y;
height = This->Device->StateBlock->viewport.Height; height = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Height;
width = This->Device->StateBlock->viewport.Width; width = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Width;
minZ = This->Device->StateBlock->viewport.MinZ; minZ = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.MinZ;
maxZ = This->Device->StateBlock->viewport.MaxZ; maxZ = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.MaxZ;
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ); TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ); glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
checkGLcall("glOrtho"); checkGLcall("glOrtho");
@ -385,34 +379,34 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
checkGLcall("glTranslatef(0.5, 0.5, 0)"); checkGLcall("glTranslatef(0.5, 0.5, 0)");
} }
if (This == This->Device->backBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
glDrawBuffer(GL_BACK); glDrawBuffer(GL_BACK);
} else if (This == This->Device->frontBuffer || This == This->Device->renderTarget) { } else if (This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer || This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
glDrawBuffer(GL_FRONT); glDrawBuffer(GL_FRONT);
} }
vcheckGLcall("glDrawBuffer"); vcheckGLcall("glDrawBuffer");
/* If not fullscreen, we need to skip a number of bytes to find the next row of data */ /* If not fullscreen, we need to skip a number of bytes to find the next row of data */
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &skipBytes); glGetIntegerv(GL_UNPACK_ROW_LENGTH, &skipBytes);
glPixelStorei(GL_UNPACK_ROW_LENGTH, This->myDesc.Width); glPixelStorei(GL_UNPACK_ROW_LENGTH, D3D8_SURFACE(This)->currentDesc.Width);
/* And back buffers are not blended */ /* And back buffers are not blended */
glDisable(GL_BLEND); glDisable(GL_BLEND);
glRasterPos3i(This->lockedRect.left, This->lockedRect.top, 1); glRasterPos3i(D3D8_SURFACE(This)->lockedRect.left, D3D8_SURFACE(This)->lockedRect.top, 1);
vcheckGLcall("glRasterPos2f"); vcheckGLcall("glRasterPos2f");
switch (This->myDesc.Format) { switch (D3D8_SURFACE(This)->resource.format) {
case D3DFMT_R5G6B5: case D3DFMT_R5G6B5:
{ {
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1, glDrawPixels(D3D8_SURFACE(This)->lockedRect.right - D3D8_SURFACE(This)->lockedRect.left, (D3D8_SURFACE(This)->lockedRect.bottom - D3D8_SURFACE(This)->lockedRect.top)-1,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, This->allocatedMemory); GL_RGB, GL_UNSIGNED_SHORT_5_6_5, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels"); vcheckGLcall("glDrawPixels");
} }
break; break;
case D3DFMT_R8G8B8: case D3DFMT_R8G8B8:
{ {
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1, glDrawPixels(D3D8_SURFACE(This)->lockedRect.right - D3D8_SURFACE(This)->lockedRect.left, (D3D8_SURFACE(This)->lockedRect.bottom - D3D8_SURFACE(This)->lockedRect.top)-1,
GL_RGB, GL_UNSIGNED_BYTE, This->allocatedMemory); GL_RGB, GL_UNSIGNED_BYTE, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels"); vcheckGLcall("glDrawPixels");
} }
break; break;
@ -420,15 +414,15 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
{ {
glPixelStorei(GL_PACK_SWAP_BYTES, TRUE); glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
vcheckGLcall("glPixelStorei"); vcheckGLcall("glPixelStorei");
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1, glDrawPixels(D3D8_SURFACE(This)->lockedRect.right - D3D8_SURFACE(This)->lockedRect.left, (D3D8_SURFACE(This)->lockedRect.bottom - D3D8_SURFACE(This)->lockedRect.top)-1,
GL_BGRA, GL_UNSIGNED_BYTE, This->allocatedMemory); GL_BGRA, GL_UNSIGNED_BYTE, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels"); vcheckGLcall("glDrawPixels");
glPixelStorei(GL_PACK_SWAP_BYTES, prev_store); glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
vcheckGLcall("glPixelStorei"); vcheckGLcall("glPixelStorei");
} }
break; break;
default: default:
FIXME("Unsupported Format %u in locking func\n", This->myDesc.Format); FIXME("Unsupported Format %u in locking func\n", D3D8_SURFACE(This)->resource.format);
} }
glPixelZoom(1.0,1.0); glPixelZoom(1.0,1.0);
@ -440,101 +434,101 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
/* Reset to previous pack row length / blending state */ /* Reset to previous pack row length / blending state */
glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes); glPixelStorei(GL_UNPACK_ROW_LENGTH, skipBytes);
if (This->Device->StateBlock->renderstate[D3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND); if (D3D8_SURFACE_GET_DEVICE(This)->StateBlock->renderstate[D3DRS_ALPHABLENDENABLE]) glEnable(GL_BLEND);
LEAVE_GL(); LEAVE_GL();
/** restore clean dirty state */ /** restore clean dirty state */
IDirect3DSurface8Impl_CleanDirtyRect(iface); IWineD3DSurface_CleanDirtyRect(This->wineD3DSurface);
} else { } else {
FIXME("unsupported unlocking to Rendering surface surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("unsupported unlocking to Rendering surface surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} }
} else if (D3DUSAGE_DEPTHSTENCIL & This->myDesc.Usage) { /* stencil surfaces */ } else if (D3DUSAGE_DEPTHSTENCIL & D3D8_SURFACE(This)->resource.usage) { /* stencil surfaces */
if (This == This->Device->depthStencilBuffer) { if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} else { } else {
FIXME("unsupported unlocking to StencilDepth surface surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("unsupported unlocking to StencilDepth surface surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} }
} else { } else {
FIXME("unsupported unlocking to surface surf@%p usage(%lu)\n", This, This->myDesc.Usage); FIXME("unsupported unlocking to surface surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} }
unlock_end: unlock_end:
This->locked = FALSE; D3D8_SURFACE(This)->locked = FALSE;
memset(&This->lockedRect, 0, sizeof(RECT)); memset(&D3D8_SURFACE(This)->lockedRect, 0, sizeof(RECT));
return D3D_OK; return D3D_OK;
} }
const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl = const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl =
{ {
/* IUnknown */
IDirect3DSurface8Impl_QueryInterface, IDirect3DSurface8Impl_QueryInterface,
IDirect3DSurface8Impl_AddRef, IDirect3DSurface8Impl_AddRef,
IDirect3DSurface8Impl_Release, IDirect3DSurface8Impl_Release,
/* IDirect3DResource8 */
IDirect3DSurface8Impl_GetDevice, IDirect3DSurface8Impl_GetDevice,
IDirect3DSurface8Impl_SetPrivateData, IDirect3DSurface8Impl_SetPrivateData,
IDirect3DSurface8Impl_GetPrivateData, IDirect3DSurface8Impl_GetPrivateData,
IDirect3DSurface8Impl_FreePrivateData, IDirect3DSurface8Impl_FreePrivateData,
/* IDirect3DSurface8 */
IDirect3DSurface8Impl_GetContainer, IDirect3DSurface8Impl_GetContainer,
IDirect3DSurface8Impl_GetDesc, IDirect3DSurface8Impl_GetDesc,
IDirect3DSurface8Impl_LockRect, IDirect3DSurface8Impl_LockRect,
IDirect3DSurface8Impl_UnlockRect, IDirect3DSurface8Impl_UnlockRect
}; };
HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT gl_target, UINT gl_level) { HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT gl_target, UINT gl_level) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface; IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (D3D8_SURFACE(This)->inTexture)
if (This->inTexture)
return D3D_OK; return D3D_OK;
if (This->inPBuffer) { if (D3D8_SURFACE(This)->inPBuffer) {
ENTER_GL(); ENTER_GL();
if (gl_level != 0) if (gl_level != 0)
FIXME("Surface in texture is only supported for level 0\n"); FIXME("Surface in texture is only supported for level 0\n");
else if (This->myDesc.Format == D3DFMT_P8 || This->myDesc.Format == D3DFMT_A8P8 || else if (D3D8_SURFACE(This)->resource.format == D3DFMT_P8 || D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8 ||
This->myDesc.Format == D3DFMT_DXT1 || This->myDesc.Format == D3DFMT_DXT2 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 ||
This->myDesc.Format == D3DFMT_DXT3 || This->myDesc.Format == D3DFMT_DXT4 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT4 ||
This->myDesc.Format == D3DFMT_DXT5) D3D8_SURFACE(This)->resource.format == D3DFMT_DXT5)
FIXME("Format %d not supported\n", This->myDesc.Format); FIXME("Format %d not supported\n", D3D8_SURFACE(This)->resource.format);
else { else {
glCopyTexImage2D(gl_target, glCopyTexImage2D(gl_target,
0, 0,
D3DFmt2GLIntFmt(This->Device, D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This),
This->myDesc.Format), D3D8_SURFACE(This)->resource.format),
0, 0,
0,/*This->surfaces[j][i]->myDesc.Height-1,*/ 0,/*This->surfaces[j][i]->myDesc.Height-1,*/
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0); 0);
TRACE("Updating target %d\n", gl_target); TRACE("Updating target %d\n", gl_target);
This->inTexture = TRUE; D3D8_SURFACE(This)->inTexture = TRUE;
} }
LEAVE_GL(); LEAVE_GL();
return D3D_OK; return D3D_OK;
} }
if ((This->myDesc.Format == D3DFMT_P8 || This->myDesc.Format == D3DFMT_A8P8) && if ((D3D8_SURFACE(This)->resource.format == D3DFMT_P8 || D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8) &&
!GL_SUPPORT_DEV(EXT_PALETTED_TEXTURE, This->Device)) { !GL_SUPPORT_DEV(EXT_PALETTED_TEXTURE, D3D8_SURFACE_GET_DEVICE(This))) {
/** /**
* wanted a paletted texture and not really support it in HW * wanted a paletted texture and not really support it in HW
* so software emulation code begin * so software emulation code begin
*/ */
UINT i; UINT i;
PALETTEENTRY* pal = This->Device->palettes[This->Device->currentPalette]; PALETTEENTRY* pal = D3D8_SURFACE_GET_DEVICE(This)->palettes[D3D8_SURFACE_GET_DEVICE(This)->currentPalette];
VOID* surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->myDesc.Width * This->myDesc.Height * sizeof(DWORD)); VOID* surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, D3D8_SURFACE(This)->currentDesc.Width * D3D8_SURFACE(This)->currentDesc.Height * sizeof(DWORD));
BYTE* dst = surface; BYTE* dst = surface;
BYTE* src = (BYTE*) This->allocatedMemory; BYTE* src = (BYTE*) D3D8_SURFACE(This)->resource.allocatedMemory;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) { for (i = 0; i < D3D8_SURFACE(This)->currentDesc.Width * D3D8_SURFACE(This)->currentDesc.Height; i++) {
BYTE color = *src++; BYTE color = *src++;
*dst++ = pal[color].peRed; *dst++ = pal[color].peRed;
*dst++ = pal[color].peGreen; *dst++ = pal[color].peGreen;
*dst++ = pal[color].peBlue; *dst++ = pal[color].peBlue;
if (This->myDesc.Format == D3DFMT_A8P8) if (D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8)
*dst++ = pal[color].peFlags; *dst++ = pal[color].peFlags;
else else
*dst++ = 0xFF; *dst++ = 0xFF;
@ -546,8 +540,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
gl_target, gl_target,
gl_level, gl_level,
GL_RGBA, GL_RGBA,
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
@ -555,8 +549,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
glTexImage2D(gl_target, glTexImage2D(gl_target,
gl_level, gl_level,
GL_RGBA, GL_RGBA,
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
@ -569,32 +563,32 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
return D3D_OK; return D3D_OK;
} }
if (This->myDesc.Format == D3DFMT_DXT1 || if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1 ||
This->myDesc.Format == D3DFMT_DXT2 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 ||
This->myDesc.Format == D3DFMT_DXT3 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 ||
This->myDesc.Format == D3DFMT_DXT4 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT4 ||
This->myDesc.Format == D3DFMT_DXT5) { D3D8_SURFACE(This)->resource.format == D3DFMT_DXT5) {
if (GL_SUPPORT_DEV(EXT_TEXTURE_COMPRESSION_S3TC, This->Device)) { if (GL_SUPPORT_DEV(EXT_TEXTURE_COMPRESSION_S3TC, D3D8_SURFACE_GET_DEVICE(This))) {
TRACE("Calling glCompressedTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, sz=%d, Mem=%p\n", TRACE("Calling glCompressedTexImage2D %x i=%d, intfmt=%x, w=%d, h=%d,0=%d, sz=%d, Mem=%p\n",
gl_target, gl_target,
gl_level, gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format), D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
This->myDesc.Size, D3D8_SURFACE(This)->resource.size,
This->allocatedMemory); D3D8_SURFACE(This)->resource.allocatedMemory);
ENTER_GL(); ENTER_GL();
GL_EXTCALL_DEV(glCompressedTexImage2DARB, This->Device)(gl_target, GL_EXTCALL_DEV(glCompressedTexImage2DARB, D3D8_SURFACE_GET_DEVICE(This))(gl_target,
gl_level, gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format), D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
This->myDesc.Size, D3D8_SURFACE(This)->resource.size,
This->allocatedMemory); D3D8_SURFACE(This)->resource.allocatedMemory);
checkGLcall("glCommpressedTexTexImage2D"); checkGLcall("glCommpressedTexTexImage2D");
LEAVE_GL(); LEAVE_GL();
@ -606,26 +600,26 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
TRACE("Calling glTexImage2D %x i=%d, d3dfmt=%s, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n", TRACE("Calling glTexImage2D %x i=%d, d3dfmt=%s, intfmt=%x, w=%d, h=%d,0=%d, glFmt=%x, glType=%x, Mem=%p\n",
gl_target, gl_target,
gl_level, gl_level,
debug_d3dformat(This->myDesc.Format), debug_d3dformat(D3D8_SURFACE(This)->resource.format),
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format), D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
D3DFmt2GLFmt(This->Device, This->myDesc.Format), D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3DFmt2GLType(This->Device, This->myDesc.Format), D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->allocatedMemory); D3D8_SURFACE(This)->resource.allocatedMemory);
ENTER_GL(); ENTER_GL();
glTexImage2D(gl_target, glTexImage2D(gl_target,
gl_level, gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format), D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->myDesc.Width, D3D8_SURFACE(This)->currentDesc.Width,
This->myDesc.Height, D3D8_SURFACE(This)->currentDesc.Height,
0, 0,
D3DFmt2GLFmt(This->Device, This->myDesc.Format), D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3DFmt2GLType(This->Device, This->myDesc.Format), D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
This->allocatedMemory); D3D8_SURFACE(This)->resource.allocatedMemory);
checkGLcall("glTexImage2D"); checkGLcall("glTexImage2D");
LEAVE_GL(); LEAVE_GL();
@ -652,114 +646,3 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
return D3D_OK; return D3D_OK;
} }
#include <errno.h>
HRESULT WINAPI IDirect3DSurface8Impl_SaveSnapshot(LPDIRECT3DSURFACE8 iface, const char* filename) {
FILE* f = NULL;
ULONG i;
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
f = fopen(filename, "w+");
if (NULL == f) {
ERR("opening of %s failed with: %s\n", filename, strerror(errno));
return D3DERR_INVALIDCALL;
}
TRACE("opened %s with format %s\n", filename, debug_d3dformat(This->myDesc.Format));
fprintf(f, "P6\n%u %u\n255\n", This->myDesc.Width, This->myDesc.Height);
switch (This->myDesc.Format) {
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
{
DWORD color;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) {
color = ((DWORD*) This->allocatedMemory)[i];
fputc((color >> 16) & 0xFF, f);
fputc((color >> 8) & 0xFF, f);
fputc((color >> 0) & 0xFF, f);
}
}
break;
case D3DFMT_R8G8B8:
{
BYTE* color;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) {
color = ((BYTE*) This->allocatedMemory) + (3 * i);
fputc((color[0]) & 0xFF, f);
fputc((color[1]) & 0xFF, f);
fputc((color[2]) & 0xFF, f);
}
}
break;
case D3DFMT_A1R5G5B5:
{
WORD color;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) {
color = ((WORD*) This->allocatedMemory)[i];
fputc(((color >> 10) & 0x1F) * 255 / 31, f);
fputc(((color >> 5) & 0x1F) * 255 / 31, f);
fputc(((color >> 0) & 0x1F) * 255 / 31, f);
}
}
break;
case D3DFMT_A4R4G4B4:
{
WORD color;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) {
color = ((WORD*) This->allocatedMemory)[i];
fputc(((color >> 8) & 0x0F) * 255 / 15, f);
fputc(((color >> 4) & 0x0F) * 255 / 15, f);
fputc(((color >> 0) & 0x0F) * 255 / 15, f);
}
}
break;
case D3DFMT_R5G6B5:
{
WORD color;
for (i = 0; i < This->myDesc.Width * This->myDesc.Height; i++) {
color = ((WORD*) This->allocatedMemory)[i];
fputc(((color >> 11) & 0x1F) * 255 / 31, f);
fputc(((color >> 5) & 0x3F) * 255 / 63, f);
fputc(((color >> 0) & 0x1F) * 255 / 31, f);
}
}
break;
default:
FIXME("Unimplemented dump mode format(%u,%s)\n", This->myDesc.Format, debug_d3dformat(This->myDesc.Format));
}
fclose(f);
return D3D_OK;
}
HRESULT WINAPI IDirect3DSurface8Impl_CleanDirtyRect(LPDIRECT3DSURFACE8 iface) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
This->Dirty = FALSE;
This->dirtyRect.left = This->myDesc.Width;
This->dirtyRect.top = This->myDesc.Height;
This->dirtyRect.right = 0;
This->dirtyRect.bottom = 0;
return D3D_OK;
}
/**
* Raphael:
* very stupid way to handle multiple dirty rects but it works :)
*/
extern HRESULT WINAPI IDirect3DSurface8Impl_AddDirtyRect(LPDIRECT3DSURFACE8 iface, CONST RECT* pDirtyRect) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
This->Dirty = TRUE;
if (NULL != pDirtyRect) {
This->dirtyRect.left = min(This->dirtyRect.left, pDirtyRect->left);
This->dirtyRect.top = min(This->dirtyRect.top, pDirtyRect->top);
This->dirtyRect.right = max(This->dirtyRect.right, pDirtyRect->right);
This->dirtyRect.bottom = max(This->dirtyRect.bottom, pDirtyRect->bottom);
} else {
This->dirtyRect.left = 0;
This->dirtyRect.top = 0;
This->dirtyRect.right = This->myDesc.Width;
This->dirtyRect.bottom = This->myDesc.Height;
}
return D3D_OK;
}

View File

@ -120,22 +120,22 @@ void WINAPI IDirect3DTexture8Impl_PreLoad(LPDIRECT3DTEXTURE8 iface) {
ENTER_GL(); ENTER_GL();
for (i = 0; i < This->levels; i++) { for (i = 0; i < This->levels; i++) {
if (i == 0 && This->surfaces[i]->textureName != 0 && This->Dirty == FALSE) { if (i == 0 && D3D8_SURFACE(This->surfaces[i])->textureName != 0 && This->Dirty == FALSE) {
glBindTexture(GL_TEXTURE_2D, This->surfaces[i]->textureName); glBindTexture(GL_TEXTURE_2D, D3D8_SURFACE(This->surfaces[i])->textureName);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, This->surfaces[i]->textureName); TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, D3D8_SURFACE(This->surfaces[i])->textureName);
/* No need to walk through all mip-map levels, since already all assigned */ /* No need to walk through all mip-map levels, since already all assigned */
i = This->levels; i = This->levels;
} else { } else {
if (i == 0) { if (i == 0) {
if (This->surfaces[i]->textureName == 0) { if (D3D8_SURFACE(This->surfaces[i])->textureName == 0) {
glGenTextures(1, &This->surfaces[i]->textureName); glGenTextures(1, &(D3D8_SURFACE(This->surfaces[i]))->textureName);
checkGLcall("glGenTextures"); checkGLcall("glGenTextures");
TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, This->surfaces[i]->textureName); TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, D3D8_SURFACE(This->surfaces[i])->textureName);
} }
glBindTexture(GL_TEXTURE_2D, This->surfaces[i]->textureName); glBindTexture(GL_TEXTURE_2D, D3D8_SURFACE(This->surfaces[i])->textureName);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
} }
IDirect3DSurface8Impl_LoadTexture((LPDIRECT3DSURFACE8) This->surfaces[i], GL_TEXTURE_2D, i); IDirect3DSurface8Impl_LoadTexture((LPDIRECT3DSURFACE8) This->surfaces[i], GL_TEXTURE_2D, i);
@ -231,7 +231,7 @@ HRESULT WINAPI IDirect3DTexture8Impl_AddDirtyRect(LPDIRECT3DTEXTURE8 ifa
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface; IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
This->Dirty = TRUE; This->Dirty = TRUE;
TRACE("(%p) : dirtyfication of surface Level (0)\n", This); TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
return IDirect3DSurface8Impl_AddDirtyRect((LPDIRECT3DSURFACE8) This->surfaces[0], pDirtyRect); return IWineD3DSurface_AddDirtyRect( (IWineD3DSurface*)(This->surfaces[0])->wineD3DSurface, pDirtyRect);
} }