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();
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);
#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
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
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 */
i = This->levels;
} else {
if (i == 0) {
if (This->surfaces[0][0]->textureName == 0) {
glGenTextures(1, &This->surfaces[0][0]->textureName);
if (D3D8_SURFACE(This->surfaces[0][0])->textureName == 0) {
glGenTextures(1, &(D3D8_SURFACE(This->surfaces[0][0]))->textureName);
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)
glBindTexture(GL_TEXTURE_CUBE_MAP, This->surfaces[0][0]->textureName);
glBindTexture(GL_TEXTURE_CUBE_MAP, D3D8_SURFACE(This->surfaces[0][0])->textureName);
#else
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->surfaces[0][0]->textureName);
#endif
@ -275,7 +275,7 @@ HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(LPDIRECT3DCUBETEXT
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
This->Dirty = TRUE;
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>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/debug.h"
#include "d3d8.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_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 */
@ -691,28 +782,12 @@ struct IDirect3DSurface8Impl
{
/* IUnknown fields */
const IDirect3DSurface8Vtbl *lpVtbl;
LONG ref;
LONG ref;
/* IDirect3DSurface8 fields */
IDirect3DDevice8Impl *Device;
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;
IWineD3DSurface *wineD3DSurface;
};
#define D3D8_SURFACE(a) ((IWineD3DSurfaceImpl*)(a->wineD3DSurface))
/* IUnknown: */
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;
}
/* 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) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
@ -313,8 +352,8 @@ ULONG WINAPI IDirect3DDevice8Impl_Release(LPDIRECT3DDEVICE8 iface) {
if (ref == 0) {
IDirect3DDevice8Impl_CleanRender(iface);
IDirect3D8_Release((LPDIRECT3D8) This->direct3d8);
IDirect3DDevice8_CleanUp(This);
IWineD3DDevice_Release(This->WineD3DDevice);
if (glXGetCurrentContext() == This->glCtx) {
glXMakeCurrent(This->display, None, NULL);
}
@ -401,11 +440,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetCursorProperties(LPDIRECT3DDEVICE8 ifac
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
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);
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);
return D3DERR_INVALIDCALL;
}
@ -655,18 +694,18 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateTexture(LPDIRECT3DDEVICE8 iface, UIN
for (i = 0; i < object->levels; i++)
{
IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpH, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[i]);
object->surfaces[i]->Container = (IUnknown*) object;
object->surfaces[i]->myDesc.Usage = Usage;
object->surfaces[i]->myDesc.Pool = Pool;
D3D8_SURFACE(object->surfaces[i])->container = (IUnknown*) object;
D3D8_SURFACE(object->surfaces[i])->resource.usage = Usage;
D3D8_SURFACE(object->surfaces[i])->resource.pool = Pool;
/**
* As written in msdn in IDirect3DTexture8::LockRect
* Textures created in D3DPOOL_DEFAULT are not lockable.
*/
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);
tmpH = max(1, tmpH / 2);
}
@ -805,22 +844,21 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateCubeTexture(LPDIRECT3DDEVICE8 iface,
/* Create the 6 faces */
for (j = 0; j < 6; j++) {
IDirect3DDevice8Impl_CreateImageSurface(iface, tmpW, tmpW, Format, (LPDIRECT3DSURFACE8*) &object->surfaces[j][i]);
object->surfaces[j][i]->Container = (IUnknown*) object;
object->surfaces[j][i]->myDesc.Usage = Usage;
object->surfaces[j][i]->myDesc.Pool = Pool;
D3D8_SURFACE(object->surfaces[j][i])->container = (IUnknown*) object;
D3D8_SURFACE(object->surfaces[j][i])->resource.usage = Usage;
D3D8_SURFACE(object->surfaces[j][i])->resource.pool = Pool;
/**
* As written in msdn in IDirect3DCubeTexture8::LockRect
* Textures created in D3DPOOL_DEFAULT are not lockable.
*/
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);
}
TRACE("(%p) : Iface@%p\n", This, object);
*ppCubeTexture = (LPDIRECT3DCUBETEXTURE8) object;
return D3D_OK;
@ -875,233 +913,81 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 iface,
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;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
TRACE("(%p) Relay\n", This);
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) {
*ppSurface = NULL;
return D3DERR_OUTOFVIDEOMEMORY;
FIXME("Allocation of memory failed\n");
*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_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);
return D3D_OK;
TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
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) {
IDirect3DSurface8Impl *object;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
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;
TRACE("Relay\n");
/* TODO: Verify that Discard is false */
return IDirect3DDevice8Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE, 0 /* Level */
,ppSurface, D3DRTYPE_SURFACE, D3DUSAGE_DEPTHSTENCIL,
D3DPOOL_DEFAULT, MultiSample, 0);
}
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;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface8Impl));
*ppSurface = (LPDIRECT3DSURFACE8) object;
object->lpVtbl = &Direct3DSurface8_Vtbl;
object->Device = This;
object->ResourceType = D3DRTYPE_SURFACE;
object->Container = (IUnknown*) This;
TRACE("(%p) Relay\n" , This);
object->ref = 1;
object->myDesc.Width = Width;
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;
return IWineD3DDevice_CopyRects(This->WineD3DDevice, pSourceSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pSourceSurface)->wineD3DSurface,
pSourceRects, cRects, pDestinationSurface == NULL ? NULL : ((IDirect3DSurface8Impl *)pDestinationSurface)->wineD3DSurface, pDestPoints);
}
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) {
IDirect3DBaseTexture8Impl* src = (IDirect3DBaseTexture8Impl*) pSourceTexture;
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);
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);
return D3DERR_INVALIDCALL;
}
@ -1263,8 +1149,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderTarget(LPDIRECT3DDEVICE8 iface, I
if (SUCCEEDED(hr)) {
/* Finally, reset the viewport as the MSDN states. */
viewport.Height = ((IDirect3DSurface8Impl*)pRenderTarget)->myDesc.Height;
viewport.Width = ((IDirect3DSurface8Impl*)pRenderTarget)->myDesc.Width;
viewport.Height = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Height;
viewport.Width = D3D8_SURFACE(((IDirect3DSurface8Impl*)pRenderTarget))->currentDesc.Width;
viewport.X = 0;
viewport.Y = 0;
viewport.MaxZ = 1.0f;
@ -1318,7 +1204,6 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
printf("Hit Enter ...\n");
getchar();
#endif
if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) {
#if 0
GLenum prev_read;
@ -1351,11 +1236,11 @@ HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
hr = IDirect3DSurface8_GetContainer((LPDIRECT3DSURFACE8) This->renderTarget, &IID_IDirect3DBaseTexture8, (void**) &cont);
if (SUCCEEDED(hr) && NULL != cont) {
/** always dirtify for now. we must find a better way to see that surface have been modified */
This->renderTarget->inPBuffer = TRUE;
This->renderTarget->inTexture = FALSE;
D3D8_SURFACE(This->renderTarget)->inPBuffer = TRUE;
D3D8_SURFACE(This->renderTarget)->inTexture = FALSE;
IDirect3DBaseTexture8Impl_SetDirty(cont, TRUE);
IDirect3DBaseTexture8_PreLoad(cont);
This->renderTarget->inPBuffer = FALSE;
D3D8_SURFACE(This->renderTarget)->inPBuffer = FALSE;
IDirect3DBaseTexture8Impl_Release(cont);
cont = NULL;
}
@ -1429,14 +1314,14 @@ HRESULT WINAPI IDirect3DDevice8Impl_Clear(LPDIRECT3DDEVICE8 iface, DWORD Count
/* 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,
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);
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);
checkGLcall("glScissor");
} else {
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.Height);
checkGLcall("glScissor");
@ -1662,7 +1547,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetViewport(LPDIRECT3DDEVICE8 iface, CONST
glDepthRange(pViewport->MinZ, pViewport->MaxZ);
checkGLcall("glDepthRange");
/* 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);
checkGLcall("glViewport");
@ -4577,10 +4462,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
int nCfgs = 0;
int attribs[256];
int nAttribs = 0;
D3DFORMAT BackBufferFormat = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Format;
D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IDirect3DSurface8Impl*) StencilSurface)->myDesc.Format : 0;
UINT Width = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Width;
UINT Height = ((IDirect3DSurface8Impl*) RenderSurface)->myDesc.Height;
D3DFORMAT BackBufferFormat = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->resource.format;
D3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? D3D8_SURFACE(((IDirect3DSurface8Impl*) StencilSurface))->resource.format : 0;
UINT Width = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Width;
UINT Height = D3D8_SURFACE(((IDirect3DSurface8Impl*) RenderSurface))->currentDesc.Height;
IDirect3DSurface8Impl* tmp;
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
@ -4727,8 +4612,8 @@ HRESULT WINAPI IDirect3DDevice8Impl_ActiveRender(LPDIRECT3DDEVICE8 iface,
#endif
}
if (BackBufferFormat != This->renderTarget->myDesc.Format &&
StencilBufferFormat != This->stencilBufferTarget->myDesc.Format) {
if (BackBufferFormat != D3D8_SURFACE(This->renderTarget)->resource.format &&
StencilBufferFormat != D3D8_SURFACE(This->stencilBufferTarget)->resource.format) {
nAttribs = 0;
PUSH2(GLX_PBUFFER_WIDTH, Width);
PUSH2(GLX_PBUFFER_HEIGHT, Height);

View File

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

View File

@ -1,9 +1,7 @@
/*
* IDirect3DSurface8 implementation
*
* Copyright 2002-2004 Jason Edmeades
* Copyright 2002-2003 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,44 +19,30 @@
*/
#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"
WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
/* IDirect3DVolume IUnknown parts follow: */
HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface,REFIID riid,LPVOID *ppobj)
{
/* IDirect3DSurface8 IUnknown parts follow: */
HRESULT WINAPI IDirect3DSurface8Impl_QueryInterface(LPDIRECT3DSURFACE8 iface, REFIID riid, LPVOID *ppobj) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|| IsEqualGUID(riid, &IID_IDirect3DSurface8)) {
IDirect3DSurface8Impl_AddRef(iface);
IUnknown_AddRef(iface);
*ppobj = This;
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;
}
ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
InterlockedIncrement(&D3D8_SURFACE(This)->resource.ref);
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);
if (ref == 0) {
HeapFree(GetProcessHeap(), 0, This->allocatedMemory);
HeapFree(GetProcessHeap(), 0, This);
IWineD3DSurface_Release(This->wineD3DSurface);
HeapFree(GetProcessHeap(), 0, This);
}
else
InterlockedDecrement(&D3D8_SURFACE(This)->resource.ref);
return ref;
}
/* IDirect3DSurface8: */
HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8** ppDevice) {
/* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8 **ppDevice) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
TRACE("(%p) : returning %p\n", This, This->Device);
*ppDevice = (LPDIRECT3DDEVICE8) This->Device;
/**
* Note Calling this method will increase the internal reference count
* on the IDirect3DDevice8 interface.
*/
IDirect3DDevice8Impl_AddRef(*ppDevice);
return D3D_OK;
return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
}
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;
FIXME("(%p) : stub\n", This);
return D3D_OK;
TRACE("(%p) Relay\n", This);
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;
FIXME("(%p) : stub\n", This);
return D3D_OK;
TRACE("(%p) Relay\n", This);
return IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
}
HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
FIXME("(%p) : stub\n", This);
return D3D_OK;
TRACE("(%p) Relay\n", This);
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;
HRESULT res;
res = IUnknown_QueryInterface(This->Container, riid, ppContainer);
res = IUnknown_QueryInterface(D3D8_SURFACE(This)->container, riid, ppContainer);
if (E_NOINTERFACE == res) {
/**
* If the surface is created using CreateImageSurface, CreateRenderTarget,
* or CreateDepthStencilSurface, the surface is considered stand alone. In this case,
* 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);
return res;
@ -127,24 +108,37 @@ HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(LPDIRECT3DSURFACE8 iface, REFI
HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3DSURFACE_DESC *pDesc) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
WINED3DSURFACE_DESC wined3ddesc;
UINT tmpInt = -1;
TRACE("(%p) Relay\n", This);
TRACE("(%p) : copying into %p\n", This, pDesc);
memcpy(pDesc, &This->myDesc, sizeof(D3DSURFACE_DESC));
return D3D_OK;
/* As d3d8 and d3d8 structures differ, pass in ptrs to where data needs to go */
memset(&wined3ddesc, 0, sizeof(wined3ddesc));
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 hr;
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
/* 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");
This->inTexture = 0;
This->inPBuffer = 0;
D3D8_SURFACE(This)->inTexture = 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
texture regions, and since the destination is an unlockable region we need
to tolerate this */
@ -152,60 +146,60 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
/*return D3DERR_INVALIDCALL; */
}
if (This == This->Device->backBuffer || This == This->Device->renderTarget || This == This->Device->frontBuffer || This->Device->depthStencilBuffer) {
if (This == This->Device->backBuffer) {
TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory);
} else if (This == This->Device->frontBuffer) {
TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory);
} else if (This == This->Device->renderTarget) {
TRACE("(%p, renderTarget) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory);
} else if (This == This->Device->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory);
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 == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
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 == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer) {
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 == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
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 == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, D3D8_SURFACE(This)->resource.allocatedMemory);
}
} 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,
where each block is 4x4 pixels, 8 bytes (dxt1) and 16 bytes (dxt2/3/4/5)
ie pitch = (width/4) * bytes per block */
if (This->myDesc.Format == D3DFMT_DXT1) /* DXT1 is 8 bytes per block */
pLockedRect->Pitch = (This->myDesc.Width/4) * 8;
else if (This->myDesc.Format == D3DFMT_DXT2 || This->myDesc.Format == D3DFMT_DXT3 ||
This->myDesc.Format == D3DFMT_DXT4 || This->myDesc.Format == D3DFMT_DXT5) /* DXT2/3/4/5 is 16 bytes per block */
pLockedRect->Pitch = (This->myDesc.Width/4) * 16;
if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1) /* DXT1 is 8 bytes per block */
pLockedRect->Pitch = (D3D8_SURFACE(This)->currentDesc.Width/4) * 8;
else if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 ||
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 = (D3D8_SURFACE(This)->currentDesc.Width/4) * 16;
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) {
pLockedRect->pBits = This->allocatedMemory;
This->lockedRect.left = 0;
This->lockedRect.top = 0;
This->lockedRect.right = This->myDesc.Width;
This->lockedRect.bottom = This->myDesc.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);
pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory;
D3D8_SURFACE(This)->lockedRect.left = 0;
D3D8_SURFACE(This)->lockedRect.top = 0;
D3D8_SURFACE(This)->lockedRect.right = D3D8_SURFACE(This)->currentDesc.Width;
D3D8_SURFACE(This)->lockedRect.bottom = D3D8_SURFACE(This)->currentDesc.Height;
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 {
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 */
pLockedRect->pBits = This->allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * This->bytesPerPixel/2));
if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1) { /* DXT1 is half byte per pixel */
pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory + (pLockedRect->Pitch * pRect->top) + ((pRect->left * D3D8_SURFACE(This)->bytesPerPixel/2));
} 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;
This->lockedRect.top = pRect->top;
This->lockedRect.right = pRect->right;
This->lockedRect.bottom = pRect->bottom;
D3D8_SURFACE(This)->lockedRect.left = pRect->left;
D3D8_SURFACE(This)->lockedRect.top = pRect->top;
D3D8_SURFACE(This)->lockedRect.right = pRect->right;
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 ;) */
} 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_read;
@ -215,7 +209,7 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
* for render->surface copy begin to begin of allocatedMemory
* unlock can be more easy
*/
pLockedRect->pBits = This->allocatedMemory;
pLockedRect->pBits = D3D8_SURFACE(This)->resource.allocatedMemory;
glFlush();
vcheckGLcall("glFlush");
@ -224,27 +218,27 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store);
vcheckGLcall("glIntegerv");
if (This == This->Device->backBuffer) {
if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
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);
} else if (This == This->Device->depthStencilBuffer) {
} else if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
ERR("Stencil Buffer lock unsupported for now\n");
}
vcheckGLcall("glReadBuffer");
{
long j;
GLenum format = D3DFmt2GLFmt(This->Device, This->myDesc.Format);
GLenum type = D3DFmt2GLType(This->Device, This->myDesc.Format);
for (j = This->lockedRect.top; j < This->lockedRect.bottom - This->lockedRect.top; ++j) {
glReadPixels(This->lockedRect.left,
This->lockedRect.bottom - j - 1,
This->lockedRect.right - This->lockedRect.left,
GLenum format = D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format);
GLenum type = D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format);
for (j = D3D8_SURFACE(This)->lockedRect.top; j < D3D8_SURFACE(This)->lockedRect.bottom - D3D8_SURFACE(This)->lockedRect.top; ++j) {
glReadPixels(D3D8_SURFACE(This)->lockedRect.left,
D3D8_SURFACE(This)->lockedRect.bottom - j - 1,
D3D8_SURFACE(This)->lockedRect.right - D3D8_SURFACE(This)->lockedRect.left,
1,
format,
type,
(char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-This->lockedRect.top)));
(char *)pLockedRect->pBits + (pLockedRect->Pitch * (j-D3D8_SURFACE(This)->lockedRect.top)));
vcheckGLcall("glReadPixels");
}
}
@ -255,15 +249,15 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
LEAVE_GL();
} 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 {
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)) {
@ -273,12 +267,12 @@ HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKE
* Dirtify on lock
* as seen in msdn docs
*/
IDirect3DSurface8Impl_AddDirtyRect(iface, &This->lockedRect);
IWineD3DSurface_AddDirtyRect(This->wineD3DSurface, &D3D8_SURFACE(This)->lockedRect);
/** Dirtify Container if needed */
if (NULL != This->Container) {
if (NULL != D3D8_SURFACE(This)->container) {
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) {
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;
}
@ -298,38 +292,38 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
GLint skipBytes = 0;
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (FALSE == This->locked) {
if (FALSE == D3D8_SURFACE(This)->locked) {
ERR("trying to Unlock an unlocked surf@%p\n", This);
return D3DERR_INVALIDCALL;
}
if (This == This->Device->backBuffer || This == This->Device->frontBuffer || This->Device->depthStencilBuffer || This == This->Device->renderTarget) {
if (This == This->Device->backBuffer) {
TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->frontBuffer) {
TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty);
} else if (This == This->Device->renderTarget) {
TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, This->Dirty);
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 == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == D3D8_SURFACE_GET_DEVICE(This)->frontBuffer) {
TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
} else if (This == D3D8_SURFACE_GET_DEVICE(This)->renderTarget) {
TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, D3D8_SURFACE(This)->Dirty);
}
} 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);
goto unlock_end;
}
if (0 == This->myDesc.Usage) { /* classic surface */
if (0 == D3D8_SURFACE(This)->resource.usage) { /* classic surface */
/**
* nothing to do
* 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_draw;
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 -
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 */
if (!This->Device->last_was_rhw) {
if (!D3D8_SURFACE_GET_DEVICE(This)->last_was_rhw) {
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
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");
/* Set up the viewport to be full viewport */
X = This->Device->StateBlock->viewport.X;
Y = This->Device->StateBlock->viewport.Y;
height = This->Device->StateBlock->viewport.Height;
width = This->Device->StateBlock->viewport.Width;
minZ = This->Device->StateBlock->viewport.MinZ;
maxZ = This->Device->StateBlock->viewport.MaxZ;
X = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.X;
Y = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Y;
height = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Height;
width = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.Width;
minZ = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.MinZ;
maxZ = D3D8_SURFACE_GET_DEVICE(This)->StateBlock->viewport.MaxZ;
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
checkGLcall("glOrtho");
@ -385,34 +379,34 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
checkGLcall("glTranslatef(0.5, 0.5, 0)");
}
if (This == This->Device->backBuffer) {
if (This == D3D8_SURFACE_GET_DEVICE(This)->backBuffer) {
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);
}
vcheckGLcall("glDrawBuffer");
/* If not fullscreen, we need to skip a number of bytes to find the next row of data */
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 */
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");
switch (This->myDesc.Format) {
switch (D3D8_SURFACE(This)->resource.format) {
case D3DFMT_R5G6B5:
{
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, This->allocatedMemory);
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, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels");
}
break;
case D3DFMT_R8G8B8:
{
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
GL_RGB, GL_UNSIGNED_BYTE, This->allocatedMemory);
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, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels");
}
break;
@ -420,15 +414,15 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
{
glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
vcheckGLcall("glPixelStorei");
glDrawPixels(This->lockedRect.right - This->lockedRect.left, (This->lockedRect.bottom - This->lockedRect.top)-1,
GL_BGRA, GL_UNSIGNED_BYTE, This->allocatedMemory);
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, D3D8_SURFACE(This)->resource.allocatedMemory);
vcheckGLcall("glDrawPixels");
glPixelStorei(GL_PACK_SWAP_BYTES, prev_store);
vcheckGLcall("glPixelStorei");
}
break;
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);
@ -440,101 +434,101 @@ HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
/* Reset to previous pack row length / blending state */
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();
/** restore clean dirty state */
IDirect3DSurface8Impl_CleanDirtyRect(iface);
IWineD3DSurface_CleanDirtyRect(This->wineD3DSurface);
} 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) {
FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, This->myDesc.Usage);
if (This == D3D8_SURFACE_GET_DEVICE(This)->depthStencilBuffer) {
FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, D3D8_SURFACE(This)->resource.usage);
} 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 {
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:
This->locked = FALSE;
memset(&This->lockedRect, 0, sizeof(RECT));
D3D8_SURFACE(This)->locked = FALSE;
memset(&D3D8_SURFACE(This)->lockedRect, 0, sizeof(RECT));
return D3D_OK;
}
const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl =
{
/* IUnknown */
IDirect3DSurface8Impl_QueryInterface,
IDirect3DSurface8Impl_AddRef,
IDirect3DSurface8Impl_Release,
/* IDirect3DResource8 */
IDirect3DSurface8Impl_GetDevice,
IDirect3DSurface8Impl_SetPrivateData,
IDirect3DSurface8Impl_GetPrivateData,
IDirect3DSurface8Impl_FreePrivateData,
/* IDirect3DSurface8 */
IDirect3DSurface8Impl_GetContainer,
IDirect3DSurface8Impl_GetDesc,
IDirect3DSurface8Impl_LockRect,
IDirect3DSurface8Impl_UnlockRect,
IDirect3DSurface8Impl_UnlockRect
};
HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT gl_target, UINT gl_level) {
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
if (This->inTexture)
if (D3D8_SURFACE(This)->inTexture)
return D3D_OK;
if (This->inPBuffer) {
if (D3D8_SURFACE(This)->inPBuffer) {
ENTER_GL();
if (gl_level != 0)
FIXME("Surface in texture is only supported for level 0\n");
else if (This->myDesc.Format == D3DFMT_P8 || This->myDesc.Format == D3DFMT_A8P8 ||
This->myDesc.Format == D3DFMT_DXT1 || This->myDesc.Format == D3DFMT_DXT2 ||
This->myDesc.Format == D3DFMT_DXT3 || This->myDesc.Format == D3DFMT_DXT4 ||
This->myDesc.Format == D3DFMT_DXT5)
FIXME("Format %d not supported\n", This->myDesc.Format);
else if (D3D8_SURFACE(This)->resource.format == D3DFMT_P8 || D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 || D3D8_SURFACE(This)->resource.format == D3DFMT_DXT4 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT5)
FIXME("Format %d not supported\n", D3D8_SURFACE(This)->resource.format);
else {
glCopyTexImage2D(gl_target,
0,
D3DFmt2GLIntFmt(This->Device,
This->myDesc.Format),
D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This),
D3D8_SURFACE(This)->resource.format),
0,
0,/*This->surfaces[j][i]->myDesc.Height-1,*/
This->myDesc.Width,
This->myDesc.Height,
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0);
TRACE("Updating target %d\n", gl_target);
This->inTexture = TRUE;
D3D8_SURFACE(This)->inTexture = TRUE;
}
LEAVE_GL();
return D3D_OK;
}
if ((This->myDesc.Format == D3DFMT_P8 || This->myDesc.Format == D3DFMT_A8P8) &&
!GL_SUPPORT_DEV(EXT_PALETTED_TEXTURE, This->Device)) {
if ((D3D8_SURFACE(This)->resource.format == D3DFMT_P8 || D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8) &&
!GL_SUPPORT_DEV(EXT_PALETTED_TEXTURE, D3D8_SURFACE_GET_DEVICE(This))) {
/**
* wanted a paletted texture and not really support it in HW
* so software emulation code begin
*/
UINT i;
PALETTEENTRY* pal = This->Device->palettes[This->Device->currentPalette];
VOID* surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->myDesc.Width * This->myDesc.Height * sizeof(DWORD));
PALETTEENTRY* pal = D3D8_SURFACE_GET_DEVICE(This)->palettes[D3D8_SURFACE_GET_DEVICE(This)->currentPalette];
VOID* surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, D3D8_SURFACE(This)->currentDesc.Width * D3D8_SURFACE(This)->currentDesc.Height * sizeof(DWORD));
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++;
*dst++ = pal[color].peRed;
*dst++ = pal[color].peGreen;
*dst++ = pal[color].peBlue;
if (This->myDesc.Format == D3DFMT_A8P8)
if (D3D8_SURFACE(This)->resource.format == D3DFMT_A8P8)
*dst++ = pal[color].peFlags;
else
*dst++ = 0xFF;
@ -546,8 +540,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
gl_target,
gl_level,
GL_RGBA,
This->myDesc.Width,
This->myDesc.Height,
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
@ -555,8 +549,8 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
glTexImage2D(gl_target,
gl_level,
GL_RGBA,
This->myDesc.Width,
This->myDesc.Height,
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
@ -569,32 +563,32 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
return D3D_OK;
}
if (This->myDesc.Format == D3DFMT_DXT1 ||
This->myDesc.Format == D3DFMT_DXT2 ||
This->myDesc.Format == D3DFMT_DXT3 ||
This->myDesc.Format == D3DFMT_DXT4 ||
This->myDesc.Format == D3DFMT_DXT5) {
if (GL_SUPPORT_DEV(EXT_TEXTURE_COMPRESSION_S3TC, This->Device)) {
if (D3D8_SURFACE(This)->resource.format == D3DFMT_DXT1 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT2 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT3 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT4 ||
D3D8_SURFACE(This)->resource.format == D3DFMT_DXT5) {
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",
gl_target,
gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format),
This->myDesc.Width,
This->myDesc.Height,
D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
This->myDesc.Size,
This->allocatedMemory);
D3D8_SURFACE(This)->resource.size,
D3D8_SURFACE(This)->resource.allocatedMemory);
ENTER_GL();
GL_EXTCALL_DEV(glCompressedTexImage2DARB, This->Device)(gl_target,
GL_EXTCALL_DEV(glCompressedTexImage2DARB, D3D8_SURFACE_GET_DEVICE(This))(gl_target,
gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format),
This->myDesc.Width,
This->myDesc.Height,
D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
This->myDesc.Size,
This->allocatedMemory);
D3D8_SURFACE(This)->resource.size,
D3D8_SURFACE(This)->resource.allocatedMemory);
checkGLcall("glCommpressedTexTexImage2D");
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",
gl_target,
gl_level,
debug_d3dformat(This->myDesc.Format),
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format),
This->myDesc.Width,
This->myDesc.Height,
debug_d3dformat(D3D8_SURFACE(This)->resource.format),
D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
D3DFmt2GLFmt(This->Device, This->myDesc.Format),
D3DFmt2GLType(This->Device, This->myDesc.Format),
This->allocatedMemory);
D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->resource.allocatedMemory);
ENTER_GL();
glTexImage2D(gl_target,
gl_level,
D3DFmt2GLIntFmt(This->Device, This->myDesc.Format),
This->myDesc.Width,
This->myDesc.Height,
D3DFmt2GLIntFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->currentDesc.Width,
D3D8_SURFACE(This)->currentDesc.Height,
0,
D3DFmt2GLFmt(This->Device, This->myDesc.Format),
D3DFmt2GLType(This->Device, This->myDesc.Format),
This->allocatedMemory);
D3DFmt2GLFmt(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3DFmt2GLType(D3D8_SURFACE_GET_DEVICE(This), D3D8_SURFACE(This)->resource.format),
D3D8_SURFACE(This)->resource.allocatedMemory);
checkGLcall("glTexImage2D");
LEAVE_GL();
@ -652,114 +646,3 @@ HRESULT WINAPI IDirect3DSurface8Impl_LoadTexture(LPDIRECT3DSURFACE8 iface, UINT
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();
for (i = 0; i < This->levels; i++) {
if (i == 0 && This->surfaces[i]->textureName != 0 && This->Dirty == FALSE) {
glBindTexture(GL_TEXTURE_2D, This->surfaces[i]->textureName);
if (i == 0 && D3D8_SURFACE(This->surfaces[i])->textureName != 0 && This->Dirty == FALSE) {
glBindTexture(GL_TEXTURE_2D, D3D8_SURFACE(This->surfaces[i])->textureName);
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 */
i = This->levels;
} else {
if (i == 0) {
if (This->surfaces[i]->textureName == 0) {
glGenTextures(1, &This->surfaces[i]->textureName);
if (D3D8_SURFACE(This->surfaces[i])->textureName == 0) {
glGenTextures(1, &(D3D8_SURFACE(This->surfaces[i]))->textureName);
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");
}
IDirect3DSurface8Impl_LoadTexture((LPDIRECT3DSURFACE8) This->surfaces[i], GL_TEXTURE_2D, i);
@ -231,7 +231,7 @@ HRESULT WINAPI IDirect3DTexture8Impl_AddDirtyRect(LPDIRECT3DTEXTURE8 ifa
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
This->Dirty = TRUE;
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);
}