mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
This is a temporary solution to our DX problem
it will take some times getting native DirectX working in user mode.
Wine Have manger ported their DirectX to Windows, And after some help
from wine (Roderick Colenbrander aka Thunderbird), That mean we got
now DirectX8 support in ReactOS from wine DirectX (base on opengl).
(rember disable the SSE in mesa before trying it, and it is untested
in ReactOS)
svn path=/trunk/; revision=28386
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = d3d8.dll
|
||||
IMPORTLIB = libd3d8.$(IMPLIBEXT)
|
||||
IMPORTS = wined3d user32 gdi32 advapi32 kernel32
|
||||
EXTRALIBS = -ldxguid -luuid
|
||||
|
||||
C_SRCS = \
|
||||
basetexture.c \
|
||||
cubetexture.c \
|
||||
d3d8_main.c \
|
||||
device.c \
|
||||
directx.c \
|
||||
indexbuffer.c \
|
||||
pixelshader.c \
|
||||
resource.c \
|
||||
stateblock.c \
|
||||
surface.c \
|
||||
swapchain.c \
|
||||
texture.c \
|
||||
vertexbuffer.c \
|
||||
vertexdeclaration.c \
|
||||
vertexshader.c \
|
||||
volume.c \
|
||||
volumetexture.c
|
||||
|
||||
RC_SRCS = version.rc
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
@DEPENDENCIES@ # everything below this line is overwritten by make depend
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* IDirect3DBaseTexture8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DBaseTexture8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DBaseTexture8Impl_QueryInterface(LPDIRECT3DBASETEXTURE8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DBaseTexture8Impl_AddRef(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DBaseTexture8Impl_Release(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DBaseTexture_Release(This->wineD3DBaseTexture);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DBaseTexture8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DBaseTexture8Impl_GetDevice(LPDIRECT3DBASETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DBaseTexture8Impl_SetPrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_SetPrivateData(This->wineD3DBaseTexture, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DBaseTexture8Impl_GetPrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_GetPrivateData(This->wineD3DBaseTexture, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DBaseTexture8Impl_FreePrivateData(LPDIRECT3DBASETEXTURE8 iface, REFGUID refguid) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_FreePrivateData(This->wineD3DBaseTexture, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DBaseTexture8Impl_SetPriority(LPDIRECT3DBASETEXTURE8 iface, DWORD PriorityNew) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_SetPriority(This->wineD3DBaseTexture, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DBaseTexture8Impl_GetPriority(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_GetPriority(This->wineD3DBaseTexture);
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DBaseTexture8Impl_PreLoad(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
IWineD3DBaseTexture_PreLoad(This->wineD3DBaseTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DBaseTexture8Impl_GetType(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_GetType(This->wineD3DBaseTexture);
|
||||
}
|
||||
|
||||
/* IDirect3DBaseTexture8 Interface follow: */
|
||||
static DWORD WINAPI IDirect3DBaseTexture8Impl_SetLOD(LPDIRECT3DBASETEXTURE8 iface, DWORD LODNew) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_SetLOD(This->wineD3DBaseTexture, LODNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DBaseTexture8Impl_GetLOD(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_GetLOD(This->wineD3DBaseTexture);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DBaseTexture8Impl_GetLevelCount(LPDIRECT3DBASETEXTURE8 iface) {
|
||||
IDirect3DBaseTexture8Impl *This = (IDirect3DBaseTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
return IWineD3DBaseTexture_GetLevelCount(This->wineD3DBaseTexture);
|
||||
}
|
||||
|
||||
const IDirect3DBaseTexture8Vtbl Direct3DBaseTexture8_Vtbl =
|
||||
{
|
||||
IDirect3DBaseTexture8Impl_QueryInterface,
|
||||
IDirect3DBaseTexture8Impl_AddRef,
|
||||
IDirect3DBaseTexture8Impl_Release,
|
||||
IDirect3DBaseTexture8Impl_GetDevice,
|
||||
IDirect3DBaseTexture8Impl_SetPrivateData,
|
||||
IDirect3DBaseTexture8Impl_GetPrivateData,
|
||||
IDirect3DBaseTexture8Impl_FreePrivateData,
|
||||
IDirect3DBaseTexture8Impl_SetPriority,
|
||||
IDirect3DBaseTexture8Impl_GetPriority,
|
||||
IDirect3DBaseTexture8Impl_PreLoad,
|
||||
IDirect3DBaseTexture8Impl_GetType,
|
||||
|
||||
IDirect3DBaseTexture8Impl_SetLOD,
|
||||
IDirect3DBaseTexture8Impl_GetLOD,
|
||||
IDirect3DBaseTexture8Impl_GetLevelCount
|
||||
};
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* IDirect3DCubeTexture8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DCubeTexture8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_QueryInterface(LPDIRECT3DCUBETEXTURE8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DCubeTexture8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DCubeTexture8Impl_AddRef(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DCubeTexture8Impl_Release(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
TRACE("Releasing child %p\n", This->wineD3DCubeTexture);
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DCubeTexture_Destroy(This->wineD3DCubeTexture, D3D8CB_DestroySurface);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DCubeTexture8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetDevice(LPDIRECT3DCUBETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n" , This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_SetPrivateData(LPDIRECT3DCUBETEXTURE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_SetPrivateData(This->wineD3DCubeTexture,refguid,pData,SizeOfData,Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetPrivateData(LPDIRECT3DCUBETEXTURE8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_GetPrivateData(This->wineD3DCubeTexture,refguid,pData,pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_FreePrivateData(LPDIRECT3DCUBETEXTURE8 iface, REFGUID refguid) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_FreePrivateData(This->wineD3DCubeTexture,refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DCubeTexture8Impl_SetPriority(LPDIRECT3DCUBETEXTURE8 iface, DWORD PriorityNew) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DCubeTexture_SetPriority(This->wineD3DCubeTexture, PriorityNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DCubeTexture8Impl_GetPriority(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DCubeTexture_GetPriority(This->wineD3DCubeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DCubeTexture8Impl_PreLoad(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DCubeTexture_PreLoad(This->wineD3DCubeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DCubeTexture8Impl_GetType(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
D3DRESOURCETYPE type;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
type = IWineD3DCubeTexture_GetType(This->wineD3DCubeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* IDirect3DCubeTexture8 IDirect3DBaseTexture8 Interface follow: */
|
||||
static DWORD WINAPI IDirect3DCubeTexture8Impl_SetLOD(LPDIRECT3DCUBETEXTURE8 iface, DWORD LODNew) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
DWORD lod;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
lod = IWineD3DCubeTexture_SetLOD(This->wineD3DCubeTexture, LODNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return lod;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLOD(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
DWORD lod;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
lod = IWineD3DCubeTexture_GetLOD((LPDIRECT3DBASETEXTURE8) This);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return lod;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DCubeTexture8Impl_GetLevelCount(LPDIRECT3DCUBETEXTURE8 iface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
DWORD cnt;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
cnt = IWineD3DCubeTexture_GetLevelCount(This->wineD3DCubeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* IDirect3DCubeTexture8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetLevelDesc(LPDIRECT3DCUBETEXTURE8 iface, UINT Level, D3DSURFACE_DESC *pDesc) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
WINED3DSURFACE_DESC wined3ddesc;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
|
||||
wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
|
||||
wined3ddesc.Type = (WINED3DRESOURCETYPE *)&pDesc->Type;
|
||||
wined3ddesc.Usage = &pDesc->Usage;
|
||||
wined3ddesc.Pool = (WINED3DPOOL *) &pDesc->Pool;
|
||||
wined3ddesc.Size = &pDesc->Size;
|
||||
wined3ddesc.MultiSampleType = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
|
||||
wined3ddesc.MultiSampleQuality = NULL; /* DirectX9 only */
|
||||
wined3ddesc.Width = &pDesc->Width;
|
||||
wined3ddesc.Height = &pDesc->Height;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_GetLevelDesc(This->wineD3DCubeTexture, Level, &wined3ddesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_GetCubeMapSurface(LPDIRECT3DCUBETEXTURE8 iface, D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface8 **ppCubeMapSurface) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hrc = D3D_OK;
|
||||
IWineD3DSurface *mySurface = NULL;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hrc = IWineD3DCubeTexture_GetCubeMapSurface(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, &mySurface);
|
||||
if (hrc == D3D_OK && NULL != ppCubeMapSurface) {
|
||||
IWineD3DCubeTexture_GetParent(mySurface, (IUnknown **)ppCubeMapSurface);
|
||||
IWineD3DCubeTexture_Release(mySurface);
|
||||
}
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_LockRect(LPDIRECT3DCUBETEXTURE8 iface, D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT *pRect, DWORD Flags) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_LockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_UnlockRect(LPDIRECT3DCUBETEXTURE8 iface, D3DCUBEMAP_FACES FaceType, UINT Level) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_UnlockRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, Level);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DCubeTexture8Impl_AddDirtyRect(LPDIRECT3DCUBETEXTURE8 iface, D3DCUBEMAP_FACES FaceType, CONST RECT *pDirtyRect) {
|
||||
IDirect3DCubeTexture8Impl *This = (IDirect3DCubeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DCubeTexture_AddDirtyRect(This->wineD3DCubeTexture, (WINED3DCUBEMAP_FACES) FaceType, pDirtyRect);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DCubeTexture8Impl_QueryInterface,
|
||||
IDirect3DCubeTexture8Impl_AddRef,
|
||||
IDirect3DCubeTexture8Impl_Release,
|
||||
/* IDirect3DResource8 */
|
||||
IDirect3DCubeTexture8Impl_GetDevice,
|
||||
IDirect3DCubeTexture8Impl_SetPrivateData,
|
||||
IDirect3DCubeTexture8Impl_GetPrivateData,
|
||||
IDirect3DCubeTexture8Impl_FreePrivateData,
|
||||
IDirect3DCubeTexture8Impl_SetPriority,
|
||||
IDirect3DCubeTexture8Impl_GetPriority,
|
||||
IDirect3DCubeTexture8Impl_PreLoad,
|
||||
IDirect3DCubeTexture8Impl_GetType,
|
||||
/* IDirect3DBaseTexture8 */
|
||||
IDirect3DCubeTexture8Impl_SetLOD,
|
||||
IDirect3DCubeTexture8Impl_GetLOD,
|
||||
IDirect3DCubeTexture8Impl_GetLevelCount,
|
||||
/* IDirect3DCubeTexture8 */
|
||||
IDirect3DCubeTexture8Impl_GetLevelDesc,
|
||||
IDirect3DCubeTexture8Impl_GetCubeMapSurface,
|
||||
IDirect3DCubeTexture8Impl_LockRect,
|
||||
IDirect3DCubeTexture8Impl_UnlockRect,
|
||||
IDirect3DCubeTexture8Impl_AddDirtyRect
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
<module name="d3d8" type="win32dll" entrypoint="0" installbase="system32" installname="d3d8.dll" allowwarnings ="true">
|
||||
<importlibrary definition="d3d8.spec.def" />
|
||||
<include base="d3d8">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="UNICODE" />
|
||||
<define name="_UNICODE" />
|
||||
<define name="__REACTOS__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<define name="__WINESRC__" />
|
||||
<define name="USE_WIN32_OPENGL" />
|
||||
|
||||
<library>uuid</library>
|
||||
<library>user32 </library>
|
||||
<library>opengl32 </library>
|
||||
<library>gdi32 </library>
|
||||
<library>advapi32 </library>
|
||||
<library>kernel32</library>
|
||||
<library>wined3d</library>
|
||||
|
||||
<file>basetexture.c</file>
|
||||
<file>cubetexture.c</file>
|
||||
<file>d3d8_main.c</file>
|
||||
<file>device.c</file>
|
||||
<file>directx.c</file>
|
||||
<file>indexbuffer.c</file>
|
||||
<file>pixelshader.c</file>
|
||||
<file>resource.c</file>
|
||||
<file>stateblock.c</file>
|
||||
<file>surface.c</file>
|
||||
<file>swapchain.c</file>
|
||||
<file>texture.c</file>
|
||||
<file>vertexbuffer.c</file>
|
||||
<file>vertexdeclaration.c</file>
|
||||
<file>vertexshader.c</file>
|
||||
<file>volume.c</file>
|
||||
<file>volumetexture.c</file>
|
||||
<file>d3d8.spec</file>
|
||||
|
||||
</module>
|
||||
@@ -0,0 +1,5 @@
|
||||
@ stdcall D3D8GetSWInfo()
|
||||
@ stdcall DebugSetMute()
|
||||
@ stdcall Direct3DCreate8(long)
|
||||
@ stdcall ValidatePixelShader(ptr long long ptr)
|
||||
@ stdcall ValidateVertexShader(ptr ptr ptr long ptr)
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Direct3D 8
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "initguid.h"
|
||||
#include "d3d8_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
static CRITICAL_SECTION_DEBUG d3d8_cs_debug =
|
||||
{
|
||||
0, 0, &d3d8_cs,
|
||||
{ &d3d8_cs_debug.ProcessLocksList,
|
||||
&d3d8_cs_debug.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": d3d8_cs") }
|
||||
};
|
||||
CRITICAL_SECTION d3d8_cs = { &d3d8_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
HRESULT WINAPI D3D8GetSWInfo(void) {
|
||||
FIXME("(void): stub\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WINAPI DebugSetMute(void) {
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) {
|
||||
IDirect3D8Impl* object;
|
||||
TRACE("SDKVersion = %x\n", SDKVersion);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D8Impl));
|
||||
|
||||
object->lpVtbl = &Direct3D8_Vtbl;
|
||||
object->ref = 1;
|
||||
object->WineD3D = WineDirect3DCreate(SDKVersion, 8, (IUnknown *)object);
|
||||
|
||||
TRACE("Created Direct3D object @ %p, WineObj @ %p\n", object, object->WineD3D);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
|
||||
return (IDirect3D8*) object;
|
||||
}
|
||||
|
||||
/* At process attach */
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
TRACE("fdwReason=%d\n", fdwReason);
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ValidateVertexShader (D3D8.@)
|
||||
*
|
||||
* I've seen reserved1 and reserved2 always passed as 0's
|
||||
* bool seems always passed as 0 or 1, but other values work as well....
|
||||
* toto result?
|
||||
*/
|
||||
HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL bool, DWORD* toto)
|
||||
{
|
||||
HRESULT ret;
|
||||
FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
|
||||
|
||||
if (!vertexshader)
|
||||
return E_FAIL;
|
||||
|
||||
if (reserved1 || reserved2)
|
||||
return E_FAIL;
|
||||
|
||||
switch(*vertexshader) {
|
||||
case 0xFFFE0101:
|
||||
case 0xFFFE0100:
|
||||
ret=S_OK;
|
||||
break;
|
||||
default:
|
||||
ERR("vertexshader version mismatch\n");
|
||||
ret=E_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ValidatePixelShader (D3D8.@)
|
||||
*
|
||||
* PARAMS
|
||||
* toto result?
|
||||
*/
|
||||
HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
|
||||
{
|
||||
HRESULT ret;
|
||||
FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
|
||||
|
||||
if (!pixelshader)
|
||||
return E_FAIL;
|
||||
|
||||
if (reserved1)
|
||||
return E_FAIL;
|
||||
|
||||
switch(*pixelshader) {
|
||||
case 0xFFFF0100:
|
||||
case 0xFFFF0101:
|
||||
case 0xFFFF0102:
|
||||
case 0xFFFF0103:
|
||||
case 0xFFFF0104:
|
||||
ret=S_OK;
|
||||
break;
|
||||
default:
|
||||
ERR("pixelshader version mismatch\n");
|
||||
ret=E_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,670 @@
|
||||
/*
|
||||
* Direct3D 8 private include file
|
||||
*
|
||||
* Copyright 2002-2004 Jason Edmeades
|
||||
* Copyright 2003-2004 Raphael Junqueira
|
||||
* Copyright 2004 Christian Costa
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_D3D8_PRIVATE_H
|
||||
#define __WINE_D3D8_PRIVATE_H
|
||||
|
||||
#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"
|
||||
|
||||
/* Device caps */
|
||||
#define INITIAL_SHADER_HANDLE_TABLE_SIZE 64
|
||||
|
||||
/* CreateVertexShader can return > 0xFFFF */
|
||||
#define VS_HIGHESTFIXEDFXF 0xF0000000
|
||||
|
||||
/* ===========================================================================
|
||||
Macros
|
||||
=========================================================================== */
|
||||
/* Not nice, but it lets wined3d support different versions of directx */
|
||||
#define D3D8CAPSTOWINECAPS(_pD3D8Caps, _pWineCaps) \
|
||||
_pWineCaps->DeviceType = (WINED3DDEVTYPE *) &_pD3D8Caps->DeviceType; \
|
||||
_pWineCaps->AdapterOrdinal = &_pD3D8Caps->AdapterOrdinal; \
|
||||
_pWineCaps->Caps = &_pD3D8Caps->Caps; \
|
||||
_pWineCaps->Caps2 = &_pD3D8Caps->Caps2; \
|
||||
_pWineCaps->Caps3 = &_pD3D8Caps->Caps3; \
|
||||
_pWineCaps->PresentationIntervals = &_pD3D8Caps->PresentationIntervals; \
|
||||
_pWineCaps->CursorCaps = &_pD3D8Caps->CursorCaps; \
|
||||
_pWineCaps->DevCaps = &_pD3D8Caps->DevCaps; \
|
||||
_pWineCaps->PrimitiveMiscCaps = &_pD3D8Caps->PrimitiveMiscCaps; \
|
||||
_pWineCaps->RasterCaps = &_pD3D8Caps->RasterCaps; \
|
||||
_pWineCaps->ZCmpCaps = &_pD3D8Caps->ZCmpCaps; \
|
||||
_pWineCaps->SrcBlendCaps = &_pD3D8Caps->SrcBlendCaps; \
|
||||
_pWineCaps->DestBlendCaps = &_pD3D8Caps->DestBlendCaps; \
|
||||
_pWineCaps->AlphaCmpCaps = &_pD3D8Caps->AlphaCmpCaps; \
|
||||
_pWineCaps->ShadeCaps = &_pD3D8Caps->ShadeCaps; \
|
||||
_pWineCaps->TextureCaps = &_pD3D8Caps->TextureCaps; \
|
||||
_pWineCaps->TextureFilterCaps = &_pD3D8Caps->TextureFilterCaps; \
|
||||
_pWineCaps->CubeTextureFilterCaps = &_pD3D8Caps->CubeTextureFilterCaps; \
|
||||
_pWineCaps->VolumeTextureFilterCaps = &_pD3D8Caps->VolumeTextureFilterCaps; \
|
||||
_pWineCaps->TextureAddressCaps = &_pD3D8Caps->TextureAddressCaps; \
|
||||
_pWineCaps->VolumeTextureAddressCaps = &_pD3D8Caps->VolumeTextureAddressCaps; \
|
||||
_pWineCaps->LineCaps = &_pD3D8Caps->LineCaps; \
|
||||
_pWineCaps->MaxTextureWidth = &_pD3D8Caps->MaxTextureWidth; \
|
||||
_pWineCaps->MaxTextureHeight = &_pD3D8Caps->MaxTextureHeight; \
|
||||
_pWineCaps->MaxVolumeExtent = &_pD3D8Caps->MaxVolumeExtent; \
|
||||
_pWineCaps->MaxTextureRepeat = &_pD3D8Caps->MaxTextureRepeat; \
|
||||
_pWineCaps->MaxTextureAspectRatio = &_pD3D8Caps->MaxTextureAspectRatio; \
|
||||
_pWineCaps->MaxAnisotropy = &_pD3D8Caps->MaxAnisotropy; \
|
||||
_pWineCaps->MaxVertexW = &_pD3D8Caps->MaxVertexW; \
|
||||
_pWineCaps->GuardBandLeft = &_pD3D8Caps->GuardBandLeft; \
|
||||
_pWineCaps->GuardBandTop = &_pD3D8Caps->GuardBandTop; \
|
||||
_pWineCaps->GuardBandRight = &_pD3D8Caps->GuardBandRight; \
|
||||
_pWineCaps->GuardBandBottom = &_pD3D8Caps->GuardBandBottom; \
|
||||
_pWineCaps->ExtentsAdjust = &_pD3D8Caps->ExtentsAdjust; \
|
||||
_pWineCaps->StencilCaps = &_pD3D8Caps->StencilCaps; \
|
||||
_pWineCaps->FVFCaps = &_pD3D8Caps->FVFCaps; \
|
||||
_pWineCaps->TextureOpCaps = &_pD3D8Caps->TextureOpCaps; \
|
||||
_pWineCaps->MaxTextureBlendStages = &_pD3D8Caps->MaxTextureBlendStages; \
|
||||
_pWineCaps->MaxSimultaneousTextures = &_pD3D8Caps->MaxSimultaneousTextures; \
|
||||
_pWineCaps->VertexProcessingCaps = &_pD3D8Caps->VertexProcessingCaps; \
|
||||
_pWineCaps->MaxActiveLights = &_pD3D8Caps->MaxActiveLights; \
|
||||
_pWineCaps->MaxUserClipPlanes = &_pD3D8Caps->MaxUserClipPlanes; \
|
||||
_pWineCaps->MaxVertexBlendMatrices = &_pD3D8Caps->MaxVertexBlendMatrices; \
|
||||
_pWineCaps->MaxVertexBlendMatrixIndex = &_pD3D8Caps->MaxVertexBlendMatrixIndex; \
|
||||
_pWineCaps->MaxPointSize = &_pD3D8Caps->MaxPointSize; \
|
||||
_pWineCaps->MaxPrimitiveCount = &_pD3D8Caps->MaxPrimitiveCount; \
|
||||
_pWineCaps->MaxVertexIndex = &_pD3D8Caps->MaxVertexIndex; \
|
||||
_pWineCaps->MaxStreams = &_pD3D8Caps->MaxStreams; \
|
||||
_pWineCaps->MaxStreamStride = &_pD3D8Caps->MaxStreamStride; \
|
||||
_pWineCaps->VertexShaderVersion = &_pD3D8Caps->VertexShaderVersion; \
|
||||
_pWineCaps->MaxVertexShaderConst = &_pD3D8Caps->MaxVertexShaderConst; \
|
||||
_pWineCaps->PixelShaderVersion = &_pD3D8Caps->PixelShaderVersion; \
|
||||
_pWineCaps->PixelShader1xMaxValue = &_pD3D8Caps->MaxPixelShaderValue;
|
||||
|
||||
/* Direct3D8 Interfaces: */
|
||||
typedef struct IDirect3DBaseTexture8Impl IDirect3DBaseTexture8Impl;
|
||||
typedef struct IDirect3DVolumeTexture8Impl IDirect3DVolumeTexture8Impl;
|
||||
typedef struct IDirect3D8Impl IDirect3D8Impl;
|
||||
typedef struct IDirect3DDevice8Impl IDirect3DDevice8Impl;
|
||||
typedef struct IDirect3DTexture8Impl IDirect3DTexture8Impl;
|
||||
typedef struct IDirect3DCubeTexture8Impl IDirect3DCubeTexture8Impl;
|
||||
typedef struct IDirect3DIndexBuffer8Impl IDirect3DIndexBuffer8Impl;
|
||||
typedef struct IDirect3DSurface8Impl IDirect3DSurface8Impl;
|
||||
typedef struct IDirect3DSwapChain8Impl IDirect3DSwapChain8Impl;
|
||||
typedef struct IDirect3DResource8Impl IDirect3DResource8Impl;
|
||||
typedef struct IDirect3DVolume8Impl IDirect3DVolume8Impl;
|
||||
typedef struct IDirect3DVertexBuffer8Impl IDirect3DVertexBuffer8Impl;
|
||||
|
||||
/** Private Interfaces: */
|
||||
typedef struct IDirect3DStateBlockImpl IDirect3DStateBlockImpl;
|
||||
typedef struct IDirect3DVertexShaderImpl IDirect3DVertexShaderImpl;
|
||||
typedef struct IDirect3DPixelShaderImpl IDirect3DPixelShaderImpl;
|
||||
typedef struct IDirect3DVertexShaderDeclarationImpl IDirect3DVertexShaderDeclarationImpl;
|
||||
|
||||
/* Advance declaration of structures to satisfy compiler */
|
||||
typedef struct IDirect3DVertexShader8Impl IDirect3DVertexShader8Impl;
|
||||
|
||||
/* Global critical section */
|
||||
extern CRITICAL_SECTION d3d8_cs;
|
||||
|
||||
/* ===========================================================================
|
||||
The interfactes themselves
|
||||
=========================================================================== */
|
||||
|
||||
/* ---------- */
|
||||
/* IDirect3D8 */
|
||||
/* ---------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3D8Vtbl Direct3D8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3D implementation structure
|
||||
*/
|
||||
struct IDirect3D8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3D8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* The WineD3D device */
|
||||
IWineD3D *WineD3D;
|
||||
};
|
||||
|
||||
/* ---------------- */
|
||||
/* IDirect3DDevice8 */
|
||||
/* ---------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DDevice8Vtbl Direct3DDevice8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DDevice8 implementation structure
|
||||
*/
|
||||
|
||||
typedef void * shader_handle;
|
||||
|
||||
struct FvfToDecl
|
||||
{
|
||||
DWORD fvf;
|
||||
IWineD3DVertexDeclaration *decl;
|
||||
};
|
||||
|
||||
struct IDirect3DDevice8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DDevice8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
/* But what about baseVertexIndex in state blocks? hmm... it may be a better idea to pass this to wined3d */
|
||||
IWineD3DDevice *WineD3DDevice;
|
||||
DWORD shader_handle_table_size;
|
||||
DWORD allocated_shader_handles;
|
||||
shader_handle *shader_handles;
|
||||
shader_handle *free_shader_handles;
|
||||
|
||||
/* FVF management */
|
||||
struct FvfToDecl *decls;
|
||||
UINT numConvertedDecls, declArraySize;
|
||||
|
||||
/* Avoids recursion with nested ReleaseRef to 0 */
|
||||
BOOL inDestruction;
|
||||
};
|
||||
|
||||
/* ---------------- */
|
||||
/* IDirect3DVolume8 */
|
||||
/* ---------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVolume8 implementation structure
|
||||
*/
|
||||
struct IDirect3DVolume8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DVolume8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DVolume8 fields */
|
||||
IWineD3DVolume *wineD3DVolume;
|
||||
|
||||
/* The volume container */
|
||||
IUnknown *container;
|
||||
|
||||
/* If set forward refcounting to this object */
|
||||
IUnknown *forwardReference;
|
||||
};
|
||||
|
||||
/* ------------------- */
|
||||
/* IDirect3DSwapChain8 */
|
||||
/* ------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DSwapChain8Vtbl Direct3DSwapChain8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DSwapChain8 implementation structure
|
||||
*/
|
||||
struct IDirect3DSwapChain8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DSwapChain8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DSwapChain8 fields */
|
||||
IWineD3DSwapChain *wineD3DSwapChain;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* ----------------- */
|
||||
/* IDirect3DSurface8 */
|
||||
/* ----------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DSurface8Vtbl Direct3DSurface8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DSurface8 implementation structure
|
||||
*/
|
||||
struct IDirect3DSurface8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DSurface8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DSurface8 fields */
|
||||
IWineD3DSurface *wineD3DSurface;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
|
||||
/* The surface container */
|
||||
IUnknown *container;
|
||||
|
||||
/* If set forward refcounting to this object */
|
||||
IUnknown *forwardReference;
|
||||
|
||||
/* Flags an implicit surface */
|
||||
BOOL isImplicit;
|
||||
};
|
||||
|
||||
/* ------------------ */
|
||||
/* IDirect3DResource8 */
|
||||
/* ------------------ */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DResource8Vtbl Direct3DResource8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DResource8 implementation structure
|
||||
*/
|
||||
struct IDirect3DResource8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DResource8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DResource *wineD3DResource;
|
||||
};
|
||||
extern HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice);
|
||||
|
||||
/* ---------------------- */
|
||||
/* IDirect3DVertexBuffer8 */
|
||||
/* ---------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVertexBuffer8 implementation structure
|
||||
*/
|
||||
struct IDirect3DVertexBuffer8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DVertexBuffer8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DVertexBuffer *wineD3DVertexBuffer;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* --------------------- */
|
||||
/* IDirect3DIndexBuffer8 */
|
||||
/* --------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DIndexBuffer8Vtbl Direct3DIndexBuffer8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DIndexBuffer8 implementation structure
|
||||
*/
|
||||
struct IDirect3DIndexBuffer8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DIndexBuffer8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DIndexBuffer *wineD3DIndexBuffer;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* --------------------- */
|
||||
/* IDirect3DBaseTexture8 */
|
||||
/* --------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DBaseTexture8 implementation structure
|
||||
*/
|
||||
struct IDirect3DBaseTexture8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DBaseTexture8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DBaseTexture *wineD3DBaseTexture;
|
||||
};
|
||||
|
||||
/* --------------------- */
|
||||
/* IDirect3DCubeTexture8 */
|
||||
/* --------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DCubeTexture8 implementation structure
|
||||
*/
|
||||
struct IDirect3DCubeTexture8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DCubeTexture8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DCubeTexture *wineD3DCubeTexture;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* ----------------- */
|
||||
/* IDirect3DTexture8 */
|
||||
/* ----------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DTexture8 implementation structure
|
||||
*/
|
||||
struct IDirect3DTexture8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DTexture8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResourc8 fields */
|
||||
IWineD3DTexture *wineD3DTexture;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* ----------------------- */
|
||||
/* IDirect3DVolumeTexture8 */
|
||||
/* ----------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVolumeTexture8 implementation structure
|
||||
*/
|
||||
struct IDirect3DVolumeTexture8Impl
|
||||
{
|
||||
/* IUnknown fields */
|
||||
const IDirect3DVolumeTexture8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DVolumeTexture *wineD3DVolumeTexture;
|
||||
|
||||
/* Parent reference */
|
||||
LPDIRECT3DDEVICE8 parentDevice;
|
||||
};
|
||||
|
||||
/* ----------------------- */
|
||||
/* IDirect3DStateBlockImpl */
|
||||
/* ----------------------- */
|
||||
|
||||
/* TODO: Generate a valid GUIDs */
|
||||
/* {83B073CE-6F30-11d9-C687-00046142C14F} */
|
||||
DEFINE_GUID(IID_IDirect3DStateBlock8,
|
||||
0x83b073ce, 0x6f30, 0x11d9, 0xc6, 0x87, 0x0, 0x4, 0x61, 0x42, 0xc1, 0x4f);
|
||||
|
||||
DEFINE_GUID(IID_IDirect3DVertexDeclaration8,
|
||||
0x5dd7478d, 0xcbf3, 0x41a6, 0x8c, 0xfd, 0xfd, 0x19, 0x2b, 0x11, 0xc7, 0x90);
|
||||
|
||||
DEFINE_GUID(IID_IDirect3DVertexShader8,
|
||||
0xefc5557e, 0x6265, 0x4613, 0x8a, 0x94, 0x43, 0x85, 0x78, 0x89, 0xeb, 0x36);
|
||||
|
||||
DEFINE_GUID(IID_IDirect3DPixelShader8,
|
||||
0x6d3bdbdc, 0x5b02, 0x4415, 0xb8, 0x52, 0xce, 0x5e, 0x8b, 0xcc, 0xb2, 0x89);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DStateBlock8 interface
|
||||
*/
|
||||
#define INTERFACE IDirect3DStateBlock8
|
||||
DECLARE_INTERFACE_(IDirect3DStateBlock8, IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IDirect3DStateBlock9 methods ***/
|
||||
STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE;
|
||||
STDMETHOD(Capture)(THIS) PURE;
|
||||
STDMETHOD(Apply)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
#define IDirect3DStateBlock8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDirect3DStateBlock8_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDirect3DStateBlock8_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IDirect3DStateBlock9 methods ***/
|
||||
#define IDirect3DStateBlock8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
|
||||
#define IDirect3DStateBlock8_Capture(p) (p)->lpVtbl->Capture(p)
|
||||
#define IDirect3DStateBlock8_Apply(p) (p)->lpVtbl->Apply(p)
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DStateBlock implementation structure
|
||||
*/
|
||||
typedef struct IDirect3DStateBlock8Impl {
|
||||
/* IUnknown fields */
|
||||
const IDirect3DStateBlock8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
/* IDirect3DResource8 fields */
|
||||
IWineD3DStateBlock *wineD3DStateBlock;
|
||||
} IDirect3DStateBlock8Impl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVertexDeclaration8 interface
|
||||
*/
|
||||
#define INTERFACE IDirect3DVertexDeclaration8
|
||||
DECLARE_INTERFACE_(IDirect3DVertexDeclaration8, IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** obj_ptr) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
#define IDirect3DVertexDeclaration8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDirect3DVertexDeclaration8_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDirect3DVertexDeclaration8_Release(p) (p)->lpVtbl->Release(p)
|
||||
|
||||
/*** Implementation ***/
|
||||
extern const IDirect3DVertexDeclaration8Vtbl Direct3DVertexDeclaration8_Vtbl;
|
||||
|
||||
typedef struct {
|
||||
const IDirect3DVertexDeclaration8Vtbl *lpVtbl;
|
||||
LONG ref_count;
|
||||
|
||||
DWORD *elements;
|
||||
DWORD elements_size; /* Size of elements, in bytes */
|
||||
|
||||
IWineD3DVertexDeclaration *wined3d_vertex_declaration;
|
||||
} IDirect3DVertexDeclaration8Impl;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVertexShader9 interface
|
||||
*/
|
||||
#define INTERFACE IDirect3DVertexShader8
|
||||
DECLARE_INTERFACE_(IDirect3DVertexShader8, IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IDirect3DVertexShader9 methods ***/
|
||||
STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE;
|
||||
STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
#define IDirect3DVertexShader8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDirect3DVertexShader8_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDirect3DVertexShader8_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IDirect3DVertexShader8 methods ***/
|
||||
#define IDirect3DVertexShader8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
|
||||
#define IDirect3DVertexShader8_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b)
|
||||
|
||||
/* ------------------------- */
|
||||
/* IDirect3DVertexShader8Impl */
|
||||
/* ------------------------- */
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DPixelShader9 interface
|
||||
*/
|
||||
#define INTERFACE IDirect3DPixelShader8
|
||||
DECLARE_INTERFACE_(IDirect3DPixelShader8,IUnknown)
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
/*** IDirect3DPixelShader8 methods ***/
|
||||
STDMETHOD(GetDevice)(THIS_ struct IDirect3DDevice8** ppDevice) PURE;
|
||||
STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
#define IDirect3DPixelShader8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IDirect3DPixelShader8_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IDirect3DPixelShader8_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IDirect3DPixelShader8 methods ***/
|
||||
#define IDirect3DPixelShader8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
|
||||
#define IDirect3DPixelShader8_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DVertexShader implementation structure
|
||||
*/
|
||||
|
||||
struct IDirect3DVertexShader8Impl {
|
||||
const IDirect3DVertexShader8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
shader_handle *handle;
|
||||
IDirect3DVertexDeclaration8 *vertex_declaration;
|
||||
IWineD3DVertexShader *wineD3DVertexShader;
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------ */
|
||||
/* IDirect3DPixelShaderImpl */
|
||||
/* ------------------------ */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interface implementation structures
|
||||
*/
|
||||
extern const IDirect3DPixelShader8Vtbl Direct3DPixelShader8_Vtbl;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DPixelShader implementation structure
|
||||
*/
|
||||
typedef struct IDirect3DPixelShader8Impl {
|
||||
const IDirect3DPixelShader8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
shader_handle *handle;
|
||||
/* The device, to be replaced by an IDirect3DDeviceImpl */
|
||||
IWineD3DPixelShader *wineD3DPixelShader;
|
||||
} IDirect3DPixelShader8Impl;
|
||||
|
||||
/**
|
||||
* Internals functions
|
||||
*
|
||||
* to see how not defined it here
|
||||
*/
|
||||
void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader);
|
||||
size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, WINED3DVERTEXELEMENT **wined3d_elements);
|
||||
|
||||
/* Callbacks */
|
||||
extern HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
|
||||
WINED3DFORMAT Format, DWORD Usage, WINED3DPOOL Pool, UINT Level,
|
||||
WINED3DCUBEMAP_FACES Face, IWineD3DSurface** ppSurface,
|
||||
HANDLE* pSharedHandle);
|
||||
|
||||
extern HRESULT WINAPI D3D8CB_CreateVolume(IUnknown *pDevice, IUnknown *pSuperior, UINT Width, UINT Height, UINT Depth,
|
||||
WINED3DFORMAT Format, WINED3DPOOL Pool, DWORD Usage,
|
||||
IWineD3DVolume **ppVolume,
|
||||
HANDLE * pSharedHandle);
|
||||
|
||||
extern HRESULT WINAPI D3D8CB_CreateDepthStencilSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
|
||||
WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample,
|
||||
DWORD MultisampleQuality, BOOL Discard,
|
||||
IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
|
||||
|
||||
extern HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
|
||||
WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample,
|
||||
DWORD MultisampleQuality, BOOL Lockable,
|
||||
IWineD3DSurface** ppSurface, HANDLE* pSharedHandle);
|
||||
|
||||
extern ULONG WINAPI D3D8CB_DestroySwapChain (IWineD3DSwapChain *pSwapChain);
|
||||
|
||||
extern ULONG WINAPI D3D8CB_DestroyDepthStencilSurface (IWineD3DSurface *pSurface);
|
||||
|
||||
extern ULONG WINAPI D3D8CB_DestroyRenderTarget (IWineD3DSurface *pSurface);
|
||||
|
||||
extern ULONG WINAPI D3D8CB_DestroySurface(IWineD3DSurface *pSurface);
|
||||
|
||||
extern ULONG WINAPI D3D8CB_DestroyVolume(IWineD3DVolume *pVolume);
|
||||
|
||||
#endif /* __WINE_D3DX8_PRIVATE_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,507 @@
|
||||
/*
|
||||
* IDirect3D8 implementation
|
||||
*
|
||||
* Copyright 2002-2004 Jason Edmeades
|
||||
* Copyright 2003-2004 Raphael Junqueira
|
||||
* Copyright 2004 Christian Costa
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3D IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3D8Impl_QueryInterface(LPDIRECT3D8 iface, REFIID riid,LPVOID *ppobj)
|
||||
{
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3D8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid),ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3D8Impl_AddRef(LPDIRECT3D8 iface) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3D8Impl_Release(LPDIRECT3D8 iface) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
TRACE("Releasing wined3d %p\n", This->WineD3D);
|
||||
IWineD3D_Release(This->WineD3D);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3D8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3D8Impl_RegisterSoftwareDevice (LPDIRECT3D8 iface, void* pInitializeFunction) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%p)\n", This, pInitializeFunction);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_RegisterSoftwareDevice(This->WineD3D, pInitializeFunction);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static UINT WINAPI IDirect3D8Impl_GetAdapterCount (LPDIRECT3D8 iface) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_GetAdapterCount(This->WineD3D);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_GetAdapterIdentifier (LPDIRECT3D8 iface,
|
||||
UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8* pIdentifier) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
WINED3DADAPTER_IDENTIFIER adapter_id;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%d,%08x, %p\n", This, Adapter, Flags, pIdentifier);
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
/* dx8 and dx9 have different structures to be filled in, with incompatible
|
||||
layouts so pass in pointers to the places to be filled via an internal
|
||||
structure */
|
||||
adapter_id.Driver = pIdentifier->Driver;
|
||||
adapter_id.Description = pIdentifier->Description;
|
||||
adapter_id.DeviceName = NULL; /* d3d9 only */
|
||||
adapter_id.DriverVersion = &pIdentifier->DriverVersion;
|
||||
adapter_id.VendorId = &pIdentifier->VendorId;
|
||||
adapter_id.DeviceId = &pIdentifier->DeviceId;
|
||||
adapter_id.SubSysId = &pIdentifier->SubSysId;
|
||||
adapter_id.Revision = &pIdentifier->Revision;
|
||||
adapter_id.DeviceIdentifier = &pIdentifier->DeviceIdentifier;
|
||||
adapter_id.WHQLLevel = &pIdentifier->WHQLLevel;
|
||||
|
||||
hr = IWineD3D_GetAdapterIdentifier(This->WineD3D, Adapter, Flags, &adapter_id);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static UINT WINAPI IDirect3D8Impl_GetAdapterModeCount (LPDIRECT3D8 iface,UINT Adapter) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%d)\n", This, Adapter);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_GetAdapterModeCount(This->WineD3D, Adapter, 0 /* format */);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_EnumAdapterModes (LPDIRECT3D8 iface, UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%d, %d, %p)\n", This, Adapter, Mode, pMode);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_EnumAdapterModes(This->WineD3D, Adapter, WINED3DFMT_UNKNOWN, Mode, (WINED3DDISPLAYMODE *) pMode);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_GetAdapterDisplayMode (LPDIRECT3D8 iface, UINT Adapter, D3DDISPLAYMODE* pMode) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%d,%p)\n", This, Adapter, pMode);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_GetAdapterDisplayMode(This->WineD3D, Adapter, (WINED3DDISPLAYMODE *) pMode);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_CheckDeviceType (LPDIRECT3D8 iface,
|
||||
UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat,
|
||||
D3DFORMAT BackBufferFormat, BOOL Windowed) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%d, %d, %d, %d, %s)\n", This, Adapter, CheckType, DisplayFormat, BackBufferFormat, Windowed ? "true" : "false");
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_CheckDeviceType(This->WineD3D, Adapter, CheckType, DisplayFormat,
|
||||
BackBufferFormat, Windowed);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 iface,
|
||||
UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
|
||||
DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, AdapterFormat,
|
||||
Usage, RType, CheckFormat);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_CheckDeviceMultiSampleType(LPDIRECT3D8 iface,
|
||||
UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
|
||||
BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)-<(%d, %d, %d, %s, %d)\n", This, Adapter, DeviceType, SurfaceFormat, Windowed ? "true" : "false", MultiSampleType);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_CheckDeviceMultiSampleType(This->WineD3D, Adapter, DeviceType, SurfaceFormat,
|
||||
Windowed, (WINED3DMULTISAMPLE_TYPE) MultiSampleType, NULL);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_CheckDepthStencilMatch(LPDIRECT3D8 iface,
|
||||
UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
|
||||
D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)-<(%d, %d, %d, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3D_CheckDepthStencilMatch(This->WineD3D, Adapter, DeviceType, AdapterFormat,
|
||||
RenderTargetFormat, DepthStencilFormat);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HRESULT hrc = D3D_OK;
|
||||
WINED3DCAPS *pWineCaps;
|
||||
|
||||
TRACE("(%p) Relay %d %u %p\n", This, Adapter, DeviceType, pCaps);
|
||||
|
||||
if(NULL == pCaps){
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
|
||||
if(pWineCaps == NULL){
|
||||
return D3DERR_INVALIDCALL; /*well this is what MSDN says to return*/
|
||||
}
|
||||
D3D8CAPSTOWINECAPS(pCaps, pWineCaps)
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hrc = IWineD3D_GetDeviceCaps(This->WineD3D, Adapter, DeviceType, pWineCaps);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
HeapFree(GetProcessHeap(), 0, pWineCaps);
|
||||
|
||||
/* D3D8 doesn't support SM 2.0 or higher, so clamp to 1.x */
|
||||
if(pCaps->PixelShaderVersion > D3DPS_VERSION(1,4)){
|
||||
pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
|
||||
}
|
||||
if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
|
||||
pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
|
||||
}
|
||||
|
||||
TRACE("(%p) returning %p\n", This, pCaps);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
static HMONITOR WINAPI IDirect3D8Impl_GetAdapterMonitor(LPDIRECT3D8 iface, UINT Adapter) {
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
HMONITOR ret;
|
||||
TRACE("(%p)->(%d)\n", This, Adapter);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3D_GetAdapterMonitor(This->WineD3D, Adapter);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Internal function called back during the CreateDevice to create a render target */
|
||||
HRESULT WINAPI D3D8CB_CreateRenderTarget(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
|
||||
WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample,
|
||||
DWORD MultisampleQuality, BOOL Lockable,
|
||||
IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
|
||||
HRESULT res = D3D_OK;
|
||||
IDirect3DSurface8Impl *d3dSurface = NULL;
|
||||
|
||||
TRACE("(%p) call back\n", device);
|
||||
res = IDirect3DDevice8_CreateRenderTarget((IDirect3DDevice8 *)device, Width, Height,
|
||||
(D3DFORMAT)Format, MultiSample, Lockable,
|
||||
(IDirect3DSurface8 **)&d3dSurface);
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
*ppSurface = d3dSurface->wineD3DSurface;
|
||||
d3dSurface->container = device;
|
||||
d3dSurface->isImplicit = TRUE;
|
||||
/* Implicit surfaces are created with an refcount of 0 */
|
||||
IUnknown_Release((IUnknown *)d3dSurface);
|
||||
} else {
|
||||
*ppSurface = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ULONG WINAPI D3D8CB_DestroyRenderTarget(IWineD3DSurface *pSurface) {
|
||||
IDirect3DSurface8Impl* surfaceParent;
|
||||
TRACE("(%p) call back\n", pSurface);
|
||||
|
||||
IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
|
||||
surfaceParent->isImplicit = FALSE;
|
||||
/* Surface had refcount of 0 GetParent addrefed to 1, so 1 Release is enough */
|
||||
return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
|
||||
}
|
||||
|
||||
/* Callback for creating the inplicite swapchain when the device is created */
|
||||
static HRESULT WINAPI D3D8CB_CreateAdditionalSwapChain(IUnknown *device,
|
||||
WINED3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
IWineD3DSwapChain ** ppSwapChain){
|
||||
HRESULT res = D3D_OK;
|
||||
IDirect3DSwapChain8Impl *d3dSwapChain = NULL;
|
||||
D3DPRESENT_PARAMETERS localParameters;
|
||||
TRACE("(%p) call back\n", device);
|
||||
|
||||
/* Copy the presentation parameters */
|
||||
localParameters.BackBufferWidth = pPresentationParameters->BackBufferWidth;
|
||||
localParameters.BackBufferHeight = pPresentationParameters->BackBufferHeight;
|
||||
localParameters.BackBufferFormat = pPresentationParameters->BackBufferFormat;
|
||||
localParameters.BackBufferCount = pPresentationParameters->BackBufferCount;
|
||||
localParameters.MultiSampleType = pPresentationParameters->MultiSampleType;
|
||||
localParameters.SwapEffect = pPresentationParameters->SwapEffect;
|
||||
localParameters.hDeviceWindow = pPresentationParameters->hDeviceWindow;
|
||||
localParameters.Windowed = pPresentationParameters->Windowed;
|
||||
localParameters.EnableAutoDepthStencil = pPresentationParameters->EnableAutoDepthStencil;
|
||||
localParameters.AutoDepthStencilFormat = pPresentationParameters->AutoDepthStencilFormat;
|
||||
localParameters.Flags = pPresentationParameters->Flags;
|
||||
localParameters.FullScreen_RefreshRateInHz = pPresentationParameters->FullScreen_RefreshRateInHz;
|
||||
localParameters.FullScreen_PresentationInterval = pPresentationParameters->PresentationInterval;
|
||||
|
||||
res = IDirect3DDevice8_CreateAdditionalSwapChain((IDirect3DDevice8 *)device, &localParameters, (IDirect3DSwapChain8 **)&d3dSwapChain);
|
||||
|
||||
/* Copy back the presentation parameters */
|
||||
pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
|
||||
pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
|
||||
pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat;
|
||||
pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
|
||||
pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
|
||||
pPresentationParameters->SwapEffect = localParameters.SwapEffect;
|
||||
pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
|
||||
pPresentationParameters->Windowed = localParameters.Windowed;
|
||||
pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
|
||||
pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat;
|
||||
pPresentationParameters->Flags = localParameters.Flags;
|
||||
pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
|
||||
pPresentationParameters->PresentationInterval = localParameters.FullScreen_PresentationInterval;
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
*ppSwapChain = d3dSwapChain->wineD3DSwapChain;
|
||||
IUnknown_Release(d3dSwapChain->parentDevice);
|
||||
d3dSwapChain->parentDevice = NULL;
|
||||
} else {
|
||||
*ppSwapChain = NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ULONG WINAPI D3D8CB_DestroySwapChain(IWineD3DSwapChain *pSwapChain) {
|
||||
IUnknown* swapChainParent;
|
||||
TRACE("(%p) call back\n", pSwapChain);
|
||||
|
||||
IWineD3DSwapChain_GetParent(pSwapChain, &swapChainParent);
|
||||
IUnknown_Release(swapChainParent);
|
||||
return IUnknown_Release(swapChainParent);
|
||||
}
|
||||
|
||||
/* Internal function called back during the CreateDevice to create a render target */
|
||||
HRESULT WINAPI D3D8CB_CreateDepthStencilSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,
|
||||
WINED3DFORMAT Format, WINED3DMULTISAMPLE_TYPE MultiSample,
|
||||
DWORD MultisampleQuality, BOOL Discard,
|
||||
IWineD3DSurface** ppSurface, HANDLE* pSharedHandle) {
|
||||
HRESULT res = D3D_OK;
|
||||
IDirect3DSurface8Impl *d3dSurface = NULL;
|
||||
TRACE("(%p) call back\n", device);
|
||||
|
||||
res = IDirect3DDevice8_CreateDepthStencilSurface((IDirect3DDevice8 *)device, Width, Height,
|
||||
(D3DFORMAT)Format, MultiSample, (IDirect3DSurface8 **)&d3dSurface);
|
||||
if (SUCCEEDED(res)) {
|
||||
*ppSurface = d3dSurface->wineD3DSurface;
|
||||
d3dSurface->container = device;
|
||||
d3dSurface->isImplicit = TRUE;
|
||||
/* Implicit surfaces are created with an refcount of 0 */
|
||||
IUnknown_Release((IUnknown *)d3dSurface);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ULONG WINAPI D3D8CB_DestroyDepthStencilSurface(IWineD3DSurface *pSurface) {
|
||||
IDirect3DSurface8Impl* surfaceParent;
|
||||
TRACE("(%p) call back\n", pSurface);
|
||||
|
||||
IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
|
||||
surfaceParent->isImplicit = FALSE;
|
||||
/* Surface had refcount of 0 GetParent addrefed to 1, so 1 Release is enough */
|
||||
return IDirect3DSurface8_Release((IDirect3DSurface8*) surfaceParent);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3D8Impl_CreateDevice(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
|
||||
DWORD BehaviourFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
IDirect3DDevice8** ppReturnedDeviceInterface) {
|
||||
|
||||
IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
|
||||
IDirect3DDevice8Impl *object = NULL;
|
||||
WINED3DPRESENT_PARAMETERS localParameters;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* Check the validity range of the adapter parameter */
|
||||
if (Adapter >= IDirect3D8Impl_GetAdapterCount(iface)) {
|
||||
*ppReturnedDeviceInterface = NULL;
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
/* Allocate the storage for the device object */
|
||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDevice8Impl));
|
||||
if (NULL == object) {
|
||||
FIXME("Allocation of memory failed\n");
|
||||
*ppReturnedDeviceInterface = NULL;
|
||||
return D3DERR_OUTOFVIDEOMEMORY;
|
||||
}
|
||||
|
||||
object->lpVtbl = &Direct3DDevice8_Vtbl;
|
||||
object->ref = 1;
|
||||
object->shader_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, INITIAL_SHADER_HANDLE_TABLE_SIZE * sizeof(shader_handle));
|
||||
object->shader_handle_table_size = INITIAL_SHADER_HANDLE_TABLE_SIZE;
|
||||
*ppReturnedDeviceInterface = (IDirect3DDevice8 *)object;
|
||||
|
||||
/* Allocate an associated WineD3DDevice object */
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr =IWineD3D_CreateDevice(This->WineD3D, Adapter, DeviceType, hFocusWindow, BehaviourFlags, &object->WineD3DDevice, (IUnknown *)object);
|
||||
|
||||
if (hr != D3D_OK) {
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
*ppReturnedDeviceInterface = NULL;
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
TRACE("(%p) : Created Device %p\n", This, object);
|
||||
|
||||
localParameters.BackBufferWidth = pPresentationParameters->BackBufferWidth;
|
||||
localParameters.BackBufferHeight = pPresentationParameters->BackBufferHeight;
|
||||
localParameters.BackBufferFormat = pPresentationParameters->BackBufferFormat;
|
||||
localParameters.BackBufferCount = pPresentationParameters->BackBufferCount;
|
||||
localParameters.MultiSampleType = pPresentationParameters->MultiSampleType;
|
||||
localParameters.MultiSampleQuality = 0; /* d3d9 only */
|
||||
localParameters.SwapEffect = pPresentationParameters->SwapEffect;
|
||||
localParameters.hDeviceWindow = pPresentationParameters->hDeviceWindow;
|
||||
localParameters.Windowed = pPresentationParameters->Windowed;
|
||||
localParameters.EnableAutoDepthStencil = pPresentationParameters->EnableAutoDepthStencil;
|
||||
localParameters.AutoDepthStencilFormat = pPresentationParameters->AutoDepthStencilFormat;
|
||||
localParameters.Flags = pPresentationParameters->Flags;
|
||||
localParameters.FullScreen_RefreshRateInHz = pPresentationParameters->FullScreen_RefreshRateInHz;
|
||||
localParameters.PresentationInterval = pPresentationParameters->FullScreen_PresentationInterval;
|
||||
|
||||
if(BehaviourFlags & D3DCREATE_MULTITHREADED) {
|
||||
IWineD3DDevice_SetMultithreaded(object->WineD3DDevice);
|
||||
}
|
||||
|
||||
hr = IWineD3DDevice_Init3D(object->WineD3DDevice, &localParameters, D3D8CB_CreateAdditionalSwapChain);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
|
||||
pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
|
||||
pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
|
||||
pPresentationParameters->BackBufferFormat = localParameters.BackBufferFormat;
|
||||
pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
|
||||
pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
|
||||
pPresentationParameters->SwapEffect = localParameters.SwapEffect;
|
||||
pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
|
||||
pPresentationParameters->Windowed = localParameters.Windowed;
|
||||
pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
|
||||
pPresentationParameters->AutoDepthStencilFormat = localParameters.AutoDepthStencilFormat;
|
||||
pPresentationParameters->Flags = localParameters.Flags;
|
||||
pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
|
||||
pPresentationParameters->FullScreen_PresentationInterval = localParameters.PresentationInterval;
|
||||
|
||||
if (hr != D3D_OK) {
|
||||
FIXME("(%p) D3D Initialization failed for WineD3DDevice %p\n", This, object->WineD3DDevice);
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
*ppReturnedDeviceInterface = NULL;
|
||||
}
|
||||
|
||||
object->declArraySize = 16;
|
||||
object->decls = HeapAlloc(GetProcessHeap(), 0, object->declArraySize * sizeof(*object->decls));
|
||||
if(!object->decls) {
|
||||
ERR("Out of memory\n");
|
||||
IWineD3DDevice_Release(object->WineD3DDevice);
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
*ppReturnedDeviceInterface = NULL;
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
const IDirect3D8Vtbl Direct3D8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3D8Impl_QueryInterface,
|
||||
IDirect3D8Impl_AddRef,
|
||||
IDirect3D8Impl_Release,
|
||||
/* IDirect3D8 */
|
||||
IDirect3D8Impl_RegisterSoftwareDevice,
|
||||
IDirect3D8Impl_GetAdapterCount,
|
||||
IDirect3D8Impl_GetAdapterIdentifier,
|
||||
IDirect3D8Impl_GetAdapterModeCount,
|
||||
IDirect3D8Impl_EnumAdapterModes,
|
||||
IDirect3D8Impl_GetAdapterDisplayMode,
|
||||
IDirect3D8Impl_CheckDeviceType,
|
||||
IDirect3D8Impl_CheckDeviceFormat,
|
||||
IDirect3D8Impl_CheckDeviceMultiSampleType,
|
||||
IDirect3D8Impl_CheckDepthStencilMatch,
|
||||
IDirect3D8Impl_GetDeviceCaps,
|
||||
IDirect3D8Impl_GetAdapterMonitor,
|
||||
IDirect3D8Impl_CreateDevice
|
||||
};
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* IDirect3DIndexBuffer8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DIndexBuffer8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_QueryInterface(LPDIRECT3DINDEXBUFFER8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DIndexBuffer8Impl_AddRef(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DIndexBuffer8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXBUFFER8 iface, REFGUID refguid) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8 iface, DWORD PriorityNew) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
D3DRESOURCETYPE type;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
type = IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* IDirect3DIndexBuffer8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 iface) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 iface, D3DINDEXBUFFER_DESC *pDesc) {
|
||||
IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
const IDirect3DIndexBuffer8Vtbl Direct3DIndexBuffer8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DIndexBuffer8Impl_QueryInterface,
|
||||
IDirect3DIndexBuffer8Impl_AddRef,
|
||||
IDirect3DIndexBuffer8Impl_Release,
|
||||
/* IDirect3DResource8 */
|
||||
IDirect3DIndexBuffer8Impl_GetDevice,
|
||||
IDirect3DIndexBuffer8Impl_SetPrivateData,
|
||||
IDirect3DIndexBuffer8Impl_GetPrivateData,
|
||||
IDirect3DIndexBuffer8Impl_FreePrivateData,
|
||||
IDirect3DIndexBuffer8Impl_SetPriority,
|
||||
IDirect3DIndexBuffer8Impl_GetPriority,
|
||||
IDirect3DIndexBuffer8Impl_PreLoad,
|
||||
IDirect3DIndexBuffer8Impl_GetType,
|
||||
/* IDirect3DIndexBuffer8 */
|
||||
IDirect3DIndexBuffer8Impl_Lock,
|
||||
IDirect3DIndexBuffer8Impl_Unlock,
|
||||
IDirect3DIndexBuffer8Impl_GetDesc
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* IDirect3DPixelShader8 implementation
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Raphael Junqueira
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DPixelShader8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DPixelShader8Impl_QueryInterface(IDirect3DPixelShader8 *iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DPixelShader8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DPixelShader8Impl_AddRef(IDirect3DPixelShader8 *iface) {
|
||||
IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DPixelShader8Impl_Release(IDirect3DPixelShader8 * iface) {
|
||||
IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DPixelShader_Release(This->wineD3DPixelShader);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DPixelShader8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DPixelShader8Impl_GetDevice(IDirect3DPixelShader8 *iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface;
|
||||
IWineD3DDevice *myDevice = NULL;
|
||||
|
||||
TRACE("(%p) : Relay\n", This);
|
||||
|
||||
IWineD3DPixelShader_GetDevice(This->wineD3DPixelShader, &myDevice);
|
||||
IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
|
||||
IWineD3DDevice_Release(myDevice);
|
||||
TRACE("(%p) returning (%p)\n", This, *ppDevice);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DPixelShader8Impl_GetFunction(IDirect3DPixelShader8 *iface, VOID *pData, UINT *pSizeOfData) {
|
||||
IDirect3DPixelShader8Impl *This = (IDirect3DPixelShader8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DPixelShader_GetFunction(This->wineD3DPixelShader, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
|
||||
const IDirect3DPixelShader8Vtbl Direct3DPixelShader8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DPixelShader8Impl_QueryInterface,
|
||||
IDirect3DPixelShader8Impl_AddRef,
|
||||
IDirect3DPixelShader8Impl_Release,
|
||||
/* IDirect3DPixelShader8 */
|
||||
IDirect3DPixelShader8Impl_GetDevice,
|
||||
IDirect3DPixelShader8Impl_GetFunction
|
||||
};
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* IDirect3DResource8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DResource8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DResource8Impl_QueryInterface(LPDIRECT3DRESOURCE8 iface, REFIID riid, LPVOID* ppobj) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DResource8Impl_AddRef(LPDIRECT3DRESOURCE8 iface) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DResource8Impl_Release(LPDIRECT3DRESOURCE8 iface) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DResource_Release(This->wineD3DResource);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DResource8 Interface follow: */
|
||||
HRESULT WINAPI IDirect3DResource8Impl_GetDevice(LPDIRECT3DRESOURCE8 iface, IDirect3DDevice8** ppDevice) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
IWineD3DDevice *myDevice = NULL;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
IWineD3DResource_GetDevice(This->wineD3DResource, &myDevice);
|
||||
IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
|
||||
IWineD3DDevice_Release(myDevice);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DResource8Impl_SetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_SetPrivateData(This->wineD3DResource, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DResource8Impl_GetPrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_GetPrivateData(This->wineD3DResource, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DResource8Impl_FreePrivateData(LPDIRECT3DRESOURCE8 iface, REFGUID refguid) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_FreePrivateData(This->wineD3DResource, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DResource8Impl_SetPriority(LPDIRECT3DRESOURCE8 iface, DWORD PriorityNew) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_SetPriority(This->wineD3DResource, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DResource8Impl_GetPriority(LPDIRECT3DRESOURCE8 iface) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_GetPriority(This->wineD3DResource);
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DResource8Impl_PreLoad(LPDIRECT3DRESOURCE8 iface) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
IWineD3DResource_PreLoad(This->wineD3DResource);
|
||||
return;
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DResource8Impl_GetType(LPDIRECT3DRESOURCE8 iface) {
|
||||
IDirect3DResource8Impl *This = (IDirect3DResource8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DResource_GetType(This->wineD3DResource);
|
||||
}
|
||||
|
||||
const IDirect3DResource8Vtbl Direct3DResource8_Vtbl =
|
||||
{
|
||||
IDirect3DResource8Impl_QueryInterface,
|
||||
IDirect3DResource8Impl_AddRef,
|
||||
IDirect3DResource8Impl_Release,
|
||||
IDirect3DResource8Impl_GetDevice,
|
||||
IDirect3DResource8Impl_SetPrivateData,
|
||||
IDirect3DResource8Impl_GetPrivateData,
|
||||
IDirect3DResource8Impl_FreePrivateData,
|
||||
IDirect3DResource8Impl_SetPriority,
|
||||
IDirect3DResource8Impl_GetPriority,
|
||||
IDirect3DResource8Impl_PreLoad,
|
||||
IDirect3DResource8Impl_GetType
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* IDirect3DStateBlock8 implementation
|
||||
*
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* NOTE: DirectX8 doesn't export a IDirect3DStateBlock8, the interface is used internally to keep d3d8 and d3d9 as simila as possible */
|
||||
/* IDirect3DStateBlock8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DStateBlock8Impl_QueryInterface(IDirect3DStateBlock8 *iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DStateBlock8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DStateBlock8Impl_AddRef(IDirect3DStateBlock8 *iface) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IWineD3DStateBlock_Release(This->wineD3DStateBlock);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DStateBlock8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *iface) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface) {
|
||||
IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
return IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
|
||||
}
|
||||
|
||||
const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DStateBlock8Impl_QueryInterface,
|
||||
IDirect3DStateBlock8Impl_AddRef,
|
||||
IDirect3DStateBlock8Impl_Release,
|
||||
/* IDirect3DStateBlock8 */
|
||||
IDirect3DStateBlock8Impl_GetDevice,
|
||||
IDirect3DStateBlock8Impl_Capture,
|
||||
IDirect3DStateBlock8Impl_Apply
|
||||
};
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* IDirect3DSurface8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DSurface8 IUnknown parts follow: */
|
||||
static 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)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DSurface8Impl_AddRef(LPDIRECT3DSURFACE8 iface) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (This->forwardReference) {
|
||||
/* Forward refcounting */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_AddRef(This->forwardReference);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
if(ref == 1 && This->parentDevice) IUnknown_AddRef(This->parentDevice);
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DSurface8Impl_Release(LPDIRECT3DSURFACE8 iface) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (This->forwardReference) {
|
||||
/* Forward refcounting */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_Release(This->forwardReference);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
if (This->parentDevice) IUnknown_Release(This->parentDevice);
|
||||
/* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
|
||||
if (!This->isImplicit) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DSurface_Release(This->wineD3DSurface);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
/* IDirect3DSurface8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_GetDevice(LPDIRECT3DSURFACE8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p)->(%p)\n", This, ppDevice);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_SetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSurface_SetPrivateData(This->wineD3DSurface, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_GetPrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSurface_GetPrivateData(This->wineD3DSurface, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_FreePrivateData(LPDIRECT3DSURFACE8 iface, REFGUID refguid) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSurface_FreePrivateData(This->wineD3DSurface, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* IDirect3DSurface8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_GetContainer(LPDIRECT3DSURFACE8 iface, REFIID riid, void **ppContainer) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
if (!This->container) return E_NOINTERFACE;
|
||||
|
||||
res = IUnknown_QueryInterface(This->container, riid, ppContainer);
|
||||
|
||||
TRACE("(%p) : returning %p\n", This, *ppContainer);
|
||||
return res;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_GetDesc(LPDIRECT3DSURFACE8 iface, D3DSURFACE_DESC *pDesc) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
WINED3DSURFACE_DESC wined3ddesc;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
|
||||
memset(&wined3ddesc, 0, sizeof(wined3ddesc));
|
||||
wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
|
||||
wined3ddesc.Type = (WINED3DRESOURCETYPE *)&pDesc->Type;
|
||||
wined3ddesc.Usage = &pDesc->Usage;
|
||||
wined3ddesc.Pool = (WINED3DPOOL *) &pDesc->Pool;
|
||||
wined3ddesc.Size = &pDesc->Size;
|
||||
wined3ddesc.MultiSampleType = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
|
||||
wined3ddesc.Width = &pDesc->Width;
|
||||
wined3ddesc.Height = &pDesc->Height;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSurface_GetDesc(This->wineD3DSurface, &wined3ddesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_LockRect(LPDIRECT3DSURFACE8 iface, D3DLOCKED_RECT *pLockedRect, CONST RECT *pRect, DWORD Flags) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
TRACE("(%p) calling IWineD3DSurface_LockRect %p %p %p %d\n", This, This->wineD3DSurface, pLockedRect, pRect, Flags);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
if (pRect) {
|
||||
D3DSURFACE_DESC desc;
|
||||
IDirect3DSurface8_GetDesc(iface, &desc);
|
||||
|
||||
if ((pRect->left < 0)
|
||||
|| (pRect->top < 0)
|
||||
|| (pRect->left >= pRect->right)
|
||||
|| (pRect->top >= pRect->bottom)
|
||||
|| (pRect->right > desc.Width)
|
||||
|| (pRect->bottom > desc.Height)) {
|
||||
WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
}
|
||||
|
||||
hr = IWineD3DSurface_LockRect(This->wineD3DSurface, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSurface8Impl_UnlockRect(LPDIRECT3DSURFACE8 iface) {
|
||||
IDirect3DSurface8Impl *This = (IDirect3DSurface8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSurface_UnlockRect(This->wineD3DSurface);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* IDirect3DSwapChain8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DSwapChain IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DSwapChain8Impl_QueryInterface(LPDIRECT3DSWAPCHAIN8 iface, REFIID riid, LPVOID* ppobj)
|
||||
{
|
||||
IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DSwapChain8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DSwapChain8Impl_AddRef(LPDIRECT3DSWAPCHAIN8 iface) {
|
||||
IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DSwapChain8Impl_Release(LPDIRECT3DSWAPCHAIN8 iface) {
|
||||
IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DSwapChain_Destroy(This->wineD3DSwapChain, D3D8CB_DestroyRenderTarget);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
if (This->parentDevice) IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DSwapChain8 parts follow: */
|
||||
static HRESULT WINAPI IDirect3DSwapChain8Impl_Present(LPDIRECT3DSWAPCHAIN8 iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion) {
|
||||
IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DSwapChain_Present(This->wineD3DSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DSwapChain8Impl_GetBackBuffer(LPDIRECT3DSWAPCHAIN8 iface, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface8** ppBackBuffer) {
|
||||
IDirect3DSwapChain8Impl *This = (IDirect3DSwapChain8Impl *)iface;
|
||||
HRESULT hrc = D3D_OK;
|
||||
IWineD3DSurface *mySurface = NULL;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hrc = IWineD3DSwapChain_GetBackBuffer(This->wineD3DSwapChain, iBackBuffer, (WINED3DBACKBUFFER_TYPE )Type, &mySurface);
|
||||
if (hrc == D3D_OK && NULL != mySurface) {
|
||||
IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppBackBuffer);
|
||||
IWineD3DSurface_Release(mySurface);
|
||||
}
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
const IDirect3DSwapChain8Vtbl Direct3DSwapChain8_Vtbl =
|
||||
{
|
||||
IDirect3DSwapChain8Impl_QueryInterface,
|
||||
IDirect3DSwapChain8Impl_AddRef,
|
||||
IDirect3DSwapChain8Impl_Release,
|
||||
IDirect3DSwapChain8Impl_Present,
|
||||
IDirect3DSwapChain8Impl_GetBackBuffer
|
||||
};
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* IDirect3DTexture8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DTexture8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_QueryInterface(LPDIRECT3DTEXTURE8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DTexture8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p) not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DTexture8Impl_AddRef(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DTexture8Impl_Release(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DTexture_Destroy(This->wineD3DTexture, D3D8CB_DestroySurface);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DTexture8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_GetDevice(LPDIRECT3DTEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_SetPrivateData(LPDIRECT3DTEXTURE8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_SetPrivateData(This->wineD3DTexture, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_GetPrivateData(LPDIRECT3DTEXTURE8 iface, REFGUID refguid, void *pData, DWORD* pSizeOfData) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_GetPrivateData(This->wineD3DTexture, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_FreePrivateData(LPDIRECT3DTEXTURE8 iface, REFGUID refguid) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_FreePrivateData(This->wineD3DTexture, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DTexture8Impl_SetPriority(LPDIRECT3DTEXTURE8 iface, DWORD PriorityNew) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DTexture_SetPriority(This->wineD3DTexture, PriorityNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DTexture8Impl_GetPriority(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DTexture_GetPriority(This->wineD3DTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DTexture8Impl_PreLoad(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DTexture_PreLoad(This->wineD3DTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DTexture8Impl_GetType(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
D3DRESOURCETYPE type;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
type = IWineD3DTexture_GetType(This->wineD3DTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* IDirect3DTexture8 IDirect3DBaseTexture8 Interface follow: */
|
||||
static DWORD WINAPI IDirect3DTexture8Impl_SetLOD(LPDIRECT3DTEXTURE8 iface, DWORD LODNew) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DTexture_SetLOD(This->wineD3DTexture, LODNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DTexture8Impl_GetLOD(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DTexture_GetLOD(This->wineD3DTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DTexture8Impl_GetLevelCount(LPDIRECT3DTEXTURE8 iface) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DTexture_GetLevelCount(This->wineD3DTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* IDirect3DTexture8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_GetLevelDesc(LPDIRECT3DTEXTURE8 iface, UINT Level, D3DSURFACE_DESC *pDesc) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
|
||||
WINED3DSURFACE_DESC wined3ddesc;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
|
||||
memset(&wined3ddesc, 0, sizeof(wined3ddesc));
|
||||
wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
|
||||
wined3ddesc.Type = (WINED3DRESOURCETYPE *)&pDesc->Type;
|
||||
wined3ddesc.Usage = &pDesc->Usage;
|
||||
wined3ddesc.Pool = (WINED3DPOOL *) &pDesc->Pool;
|
||||
wined3ddesc.Size = &pDesc->Size;
|
||||
wined3ddesc.MultiSampleType = (WINED3DMULTISAMPLE_TYPE *) &pDesc->MultiSampleType;
|
||||
wined3ddesc.Width = &pDesc->Width;
|
||||
wined3ddesc.Height = &pDesc->Height;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_GetLevelDesc(This->wineD3DTexture, Level, &wined3ddesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_GetSurfaceLevel(LPDIRECT3DTEXTURE8 iface, UINT Level, IDirect3DSurface8 **ppSurfaceLevel) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hrc = D3D_OK;
|
||||
IWineD3DSurface *mySurface = NULL;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hrc = IWineD3DTexture_GetSurfaceLevel(This->wineD3DTexture, Level, &mySurface);
|
||||
if (hrc == D3D_OK && NULL != ppSurfaceLevel) {
|
||||
IWineD3DSurface_GetParent(mySurface, (IUnknown **)ppSurfaceLevel);
|
||||
IWineD3DSurface_Release(mySurface);
|
||||
}
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_LockRect(LPDIRECT3DTEXTURE8 iface, UINT Level, D3DLOCKED_RECT *pLockedRect, CONST RECT *pRect, DWORD Flags) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_LockRect(This->wineD3DTexture, Level, (WINED3DLOCKED_RECT *) pLockedRect, pRect, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_UnlockRect(LPDIRECT3DTEXTURE8 iface, UINT Level) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_UnlockRect(This->wineD3DTexture, Level);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DTexture8Impl_AddDirtyRect(LPDIRECT3DTEXTURE8 iface, CONST RECT *pDirtyRect) {
|
||||
IDirect3DTexture8Impl *This = (IDirect3DTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DTexture_AddDirtyRect(This->wineD3DTexture, pDirtyRect);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DTexture8Impl_QueryInterface,
|
||||
IDirect3DTexture8Impl_AddRef,
|
||||
IDirect3DTexture8Impl_Release,
|
||||
/* IDirect3DResource8 */
|
||||
IDirect3DTexture8Impl_GetDevice,
|
||||
IDirect3DTexture8Impl_SetPrivateData,
|
||||
IDirect3DTexture8Impl_GetPrivateData,
|
||||
IDirect3DTexture8Impl_FreePrivateData,
|
||||
IDirect3DTexture8Impl_SetPriority,
|
||||
IDirect3DTexture8Impl_GetPriority,
|
||||
IDirect3DTexture8Impl_PreLoad,
|
||||
IDirect3DTexture8Impl_GetType,
|
||||
/* IDirect3dBaseTexture8 */
|
||||
IDirect3DTexture8Impl_SetLOD,
|
||||
IDirect3DTexture8Impl_GetLOD,
|
||||
IDirect3DTexture8Impl_GetLevelCount,
|
||||
/* IDirect3DTexture8 */
|
||||
IDirect3DTexture8Impl_GetLevelDesc,
|
||||
IDirect3DTexture8Impl_GetSurfaceLevel,
|
||||
IDirect3DTexture8Impl_LockRect,
|
||||
IDirect3DTexture8Impl_UnlockRect,
|
||||
IDirect3DTexture8Impl_AddDirtyRect
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2001 Ove Kaaven
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine Direct3D"
|
||||
#define WINE_FILENAME_STR "d3d8.dll"
|
||||
#define WINE_FILEVERSION 5,3,1,904
|
||||
#define WINE_FILEVERSION_STR "5.3.1.904"
|
||||
#define WINE_PRODUCTVERSION 5,3,1,904
|
||||
#define WINE_PRODUCTVERSION_STR "5.3.1.904"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* IDirect3DVertexBuffer8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DVertexBuffer8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_QueryInterface(LPDIRECT3DVERTEXBUFFER8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexBuffer8Impl_AddRef(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexBuffer8Impl_Release(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DVertexBuffer8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDevice(LPDIRECT3DVERTEXBUFFER8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_FreePrivateData(LPDIRECT3DVERTEXBUFFER8 iface, REFGUID refguid) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVertexBuffer8Impl_SetPriority(LPDIRECT3DVERTEXBUFFER8 iface, DWORD PriorityNew) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVertexBuffer8Impl_GetPriority(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
D3DRESOURCETYPE type;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
type = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* IDirect3DVertexBuffer8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Lock(LPDIRECT3DVERTEXBUFFER8 iface, UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8 iface) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 iface, D3DVERTEXBUFFER_DESC *pDesc) {
|
||||
IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DVertexBuffer8Impl_QueryInterface,
|
||||
IDirect3DVertexBuffer8Impl_AddRef,
|
||||
IDirect3DVertexBuffer8Impl_Release,
|
||||
/* IDirect3DResource8 */
|
||||
IDirect3DVertexBuffer8Impl_GetDevice,
|
||||
IDirect3DVertexBuffer8Impl_SetPrivateData,
|
||||
IDirect3DVertexBuffer8Impl_GetPrivateData,
|
||||
IDirect3DVertexBuffer8Impl_FreePrivateData,
|
||||
IDirect3DVertexBuffer8Impl_SetPriority,
|
||||
IDirect3DVertexBuffer8Impl_GetPriority,
|
||||
IDirect3DVertexBuffer8Impl_PreLoad,
|
||||
IDirect3DVertexBuffer8Impl_GetType,
|
||||
/* IDirect3DVertexBuffer8 */
|
||||
IDirect3DVertexBuffer8Impl_Lock,
|
||||
IDirect3DVertexBuffer8Impl_Unlock,
|
||||
IDirect3DVertexBuffer8Impl_GetDesc
|
||||
};
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* IDirect3DVertexDeclaration8 implementation
|
||||
*
|
||||
* Copyright 2007 Henri Verbeet
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* IDirect3DVertexDeclaration8 is internal to our implementation.
|
||||
* It's not visible in the API. */
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IUnknown */
|
||||
static HRESULT WINAPI IDirect3DVertexDeclaration8Impl_QueryInterface(IDirect3DVertexDeclaration8 *iface, REFIID riid, void **obj_ptr)
|
||||
{
|
||||
TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), obj_ptr);
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DVertexDeclaration8))
|
||||
{
|
||||
IUnknown_AddRef(iface);
|
||||
*obj_ptr = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*obj_ptr = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexDeclaration8Impl_AddRef(IDirect3DVertexDeclaration8 *iface)
|
||||
{
|
||||
IDirect3DVertexDeclaration8Impl *This = (IDirect3DVertexDeclaration8Impl *)iface;
|
||||
|
||||
ULONG ref_count = InterlockedIncrement(&This->ref_count);
|
||||
TRACE("(%p) : AddRef increasing to %d\n", This, ref_count);
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexDeclaration8Impl_Release(IDirect3DVertexDeclaration8 *iface)
|
||||
{
|
||||
IDirect3DVertexDeclaration8Impl *This = (IDirect3DVertexDeclaration8Impl *)iface;
|
||||
|
||||
ULONG ref_count = InterlockedDecrement(&This->ref_count);
|
||||
TRACE("(%p) : Releasing to %d\n", This, ref_count);
|
||||
|
||||
if (!ref_count) {
|
||||
IWineD3DVertexDeclaration_Release(This->wined3d_vertex_declaration);
|
||||
HeapFree(GetProcessHeap(), 0, This->elements);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
static const char *debug_d3dvsdt_type(D3DVSDT_TYPE d3dvsdt_type)
|
||||
{
|
||||
switch (d3dvsdt_type)
|
||||
{
|
||||
#define D3DVSDT_TYPE_TO_STR(u) case u: return #u
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT1);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT2);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT3);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT4);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_D3DCOLOR);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_UBYTE4);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT2);
|
||||
D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT4);
|
||||
#undef D3DVSDT_TYPE_TO_STR
|
||||
default:
|
||||
FIXME("Unrecognized D3DVSDT_TYPE %#x\n", d3dvsdt_type);
|
||||
return "unrecognized";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *debug_d3dvsde_register(D3DVSDE_REGISTER d3dvsde_register)
|
||||
{
|
||||
switch (d3dvsde_register)
|
||||
{
|
||||
#define D3DVSDE_REGISTER_TO_STR(u) case u: return #u
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDWEIGHT);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDINDICES);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_PSIZE);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_DIFFUSE);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_SPECULAR);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD0);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD1);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD2);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD3);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD4);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD5);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD6);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD7);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION2);
|
||||
D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL2);
|
||||
#undef D3DVSDE_REGISTER_TO_STR
|
||||
default:
|
||||
FIXME("Unrecognized D3DVSDE_REGISTER %#x\n", d3dvsde_register);
|
||||
return "unrecognized";
|
||||
}
|
||||
}
|
||||
|
||||
static size_t parse_token(const DWORD* pToken)
|
||||
{
|
||||
const DWORD token = *pToken;
|
||||
size_t tokenlen = 1;
|
||||
|
||||
switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
|
||||
case D3DVSD_TOKEN_NOP:
|
||||
TRACE(" 0x%08x NOP()\n", token);
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_STREAM:
|
||||
if (token & D3DVSD_STREAMTESSMASK)
|
||||
{
|
||||
TRACE(" 0x%08x STREAM_TESS()\n", token);
|
||||
} else {
|
||||
TRACE(" 0x%08x STREAM(%u)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_STREAMDATA:
|
||||
if (token & 0x10000000)
|
||||
{
|
||||
TRACE(" 0x%08x SKIP(%u)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
|
||||
} else {
|
||||
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
|
||||
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
|
||||
TRACE(" 0x%08x REG(%s, %s)\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_TESSELLATOR:
|
||||
if (token & 0x10000000)
|
||||
{
|
||||
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
|
||||
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
|
||||
TRACE(" 0x%08x TESSUV(%s) as %s\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
|
||||
} else {
|
||||
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
|
||||
DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
|
||||
DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
|
||||
TRACE(" 0x%08x TESSNORMAL(%s, %s) as %s\n", token, debug_d3dvsde_register(regin),
|
||||
debug_d3dvsde_register(regout), debug_d3dvsdt_type(type));
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_CONSTMEM:
|
||||
{
|
||||
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
|
||||
tokenlen = (4 * count) + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_EXT:
|
||||
{
|
||||
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
|
||||
DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT);
|
||||
TRACE(" 0x%08x EXT(%u, %u)\n", token, count, extinfo);
|
||||
/* todo ... print extension */
|
||||
tokenlen = count + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DVSD_TOKEN_END:
|
||||
TRACE(" 0x%08x END()\n", token);
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE(" 0x%08x UNKNOWN\n", token);
|
||||
/* argg error */
|
||||
}
|
||||
|
||||
return tokenlen;
|
||||
}
|
||||
|
||||
void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader)
|
||||
{
|
||||
const DWORD *token = d3d8_elements;
|
||||
|
||||
while (*token != D3DVSD_END())
|
||||
{
|
||||
if (((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) == D3DVSD_TOKEN_CONSTMEM)
|
||||
{
|
||||
DWORD count = ((*token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
|
||||
DWORD constant_idx = ((*token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
|
||||
HRESULT hr;
|
||||
|
||||
if (TRACE_ON(d3d8))
|
||||
{
|
||||
DWORD i;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
TRACE("c[%u] = (%8f, %8f, %8f, %8f)\n",
|
||||
constant_idx,
|
||||
*(const float *)(token + i * 4 + 1),
|
||||
*(const float *)(token + i * 4 + 2),
|
||||
*(const float *)(token + i * 4 + 3),
|
||||
*(const float *)(token + i * 4 + 4));
|
||||
}
|
||||
}
|
||||
hr = IWineD3DVertexShader_SetLocalConstantsF(wined3d_vertex_shader, constant_idx, (const float *)token+1, count);
|
||||
if (FAILED(hr)) ERR("Failed setting shader constants\n");
|
||||
}
|
||||
|
||||
token += parse_token(token);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: Make sure these are in the correct numerical order. (see /include/wined3d_types.h) */
|
||||
static const size_t wined3d_type_sizes[WINED3DDECLTYPE_UNUSED] = {
|
||||
/*WINED3DDECLTYPE_FLOAT1*/ 1 * sizeof(float),
|
||||
/*WINED3DDECLTYPE_FLOAT2*/ 2 * sizeof(float),
|
||||
/*WINED3DDECLTYPE_FLOAT3*/ 3 * sizeof(float),
|
||||
/*WINED3DDECLTYPE_FLOAT4*/ 4 * sizeof(float),
|
||||
/*WINED3DDECLTYPE_D3DCOLOR*/ 4 * sizeof(BYTE),
|
||||
/*WINED3DDECLTYPE_UBYTE4*/ 4 * sizeof(BYTE),
|
||||
/*WINED3DDECLTYPE_SHORT2*/ 2 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_SHORT4*/ 4 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_UBYTE4N*/ 4 * sizeof(BYTE),
|
||||
/*WINED3DDECLTYPE_SHORT2N*/ 2 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_SHORT4N*/ 4 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_USHORT2N*/ 2 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_USHORT4N*/ 4 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_UDEC3*/ 3 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_DEC3N*/ 3 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_FLOAT16_2*/ 2 * sizeof(short int),
|
||||
/*WINED3DDECLTYPE_FLOAT16_4*/ 4 * sizeof(short int)
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
BYTE usage;
|
||||
BYTE usage_idx;
|
||||
} wined3d_usage_t;
|
||||
|
||||
static const wined3d_usage_t wined3d_usage_lookup[] = {
|
||||
/*D3DVSDE_POSITION*/ {WINED3DDECLUSAGE_POSITION, 0},
|
||||
/*D3DVSDE_BLENDWEIGHT*/ {WINED3DDECLUSAGE_BLENDWEIGHT, 0},
|
||||
/*D3DVSDE_BLENDINDICES*/ {WINED3DDECLUSAGE_BLENDINDICES, 0},
|
||||
/*D3DVSDE_NORMAL*/ {WINED3DDECLUSAGE_NORMAL, 0},
|
||||
/*D3DVSDE_PSIZE*/ {WINED3DDECLUSAGE_PSIZE, 0},
|
||||
/*D3DVSDE_DIFFUSE*/ {WINED3DDECLUSAGE_COLOR, 0},
|
||||
/*D3DVSDE_SPECULAR*/ {WINED3DDECLUSAGE_COLOR, 1},
|
||||
/*D3DVSDE_TEXCOORD0*/ {WINED3DDECLUSAGE_TEXCOORD, 0},
|
||||
/*D3DVSDE_TEXCOORD1*/ {WINED3DDECLUSAGE_TEXCOORD, 1},
|
||||
/*D3DVSDE_TEXCOORD2*/ {WINED3DDECLUSAGE_TEXCOORD, 2},
|
||||
/*D3DVSDE_TEXCOORD3*/ {WINED3DDECLUSAGE_TEXCOORD, 3},
|
||||
/*D3DVSDE_TEXCOORD4*/ {WINED3DDECLUSAGE_TEXCOORD, 4},
|
||||
/*D3DVSDE_TEXCOORD5*/ {WINED3DDECLUSAGE_TEXCOORD, 5},
|
||||
/*D3DVSDE_TEXCOORD6*/ {WINED3DDECLUSAGE_TEXCOORD, 6},
|
||||
/*D3DVSDE_TEXCOORD7*/ {WINED3DDECLUSAGE_TEXCOORD, 7},
|
||||
/*D3DVSDE_POSITION2*/ {WINED3DDECLUSAGE_POSITION, 1},
|
||||
/*D3DVSDE_NORMAL2*/ {WINED3DDECLUSAGE_NORMAL, 1},
|
||||
};
|
||||
|
||||
/* TODO: find out where rhw (or positionT) is for declaration8 */
|
||||
size_t convert_to_wined3d_declaration(const DWORD *d3d8_elements, DWORD *d3d8_elements_size, WINED3DVERTEXELEMENT **wined3d_elements)
|
||||
{
|
||||
const DWORD *token = d3d8_elements;
|
||||
WINED3DVERTEXELEMENT *element;
|
||||
D3DVSD_TOKENTYPE token_type;
|
||||
unsigned int element_count = 0;
|
||||
DWORD stream = 0;
|
||||
int offset = 0;
|
||||
|
||||
TRACE("d3d8_elements %p, wined3d_elements %p\n", d3d8_elements, wined3d_elements);
|
||||
|
||||
/* 128 should be enough for anyone... */
|
||||
*wined3d_elements = HeapAlloc(GetProcessHeap(), 0, 128 * sizeof(WINED3DVERTEXELEMENT));
|
||||
while (D3DVSD_END() != *token)
|
||||
{
|
||||
token_type = ((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
|
||||
|
||||
if (token_type == D3DVSD_TOKEN_STREAM && !(*token & D3DVSD_STREAMTESSMASK))
|
||||
{
|
||||
stream = ((*token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
|
||||
offset = 0;
|
||||
} else if (token_type == D3DVSD_TOKEN_STREAMDATA && !(token_type & 0x10000000)) {
|
||||
DWORD type = ((*token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
|
||||
DWORD reg = ((*token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
|
||||
|
||||
TRACE("Adding element %d:\n", element_count);
|
||||
|
||||
element = *wined3d_elements + element_count++;
|
||||
element->Stream = stream;
|
||||
element->Method = WINED3DDECLMETHOD_DEFAULT;
|
||||
element->Usage = wined3d_usage_lookup[reg].usage;
|
||||
element->UsageIndex = wined3d_usage_lookup[reg].usage_idx;
|
||||
element->Type = type;
|
||||
element->Offset = offset;
|
||||
element->Reg = reg;
|
||||
|
||||
offset += wined3d_type_sizes[type];
|
||||
} else if (token_type == D3DVSD_TOKEN_STREAMDATA && (token_type & 0x10000000)) {
|
||||
TRACE(" 0x%08x SKIP(%u)\n", token_type, ((token_type & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
|
||||
offset += sizeof(DWORD) * ((token_type & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
|
||||
}
|
||||
|
||||
if (element_count >= 127) {
|
||||
ERR("More than 127 elements?\n");
|
||||
break;
|
||||
}
|
||||
|
||||
token += parse_token(token);
|
||||
}
|
||||
|
||||
/* END */
|
||||
element = *wined3d_elements + element_count++;
|
||||
element->Stream = 0xFF;
|
||||
element->Type = WINED3DDECLTYPE_UNUSED;
|
||||
|
||||
*d3d8_elements_size = (++token - d3d8_elements) * sizeof(DWORD);
|
||||
|
||||
return element_count;
|
||||
}
|
||||
|
||||
const IDirect3DVertexDeclaration8Vtbl Direct3DVertexDeclaration8_Vtbl =
|
||||
{
|
||||
IDirect3DVertexDeclaration8Impl_QueryInterface,
|
||||
IDirect3DVertexDeclaration8Impl_AddRef,
|
||||
IDirect3DVertexDeclaration8Impl_Release
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* IDirect3DVertexShader8 implementation
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Raphael Junqueira
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DVertexShader8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DVertexShader8Impl_QueryInterface(IDirect3DVertexShader8 *iface, REFIID riid, LPVOID* ppobj) {
|
||||
IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DVertexShader8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexShader8Impl_AddRef(IDirect3DVertexShader8 *iface) {
|
||||
IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *iface) {
|
||||
IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
IDirect3DVertexDeclaration8_Release(This->vertex_declaration);
|
||||
IWineD3DVertexShader_Release(This->wineD3DVertexShader);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DVertexShader8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVertexShader8Impl_GetDevice(IDirect3DVertexShader8 *iface, IDirect3DDevice8** ppDevice) {
|
||||
IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
|
||||
IWineD3DDevice *myDevice = NULL;
|
||||
HRESULT hr = D3D_OK;
|
||||
TRACE("(%p) : Relay\n", This);
|
||||
|
||||
if (D3D_OK == (hr = IWineD3DVertexShader_GetDevice(This->wineD3DVertexShader, &myDevice) && myDevice != NULL)) {
|
||||
hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
|
||||
IWineD3DDevice_Release(myDevice);
|
||||
} else {
|
||||
*ppDevice = NULL;
|
||||
}
|
||||
TRACE("(%p) returning (%p)\n", This, *ppDevice);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVertexShader8Impl_GetFunction(IDirect3DVertexShader8 *iface, VOID* pData, UINT* pSizeOfData) {
|
||||
IDirect3DVertexShader8Impl *This = (IDirect3DVertexShader8Impl *)iface;
|
||||
|
||||
TRACE("(%p) : Relay\n", This);
|
||||
return IWineD3DVertexShader_GetFunction(This->wineD3DVertexShader, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
|
||||
const IDirect3DVertexShader8Vtbl Direct3DVertexShader8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DVertexShader8Impl_QueryInterface,
|
||||
IDirect3DVertexShader8Impl_AddRef,
|
||||
IDirect3DVertexShader8Impl_Release,
|
||||
/* IDirect3DVertexShader8 */
|
||||
IDirect3DVertexShader8Impl_GetDevice,
|
||||
IDirect3DVertexShader8Impl_GetFunction
|
||||
};
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* IDirect3DVolume8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DVolume8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_QueryInterface(LPDIRECT3DVOLUME8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DVolume8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVolume8Impl_AddRef(LPDIRECT3DVOLUME8 iface) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (This->forwardReference) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_AddRef(This->forwardReference);
|
||||
} else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVolume8Impl_Release(LPDIRECT3DVOLUME8 iface) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if (This->forwardReference) {
|
||||
/* Forward to the containerParent */
|
||||
TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference);
|
||||
return IUnknown_Release(This->forwardReference);
|
||||
}
|
||||
else {
|
||||
/* No container, handle our own refcounting */
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVolume_Release(This->wineD3DVolume);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
/* IDirect3DVolume8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_GetDevice(LPDIRECT3DVOLUME8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
IWineD3DDevice *myDevice = NULL;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVolume_GetDevice(This->wineD3DVolume, &myDevice);
|
||||
IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
|
||||
IWineD3DDevice_Release(myDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_SetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, CONST void *pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_SetPrivateData(This->wineD3DVolume, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_GetPrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid, void *pData, DWORD* pSizeOfData) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_GetPrivateData(This->wineD3DVolume, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_FreePrivateData(LPDIRECT3DVOLUME8 iface, REFGUID refguid) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_FreePrivateData(This->wineD3DVolume, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_GetContainer(LPDIRECT3DVOLUME8 iface, REFIID riid, void **ppContainer) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT res;
|
||||
|
||||
TRACE("(This %p, riid %s, ppContainer %p)\n", This, debugstr_guid(riid), ppContainer);
|
||||
|
||||
if (!This->container) return E_NOINTERFACE;
|
||||
|
||||
if (!ppContainer) {
|
||||
ERR("Called without a valid ppContainer.\n");
|
||||
}
|
||||
|
||||
res = IUnknown_QueryInterface(This->container, riid, ppContainer);
|
||||
|
||||
TRACE("Returning ppContainer %p, *ppContainer %p\n", ppContainer, *ppContainer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_GetDesc(LPDIRECT3DVOLUME8 iface, D3DVOLUME_DESC *pDesc) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
WINED3DVOLUME_DESC wined3ddesc;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* As d3d8 and d3d9 structures differ, pass in ptrs to where data needs to go */
|
||||
wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
|
||||
wined3ddesc.Type = (WINED3DRESOURCETYPE *)&pDesc->Type;
|
||||
wined3ddesc.Usage = &pDesc->Usage;
|
||||
wined3ddesc.Pool = (WINED3DPOOL *) &pDesc->Pool;
|
||||
wined3ddesc.Size = &pDesc->Size;
|
||||
wined3ddesc.Width = &pDesc->Width;
|
||||
wined3ddesc.Height = &pDesc->Height;
|
||||
wined3ddesc.Depth = &pDesc->Depth;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_GetDesc(This->wineD3DVolume, &wined3ddesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_LockBox(LPDIRECT3DVOLUME8 iface, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox, DWORD Flags) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) relay %p %p %p %d\n", This, This->wineD3DVolume, pLockedVolume, pBox, Flags);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_LockBox(This->wineD3DVolume, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolume8Impl_UnlockBox(LPDIRECT3DVOLUME8 iface) {
|
||||
IDirect3DVolume8Impl *This = (IDirect3DVolume8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) relay %p\n", This, This->wineD3DVolume);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolume_UnlockBox(This->wineD3DVolume);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const IDirect3DVolume8Vtbl Direct3DVolume8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DVolume8Impl_QueryInterface,
|
||||
IDirect3DVolume8Impl_AddRef,
|
||||
IDirect3DVolume8Impl_Release,
|
||||
/* IDirect3DVolume8 */
|
||||
IDirect3DVolume8Impl_GetDevice,
|
||||
IDirect3DVolume8Impl_SetPrivateData,
|
||||
IDirect3DVolume8Impl_GetPrivateData,
|
||||
IDirect3DVolume8Impl_FreePrivateData,
|
||||
IDirect3DVolume8Impl_GetContainer,
|
||||
IDirect3DVolume8Impl_GetDesc,
|
||||
IDirect3DVolume8Impl_LockBox,
|
||||
IDirect3DVolume8Impl_UnlockBox
|
||||
};
|
||||
|
||||
|
||||
/* Internal function called back during the CreateVolumeTexture */
|
||||
HRESULT WINAPI D3D8CB_CreateVolume(IUnknown *pDevice, IUnknown *pSuperior, UINT Width, UINT Height, UINT Depth,
|
||||
WINED3DFORMAT Format, WINED3DPOOL Pool, DWORD Usage,
|
||||
IWineD3DVolume **ppVolume,
|
||||
HANDLE * pSharedHandle) {
|
||||
IDirect3DVolume8Impl *object;
|
||||
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)pDevice;
|
||||
HRESULT hrc = D3D_OK;
|
||||
|
||||
/* Allocate the storage for the device */
|
||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVolume8Impl));
|
||||
if (NULL == object) {
|
||||
FIXME("Allocation of memory failed\n");
|
||||
*ppVolume = NULL;
|
||||
return D3DERR_OUTOFVIDEOMEMORY;
|
||||
}
|
||||
|
||||
object->lpVtbl = &Direct3DVolume8_Vtbl;
|
||||
object->ref = 1;
|
||||
hrc = IWineD3DDevice_CreateVolume(This->WineD3DDevice, Width, Height, Depth, Usage, Format,
|
||||
Pool, &object->wineD3DVolume, pSharedHandle, (IUnknown *)object);
|
||||
if (hrc != D3D_OK) {
|
||||
/* free up object */
|
||||
FIXME("(%p) call to IWineD3DDevice_CreateVolume failed\n", This);
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
*ppVolume = NULL;
|
||||
} else {
|
||||
*ppVolume = (IWineD3DVolume *)object->wineD3DVolume;
|
||||
object->container = pSuperior;
|
||||
object->forwardReference = pSuperior;
|
||||
}
|
||||
TRACE("(%p) Created volume %p\n", This, *ppVolume);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
ULONG WINAPI D3D8CB_DestroyVolume(IWineD3DVolume *pVolume) {
|
||||
IDirect3DVolume8Impl* volumeParent;
|
||||
|
||||
IWineD3DVolume_GetParent(pVolume, (IUnknown **) &volumeParent);
|
||||
/* GetParent's AddRef was forwarded to an object in destruction.
|
||||
* Releasing it here again would cause an endless recursion. */
|
||||
volumeParent->forwardReference = NULL;
|
||||
return IDirect3DVolume8_Release((IDirect3DVolume8*) volumeParent);
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* IDirect3DVolumeTexture8 implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "d3d8_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
|
||||
|
||||
/* IDirect3DVolumeTexture8 IUnknown parts follow: */
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_QueryInterface(LPDIRECT3DVOLUMETEXTURE8 iface, REFIID riid, LPVOID *ppobj) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DResource8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
|
||||
|| IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVolumeTexture8Impl_AddRef(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : AddRef from %d\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirect3DVolumeTexture8Impl_Release(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVolumeTexture_Destroy(This->wineD3DVolumeTexture, D3D8CB_DestroyVolume);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
IUnknown_Release(This->parentDevice);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* IDirect3DVolumeTexture8 IDirect3DResource8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetDevice(LPDIRECT3DVOLUMETEXTURE8 iface, IDirect3DDevice8 **ppDevice) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_SetPrivateData(LPDIRECT3DVOLUMETEXTURE8 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_SetPrivateData(This->wineD3DVolumeTexture, refguid, pData, SizeOfData, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetPrivateData(LPDIRECT3DVOLUMETEXTURE8 iface, REFGUID refguid, void *pData, DWORD *pSizeOfData) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_GetPrivateData(This->wineD3DVolumeTexture, refguid, pData, pSizeOfData);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_FreePrivateData(LPDIRECT3DVOLUMETEXTURE8 iface, REFGUID refguid) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_FreePrivateData(This->wineD3DVolumeTexture, refguid);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetPriority(LPDIRECT3DVOLUMETEXTURE8 iface, DWORD PriorityNew) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVolumeTexture_SetPriority(This->wineD3DVolumeTexture, PriorityNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetPriority(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVolumeTexture_GetPriority(This->wineD3DVolumeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void WINAPI IDirect3DVolumeTexture8Impl_PreLoad(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
IWineD3DVolumeTexture_PreLoad(This->wineD3DVolumeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
}
|
||||
|
||||
static D3DRESOURCETYPE WINAPI IDirect3DVolumeTexture8Impl_GetType(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
D3DRESOURCETYPE type;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
type = IWineD3DVolumeTexture_GetType(This->wineD3DVolumeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* IDirect3DVolumeTexture8 IDirect3DBaseTexture8 Interface follow: */
|
||||
static DWORD WINAPI IDirect3DVolumeTexture8Impl_SetLOD(LPDIRECT3DVOLUMETEXTURE8 iface, DWORD LODNew) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVolumeTexture_SetLOD(This->wineD3DVolumeTexture, LODNew);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLOD(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVolumeTexture_GetLOD(This->wineD3DVolumeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirect3DVolumeTexture8Impl_GetLevelCount(LPDIRECT3DVOLUMETEXTURE8 iface) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
DWORD ret;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
ret = IWineD3DVolumeTexture_GetLevelCount(This->wineD3DVolumeTexture);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* IDirect3DVolumeTexture8 Interface follow: */
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetLevelDesc(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level, D3DVOLUME_DESC* pDesc) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
WINED3DVOLUME_DESC wined3ddesc;
|
||||
UINT tmpInt = -1;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
/* As d3d8 and d3d8 structures differ, pass in ptrs to where data needs to go */
|
||||
wined3ddesc.Format = (WINED3DFORMAT *)&pDesc->Format;
|
||||
wined3ddesc.Type = (WINED3DRESOURCETYPE *)&pDesc->Type;
|
||||
wined3ddesc.Usage = &pDesc->Usage;
|
||||
wined3ddesc.Pool = (WINED3DPOOL *) &pDesc->Pool;
|
||||
wined3ddesc.Size = &tmpInt;
|
||||
wined3ddesc.Width = &pDesc->Width;
|
||||
wined3ddesc.Height = &pDesc->Height;
|
||||
wined3ddesc.Depth = &pDesc->Depth;
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_GetLevelDesc(This->wineD3DVolumeTexture, Level, &wined3ddesc);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_GetVolumeLevel(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level, IDirect3DVolume8 **ppVolumeLevel) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hrc = D3D_OK;
|
||||
IWineD3DVolume *myVolume = NULL;
|
||||
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hrc = IWineD3DVolumeTexture_GetVolumeLevel(This->wineD3DVolumeTexture, Level, &myVolume);
|
||||
if (hrc == D3D_OK && NULL != ppVolumeLevel) {
|
||||
IWineD3DVolumeTexture_GetParent(myVolume, (IUnknown **)ppVolumeLevel);
|
||||
IWineD3DVolumeTexture_Release(myVolume);
|
||||
}
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hrc;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_LockBox(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level, D3DLOCKED_BOX *pLockedVolume, CONST D3DBOX *pBox, DWORD Flags) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay %p %p %p %d\n", This, This->wineD3DVolumeTexture, pLockedVolume, pBox,Flags);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_LockBox(This->wineD3DVolumeTexture, Level, (WINED3DLOCKED_BOX *) pLockedVolume, (CONST WINED3DBOX *) pBox, Flags);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_UnlockBox(LPDIRECT3DVOLUMETEXTURE8 iface, UINT Level) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay %p %d\n", This, This->wineD3DVolumeTexture, Level);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_UnlockBox(This->wineD3DVolumeTexture, Level);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirect3DVolumeTexture8Impl_AddDirtyBox(LPDIRECT3DVOLUMETEXTURE8 iface, CONST D3DBOX *pDirtyBox) {
|
||||
IDirect3DVolumeTexture8Impl *This = (IDirect3DVolumeTexture8Impl *)iface;
|
||||
HRESULT hr;
|
||||
TRACE("(%p) Relay\n", This);
|
||||
|
||||
EnterCriticalSection(&d3d8_cs);
|
||||
hr = IWineD3DVolumeTexture_AddDirtyBox(This->wineD3DVolumeTexture, (CONST WINED3DBOX *) pDirtyBox);
|
||||
LeaveCriticalSection(&d3d8_cs);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IDirect3DVolumeTexture8Impl_QueryInterface,
|
||||
IDirect3DVolumeTexture8Impl_AddRef,
|
||||
IDirect3DVolumeTexture8Impl_Release,
|
||||
/* IDirect3DResource8 */
|
||||
IDirect3DVolumeTexture8Impl_GetDevice,
|
||||
IDirect3DVolumeTexture8Impl_SetPrivateData,
|
||||
IDirect3DVolumeTexture8Impl_GetPrivateData,
|
||||
IDirect3DVolumeTexture8Impl_FreePrivateData,
|
||||
IDirect3DVolumeTexture8Impl_SetPriority,
|
||||
IDirect3DVolumeTexture8Impl_GetPriority,
|
||||
IDirect3DVolumeTexture8Impl_PreLoad,
|
||||
IDirect3DVolumeTexture8Impl_GetType,
|
||||
/* IDirect3DBaseTexture8 */
|
||||
IDirect3DVolumeTexture8Impl_SetLOD,
|
||||
IDirect3DVolumeTexture8Impl_GetLOD,
|
||||
IDirect3DVolumeTexture8Impl_GetLevelCount,
|
||||
/* IDirect3DVolumeTexture8 */
|
||||
IDirect3DVolumeTexture8Impl_GetLevelDesc,
|
||||
IDirect3DVolumeTexture8Impl_GetVolumeLevel,
|
||||
IDirect3DVolumeTexture8Impl_LockBox,
|
||||
IDirect3DVolumeTexture8Impl_UnlockBox,
|
||||
IDirect3DVolumeTexture8Impl_AddDirtyBox
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
This Is wine DirectX support.
|
||||
It works in reactos and windows
|
||||
When ReactOS own ReactX are inplace
|
||||
this file will be remove from our SVN
|
||||
for now they stay as tempary sovlotions
|
||||
|
||||
|
||||
People that have help getting this thing
|
||||
to working in ReactOS Building system
|
||||
|
||||
Roderick Colenbrander - thunderbird2k at gmx dot net
|
||||
The informations how to build it and done
|
||||
the windows port in wine (wine devloper)
|
||||
|
||||
Magnus Olsen aka GreatLord
|
||||
Did import it to ReactOS and setupup
|
||||
the build
|
||||
|
||||
GedMurphy
|
||||
Did help with minor issue, info how to
|
||||
make DllMain being call
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE project SYSTEM "tools/rbuild/project.dtd">
|
||||
<group>
|
||||
<directory name="wined3d">
|
||||
<xi:include href="wined3d/wined3d.rbuild" />
|
||||
</directory>
|
||||
<directory name="d3d8">
|
||||
<xi:include href="d3d8/d3d8.rbuild" />
|
||||
</directory>
|
||||
</group>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = wined3d.dll
|
||||
IMPORTLIB = libwined3d.$(IMPLIBEXT)
|
||||
IMPORTS = user32 gdi32 advapi32 kernel32
|
||||
EXTRALIBS = -luuid
|
||||
|
||||
C_SRCS = \
|
||||
arb_program_shader.c \
|
||||
baseshader.c \
|
||||
basetexture.c \
|
||||
clipper.c \
|
||||
context.c \
|
||||
cubetexture.c \
|
||||
device.c \
|
||||
directx.c \
|
||||
drawprim.c \
|
||||
glsl_shader.c \
|
||||
indexbuffer.c \
|
||||
palette.c \
|
||||
pixelshader.c \
|
||||
query.c \
|
||||
resource.c \
|
||||
state.c \
|
||||
stateblock.c \
|
||||
surface.c \
|
||||
surface_gdi.c \
|
||||
swapchain.c \
|
||||
texture.c \
|
||||
utils.c \
|
||||
vertexbuffer.c \
|
||||
vertexdeclaration.c \
|
||||
vertexshader.c \
|
||||
volume.c \
|
||||
volumetexture.c \
|
||||
wined3d_main.c
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
@DEPENDENCIES@ # everything below this line is overwritten by make depend
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* IWineD3DBaseTexture Implementation
|
||||
*
|
||||
* Copyright 2002-2004 Jason Edmeades
|
||||
* Copyright 2002-2004 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DBaseTexture IUnknown parts follow
|
||||
******************************************* */
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface(IWineD3DBaseTexture *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseTexture)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG WINAPI IWineD3DBaseTextureImpl_AddRef(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->resource.ref);
|
||||
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This,ref - 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->resource.ref);
|
||||
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
|
||||
if (ref == 0) {
|
||||
IWineD3DBaseTextureImpl_CleanUp(iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* class static */
|
||||
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
|
||||
TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
|
||||
if (This->baseTexture.textureName != 0) {
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
|
||||
glDeleteTextures(1, &This->baseTexture.textureName);
|
||||
LEAVE_GL();
|
||||
}
|
||||
IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DBaseTexture IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice(IWineD3DBaseTexture *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData(IWineD3DBaseTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData(IWineD3DBaseTexture *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
DWORD WINAPI IWineD3DBaseTextureImpl_SetPriority(IWineD3DBaseTexture *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
DWORD WINAPI IWineD3DBaseTextureImpl_GetPriority(IWineD3DBaseTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
void WINAPI IWineD3DBaseTextureImpl_PreLoad(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType(IWineD3DBaseTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DBaseTexture IWineD3DBaseTexture parts follow
|
||||
****************************************************** */
|
||||
|
||||
/* There is no OpenGL equivilent of setLOD, getLOD, all they do it priortise testure loading
|
||||
* so just pretend that they work unless something really needs a failure. */
|
||||
DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
|
||||
if (This->resource.pool != WINED3DPOOL_MANAGED) {
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if(LODNew >= This->baseTexture.levels)
|
||||
LODNew = This->baseTexture.levels - 1;
|
||||
This->baseTexture.LOD = LODNew;
|
||||
|
||||
TRACE("(%p) : set bogus LOD to %d\n", This, This->baseTexture.LOD);
|
||||
|
||||
return This->baseTexture.LOD;
|
||||
}
|
||||
|
||||
DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
|
||||
if (This->resource.pool != WINED3DPOOL_MANAGED) {
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
TRACE("(%p) : returning %d\n", This, This->baseTexture.LOD);
|
||||
|
||||
return This->baseTexture.LOD;
|
||||
}
|
||||
|
||||
DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
TRACE("(%p) : returning %d\n", This, This->baseTexture.levels);
|
||||
return This->baseTexture.levels;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
|
||||
if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
|
||||
TRACE("(%p) : returning invalid call\n", This);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
This->baseTexture.filterType = FilterType;
|
||||
TRACE("(%p) :\n", This);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
FIXME("(%p) : stub\n", This);
|
||||
if (!(This->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) {
|
||||
return WINED3DTEXF_NONE;
|
||||
}
|
||||
return This->baseTexture.filterType;
|
||||
}
|
||||
|
||||
void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
/* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */
|
||||
FIXME("(%p) : stub\n", This);
|
||||
return ;
|
||||
}
|
||||
|
||||
/* Internal function, No d3d mapping */
|
||||
BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty(IWineD3DBaseTexture *iface, BOOL dirty) {
|
||||
BOOL old;
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
old = This->baseTexture.dirty;
|
||||
This->baseTexture.dirty = dirty;
|
||||
return old;
|
||||
}
|
||||
|
||||
BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
return This->baseTexture.dirty;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
HRESULT hr = WINED3D_OK;
|
||||
UINT textureDimensions;
|
||||
BOOL isNewTexture = FALSE;
|
||||
TRACE("(%p) : About to bind texture\n", This);
|
||||
|
||||
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
|
||||
ENTER_GL();
|
||||
/* Generate a texture name if we don't already have one */
|
||||
if (This->baseTexture.textureName == 0) {
|
||||
glGenTextures(1, &This->baseTexture.textureName);
|
||||
checkGLcall("glGenTextures");
|
||||
TRACE("Generated texture %d\n", This->baseTexture.textureName);
|
||||
if (This->resource.pool == WINED3DPOOL_DEFAULT) {
|
||||
/* Tell opengl to try and keep this texture in video ram (well mostly) */
|
||||
GLclampf tmp;
|
||||
tmp = 0.9f;
|
||||
glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp);
|
||||
|
||||
}
|
||||
/* Initialise the state of the texture object
|
||||
to the openGL defaults, not the directx defaults */
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_WRAP;
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_WRAP;
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = WINED3DTADDRESS_WRAP;
|
||||
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_LINEAR;
|
||||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
|
||||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_DMAPOFFSET] = 0;
|
||||
This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
|
||||
IWineD3DBaseTexture_SetDirty(iface, TRUE);
|
||||
isNewTexture = TRUE;
|
||||
}
|
||||
|
||||
/* Bind the texture */
|
||||
if (This->baseTexture.textureName != 0) {
|
||||
glBindTexture(textureDimensions, This->baseTexture.textureName);
|
||||
checkGLcall("glBindTexture");
|
||||
if (isNewTexture) {
|
||||
/* For a new texture we have to set the textures levels after binding the texture.
|
||||
* In theory this is all we should ever have to do, but because ATI's drivers are broken, we
|
||||
* also need to set the texture dimensions before the texture is set */
|
||||
TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1);
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1);
|
||||
checkGLcall("glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)");
|
||||
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
|
||||
/* Cubemaps are always set to clamp, regardeless of the sampler state. */
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
} else { /* this only happened if we've run out of openGL textures */
|
||||
WARN("This texture doesn't have an openGL texture assigned to it\n");
|
||||
hr = WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
LEAVE_GL();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
UINT textureDimensions;
|
||||
|
||||
TRACE("(%p) : About to bind texture\n", This);
|
||||
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
|
||||
|
||||
ENTER_GL();
|
||||
|
||||
glBindTexture(textureDimensions, 0);
|
||||
#if 0 /* TODO: context manager support */
|
||||
IWineD3DContextManager_PopState(This->contextManager, textureDimensions, ENABLED, NOW /* make sure the state is applied now */);
|
||||
#else
|
||||
glDisable(textureDimensions);
|
||||
#endif
|
||||
|
||||
LEAVE_GL();
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *iface){
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
FIXME("(%p) : This shouldn't be called\n", This);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {
|
||||
switch(Type) {
|
||||
case WINED3DSAMP_ADDRESSU:
|
||||
return GL_TEXTURE_WRAP_S;
|
||||
case WINED3DSAMP_ADDRESSV:
|
||||
return GL_TEXTURE_WRAP_T;
|
||||
case WINED3DSAMP_ADDRESSW:
|
||||
return GL_TEXTURE_WRAP_R;
|
||||
default:
|
||||
FIXME("Unexpected warp type %d\n", Type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply_wrap(const GLint textureDimensions, const DWORD state, const GLint type) {
|
||||
GLint wrapParm;
|
||||
|
||||
if (state < minLookup[WINELOOKUP_WARPPARAM] || state > maxLookup[WINELOOKUP_WARPPARAM]) {
|
||||
FIXME("Unrecognized or unsupported WINED3DTADDRESS_U value %d\n", state);
|
||||
} else {
|
||||
if(textureDimensions==GL_TEXTURE_CUBE_MAP_ARB) {
|
||||
/* Cubemaps are always set to clamp, regardeless of the sampler state. */
|
||||
wrapParm = GL_CLAMP_TO_EDGE;
|
||||
} else {
|
||||
wrapParm = stateLookup[WINELOOKUP_WARPPARAM][state - minLookup[WINELOOKUP_WARPPARAM]];
|
||||
}
|
||||
TRACE("Setting WRAP_S to %d for %x\n", wrapParm, textureDimensions);
|
||||
glTexParameteri(textureDimensions, type, wrapParm);
|
||||
checkGLcall("glTexParameteri(..., type, wrapParm)");
|
||||
}
|
||||
}
|
||||
|
||||
void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface,
|
||||
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
|
||||
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
|
||||
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
|
||||
DWORD state;
|
||||
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
|
||||
|
||||
IWineD3DBaseTexture_PreLoad(iface);
|
||||
|
||||
if(samplerStates[WINED3DSAMP_ADDRESSU] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]) {
|
||||
state = samplerStates[WINED3DSAMP_ADDRESSU];
|
||||
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S);
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = state;
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_ADDRESSV] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]) {
|
||||
state = samplerStates[WINED3DSAMP_ADDRESSV];
|
||||
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T);
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = state;
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_ADDRESSW] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]) {
|
||||
state = samplerStates[WINED3DSAMP_ADDRESSW];
|
||||
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R);
|
||||
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = state;
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_BORDERCOLOR] != This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR]) {
|
||||
float col[4];
|
||||
|
||||
state = samplerStates[WINED3DSAMP_BORDERCOLOR];
|
||||
D3DCOLORTOGLFLOAT4(state, col);
|
||||
TRACE("Setting border color for %u to %x\n", textureDimensions, state);
|
||||
glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
|
||||
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
|
||||
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = state;
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_MAGFILTER] != This->baseTexture.states[WINED3DTEXSTA_MAGFILTER]) {
|
||||
GLint glValue;
|
||||
state = samplerStates[WINED3DSAMP_MAGFILTER];
|
||||
if (state < minLookup[WINELOOKUP_MAGFILTER] || state > maxLookup[WINELOOKUP_MAGFILTER]) {
|
||||
FIXME("Unrecognized or unsupported MAGFILTER* value %d\n", state);
|
||||
}
|
||||
glValue = stateLookup[WINELOOKUP_MAGFILTER][state - minLookup[WINELOOKUP_MAGFILTER]];
|
||||
TRACE("ValueMAG=%d setting MAGFILTER to %x\n", state, glValue);
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, glValue);
|
||||
/* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
|
||||
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && WINED3DTEXF_ANISOTROPIC == state) {
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
|
||||
}
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = state;
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_MINFILTER] != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] ||
|
||||
samplerStates[WINED3DSAMP_MIPFILTER] != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] ||
|
||||
samplerStates[WINED3DSAMP_MAXMIPLEVEL] != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]) {
|
||||
GLint glValue;
|
||||
|
||||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
|
||||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
|
||||
|
||||
if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] < WINED3DTEXF_NONE ||
|
||||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] < WINED3DTEXF_NONE ||
|
||||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
|
||||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
|
||||
{
|
||||
|
||||
FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
|
||||
This->baseTexture.states[WINED3DTEXSTA_MINFILTER],
|
||||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]);
|
||||
}
|
||||
glValue = minMipLookup[min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
|
||||
[min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), WINED3DTEXF_LINEAR)];
|
||||
|
||||
TRACE("ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x\n",
|
||||
samplerStates[WINED3DSAMP_MINFILTER],
|
||||
samplerStates[WINED3DSAMP_MIPFILTER], glValue);
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, glValue);
|
||||
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
|
||||
|
||||
if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
|
||||
glValue = 0;
|
||||
} else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
|
||||
glValue = This->baseTexture.levels - 1;
|
||||
} else {
|
||||
glValue = This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];
|
||||
}
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
|
||||
}
|
||||
|
||||
if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) {
|
||||
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
|
||||
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
|
||||
} else {
|
||||
WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
|
||||
}
|
||||
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DBaseTextureImpl_QueryInterface,
|
||||
IWineD3DBaseTextureImpl_AddRef,
|
||||
IWineD3DBaseTextureImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DBaseTextureImpl_GetParent,
|
||||
IWineD3DBaseTextureImpl_GetDevice,
|
||||
IWineD3DBaseTextureImpl_SetPrivateData,
|
||||
IWineD3DBaseTextureImpl_GetPrivateData,
|
||||
IWineD3DBaseTextureImpl_FreePrivateData,
|
||||
IWineD3DBaseTextureImpl_SetPriority,
|
||||
IWineD3DBaseTextureImpl_GetPriority,
|
||||
IWineD3DBaseTextureImpl_PreLoad,
|
||||
IWineD3DBaseTextureImpl_GetType,
|
||||
/*IWineD3DBaseTexture*/
|
||||
IWineD3DBaseTextureImpl_SetLOD,
|
||||
IWineD3DBaseTextureImpl_GetLOD,
|
||||
IWineD3DBaseTextureImpl_GetLevelCount,
|
||||
IWineD3DBaseTextureImpl_SetAutoGenFilterType,
|
||||
IWineD3DBaseTextureImpl_GetAutoGenFilterType,
|
||||
IWineD3DBaseTextureImpl_GenerateMipSubLevels,
|
||||
IWineD3DBaseTextureImpl_SetDirty,
|
||||
IWineD3DBaseTextureImpl_GetDirty,
|
||||
/* internal */
|
||||
IWineD3DBaseTextureImpl_BindTexture,
|
||||
IWineD3DBaseTextureImpl_UnBindTexture,
|
||||
IWineD3DBaseTextureImpl_GetTextureDimensions,
|
||||
IWineD3DBaseTextureImpl_ApplyStateChanges
|
||||
|
||||
};
|
||||
@@ -0,0 +1,203 @@
|
||||
/* IWineD3DClipper implementation
|
||||
*
|
||||
* Copyright 2000 (c) Marcus Meissner
|
||||
* Copyright 2000 (c) TransGaming Technologies Inc.
|
||||
* Copyright 2006 (c) Stefan Dösinger
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_FLOAT_H
|
||||
# include <float.h>
|
||||
#endif
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_QueryInterface(IWineD3DClipper *iface, REFIID riid, void **Obj)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
|
||||
TRACE("(%p)->(%p,%p)\n", This, riid, Obj);
|
||||
if (IsEqualGUID(&IID_IUnknown, riid)
|
||||
|| IsEqualGUID(&IID_IWineD3DClipper, riid))
|
||||
{
|
||||
*Obj = iface;
|
||||
IWineD3DClipper_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DClipperImpl_AddRef(IWineD3DClipper *iface )
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DClipperImpl_Release(IWineD3DClipper *iface)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
|
||||
|
||||
if (ref == 0)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return 0;
|
||||
}
|
||||
else return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_GetParent(IWineD3DClipper *iface, IUnknown **Parent)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
TRACE("(%p)->(%p)\n", This, Parent);
|
||||
|
||||
*Parent = This->Parent;
|
||||
IUnknown_AddRef(*Parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_SetHwnd(IWineD3DClipper *iface, DWORD Flags, HWND hWnd)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
|
||||
TRACE("(%p)->(0x%08x,%p)\n", This, Flags, hWnd);
|
||||
if( Flags )
|
||||
{
|
||||
FIXME("Flags = 0x%08x, not supported.\n",Flags);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
This->hWnd = hWnd;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, RECT *Rect, RGNDATA *ClipList, DWORD *Size)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
TRACE("(%p,%p,%p,%p)\n", This, Rect, ClipList, Size);
|
||||
|
||||
if (This->hWnd)
|
||||
{
|
||||
HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
|
||||
if (hDC)
|
||||
{
|
||||
HRGN hRgn = CreateRectRgn(0,0,0,0);
|
||||
if (GetRandomRgn(hDC, hRgn, SYSRGN))
|
||||
{
|
||||
if (GetVersion() & 0x80000000)
|
||||
{
|
||||
/* map region to screen coordinates */
|
||||
POINT org;
|
||||
GetDCOrgEx( hDC, &org );
|
||||
OffsetRgn( hRgn, org.x, org.y );
|
||||
}
|
||||
if (Rect)
|
||||
{
|
||||
HRGN hRgnClip = CreateRectRgn(Rect->left, Rect->top,
|
||||
Rect->right, Rect->bottom);
|
||||
CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
|
||||
DeleteObject(hRgnClip);
|
||||
}
|
||||
*Size = GetRegionData(hRgn, *Size, ClipList);
|
||||
}
|
||||
DeleteObject(hRgn);
|
||||
ReleaseDC(This->hWnd, hDC);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
static int warned = 0;
|
||||
if (warned++ < 10)
|
||||
FIXME("(%p,%p,%p,%p),stub!\n",This,Rect,ClipList,Size);
|
||||
if (Size) *Size=0;
|
||||
return WINEDDERR_NOCLIPLIST;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_SetClipList(IWineD3DClipper *iface, RGNDATA *rgn, DWORD Flags)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
static int warned = 0;
|
||||
|
||||
if (warned++ < 10 || rgn == NULL)
|
||||
FIXME("(%p,%p,%d),stub!\n",This,rgn,Flags);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_GetHwnd(IWineD3DClipper *iface, HWND *hwnd)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
TRACE("(%p)->(%p)\n", This, hwnd);
|
||||
|
||||
*hwnd = This->hWnd;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DClipperImpl_IsClipListChanged(IWineD3DClipper *iface, BOOL *changed)
|
||||
{
|
||||
IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
|
||||
FIXME("(%p)->(%p),stub!\n",This,changed);
|
||||
|
||||
/* XXX What is safest? */
|
||||
*changed = FALSE;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static const IWineD3DClipperVtbl IWineD3DClipper_Vtbl =
|
||||
{
|
||||
IWineD3DClipperImpl_QueryInterface,
|
||||
IWineD3DClipperImpl_AddRef,
|
||||
IWineD3DClipperImpl_Release,
|
||||
IWineD3DClipperImpl_GetParent,
|
||||
IWineD3DClipperImpl_GetClipList,
|
||||
IWineD3DClipperImpl_GetHwnd,
|
||||
IWineD3DClipperImpl_IsClipListChanged,
|
||||
IWineD3DClipperImpl_SetClipList,
|
||||
IWineD3DClipperImpl_SetHwnd
|
||||
};
|
||||
|
||||
IWineD3DClipper* WINAPI WineDirect3DCreateClipper(IUnknown *Parent)
|
||||
{
|
||||
IWineD3DClipperImpl *obj;
|
||||
|
||||
TRACE("Creating clipper, parent %p\n", Parent);
|
||||
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
|
||||
if(!obj)
|
||||
{
|
||||
ERR("Out of memory when trying to allocate a WineD3D Clipper\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj->lpVtbl = &IWineD3DClipper_Vtbl;
|
||||
obj->Parent = Parent;
|
||||
|
||||
IWineD3DClipper_AddRef((IWineD3DClipper *)obj);
|
||||
return (IWineD3DClipper *) obj;
|
||||
}
|
||||
@@ -0,0 +1,890 @@
|
||||
/*
|
||||
* Context and render target management in wined3d
|
||||
*
|
||||
* Copyright 2007 Stefan Dösinger for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_FLOAT_H
|
||||
# include <float.h>
|
||||
#endif
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
|
||||
#define GLINFO_LOCATION This->adapter->gl_info
|
||||
|
||||
/*****************************************************************************
|
||||
* Context_MarkStateDirty
|
||||
*
|
||||
* Marks a state in a context dirty. Only one context, opposed to
|
||||
* IWineD3DDeviceImpl_MarkStateDirty, which marks the state dirty in all
|
||||
* contexts
|
||||
*
|
||||
* Params:
|
||||
* context: Context to mark the state dirty in
|
||||
* state: State to mark dirty
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void Context_MarkStateDirty(WineD3DContext *context, DWORD state) {
|
||||
DWORD rep = StateTable[state].representative;
|
||||
DWORD idx;
|
||||
BYTE shift;
|
||||
|
||||
if(!rep || isStateDirty(context, rep)) return;
|
||||
|
||||
context->dirtyArray[context->numDirtyEntries++] = rep;
|
||||
idx = rep >> 5;
|
||||
shift = rep & 0x1f;
|
||||
context->isStateDirty[idx] |= (1 << shift);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* AddContextToArray
|
||||
*
|
||||
* Adds a context to the context array. Helper function for CreateContext
|
||||
*
|
||||
* This method is not called in performance-critical code paths, only when a
|
||||
* new render target or swapchain is created. Thus performance is not an issue
|
||||
* here.
|
||||
*
|
||||
* Params:
|
||||
* This: Device to add the context for
|
||||
* hdc: device context
|
||||
* glCtx: WGL context to add
|
||||
* pbuffer: optional pbuffer used with this context
|
||||
*
|
||||
*****************************************************************************/
|
||||
static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) {
|
||||
WineD3DContext **oldArray = This->contexts;
|
||||
DWORD state;
|
||||
|
||||
This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1));
|
||||
if(This->contexts == NULL) {
|
||||
ERR("Unable to grow the context array\n");
|
||||
This->contexts = oldArray;
|
||||
return NULL;
|
||||
}
|
||||
if(oldArray) {
|
||||
memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts);
|
||||
}
|
||||
|
||||
This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineD3DContext));
|
||||
if(This->contexts[This->numContexts] == NULL) {
|
||||
ERR("Unable to allocate a new context\n");
|
||||
HeapFree(GetProcessHeap(), 0, This->contexts);
|
||||
This->contexts = oldArray;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
This->contexts[This->numContexts]->hdc = hdc;
|
||||
This->contexts[This->numContexts]->glCtx = glCtx;
|
||||
This->contexts[This->numContexts]->pbuffer = pbuffer;
|
||||
This->contexts[This->numContexts]->win_handle = win_handle;
|
||||
HeapFree(GetProcessHeap(), 0, oldArray);
|
||||
|
||||
/* Mark all states dirty to force a proper initialization of the states on the first use of the context
|
||||
*/
|
||||
for(state = 0; state <= STATE_HIGHEST; state++) {
|
||||
Context_MarkStateDirty(This->contexts[This->numContexts], state);
|
||||
}
|
||||
|
||||
This->numContexts++;
|
||||
TRACE("Created context %p\n", This->contexts[This->numContexts - 1]);
|
||||
return This->contexts[This->numContexts - 1];
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* CreateContext
|
||||
*
|
||||
* Creates a new context for a window, or a pbuffer context.
|
||||
*
|
||||
* * Params:
|
||||
* This: Device to activate the context for
|
||||
* target: Surface this context will render to
|
||||
* win_handle: handle to the window which we are drawing to
|
||||
* create_pbuffer: tells whether to create a pbuffer or not
|
||||
* pPresentParameters: contains the pixelformats to use for onscreen rendering
|
||||
*
|
||||
*****************************************************************************/
|
||||
WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) {
|
||||
HDC oldDrawable, hdc;
|
||||
HPBUFFERARB pbuffer = NULL;
|
||||
HGLRC ctx = NULL, oldCtx;
|
||||
WineD3DContext *ret = NULL;
|
||||
int s;
|
||||
|
||||
TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
|
||||
|
||||
if(create_pbuffer) {
|
||||
HDC hdc_parent = GetDC(win_handle);
|
||||
int iPixelFormat = 0;
|
||||
short red, green, blue, alphaBits, colorBits;
|
||||
short depthBits, stencilBits;
|
||||
|
||||
IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
|
||||
WINED3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
|
||||
|
||||
int attribs[256];
|
||||
int nAttribs = 0;
|
||||
unsigned int nFormats;
|
||||
|
||||
#define PUSH1(att) attribs[nAttribs++] = (att);
|
||||
#define PUSH2(att,value) attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
|
||||
|
||||
/* Retrieve the specifications for the pixelformat from the backbuffer / stencilbuffer */
|
||||
getColorBits(target->resource.format, &red, &green, &blue, &alphaBits, &colorBits);
|
||||
getDepthStencilBits(StencilBufferFormat, &depthBits, &stencilBits);
|
||||
PUSH2(WGL_DRAW_TO_PBUFFER_ARB, 1); /* We need pbuffer support; doublebuffering isn't needed */
|
||||
PUSH2(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); /* Make sure we don't get a float or color index format */
|
||||
PUSH2(WGL_COLOR_BITS_ARB, colorBits);
|
||||
PUSH2(WGL_ALPHA_BITS_ARB, alphaBits);
|
||||
PUSH2(WGL_DEPTH_BITS_ARB, depthBits);
|
||||
PUSH2(WGL_STENCIL_BITS_ARB, stencilBits);
|
||||
PUSH1(0); /* end the list */
|
||||
|
||||
#undef PUSH1
|
||||
#undef PUSH2
|
||||
|
||||
/* Try to find a pixelformat that matches exactly. If that fails let ChoosePixelFormat try to find a close match */
|
||||
if(!GL_EXTCALL(wglChoosePixelFormatARB(hdc_parent, (const int*)&attribs, NULL, 1, &iPixelFormat, &nFormats)))
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
TRACE("Falling back to ChoosePixelFormat as wglChoosePixelFormatARB failed\n");
|
||||
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER_DONTCARE | PFD_DRAW_TO_WINDOW;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = colorBits;
|
||||
pfd.cDepthBits = depthBits;
|
||||
pfd.cStencilBits = stencilBits;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
|
||||
iPixelFormat = ChoosePixelFormat(hdc_parent, &pfd);
|
||||
if(!iPixelFormat) {
|
||||
/* If this happens something is very wrong as ChoosePixelFormat barely fails */
|
||||
ERR("Can't find a suitable iPixelFormat for the pbuffer\n");
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Creating a pBuffer drawable for the new context\n");
|
||||
pbuffer = GL_EXTCALL(wglCreatePbufferARB(hdc_parent, iPixelFormat, target->currentDesc.Width, target->currentDesc.Height, 0));
|
||||
if(!pbuffer) {
|
||||
ERR("Cannot create a pbuffer\n");
|
||||
ReleaseDC(win_handle, hdc_parent);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* In WGL a pbuffer is 'wrapped' inside a HDC to 'fool' wglMakeCurrent */
|
||||
hdc = GL_EXTCALL(wglGetPbufferDCARB(pbuffer));
|
||||
if(!hdc) {
|
||||
ERR("Cannot get a HDC for pbuffer (%p)\n", pbuffer);
|
||||
GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
|
||||
ReleaseDC(win_handle, hdc_parent);
|
||||
goto out;
|
||||
}
|
||||
ReleaseDC(win_handle, hdc_parent);
|
||||
} else {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int iPixelFormat;
|
||||
short red, green, blue, alpha;
|
||||
short colorBits;
|
||||
short depthBits, stencilBits;
|
||||
int res;
|
||||
|
||||
hdc = GetDC(win_handle);
|
||||
if(hdc == NULL) {
|
||||
ERR("Cannot retrieve a device context!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* PixelFormat selection */
|
||||
/* TODO: fill cColorBits/cDepthBits with target->resource.format */
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 32;
|
||||
pfd.cDepthBits = 0;
|
||||
pfd.cStencilBits = 0;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
|
||||
/* Try to match the colorBits of the d3d format */
|
||||
if(getColorBits(target->resource.format, &red, &green, &blue, &alpha, &colorBits))
|
||||
pfd.cColorBits = colorBits;
|
||||
|
||||
/* Retrieve the depth stencil format from the present parameters.
|
||||
* The choice of the proper format can give a nice performance boost
|
||||
* in case of GPU limited programs. */
|
||||
if(pPresentParms->EnableAutoDepthStencil) {
|
||||
TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat));
|
||||
if(getDepthStencilBits(pPresentParms->AutoDepthStencilFormat, &depthBits, &stencilBits)) {
|
||||
pfd.cDepthBits = depthBits;
|
||||
pfd.cStencilBits = stencilBits;
|
||||
}
|
||||
}
|
||||
|
||||
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
|
||||
if(!iPixelFormat) {
|
||||
/* If this happens something is very wrong as ChoosePixelFormat barely fails */
|
||||
ERR("Can't find a suitable iPixelFormat\n");
|
||||
}
|
||||
|
||||
DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
|
||||
res = SetPixelFormat(hdc, iPixelFormat, NULL);
|
||||
if(!res) {
|
||||
int oldPixelFormat = GetPixelFormat(hdc);
|
||||
|
||||
if(oldPixelFormat) {
|
||||
/* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
|
||||
* There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */
|
||||
ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
|
||||
}
|
||||
else {
|
||||
ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx = pwglCreateContext(hdc);
|
||||
if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
|
||||
|
||||
if(!ctx) {
|
||||
ERR("Failed to create a WGL context\n");
|
||||
if(create_pbuffer) {
|
||||
GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
|
||||
GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer);
|
||||
if(!ret) {
|
||||
ERR("Failed to add the newly created context to the context list\n");
|
||||
pwglDeleteContext(ctx);
|
||||
if(create_pbuffer) {
|
||||
GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
|
||||
GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
ret->surface = (IWineD3DSurface *) target;
|
||||
ret->isPBuffer = create_pbuffer;
|
||||
ret->tid = GetCurrentThreadId();
|
||||
|
||||
TRACE("Successfully created new context %p\n", ret);
|
||||
|
||||
/* Set up the context defaults */
|
||||
oldCtx = pwglGetCurrentContext();
|
||||
oldDrawable = pwglGetCurrentDC();
|
||||
if(pwglMakeCurrent(hdc, ctx) == FALSE) {
|
||||
ERR("Cannot activate context to set up defaults\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
TRACE("Setting up the screen\n");
|
||||
/* Clear the screen */
|
||||
glClearColor(1.0, 0.0, 0.0, 0.0);
|
||||
checkGLcall("glClearColor");
|
||||
glClearIndex(0);
|
||||
glClearDepth(1);
|
||||
glClearStencil(0xffff);
|
||||
|
||||
checkGLcall("glClear");
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
checkGLcall("glColor3f");
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
checkGLcall("glEnable");
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
|
||||
checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
|
||||
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
|
||||
|
||||
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
|
||||
checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);
|
||||
checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);");
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);
|
||||
checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);");
|
||||
|
||||
if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
|
||||
/* Most textures will use client storage if supported. Exceptions are non-native power of 2 textures
|
||||
* and textures in DIB sections(due to the memory protection).
|
||||
*/
|
||||
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
|
||||
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
|
||||
}
|
||||
if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
|
||||
/* Direct3D always uses n-1 weights for n world matrices and uses 1 - sum for the last one
|
||||
* this is equal to GL_WEIGHT_SUM_UNITY_ARB. Enabling it doesn't do anything unless
|
||||
* GL_VERTEX_BLEND_ARB isn't enabled too
|
||||
*/
|
||||
glEnable(GL_WEIGHT_SUM_UNITY_ARB);
|
||||
checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
|
||||
}
|
||||
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
|
||||
glEnable(GL_TEXTURE_SHADER_NV);
|
||||
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
|
||||
|
||||
/* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
|
||||
* the previous texture where to source the offset from is always unit - 1.
|
||||
*/
|
||||
for(s = 1; s < GL_LIMITS(textures); s++) {
|
||||
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
|
||||
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
|
||||
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...\n");
|
||||
}
|
||||
}
|
||||
if(GL_SUPPORT(ARB_POINT_SPRITE)) {
|
||||
for(s = 0; s < GL_LIMITS(textures); s++) {
|
||||
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
|
||||
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
|
||||
checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(oldDrawable && oldCtx) {
|
||||
pwglMakeCurrent(oldDrawable, oldCtx);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* RemoveContextFromArray
|
||||
*
|
||||
* Removes a context from the context manager. The opengl context is not
|
||||
* destroyed or unset. context is not a valid pointer after that call.
|
||||
*
|
||||
* Similar to the former call this isn't a performance critical function. A
|
||||
* helper function for DestroyContext.
|
||||
*
|
||||
* Params:
|
||||
* This: Device to activate the context for
|
||||
* context: Context to remove
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *context) {
|
||||
UINT t, s;
|
||||
WineD3DContext **oldArray = This->contexts;
|
||||
|
||||
TRACE("Removing ctx %p\n", context);
|
||||
|
||||
This->numContexts--;
|
||||
|
||||
if(This->numContexts) {
|
||||
This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * This->numContexts);
|
||||
if(!This->contexts) {
|
||||
ERR("Cannot allocate a new context array, PANIC!!!\n");
|
||||
}
|
||||
t = 0;
|
||||
for(s = 0; s < This->numContexts; s++) {
|
||||
if(oldArray[s] == context) continue;
|
||||
This->contexts[t] = oldArray[s];
|
||||
t++;
|
||||
}
|
||||
} else {
|
||||
This->contexts = NULL;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, context);
|
||||
HeapFree(GetProcessHeap(), 0, oldArray);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* DestroyContext
|
||||
*
|
||||
* Destroys a wineD3DContext
|
||||
*
|
||||
* Params:
|
||||
* This: Device to activate the context for
|
||||
* context: Context to destroy
|
||||
*
|
||||
*****************************************************************************/
|
||||
void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
|
||||
|
||||
/* check that we are the current context first */
|
||||
TRACE("Destroying ctx %p\n", context);
|
||||
if(pwglGetCurrentContext() == context->glCtx){
|
||||
pwglMakeCurrent(NULL, NULL);
|
||||
}
|
||||
|
||||
if(context->isPBuffer) {
|
||||
GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc));
|
||||
GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer));
|
||||
} else ReleaseDC(context->win_handle, context->hdc);
|
||||
pwglDeleteContext(context->glCtx);
|
||||
|
||||
RemoveContextFromArray(This, context);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* SetupForBlit
|
||||
*
|
||||
* Sets up a context for DirectDraw blitting.
|
||||
* All texture units are disabled, except unit 0
|
||||
* Texture unit 0 is activted where GL_TEXTURE_2D is activated
|
||||
* fog, lighting, blending, alpha test, z test, scissor test, culling diabled
|
||||
* color writing enabled for all channels
|
||||
* register combiners disabled, shaders disabled
|
||||
* world matris is set to identity, texture matrix 0 too
|
||||
* projection matrix is setup for drawing screen coordinates
|
||||
*
|
||||
* Params:
|
||||
* This: Device to activate the context for
|
||||
* context: Context to setup
|
||||
* width: render target width
|
||||
* height: render target height
|
||||
*
|
||||
*****************************************************************************/
|
||||
static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
|
||||
int i;
|
||||
|
||||
TRACE("Setting up context %p for blitting\n", context);
|
||||
if(context->last_was_blit) {
|
||||
TRACE("Context is already set up for blitting, nothing to do\n");
|
||||
return;
|
||||
}
|
||||
context->last_was_blit = TRUE;
|
||||
|
||||
/* TODO: Use a display list */
|
||||
|
||||
/* Disable shaders */
|
||||
This->shader_backend->shader_cleanup((IWineD3DDevice *) This);
|
||||
Context_MarkStateDirty(context, STATE_VSHADER);
|
||||
Context_MarkStateDirty(context, STATE_PIXELSHADER);
|
||||
|
||||
/* Disable all textures. The caller can then bind a texture it wants to blit
|
||||
* from
|
||||
*/
|
||||
if(GL_SUPPORT(NV_REGISTER_COMBINERS)) {
|
||||
glDisable(GL_REGISTER_COMBINERS_NV);
|
||||
checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
|
||||
}
|
||||
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
|
||||
/* The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
|
||||
* function texture unit. No need to care for higher samplers
|
||||
*/
|
||||
for(i = GL_LIMITS(textures) - 1; i > 0 ; i--) {
|
||||
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
|
||||
checkGLcall("glActiveTextureARB");
|
||||
|
||||
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
|
||||
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
|
||||
}
|
||||
glDisable(GL_TEXTURE_3D);
|
||||
checkGLcall("glDisable GL_TEXTURE_3D");
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
checkGLcall("glDisable GL_TEXTURE_2D");
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
|
||||
|
||||
Context_MarkStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP));
|
||||
Context_MarkStateDirty(context, STATE_SAMPLER(i));
|
||||
}
|
||||
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
|
||||
checkGLcall("glActiveTextureARB");
|
||||
}
|
||||
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
|
||||
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
||||
checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
|
||||
}
|
||||
glDisable(GL_TEXTURE_3D);
|
||||
checkGLcall("glDisable GL_TEXTURE_3D");
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
checkGLcall("glEnable GL_TEXTURE_2D");
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
checkGLcall("glMatrixMode(GL_TEXTURE)");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity()");
|
||||
Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0));
|
||||
|
||||
if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
|
||||
GL_TEXTURE_LOD_BIAS_EXT,
|
||||
0.0);
|
||||
checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
|
||||
}
|
||||
Context_MarkStateDirty(context, STATE_SAMPLER(0));
|
||||
Context_MarkStateDirty(context, STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP));
|
||||
|
||||
/* Other misc states */
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
checkGLcall("glDisable(GL_ALPHA_TEST)");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHATESTENABLE));
|
||||
glDisable(GL_LIGHTING);
|
||||
checkGLcall("glDisable GL_LIGHTING");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING));
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
checkGLcall("glDisable GL_DEPTH_TEST");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE));
|
||||
glDisable(GL_FOG);
|
||||
checkGLcall("glDisable GL_FOG");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE));
|
||||
glDisable(GL_BLEND);
|
||||
checkGLcall("glDisable GL_BLEND");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE));
|
||||
glDisable(GL_CULL_FACE);
|
||||
checkGLcall("glDisable GL_CULL_FACE");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CULLMODE));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
checkGLcall("glDisable GL_STENCIL_TEST");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_STENCILENABLE));
|
||||
if(GL_SUPPORT(ARB_POINT_SPRITE)) {
|
||||
glDisable(GL_POINT_SPRITE_ARB);
|
||||
checkGLcall("glDisable GL_POINT_SPRITE_ARB");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE));
|
||||
}
|
||||
glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
checkGLcall("glColorMask");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING));
|
||||
|
||||
/* Setup transforms */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
checkGLcall("glMatrixMode(GL_MODELVIEW)");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity()");
|
||||
Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)));
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode(GL_PROJECTION)");
|
||||
glLoadIdentity();
|
||||
checkGLcall("glLoadIdentity()");
|
||||
glOrtho(0, width, height, 0, 0.0, -1.0);
|
||||
checkGLcall("glOrtho");
|
||||
Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION));
|
||||
|
||||
context->last_was_rhw = TRUE;
|
||||
Context_MarkStateDirty(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
|
||||
|
||||
glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)");
|
||||
glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)");
|
||||
glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)");
|
||||
glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)");
|
||||
glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
|
||||
glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING));
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
checkGLcall("glViewport");
|
||||
Context_MarkStateDirty(context, STATE_VIEWPORT);
|
||||
|
||||
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
|
||||
glDisable(GL_TEXTURE_SHADER_NV);
|
||||
checkGLcall("glDisable(GL_TEXTURE_SHADER_NV)");
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* findThreadContextForSwapChain
|
||||
*
|
||||
* Searches a swapchain for all contexts and picks one for the thread tid.
|
||||
* If none can be found the swapchain is requested to create a new context
|
||||
*
|
||||
*****************************************************************************/
|
||||
static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
|
||||
if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
|
||||
return ((IWineD3DSwapChainImpl *) swapchain)->context[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Create a new context for the thread */
|
||||
return IWineD3DSwapChainImpl_CreateContextForThread(swapchain);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* FindContext
|
||||
*
|
||||
* Finds a context for the current render target and thread
|
||||
*
|
||||
* Parameters:
|
||||
* target: Render target to find the context for
|
||||
* tid: Thread to activate the context for
|
||||
*
|
||||
* Returns: The needed context
|
||||
*
|
||||
*****************************************************************************/
|
||||
static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid) {
|
||||
IWineD3DSwapChain *swapchain = NULL;
|
||||
HRESULT hr;
|
||||
BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
|
||||
WineD3DContext *context = This->activeContext;
|
||||
BOOL oldRenderOffscreen = This->render_offscreen;
|
||||
|
||||
hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
|
||||
if(hr == WINED3D_OK && swapchain) {
|
||||
TRACE("Rendering onscreen\n");
|
||||
|
||||
context = findThreadContextForSwapChain(swapchain, tid);
|
||||
|
||||
This->render_offscreen = FALSE;
|
||||
/* The context != This->activeContext will catch a NOP context change. This can occur
|
||||
* if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
|
||||
* rendering. No context change is needed in that case
|
||||
*/
|
||||
|
||||
if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
|
||||
if(((IWineD3DSwapChainImpl *) swapchain)->backBuffer) {
|
||||
glDrawBuffer(GL_BACK);
|
||||
checkGLcall("glDrawBuffer(GL_BACK)");
|
||||
} else {
|
||||
glDrawBuffer(GL_FRONT);
|
||||
checkGLcall("glDrawBuffer(GL_FRONT)");
|
||||
}
|
||||
} else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
|
||||
if(This->pbufferContext && tid == This->pbufferContext->tid) {
|
||||
This->pbufferContext->tid = 0;
|
||||
}
|
||||
}
|
||||
IWineD3DSwapChain_Release(swapchain);
|
||||
|
||||
if(oldRenderOffscreen) {
|
||||
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
|
||||
Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
|
||||
Context_MarkStateDirty(context, STATE_VDECL);
|
||||
Context_MarkStateDirty(context, STATE_VIEWPORT);
|
||||
Context_MarkStateDirty(context, STATE_SCISSORRECT);
|
||||
}
|
||||
|
||||
} else {
|
||||
TRACE("Rendering offscreen\n");
|
||||
This->render_offscreen = TRUE;
|
||||
|
||||
switch(wined3d_settings.offscreen_rendering_mode) {
|
||||
case ORM_FBO:
|
||||
/* FBOs do not need a different context. Stay with whatever context is active at the moment */
|
||||
if(This->activeContext && tid == This->lastThread) {
|
||||
context = This->activeContext;
|
||||
} else {
|
||||
/* This may happen if the app jumps streight into offscreen rendering
|
||||
* Start using the context of the primary swapchain. tid == 0 is no problem
|
||||
* for findThreadContextForSwapChain.
|
||||
*
|
||||
* Can also happen on thread switches - in that case findThreadContextForSwapChain
|
||||
* is perfect to call.
|
||||
*/
|
||||
context = findThreadContextForSwapChain(This->swapchains[0], tid);
|
||||
}
|
||||
break;
|
||||
|
||||
case ORM_PBUFFER:
|
||||
{
|
||||
IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *) target;
|
||||
if(This->pbufferContext == NULL ||
|
||||
This->pbufferWidth < targetimpl->currentDesc.Width ||
|
||||
This->pbufferHeight < targetimpl->currentDesc.Height) {
|
||||
if(This->pbufferContext) {
|
||||
DestroyContext(This, This->pbufferContext);
|
||||
}
|
||||
|
||||
/* The display is irrelevant here, the window is 0. But CreateContext needs a valid X connection.
|
||||
* Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
|
||||
*/
|
||||
This->pbufferContext = CreateContext(This, targetimpl,
|
||||
((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0]->win_handle,
|
||||
TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms);
|
||||
This->pbufferWidth = targetimpl->currentDesc.Width;
|
||||
This->pbufferHeight = targetimpl->currentDesc.Height;
|
||||
}
|
||||
|
||||
if(This->pbufferContext) {
|
||||
if(This->pbufferContext->tid != 0 && This->pbufferContext->tid != tid) {
|
||||
FIXME("The PBuffr context is only supported for one thread for now!\n");
|
||||
}
|
||||
This->pbufferContext->tid = tid;
|
||||
context = This->pbufferContext;
|
||||
break;
|
||||
} else {
|
||||
ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering\n");
|
||||
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
|
||||
}
|
||||
}
|
||||
|
||||
case ORM_BACKBUFFER:
|
||||
/* Stay with the currently active context for back buffer rendering */
|
||||
if(This->activeContext && tid == This->lastThread) {
|
||||
context = This->activeContext;
|
||||
} else {
|
||||
/* This may happen if the app jumps streight into offscreen rendering
|
||||
* Start using the context of the primary swapchain. tid == 0 is no problem
|
||||
* for findThreadContextForSwapChain.
|
||||
*
|
||||
* Can also happen on thread switches - in that case findThreadContextForSwapChain
|
||||
* is perfect to call.
|
||||
*/
|
||||
context = findThreadContextForSwapChain(This->swapchains[0], tid);
|
||||
}
|
||||
glDrawBuffer(This->offscreenBuffer);
|
||||
checkGLcall("glDrawBuffer(This->offscreenBuffer)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
|
||||
/* Make sure we have a OpenGL texture name so the PreLoad() used to read the buffer
|
||||
* back when we are done won't mark us dirty.
|
||||
*/
|
||||
IWineD3DSurface_PreLoad(target);
|
||||
}
|
||||
|
||||
if(!oldRenderOffscreen) {
|
||||
Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
|
||||
Context_MarkStateDirty(context, WINED3DTS_PROJECTION);
|
||||
Context_MarkStateDirty(context, STATE_VDECL);
|
||||
Context_MarkStateDirty(context, STATE_VIEWPORT);
|
||||
Context_MarkStateDirty(context, STATE_SCISSORRECT);
|
||||
}
|
||||
}
|
||||
if (readTexture) {
|
||||
BOOL oldInDraw = This->isInDraw;
|
||||
|
||||
/* PreLoad requires a context to load the texture, thus it will call ActivateContext.
|
||||
* Set the isInDraw to true to signal PreLoad that it has a context. Will be tricky
|
||||
* when using offscreen rendering with multithreading
|
||||
*/
|
||||
This->isInDraw = TRUE;
|
||||
|
||||
/* Do that before switching the context:
|
||||
* Read the back buffer of the old drawable into the destination texture
|
||||
*/
|
||||
IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
|
||||
|
||||
/* Assume that the drawable will be modified by some other things now */
|
||||
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INDRAWABLE;
|
||||
|
||||
This->isInDraw = oldInDraw;
|
||||
}
|
||||
|
||||
if(oldRenderOffscreen != This->render_offscreen && This->depth_copy_state != WINED3D_DCS_NO_COPY) {
|
||||
This->depth_copy_state = WINED3D_DCS_COPY;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ActivateContext
|
||||
*
|
||||
* Finds a rendering context and drawable matching the device and render
|
||||
* target for the current thread, activates them and puts them into the
|
||||
* requested state.
|
||||
*
|
||||
* Params:
|
||||
* This: Device to activate the context for
|
||||
* target: Requested render target
|
||||
* usage: Prepares the context for blitting, drawing or other actions
|
||||
*
|
||||
*****************************************************************************/
|
||||
void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
|
||||
DWORD tid = GetCurrentThreadId();
|
||||
int i;
|
||||
DWORD dirtyState, idx;
|
||||
BYTE shift;
|
||||
WineD3DContext *context;
|
||||
|
||||
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
|
||||
|
||||
ENTER_GL();
|
||||
if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
|
||||
context = FindContext(This, target, tid);
|
||||
This->lastActiveRenderTarget = target;
|
||||
This->lastThread = tid;
|
||||
} else {
|
||||
/* Stick to the old context */
|
||||
context = This->activeContext;
|
||||
}
|
||||
|
||||
/* Activate the opengl context */
|
||||
if(context != This->activeContext) {
|
||||
BOOL ret;
|
||||
TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
|
||||
LEAVE_GL();
|
||||
ret = pwglMakeCurrent(context->hdc, context->glCtx);
|
||||
ENTER_GL();
|
||||
if(ret == FALSE) {
|
||||
ERR("Failed to activate the new context\n");
|
||||
}
|
||||
This->activeContext = context;
|
||||
}
|
||||
|
||||
switch(usage) {
|
||||
case CTXUSAGE_RESOURCELOAD:
|
||||
/* This does not require any special states to be set up */
|
||||
break;
|
||||
|
||||
case CTXUSAGE_CLEAR:
|
||||
if(context->last_was_blit && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
|
||||
glEnable(GL_TEXTURE_SHADER_NV);
|
||||
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
|
||||
}
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
checkGLcall("glEnable GL_SCISSOR_TEST");
|
||||
context->last_was_blit = FALSE;
|
||||
Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE));
|
||||
Context_MarkStateDirty(context, STATE_SCISSORRECT);
|
||||
break;
|
||||
|
||||
case CTXUSAGE_DRAWPRIM:
|
||||
/* This needs all dirty states applied */
|
||||
if(context->last_was_blit && GL_SUPPORT(NV_TEXTURE_SHADER2)) {
|
||||
glEnable(GL_TEXTURE_SHADER_NV);
|
||||
checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
|
||||
}
|
||||
|
||||
IWineD3DDeviceImpl_FindTexUnitMap(This);
|
||||
|
||||
for(i=0; i < context->numDirtyEntries; i++) {
|
||||
dirtyState = context->dirtyArray[i];
|
||||
idx = dirtyState >> 5;
|
||||
shift = dirtyState & 0x1f;
|
||||
context->isStateDirty[idx] &= ~(1 << shift);
|
||||
StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
|
||||
}
|
||||
context->numDirtyEntries = 0; /* This makes the whole list clean */
|
||||
context->last_was_blit = FALSE;
|
||||
break;
|
||||
|
||||
case CTXUSAGE_BLIT:
|
||||
SetupForBlit(This, context,
|
||||
((IWineD3DSurfaceImpl *)target)->currentDesc.Width,
|
||||
((IWineD3DSurfaceImpl *)target)->currentDesc.Height);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unexpected context usage requested\n");
|
||||
}
|
||||
LEAVE_GL();
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* IWineD3DCubeTexture implementation
|
||||
*
|
||||
* Copyright 2002-2005 Jason Edmeades
|
||||
* Copyright 2002-2005 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
static const GLenum cube_targets[6] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
|
||||
};
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DCubeTexture IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_QueryInterface(IWineD3DCubeTexture *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseTexture)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DTexture)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DCubeTextureImpl_AddRef(IWineD3DCubeTexture *iface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref);
|
||||
return InterlockedIncrement(&This->resource.ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
|
||||
ref = InterlockedDecrement(&This->resource.ref);
|
||||
if (ref == 0) {
|
||||
IWineD3DCubeTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DCubeTexture IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_GetDevice(IWineD3DCubeTexture *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_SetPrivateData(IWineD3DCubeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_GetPrivateData(IWineD3DCubeTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_FreePrivateData(IWineD3DCubeTexture *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DCubeTextureImpl_SetPriority(IWineD3DCubeTexture *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DCubeTextureImpl_GetPriority(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
|
||||
/* Override the IWineD3DResource Preload method */
|
||||
unsigned int i,j;
|
||||
BOOL setGlTextureDesc = FALSE;
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
BOOL srgb_mode = This->baseTexture.is_srgb;
|
||||
BOOL srgb_was_toggled = FALSE;
|
||||
|
||||
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty);
|
||||
|
||||
if (This->baseTexture.textureName == 0) setGlTextureDesc = TRUE;
|
||||
|
||||
/* We only have to activate a context for gl when we're not drawing. In most cases PreLoad will be called during draw
|
||||
* and a context was activated at the beginning of drawPrimitive
|
||||
*/
|
||||
if(!device->isInDraw) {
|
||||
/* No danger of recursive calls, ActivateContext sets isInDraw to true when loading
|
||||
* offscreen render targets into their texture
|
||||
*/
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
|
||||
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
|
||||
srgb_was_toggled = (This->baseTexture.is_srgb != srgb_mode);
|
||||
This->baseTexture.is_srgb = srgb_mode;
|
||||
}
|
||||
IWineD3DCubeTexture_BindTexture(iface);
|
||||
|
||||
ENTER_GL();
|
||||
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
|
||||
if (This->baseTexture.dirty) {
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
|
||||
if(setGlTextureDesc)
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
|
||||
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
|
||||
}
|
||||
}
|
||||
} else if (srgb_was_toggled) {
|
||||
/* Loop is repeated in the else block with the extra AddDirtyRect line to avoid the alternative of
|
||||
* checking srgb_was_toggled in every iteration, even when the texture is just dirty
|
||||
*/
|
||||
if (This->baseTexture.srgb_mode_change_count < 20)
|
||||
++This->baseTexture.srgb_mode_change_count;
|
||||
else
|
||||
FIXME("Cubetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
|
||||
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
|
||||
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[j][i], NULL);
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
|
||||
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
|
||||
}
|
||||
LEAVE_GL();
|
||||
|
||||
/* No longer dirty */
|
||||
This->baseTexture.dirty = FALSE;
|
||||
return ;
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DCubeTextureImpl_GetType(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_GetParent(IWineD3DCubeTexture *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DCubeTexture IWineD3DBaseTexture parts follow
|
||||
****************************************************** */
|
||||
static DWORD WINAPI IWineD3DCubeTextureImpl_SetLOD(IWineD3DCubeTexture *iface, DWORD LODNew) {
|
||||
return IWineD3DBaseTextureImpl_SetLOD((IWineD3DBaseTexture *)iface, LODNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DCubeTextureImpl_GetLOD(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLOD((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DCubeTextureImpl_GetLevelCount(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLevelCount((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_SetAutoGenFilterType(IWineD3DCubeTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
|
||||
return IWineD3DBaseTextureImpl_SetAutoGenFilterType((IWineD3DBaseTexture *)iface, FilterType);
|
||||
}
|
||||
|
||||
static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DCubeTextureImpl_GetAutoGenFilterType(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetAutoGenFilterType((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DCubeTextureImpl_GenerateMipSubLevels(IWineD3DCubeTexture *iface) {
|
||||
IWineD3DBaseTextureImpl_GenerateMipSubLevels((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
/* Internal function, No d3d mapping */
|
||||
static BOOL WINAPI IWineD3DCubeTextureImpl_SetDirty(IWineD3DCubeTexture *iface, BOOL dirty) {
|
||||
return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty);
|
||||
}
|
||||
|
||||
/* Internal function, No d3d mapping */
|
||||
static BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_BindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_UnBindTexture(IWineD3DCubeTexture *iface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_UnBindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static UINT WINAPI IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeTexture *iface){
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return GL_TEXTURE_CUBE_MAP_ARB;
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface,
|
||||
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
|
||||
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
float matrix[16];
|
||||
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
|
||||
|
||||
|
||||
/* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */
|
||||
if(This->pow2scalingFactor != 1.0f) {
|
||||
if((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU &&
|
||||
(~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
memset(matrix, 0 , sizeof(matrix));
|
||||
|
||||
matrix[0] = This->pow2scalingFactor;
|
||||
matrix[5] = This->pow2scalingFactor;
|
||||
matrix[10] = This->pow2scalingFactor;
|
||||
#if 0 /* Translation fixup is no longer required (here for reminder) */
|
||||
matrix[12] = -0.25f / (float)This->edgeLength;
|
||||
matrix[13] = -0.75f / (float)This->edgeLength;
|
||||
matrix[14] = -0.25f / (float)This->edgeLength;
|
||||
#endif
|
||||
TRACE("(%p) Setup Matrix:\n", This);
|
||||
TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]);
|
||||
TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]);
|
||||
TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]);
|
||||
TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]);
|
||||
TRACE("\n");
|
||||
glMultMatrixf(matrix);
|
||||
} else {
|
||||
/* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */
|
||||
FIXME("Non-power2 texture being used with generated texture coords\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DCubeTexture IWineD3DCubeTexture parts follow
|
||||
******************************************* */
|
||||
static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
int i,j;
|
||||
TRACE("(%p) : Cleaning up\n",This);
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (This->surfaces[j][i] != NULL) {
|
||||
/* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], 0, 0);
|
||||
/* Cleanup the container */
|
||||
IWineD3DSurface_SetContainer(This->surfaces[j][i], 0);
|
||||
D3DCB_DestroySurface(This->surfaces[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface);
|
||||
/* finally delete the object */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_GetLevelDesc(IWineD3DCubeTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
TRACE("(%p) level (%d)\n", This, Level);
|
||||
return IWineD3DSurface_GetDesc(This->surfaces[0][Level], pDesc);
|
||||
}
|
||||
FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_GetCubeMapSurface(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, IWineD3DSurface** ppCubeMapSurface) {
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (Level < This->baseTexture.levels && FaceType >= WINED3DCUBEMAP_FACE_POSITIVE_X && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
|
||||
*ppCubeMapSurface = This->surfaces[FaceType][Level];
|
||||
IWineD3DSurface_AddRef(*ppCubeMapSurface);
|
||||
|
||||
hr = WINED3D_OK;
|
||||
}
|
||||
if (WINED3D_OK == hr) {
|
||||
TRACE("(%p) -> faceType(%d) level(%d) returning surface@%p\n", This, FaceType, Level, This->surfaces[FaceType][Level]);
|
||||
} else {
|
||||
WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_LockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels && FaceType >= WINED3DCUBEMAP_FACE_POSITIVE_X && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
|
||||
hr = IWineD3DSurface_LockRect(This->surfaces[FaceType][Level], pLockedRect, pRect, Flags);
|
||||
}
|
||||
|
||||
if (WINED3D_OK == hr) {
|
||||
TRACE("(%p) -> faceType(%d) level(%d) returning memory@%p success(%u)\n", This, FaceType, Level, pLockedRect->pBits, hr);
|
||||
} else {
|
||||
WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_UnlockRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, UINT Level) {
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels && FaceType >= WINED3DCUBEMAP_FACE_POSITIVE_X && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
|
||||
hr = IWineD3DSurface_UnlockRect(This->surfaces[FaceType][Level]);
|
||||
}
|
||||
|
||||
if (WINED3D_OK == hr) {
|
||||
TRACE("(%p) -> faceType(%d) level(%d) success(%u)\n", This, FaceType, Level, hr);
|
||||
} else {
|
||||
WARN("(%p) level(%d) overflow Levels(%d) Or FaceType(%d)\n", This, Level, This->baseTexture.levels, FaceType);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, WINED3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) {
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
|
||||
This->baseTexture.dirty = TRUE;
|
||||
TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
|
||||
if (FaceType >= WINED3DCUBEMAP_FACE_POSITIVE_X && FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
|
||||
hr = IWineD3DSurface_AddDirtyRect(This->surfaces[FaceType][0], pDirtyRect);
|
||||
} else {
|
||||
WARN("(%p) overflow FaceType(%d)\n", This, FaceType);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
const IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DCubeTextureImpl_QueryInterface,
|
||||
IWineD3DCubeTextureImpl_AddRef,
|
||||
IWineD3DCubeTextureImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DCubeTextureImpl_GetParent,
|
||||
IWineD3DCubeTextureImpl_GetDevice,
|
||||
IWineD3DCubeTextureImpl_SetPrivateData,
|
||||
IWineD3DCubeTextureImpl_GetPrivateData,
|
||||
IWineD3DCubeTextureImpl_FreePrivateData,
|
||||
IWineD3DCubeTextureImpl_SetPriority,
|
||||
IWineD3DCubeTextureImpl_GetPriority,
|
||||
IWineD3DCubeTextureImpl_PreLoad,
|
||||
IWineD3DCubeTextureImpl_GetType,
|
||||
/* IWineD3DBaseTexture */
|
||||
IWineD3DCubeTextureImpl_SetLOD,
|
||||
IWineD3DCubeTextureImpl_GetLOD,
|
||||
IWineD3DCubeTextureImpl_GetLevelCount,
|
||||
IWineD3DCubeTextureImpl_SetAutoGenFilterType,
|
||||
IWineD3DCubeTextureImpl_GetAutoGenFilterType,
|
||||
IWineD3DCubeTextureImpl_GenerateMipSubLevels,
|
||||
IWineD3DCubeTextureImpl_SetDirty,
|
||||
IWineD3DCubeTextureImpl_GetDirty,
|
||||
IWineD3DCubeTextureImpl_BindTexture,
|
||||
IWineD3DCubeTextureImpl_UnBindTexture,
|
||||
IWineD3DCubeTextureImpl_GetTextureDimensions,
|
||||
IWineD3DCubeTextureImpl_ApplyStateChanges,
|
||||
/* IWineD3DCubeTexture */
|
||||
IWineD3DCubeTextureImpl_Destroy,
|
||||
IWineD3DCubeTextureImpl_GetLevelDesc,
|
||||
IWineD3DCubeTextureImpl_GetCubeMapSurface,
|
||||
IWineD3DCubeTextureImpl_LockRect,
|
||||
IWineD3DCubeTextureImpl_UnlockRect,
|
||||
IWineD3DCubeTextureImpl_AddDirtyRect
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* IWineD3DIndexBuffer Implementation
|
||||
*
|
||||
* Copyright 2002-2004 Jason Edmeades
|
||||
* Copyright 2003-2004 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DIndexBuffer IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DIndexBuffer)){
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DIndexBufferImpl_AddRef(IWineD3DIndexBuffer *iface) {
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->resource.ref);
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface) {
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->resource.ref);
|
||||
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
|
||||
if (ref == 0) {
|
||||
if(This->vbo) {
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
/* No need to manually unset the buffer. glDeleteBuffers unsets it for the current context,
|
||||
* but not for other contexts. However, because the d3d buffer is destroyed the app has to
|
||||
* unset it before doing the next draw, thus dirtifying the index buffer state and forcing
|
||||
* binding a new buffer
|
||||
*/
|
||||
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
|
||||
checkGLcall("glDeleteBuffersARB");
|
||||
LEAVE_GL();
|
||||
}
|
||||
|
||||
IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DIndexBuffer IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_GetDevice(IWineD3DIndexBuffer *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_SetPrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_GetPrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_FreePrivateData(IWineD3DIndexBuffer *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DIndexBufferImpl_SetPriority(IWineD3DIndexBuffer *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface) {
|
||||
IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DIndexBufferImpl_GetType(IWineD3DIndexBuffer *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_GetParent(IWineD3DIndexBuffer *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DIndexBuffer IWineD3DIndexBuffer parts follow
|
||||
****************************************************** */
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_Lock(IWineD3DIndexBuffer *iface, UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) {
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
TRACE("(%p) : offset %d, size %d, Flags=%x\n", This, OffsetToLock, SizeToLock, Flags);
|
||||
|
||||
InterlockedIncrement(&This->lockcount);
|
||||
*ppbData = (BYTE *)This->resource.allocatedMemory + OffsetToLock;
|
||||
|
||||
if(Flags & (WINED3DLOCK_READONLY | WINED3DLOCK_NO_DIRTY_UPDATE) || This->vbo == 0) {
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
if(This->dirtystart != This->dirtyend) {
|
||||
if(This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
|
||||
if(SizeToLock) {
|
||||
if(This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
|
||||
} else {
|
||||
This->dirtyend = This->resource.size;
|
||||
}
|
||||
} else {
|
||||
This->dirtystart = OffsetToLock;
|
||||
if(SizeToLock)
|
||||
This->dirtyend = OffsetToLock + SizeToLock;
|
||||
else
|
||||
This->dirtyend = This->resource.size;
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_Unlock(IWineD3DIndexBuffer *iface) {
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
unsigned long locks = InterlockedDecrement(&This->lockcount);
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
/* For now load in unlock */
|
||||
if(locks == 0 && This->vbo && (This->dirtyend - This->dirtystart) > 0) {
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
|
||||
if(device->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED) {
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
}
|
||||
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->vbo));
|
||||
checkGLcall("glBindBufferARB");
|
||||
GL_EXTCALL(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
|
||||
This->dirtystart, This->dirtyend - This->dirtystart, This->resource.allocatedMemory + This->dirtystart));
|
||||
checkGLcall("glBufferSubDataARB");
|
||||
LEAVE_GL();
|
||||
This->dirtystart = 0;
|
||||
This->dirtyend = 0;
|
||||
/* TODO: Move loading into preload when the buffer is used, that avoids dirtifying the state */
|
||||
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_INDEXBUFFER);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
static HRESULT WINAPI IWineD3DIndexBufferImpl_GetDesc(IWineD3DIndexBuffer *iface, WINED3DINDEXBUFFER_DESC *pDesc) {
|
||||
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
pDesc->Format = This->resource.format;
|
||||
pDesc->Type = This->resource.resourceType;
|
||||
pDesc->Usage = This->resource.usage;
|
||||
pDesc->Pool = This->resource.pool;
|
||||
pDesc->Size = This->resource.size;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DIndexBufferImpl_QueryInterface,
|
||||
IWineD3DIndexBufferImpl_AddRef,
|
||||
IWineD3DIndexBufferImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DIndexBufferImpl_GetParent,
|
||||
IWineD3DIndexBufferImpl_GetDevice,
|
||||
IWineD3DIndexBufferImpl_SetPrivateData,
|
||||
IWineD3DIndexBufferImpl_GetPrivateData,
|
||||
IWineD3DIndexBufferImpl_FreePrivateData,
|
||||
IWineD3DIndexBufferImpl_SetPriority,
|
||||
IWineD3DIndexBufferImpl_GetPriority,
|
||||
IWineD3DIndexBufferImpl_PreLoad,
|
||||
IWineD3DIndexBufferImpl_GetType,
|
||||
/* IWineD3DIndexBuffer */
|
||||
IWineD3DIndexBufferImpl_Lock,
|
||||
IWineD3DIndexBufferImpl_Unlock,
|
||||
IWineD3DIndexBufferImpl_GetDesc
|
||||
};
|
||||
@@ -0,0 +1,187 @@
|
||||
/* DirectDraw - IDirectPalette base interface
|
||||
*
|
||||
* Copyright 1997-2000 Marcus Meissner
|
||||
* Copyright 2000-2001 TransGaming Technologies Inc.
|
||||
* Copyright 2006 Stefan Dösinger for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
|
||||
#define SIZE_BITS (WINEDDPCAPS_1BIT | WINEDDPCAPS_2BIT | WINEDDPCAPS_4BIT | WINEDDPCAPS_8BIT)
|
||||
|
||||
static HRESULT WINAPI IWineD3DPaletteImpl_QueryInterface(IWineD3DPalette *iface, REFIID refiid, void **obj) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
|
||||
|
||||
if (IsEqualGUID(refiid, &IID_IUnknown)
|
||||
|| IsEqualGUID(refiid, &IID_IWineD3DPalette)) {
|
||||
*obj = iface;
|
||||
IWineD3DPalette_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
else {
|
||||
*obj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DPaletteImpl_AddRef(IWineD3DPalette *iface) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DPaletteImpl_Release(IWineD3DPalette *iface) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
|
||||
|
||||
if (!ref) {
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* Not called from the vtable */
|
||||
DWORD IWineD3DPaletteImpl_Size(DWORD dwFlags) {
|
||||
switch (dwFlags & SIZE_BITS) {
|
||||
case WINEDDPCAPS_1BIT: return 2;
|
||||
case WINEDDPCAPS_2BIT: return 4;
|
||||
case WINEDDPCAPS_4BIT: return 16;
|
||||
case WINEDDPCAPS_8BIT: return 256;
|
||||
default: assert(0); return 256;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPaletteImpl_GetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
|
||||
TRACE("(%p)->(%08x,%d,%d,%p)\n",This,Flags,Start,Count,PalEnt);
|
||||
|
||||
if (Flags != 0) return WINED3DERR_INVALIDCALL; /* unchecked */
|
||||
if (Start + Count > IWineD3DPaletteImpl_Size(This->Flags))
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (This->Flags & WINEDDPCAPS_8BITENTRIES)
|
||||
{
|
||||
unsigned int i;
|
||||
LPBYTE entry = (LPBYTE)PalEnt;
|
||||
|
||||
for (i=Start; i < Count+Start; i++)
|
||||
*entry++ = This->palents[i].peRed;
|
||||
}
|
||||
else
|
||||
memcpy(PalEnt, This->palents+Start, Count * sizeof(PALETTEENTRY));
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPaletteImpl_SetEntries(IWineD3DPalette *iface, DWORD Flags, DWORD Start, DWORD Count, PALETTEENTRY *PalEnt)
|
||||
{
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
ResourceList *res;
|
||||
|
||||
TRACE("(%p)->(%08x,%d,%d,%p)\n",This,Flags,Start,Count,PalEnt);
|
||||
|
||||
if (This->Flags & WINEDDPCAPS_8BITENTRIES) {
|
||||
unsigned int i;
|
||||
const BYTE* entry = (const BYTE*)PalEnt;
|
||||
|
||||
for (i=Start; i < Count+Start; i++)
|
||||
This->palents[i].peRed = *entry++;
|
||||
}
|
||||
else {
|
||||
memcpy(This->palents+Start, PalEnt, Count * sizeof(PALETTEENTRY));
|
||||
|
||||
if (This->hpal)
|
||||
SetPaletteEntries(This->hpal, Start, Count, This->palents+Start);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Now, if we are in 'depth conversion mode', update the screen palette */
|
||||
/* FIXME: we need to update the image or we won't get palette fading. */
|
||||
if (This->ddraw->d->palette_convert != NULL)
|
||||
This->ddraw->d->palette_convert(palent,This->screen_palents,start,count);
|
||||
#endif
|
||||
|
||||
/* If the palette is attached to the render target, update all render targets */
|
||||
|
||||
for(res = This->wineD3DDevice->resources; res != NULL; res=res->next) {
|
||||
if(IWineD3DResource_GetType(res->resource) == WINED3DRTYPE_SURFACE) {
|
||||
IWineD3DSurfaceImpl *impl = (IWineD3DSurfaceImpl *) res->resource;
|
||||
if(impl->palette == This)
|
||||
IWineD3DSurface_RealizePalette( (IWineD3DSurface *) res->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the palette is the primary palette, set the entries to the device */
|
||||
if(This->Flags & WINEDDPCAPS_PRIMARYSURFACE) {
|
||||
unsigned int i;
|
||||
IWineD3DDeviceImpl *device = This->wineD3DDevice;
|
||||
PALETTEENTRY *entry = PalEnt;
|
||||
|
||||
for(i = Start; i < Start+Count; i++) {
|
||||
device->palettes[device->currentPalette][i] = *entry++;
|
||||
}
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPaletteImpl_GetCaps(IWineD3DPalette *iface, DWORD *Caps) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
TRACE("(%p)->(%p)\n", This, Caps);
|
||||
|
||||
*Caps = This->Flags;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPaletteImpl_GetParent(IWineD3DPalette *iface, IUnknown **Parent) {
|
||||
IWineD3DPaletteImpl *This = (IWineD3DPaletteImpl *)iface;
|
||||
TRACE("(%p)->(%p)\n", This, Parent);
|
||||
|
||||
*Parent = (IUnknown *) This->parent;
|
||||
IUnknown_AddRef( (IUnknown *) This->parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
const IWineD3DPaletteVtbl IWineD3DPalette_Vtbl =
|
||||
{
|
||||
/*** IUnknown ***/
|
||||
IWineD3DPaletteImpl_QueryInterface,
|
||||
IWineD3DPaletteImpl_AddRef,
|
||||
IWineD3DPaletteImpl_Release,
|
||||
/*** IWineD3DPalette ***/
|
||||
IWineD3DPaletteImpl_GetParent,
|
||||
IWineD3DPaletteImpl_GetEntries,
|
||||
IWineD3DPaletteImpl_GetCaps,
|
||||
IWineD3DPaletteImpl_SetEntries
|
||||
};
|
||||
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* shaders implementation
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* Copyright 2004 Christian Costa
|
||||
* Copyright 2005 Oliver Stieber
|
||||
* Copyright 2006 Ivan Gyurdiev
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
#define GLINFO_LOCATION ((IWineD3DDeviceImpl *) This->baseShader.device)->adapter->gl_info
|
||||
|
||||
#if 0 /* Must not be 1 in cvs version */
|
||||
# define PSTRACE(A) TRACE A
|
||||
# define TRACE_VSVECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
|
||||
#else
|
||||
# define PSTRACE(A)
|
||||
# define TRACE_VSVECTOR(name)
|
||||
#endif
|
||||
|
||||
#define GLNAME_REQUIRE_GLSL ((const char *)1)
|
||||
/* *******************************************
|
||||
IWineD3DPixelShader IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseShader)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DPixelShader)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DPixelShaderImpl_AddRef(IWineD3DPixelShader *iface) {
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface) {
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0) {
|
||||
/* SetPixelShader does not AddRef. If the bound pixel shader is destroyed, the pointer in the stateblock remains
|
||||
* unchanged. Drawing again will most likely crash, even on windows. A problem can occur if the application creates
|
||||
* a new pixel shader which resides at the same address. Then SetPixelShader will think it is a NOP change, and won't
|
||||
* dirtify the state.
|
||||
*
|
||||
* Do NOT call GetPixelShader here. This will addRef and cause a recursion. And do NOT set the pixel shader to NULL,
|
||||
* Windows does not do that(Although no test exists since they'd crash randomly)
|
||||
*/
|
||||
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->pixelShader) {
|
||||
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_PIXELSHADER);
|
||||
}
|
||||
|
||||
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||
struct list *linked_programs = &This->baseShader.linked_programs;
|
||||
|
||||
TRACE("Deleting linked programs\n");
|
||||
if (linked_programs->next) {
|
||||
struct glsl_shader_prog_link *entry, *entry2;
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, pshader_entry) {
|
||||
delete_glsl_program_entry(This->baseShader.device, entry);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
||||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||
checkGLcall("glDeleteObjectARB");
|
||||
}
|
||||
shader_delete_constant_list(&This->baseShader.constantsF);
|
||||
shader_delete_constant_list(&This->baseShader.constantsB);
|
||||
shader_delete_constant_list(&This->baseShader.constantsI);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DPixelShader IWineD3DPixelShader parts follow
|
||||
******************************************* */
|
||||
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_GetParent(IWineD3DPixelShader *iface, IUnknown** parent){
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
|
||||
*parent = This->parent;
|
||||
IUnknown_AddRef(*parent);
|
||||
TRACE("(%p) : returning %p\n", This, *parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_GetDevice(IWineD3DPixelShader* iface, IWineD3DDevice **pDevice){
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
IWineD3DDevice_AddRef(This->baseShader.device);
|
||||
*pDevice = This->baseShader.device;
|
||||
TRACE("(%p) returning %p\n", This, *pDevice);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_GetFunction(IWineD3DPixelShader* impl, VOID* pData, UINT* pSizeOfData) {
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)impl;
|
||||
TRACE("(%p) : pData(%p), pSizeOfData(%p)\n", This, pData, pSizeOfData);
|
||||
|
||||
if (NULL == pData) {
|
||||
*pSizeOfData = This->baseShader.functionLength;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
if (*pSizeOfData < This->baseShader.functionLength) {
|
||||
/* MSDN claims (for d3d8 at least) that if *pSizeOfData is smaller
|
||||
* than the required size we should write the required size and
|
||||
* return D3DERR_MOREDATA. That's not actually true. */
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
if (NULL == This->baseShader.function) { /* no function defined */
|
||||
TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
|
||||
(*(DWORD **) pData) = NULL;
|
||||
} else {
|
||||
if (This->baseShader.functionLength == 0) {
|
||||
|
||||
}
|
||||
TRACE("(%p) : GetFunction copying to %p\n", This, pData);
|
||||
memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
|
||||
/* Arithmethic */
|
||||
{WINED3DSIO_NOP, "nop", "NOP", 0, 0, pshader_hw_map2gl, NULL, 0, 0},
|
||||
{WINED3DSIO_MOV, "mov", "MOV", 1, 2, pshader_hw_map2gl, shader_glsl_mov, 0, 0},
|
||||
{WINED3DSIO_ADD, "add", "ADD", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_SUB, "sub", "SUB", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_MAD, "mad", "MAD", 1, 4, pshader_hw_map2gl, shader_glsl_mad, 0, 0},
|
||||
{WINED3DSIO_MUL, "mul", "MUL", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_RCP, "rcp", "RCP", 1, 2, pshader_hw_map2gl, shader_glsl_rcp, 0, 0},
|
||||
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, pshader_hw_map2gl, shader_glsl_rsq, 0, 0},
|
||||
{WINED3DSIO_DP3, "dp3", "DP3", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0},
|
||||
{WINED3DSIO_DP4, "dp4", "DP4", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0},
|
||||
{WINED3DSIO_MIN, "min", "MIN", 1, 3, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_MAX, "max", "MAX", 1, 3, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_SLT, "slt", "SLT", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0},
|
||||
{WINED3DSIO_SGE, "sge", "SGE", 1, 3, pshader_hw_map2gl, shader_glsl_compare, 0, 0},
|
||||
{WINED3DSIO_ABS, "abs", "ABS", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_EXP, "exp", "EX2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_LOG, "log", "LG2", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_EXPP, "expp", "EXP", 1, 2, pshader_hw_map2gl, shader_glsl_expp, 0, 0},
|
||||
{WINED3DSIO_LOGP, "logp", "LOG", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_DST, "dst", "DST", 1, 3, pshader_hw_map2gl, shader_glsl_dst, 0, 0},
|
||||
{WINED3DSIO_LRP, "lrp", "LRP", 1, 4, pshader_hw_map2gl, shader_glsl_lrp, 0, 0},
|
||||
{WINED3DSIO_FRC, "frc", "FRC", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_CND, "cnd", NULL, 1, 4, pshader_hw_cnd, shader_glsl_cnd, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_CMP, "cmp", NULL, 1, 4, pshader_hw_cmp, shader_glsl_cmp, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(3,0)},
|
||||
{WINED3DSIO_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0},
|
||||
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0},
|
||||
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register,
|
||||
DP3 tmp , vec, vec;
|
||||
RSQ tmp, tmp.x;
|
||||
MUL vec.xyz, vec, tmp;
|
||||
but I think this is better because it accounts for w properly.
|
||||
DP3 tmp , vec, vec;
|
||||
RSQ tmp, tmp.x;
|
||||
MUL vec, vec, tmp;
|
||||
*/
|
||||
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, NULL, shader_glsl_sincos, WINED3DPS_VERSION(2,0), WINED3DPS_VERSION(2,1)},
|
||||
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 2, NULL, shader_glsl_sincos, WINED3DPS_VERSION(3,0), -1},
|
||||
/* TODO: dp2add can be made out of multiple instuctions */
|
||||
{WINED3DSIO_DP2ADD, "dp2add", GLNAME_REQUIRE_GLSL, 1, 4, NULL, pshader_glsl_dp2add, WINED3DPS_VERSION(2,0), -1},
|
||||
/* Matrix */
|
||||
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, NULL, shader_glsl_mnxn, 0, 0},
|
||||
/* Register declarations */
|
||||
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
|
||||
/* Flow control - requires GLSL or software shaders */
|
||||
{WINED3DSIO_REP , "rep", NULL, 0, 1, NULL, shader_glsl_rep, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_IF, "if", NULL, 0, 1, NULL, shader_glsl_if, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_IFC, "ifc", NULL, 0, 2, NULL, shader_glsl_ifc, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_ELSE, "else", NULL, 0, 0, NULL, shader_glsl_else, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_ENDIF, "endif", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_BREAK, "break", NULL, 0, 0, NULL, shader_glsl_break, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, NULL, shader_glsl_breakc, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_CALL, "call", NULL, 0, 1, NULL, shader_glsl_call, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, NULL, shader_glsl_callnz, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_LOOP, "loop", NULL, 0, 2, NULL, shader_glsl_loop, WINED3DPS_VERSION(3,0), -1},
|
||||
{WINED3DSIO_RET, "ret", NULL, 0, 0, NULL, NULL, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_ENDLOOP, "endloop", NULL, 0, 0, NULL, shader_glsl_end, WINED3DPS_VERSION(3,0), -1},
|
||||
{WINED3DSIO_LABEL, "label", NULL, 0, 1, NULL, shader_glsl_label, WINED3DPS_VERSION(2,1), -1},
|
||||
/* Constant definitions */
|
||||
{WINED3DSIO_DEF, "def", "undefined", 1, 5, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, 0, 0},
|
||||
/* Texture */
|
||||
{WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_hw_texcoord, pshader_glsl_texcoord, 0, WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, pshader_hw_texcoord, pshader_glsl_texcoord, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_map2gl, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
|
||||
{WINED3DSIO_TEX, "tex", "undefined", 1, 1, pshader_hw_tex, pshader_glsl_tex, 0, WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_TEXBEM, "texbem", "undefined", 1, 2, pshader_hw_texbem, pshader_glsl_texbem, 0, WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXBEML, "texbeml", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_hw_texreg2ar, pshader_glsl_texreg2ar, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_hw_texreg2gb, pshader_glsl_texreg2gb, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXREG2RGB, "texreg2rgb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texreg2rgb, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x2PAD, "texm3x2pad", "undefined", 1, 2, pshader_hw_texm3x2pad, pshader_glsl_texm3x2pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x2TEX, "texm3x2tex", "undefined", 1, 2, pshader_hw_texm3x2tex, pshader_glsl_texm3x2tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x3PAD, "texm3x3pad", "undefined", 1, 2, pshader_hw_texm3x3pad, pshader_glsl_texm3x3pad, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x3DIFF, "texm3x3diff", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, WINED3DPS_VERSION(0,0), WINED3DPS_VERSION(0,0)},
|
||||
{WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXDP3TEX, "texdp3tex", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXDP3, "texdp3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXM3x3, "texm3x3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
|
||||
{WINED3DSIO_TEXDEPTH, "texdepth", GLNAME_REQUIRE_GLSL, 1, 1, NULL, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
|
||||
{WINED3DSIO_DSX, "dsx", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_DSY, "dsy", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_TEXLDD, "texldd", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, WINED3DPS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DPS_VERSION(3,0), -1},
|
||||
{WINED3DSIO_PHASE, "phase", GLNAME_REQUIRE_GLSL, 0, 0, NULL, NULL, 0, 0},
|
||||
{0, NULL, NULL, 0, 0, NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
static void pshader_set_limits(
|
||||
IWineD3DPixelShaderImpl *This) {
|
||||
|
||||
This->baseShader.limits.attributes = 0;
|
||||
This->baseShader.limits.address = 0;
|
||||
This->baseShader.limits.packed_output = 0;
|
||||
|
||||
switch (This->baseShader.hex_version) {
|
||||
case WINED3DPS_VERSION(1,0):
|
||||
case WINED3DPS_VERSION(1,1):
|
||||
case WINED3DPS_VERSION(1,2):
|
||||
case WINED3DPS_VERSION(1,3):
|
||||
This->baseShader.limits.temporary = 2;
|
||||
This->baseShader.limits.constant_float = 8;
|
||||
This->baseShader.limits.constant_int = 0;
|
||||
This->baseShader.limits.constant_bool = 0;
|
||||
This->baseShader.limits.texcoord = 4;
|
||||
This->baseShader.limits.sampler = 4;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
This->baseShader.limits.label = 0;
|
||||
break;
|
||||
|
||||
case WINED3DPS_VERSION(1,4):
|
||||
This->baseShader.limits.temporary = 6;
|
||||
This->baseShader.limits.constant_float = 8;
|
||||
This->baseShader.limits.constant_int = 0;
|
||||
This->baseShader.limits.constant_bool = 0;
|
||||
This->baseShader.limits.texcoord = 6;
|
||||
This->baseShader.limits.sampler = 6;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
This->baseShader.limits.label = 0;
|
||||
break;
|
||||
|
||||
/* FIXME: temporaries must match D3DPSHADERCAPS2_0.NumTemps */
|
||||
case WINED3DPS_VERSION(2,0):
|
||||
This->baseShader.limits.temporary = 32;
|
||||
This->baseShader.limits.constant_float = 32;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.texcoord = 8;
|
||||
This->baseShader.limits.sampler = 16;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
break;
|
||||
|
||||
case WINED3DPS_VERSION(2,1):
|
||||
This->baseShader.limits.temporary = 32;
|
||||
This->baseShader.limits.constant_float = 32;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.texcoord = 8;
|
||||
This->baseShader.limits.sampler = 16;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
This->baseShader.limits.label = 16;
|
||||
break;
|
||||
|
||||
case WINED3DPS_VERSION(3,0):
|
||||
This->baseShader.limits.temporary = 32;
|
||||
This->baseShader.limits.constant_float = 224;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.texcoord = 0;
|
||||
This->baseShader.limits.sampler = 16;
|
||||
This->baseShader.limits.packed_input = 12;
|
||||
This->baseShader.limits.label = 16; /* FIXME: 2048 */
|
||||
break;
|
||||
|
||||
default: This->baseShader.limits.temporary = 32;
|
||||
This->baseShader.limits.constant_float = 32;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.texcoord = 8;
|
||||
This->baseShader.limits.sampler = 16;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
This->baseShader.limits.label = 0;
|
||||
FIXME("Unrecognized pixel shader version %#x\n",
|
||||
This->baseShader.hex_version);
|
||||
}
|
||||
}
|
||||
|
||||
/** Generate a pixel shader string using either GL_FRAGMENT_PROGRAM_ARB
|
||||
or GLSL and send it to the card */
|
||||
static inline VOID IWineD3DPixelShaderImpl_GenerateShader(
|
||||
IWineD3DPixelShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
SHADER_BUFFER buffer;
|
||||
|
||||
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
|
||||
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
|
||||
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
|
||||
HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
|
||||
This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
|
||||
This->fixupVertexBufferSize = PGMSIZE;
|
||||
This->fixupVertexBuffer[0] = 0;
|
||||
}
|
||||
buffer.buffer = This->device->fixupVertexBuffer;
|
||||
#else
|
||||
buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
|
||||
#endif
|
||||
buffer.bsize = 0;
|
||||
buffer.lineNo = 0;
|
||||
buffer.newline = TRUE;
|
||||
|
||||
if (This->baseShader.shader_mode == SHADER_GLSL) {
|
||||
|
||||
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */
|
||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
|
||||
|
||||
if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
|
||||
shader_addline(&buffer, "#extension GL_ARB_draw_buffers : enable\n");
|
||||
}
|
||||
|
||||
/* Base Declarations */
|
||||
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
|
||||
|
||||
/* Pack 3.0 inputs */
|
||||
if (This->baseShader.hex_version >= WINED3DPS_VERSION(3,0))
|
||||
pshader_glsl_input_pack(&buffer, This->semantics_in);
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
|
||||
|
||||
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
|
||||
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
|
||||
/* Some older cards like GeforceFX ones don't support multiple buffers, so also not gl_FragData */
|
||||
if(GL_SUPPORT(ARB_DRAW_BUFFERS))
|
||||
shader_addline(&buffer, "gl_FragData[0] = R0;\n");
|
||||
else
|
||||
shader_addline(&buffer, "gl_FragColor = R0;\n");
|
||||
}
|
||||
|
||||
/* Pixel shader < 3.0 do not replace the fog stage.
|
||||
* This implements linear fog computation and blending.
|
||||
* TODO: non linear fog
|
||||
* NOTE: gl_Fog.start and gl_Fog.end don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
if(This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
|
||||
shader_addline(&buffer, "float Fog = clamp(gl_FogFragCoord * gl_Fog.start + gl_Fog.end, 0.0, 1.0);\n");
|
||||
if(GL_SUPPORT(ARB_DRAW_BUFFERS))
|
||||
shader_addline(&buffer, "gl_FragData[0].xyz = mix(gl_Fog.color.xyz, gl_FragData[0].xyz, Fog);\n");
|
||||
else
|
||||
shader_addline(&buffer, "gl_FragColor.xyz = mix(gl_Fog.color.xyz, gl_FragColor.xyz, Fog);\n");
|
||||
}
|
||||
|
||||
shader_addline(&buffer, "}\n");
|
||||
|
||||
TRACE("Compiling shader object %u\n", shader_obj);
|
||||
GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer.buffer, NULL));
|
||||
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
||||
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
||||
|
||||
/* Store the shader object */
|
||||
This->baseShader.prgId = shader_obj;
|
||||
|
||||
} else if (This->baseShader.shader_mode == SHADER_ARB) {
|
||||
/* Create the hw ARB shader */
|
||||
shader_addline(&buffer, "!!ARBfp1.0\n");
|
||||
|
||||
shader_addline(&buffer, "TEMP TMP;\n"); /* Used in matrix ops */
|
||||
shader_addline(&buffer, "TEMP TMP2;\n"); /* Used in matrix ops */
|
||||
shader_addline(&buffer, "TEMP TA;\n"); /* Used for modifiers */
|
||||
shader_addline(&buffer, "TEMP TB;\n"); /* Used for modifiers */
|
||||
shader_addline(&buffer, "TEMP TC;\n"); /* Used for modifiers */
|
||||
shader_addline(&buffer, "PARAM coefdiv = { 0.5, 0.25, 0.125, 0.0625 };\n");
|
||||
shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
|
||||
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
|
||||
|
||||
/* Base Declarations */
|
||||
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
|
||||
|
||||
/* We need two variables for fog blending */
|
||||
shader_addline(&buffer, "TEMP TMP_FOG;\n");
|
||||
if (This->baseShader.hex_version >= WINED3DPS_VERSION(2,0)) {
|
||||
shader_addline(&buffer, "TEMP TMP_COLOR;\n");
|
||||
}
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
|
||||
|
||||
/* calculate fog and blend it
|
||||
* NOTE: state.fog.params.y and state.fog.params.z don't hold fog start s and end e but
|
||||
* -1/(e-s) and e/(e-s) respectively.
|
||||
*/
|
||||
shader_addline(&buffer, "MAD_SAT TMP_FOG, fragment.fogcoord, state.fog.params.y, state.fog.params.z;\n");
|
||||
if (This->baseShader.hex_version < WINED3DPS_VERSION(2,0)) {
|
||||
shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, R0, state.fog.color;\n");
|
||||
shader_addline(&buffer, "MOV result.color.a, R0.a;\n");
|
||||
} else {
|
||||
shader_addline(&buffer, "LRP result.color.rgb, TMP_FOG.x, TMP_COLOR, state.fog.color;\n");
|
||||
shader_addline(&buffer, "MOV result.color.a, TMP_COLOR.a;\n");
|
||||
}
|
||||
|
||||
shader_addline(&buffer, "END\n");
|
||||
|
||||
/* TODO: change to resource.glObjectHandle or something like that */
|
||||
GL_EXTCALL(glGenProgramsARB(1, &This->baseShader.prgId));
|
||||
|
||||
TRACE("Creating a hw pixel shader, prg=%d\n", This->baseShader.prgId);
|
||||
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, This->baseShader.prgId));
|
||||
|
||||
TRACE("Created hw pixel shader, prg=%d\n", This->baseShader.prgId);
|
||||
/* Create the program and check for errors */
|
||||
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||
buffer.bsize, buffer.buffer));
|
||||
|
||||
if (glGetError() == GL_INVALID_OPERATION) {
|
||||
GLint errPos;
|
||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
|
||||
FIXME("HW PixelShader Error at position %d: %s\n",
|
||||
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
|
||||
This->baseShader.prgId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
This->needsbumpmat = reg_maps->bumpmat;
|
||||
|
||||
#if 1 /* if were using the data buffer of device then we don't need to free it */
|
||||
HeapFree(GetProcessHeap(), 0, buffer.buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
|
||||
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
|
||||
|
||||
TRACE("(%p) : pFunction %p\n", iface, pFunction);
|
||||
|
||||
/* First pass: trace shader */
|
||||
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||
pshader_set_limits(This);
|
||||
|
||||
/* Initialize immediate constant lists */
|
||||
list_init(&This->baseShader.constantsF);
|
||||
list_init(&This->baseShader.constantsB);
|
||||
list_init(&This->baseShader.constantsI);
|
||||
|
||||
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) > 1) {
|
||||
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
||||
HRESULT hr;
|
||||
|
||||
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
|
||||
memset(reg_maps, 0, sizeof(shader_reg_maps));
|
||||
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
|
||||
This->semantics_in, NULL, pFunction, NULL);
|
||||
if (FAILED(hr)) return hr;
|
||||
/* FIXME: validate reg_maps against OpenGL */
|
||||
}
|
||||
|
||||
This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
|
||||
|
||||
TRACE("(%p) : Copying the function\n", This);
|
||||
if (NULL != pFunction) {
|
||||
void *function;
|
||||
|
||||
function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
||||
if (!function) return E_OUTOFMEMORY;
|
||||
memcpy(function, pFunction, This->baseShader.functionLength);
|
||||
This->baseShader.function = function;
|
||||
} else {
|
||||
This->baseShader.function = NULL;
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DPixelShaderImpl_CompileShader(IWineD3DPixelShader *iface) {
|
||||
|
||||
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
|
||||
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
|
||||
CONST DWORD *function = This->baseShader.function;
|
||||
|
||||
TRACE("(%p) : function %p\n", iface, function);
|
||||
|
||||
/* We're already compiled. */
|
||||
if (This->baseShader.is_compiled) return WINED3D_OK;
|
||||
|
||||
/* We don't need to compile */
|
||||
if (!function) {
|
||||
This->baseShader.is_compiled = TRUE;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) == 1) {
|
||||
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
||||
HRESULT hr;
|
||||
|
||||
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
|
||||
memset(reg_maps, 0, sizeof(shader_reg_maps));
|
||||
hr = shader_get_registers_used((IWineD3DBaseShader*)This, reg_maps,
|
||||
This->semantics_in, NULL, This->baseShader.function, deviceImpl->stateBlock);
|
||||
if (FAILED(hr)) return hr;
|
||||
/* FIXME: validate reg_maps against OpenGL */
|
||||
}
|
||||
|
||||
/* Generate the HW shader */
|
||||
TRACE("(%p) : Generating hardware program\n", This);
|
||||
IWineD3DPixelShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
|
||||
|
||||
This->baseShader.is_compiled = TRUE;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
const IWineD3DPixelShaderVtbl IWineD3DPixelShader_Vtbl =
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
IWineD3DPixelShaderImpl_QueryInterface,
|
||||
IWineD3DPixelShaderImpl_AddRef,
|
||||
IWineD3DPixelShaderImpl_Release,
|
||||
/*** IWineD3DBase methods ***/
|
||||
IWineD3DPixelShaderImpl_GetParent,
|
||||
/*** IWineD3DBaseShader methods ***/
|
||||
IWineD3DPixelShaderImpl_SetFunction,
|
||||
IWineD3DPixelShaderImpl_CompileShader,
|
||||
/*** IWineD3DPixelShader methods ***/
|
||||
IWineD3DPixelShaderImpl_GetDevice,
|
||||
IWineD3DPixelShaderImpl_GetFunction
|
||||
};
|
||||
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* IWineD3DQuery implementation
|
||||
*
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
/*
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/Queries.asp
|
||||
*
|
||||
* Occlusion Queries:
|
||||
* http://www.gris.uni-tuebingen.de/~bartz/Publications/paper/hww98.pdf
|
||||
* http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt
|
||||
*/
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DQuery IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_QueryInterface(IWineD3DQuery *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DQuery)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DQueryImpl_AddRef(IWineD3DQuery *iface) {
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0) {
|
||||
if(This->type == WINED3DQUERYTYPE_EVENT) {
|
||||
if(GL_SUPPORT(APPLE_FENCE)) {
|
||||
GL_EXTCALL(glDeleteFencesAPPLE(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
|
||||
checkGLcall("glDeleteFencesAPPLE");
|
||||
} else if(GL_SUPPORT(NV_FENCE)) {
|
||||
GL_EXTCALL(glDeleteFencesNV(1, &((WineQueryEventData *)(This->extendedData))->fenceId));
|
||||
checkGLcall("glDeleteFencesNV");
|
||||
}
|
||||
} else if(This->type == WINED3DQUERYTYPE_OCCLUSION && GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
|
||||
GL_EXTCALL(glDeleteQueriesARB(1, &((WineQueryOcclusionData *)(This->extendedData))->queryId));
|
||||
checkGLcall("glDeleteQueriesARB");
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This->extendedData);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DQuery IWineD3DQuery parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_GetParent(IWineD3DQuery *iface, IUnknown** parent){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
|
||||
*parent= (IUnknown*) parent;
|
||||
IUnknown_AddRef(*parent);
|
||||
TRACE("(%p) : returning %p\n", This, *parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_GetDevice(IWineD3DQuery* iface, IWineD3DDevice **pDevice){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
IWineD3DDevice_AddRef((IWineD3DDevice *)This->wineD3DDevice);
|
||||
*pDevice = (IWineD3DDevice *)This->wineD3DDevice;
|
||||
TRACE("(%p) returning %p\n", This, *pDevice);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
HRESULT res = S_OK;
|
||||
|
||||
TRACE("(%p) : type %#x, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, This->type, pData, dwSize, dwGetDataFlags);
|
||||
|
||||
if(dwSize == 0){
|
||||
/*you can use this method to poll the resource for the query status*/
|
||||
/*We return success(S_OK) if we support a feature, and faikure(S_FALSE) if we don't, just return success and fluff it for now*/
|
||||
return S_OK;
|
||||
}else{
|
||||
}
|
||||
|
||||
switch (This->type){
|
||||
|
||||
case WINED3DQUERYTYPE_VCACHE:
|
||||
{
|
||||
|
||||
WINED3DDEVINFO_VCACHE *data = (WINED3DDEVINFO_VCACHE *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
|
||||
data->Pattern = WINEMAKEFOURCC('C','A','C','H');
|
||||
data->OptMethod = 0; /*0 get longest strips, 1 optimize vertex cache*/
|
||||
data->CacheSize = 0; /*cache size, only required if OptMethod == 1*/
|
||||
data->MagicNumber = 0; /*only required if OptMethod == 1 (used internally)*/
|
||||
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_RESOURCEMANAGER:
|
||||
{
|
||||
WINED3DDEVINFO_RESOURCEMANAGER *data = (WINED3DDEVINFO_RESOURCEMANAGER *)pData;
|
||||
int i;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
|
||||
for(i = 0; i < WINED3DRTYPECOUNT; i++){
|
||||
/*I'm setting the default values to 1 so as to reduce the risk of a div/0 in the caller*/
|
||||
/* isTextureResident could be used to get some of this infomration */
|
||||
data->stats[i].bThrashing = FALSE;
|
||||
data->stats[i].ApproxBytesDownloaded = 1;
|
||||
data->stats[i].NumEvicts = 1;
|
||||
data->stats[i].NumVidCreates = 1;
|
||||
data->stats[i].LastPri = 1;
|
||||
data->stats[i].NumUsed = 1;
|
||||
data->stats[i].NumUsedInVidMem = 1;
|
||||
data->stats[i].WorkingSet = 1;
|
||||
data->stats[i].WorkingSetBytes = 1;
|
||||
data->stats[i].TotalManaged = 1;
|
||||
data->stats[i].TotalBytes = 1;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_VERTEXSTATS:
|
||||
{
|
||||
WINED3DDEVINFO_VERTEXSTATS *data = (WINED3DDEVINFO_VERTEXSTATS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
|
||||
data->NumRenderedTriangles = 1;
|
||||
data->NumExtraClippingTriangles = 1;
|
||||
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_EVENT:
|
||||
{
|
||||
BOOL* data = pData;
|
||||
if(GL_SUPPORT(APPLE_FENCE)) {
|
||||
*data = GL_EXTCALL(glTestFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||
checkGLcall("glTestFenceAPPLE");
|
||||
} else if(GL_SUPPORT(NV_FENCE)) {
|
||||
*data = GL_EXTCALL(glTestFenceNV(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||
checkGLcall("glTestFenceNV");
|
||||
} else {
|
||||
WARN("(%p): reporting GPU idle\n", This);
|
||||
*data = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_OCCLUSION:
|
||||
{
|
||||
DWORD* data = pData;
|
||||
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
|
||||
GLuint available;
|
||||
GLuint samples;
|
||||
GLuint queryId = ((WineQueryOcclusionData *)This->extendedData)->queryId;
|
||||
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_AVAILABLE_ARB, &available));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT_AVAILABLE)\n");
|
||||
TRACE("(%p) : available %d.\n", This, available);
|
||||
|
||||
if (available) {
|
||||
GL_EXTCALL(glGetQueryObjectuivARB(queryId, GL_QUERY_RESULT_ARB, &samples));
|
||||
checkGLcall("glGetQueryObjectuivARB(GL_QUERY_RESULT)\n");
|
||||
TRACE("(%p) : Returning %d samples.\n", This, samples);
|
||||
*data = samples;
|
||||
res = S_OK;
|
||||
} else {
|
||||
res = S_FALSE;
|
||||
}
|
||||
} else {
|
||||
FIXME("(%p) : Occlusion queries not supported. Returning 1.\n", This);
|
||||
*data = 1;
|
||||
res = S_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMP:
|
||||
{
|
||||
UINT64* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMP\n", This);
|
||||
*data = 1; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
|
||||
{
|
||||
BOOL* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPDISJOINT\n", This);
|
||||
*data = FALSE; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
|
||||
{
|
||||
UINT64* data = pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMPFREQ\n", This);
|
||||
*data = 1; /*Don't know what this is supposed to be*/
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_PIPELINETIMINGS:
|
||||
{
|
||||
WINED3DDEVINFO_PIPELINETIMINGS *data = (WINED3DDEVINFO_PIPELINETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
|
||||
|
||||
data->VertexProcessingTimePercent = 1.0f;
|
||||
data->PixelProcessingTimePercent = 1.0f;
|
||||
data->OtherGPUProcessingTimePercent = 97.0f;
|
||||
data->GPUIdleTimePercent = 1.0f;
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_INTERFACETIMINGS:
|
||||
{
|
||||
WINED3DDEVINFO_INTERFACETIMINGS *data = (WINED3DDEVINFO_INTERFACETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
|
||||
|
||||
data->WaitingForGPUToUseApplicationResourceTimePercent = 1.0f;
|
||||
data->WaitingForGPUToAcceptMoreCommandsTimePercent = 1.0f;
|
||||
data->WaitingForGPUToStayWithinLatencyTimePercent = 1.0f;
|
||||
data->WaitingForGPUExclusiveResourceTimePercent = 1.0f;
|
||||
data->WaitingForGPUOtherTimePercent = 96.0f;
|
||||
}
|
||||
|
||||
break;
|
||||
case WINED3DQUERYTYPE_VERTEXTIMINGS:
|
||||
{
|
||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
|
||||
|
||||
data->MemoryProcessingPercent = 50.0f;
|
||||
data->ComputationProcessingPercent = 50.0f;
|
||||
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_PIXELTIMINGS:
|
||||
{
|
||||
WINED3DDEVINFO_STAGETIMINGS *data = (WINED3DDEVINFO_STAGETIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
|
||||
|
||||
data->MemoryProcessingPercent = 50.0f;
|
||||
data->ComputationProcessingPercent = 50.0f;
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
||||
{
|
||||
WINED3DDEVINFO_BANDWIDTHTIMINGS *data = (WINED3DDEVINFO_BANDWIDTHTIMINGS *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
|
||||
|
||||
data->MaxBandwidthUtilized = 1.0f;
|
||||
data->FrontEndUploadMemoryUtilizedPercent = 1.0f;
|
||||
data->VertexRateUtilizedPercent = 1.0f;
|
||||
data->TriangleSetupRateUtilizedPercent = 1.0f;
|
||||
data->FillRateUtilizedPercent = 97.0f;
|
||||
}
|
||||
break;
|
||||
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
||||
{
|
||||
WINED3DDEVINFO_CACHEUTILIZATION *data = (WINED3DDEVINFO_CACHEUTILIZATION *)pData;
|
||||
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
|
||||
|
||||
data->TextureCacheHitRate = 1.0f;
|
||||
data->PostTransformVertexCacheHitRate = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
FIXME("(%p) Unhandled query type %d\n",This , This->type);
|
||||
|
||||
};
|
||||
|
||||
/*dwGetDataFlags = 0 || D3DGETDATA_FLUSH
|
||||
D3DGETDATA_FLUSH may return WINED3DERR_DEVICELOST if the device is lost
|
||||
*/
|
||||
return res; /* S_OK if the query data is available*/
|
||||
}
|
||||
|
||||
|
||||
static DWORD WINAPI IWineD3DQueryImpl_GetDataSize(IWineD3DQuery* iface){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
int dataSize = 0;
|
||||
TRACE("(%p) : type %#x\n", This, This->type);
|
||||
switch(This->type){
|
||||
case WINED3DQUERYTYPE_VCACHE:
|
||||
dataSize = sizeof(WINED3DDEVINFO_VCACHE);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_RESOURCEMANAGER:
|
||||
dataSize = sizeof(WINED3DDEVINFO_RESOURCEMANAGER);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_VERTEXSTATS:
|
||||
dataSize = sizeof(WINED3DDEVINFO_VERTEXSTATS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_EVENT:
|
||||
dataSize = sizeof(BOOL);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_OCCLUSION:
|
||||
dataSize = sizeof(DWORD);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMP:
|
||||
dataSize = sizeof(UINT64);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
|
||||
dataSize = sizeof(BOOL);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
|
||||
dataSize = sizeof(UINT64);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_PIPELINETIMINGS:
|
||||
dataSize = sizeof(WINED3DDEVINFO_PIPELINETIMINGS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_INTERFACETIMINGS:
|
||||
dataSize = sizeof(WINED3DDEVINFO_INTERFACETIMINGS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_VERTEXTIMINGS:
|
||||
dataSize = sizeof(WINED3DDEVINFO_STAGETIMINGS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_PIXELTIMINGS:
|
||||
dataSize = sizeof(WINED3DDEVINFO_STAGETIMINGS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
|
||||
dataSize = sizeof(WINED3DQUERYTYPE_BANDWIDTHTIMINGS);
|
||||
break;
|
||||
case WINED3DQUERYTYPE_CACHEUTILIZATION:
|
||||
dataSize = sizeof(WINED3DDEVINFO_CACHEUTILIZATION);
|
||||
break;
|
||||
default:
|
||||
FIXME("(%p) Unhandled query type %d\n",This , This->type);
|
||||
dataSize = 0;
|
||||
}
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
|
||||
static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
return This->type;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){
|
||||
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
|
||||
|
||||
TRACE("(%p) : dwIssueFlags %#x, type %#x\n", This, dwIssueFlags, This->type);
|
||||
|
||||
switch (This->type) {
|
||||
case WINED3DQUERYTYPE_OCCLUSION:
|
||||
if (GL_SUPPORT(ARB_OCCLUSION_QUERY)) {
|
||||
if (dwIssueFlags & WINED3DISSUE_BEGIN) {
|
||||
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, ((WineQueryOcclusionData *)This->extendedData)->queryId));
|
||||
checkGLcall("glBeginQuery()");
|
||||
}
|
||||
if (dwIssueFlags & WINED3DISSUE_END) {
|
||||
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
|
||||
checkGLcall("glEndQuery()");
|
||||
}
|
||||
} else {
|
||||
FIXME("(%p) : Occlusion queries not supported\n", This);
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3DQUERYTYPE_EVENT: {
|
||||
if (dwIssueFlags & WINED3DISSUE_END) {
|
||||
if(GL_SUPPORT(APPLE_FENCE)) {
|
||||
GL_EXTCALL(glSetFenceAPPLE(((WineQueryEventData *)This->extendedData)->fenceId));
|
||||
checkGLcall("glSetFenceAPPLE");
|
||||
} else if (GL_SUPPORT(NV_FENCE)) {
|
||||
GL_EXTCALL(glSetFenceNV(((WineQueryEventData *)This->extendedData)->fenceId, GL_ALL_COMPLETED_NV));
|
||||
checkGLcall("glSetFenceNV");
|
||||
}
|
||||
} else if(dwIssueFlags & WINED3DISSUE_BEGIN) {
|
||||
/* Started implicitly at device creation */
|
||||
ERR("Event query issued with START flag - what to do?\n");
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
/* The fixme is printed when the app asks for the resulting data */
|
||||
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* IWineD3DQuery VTbl follows
|
||||
**********************************************************/
|
||||
|
||||
const IWineD3DQueryVtbl IWineD3DQuery_Vtbl =
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
IWineD3DQueryImpl_QueryInterface,
|
||||
IWineD3DQueryImpl_AddRef,
|
||||
IWineD3DQueryImpl_Release,
|
||||
/*** IWineD3Dquery methods ***/
|
||||
IWineD3DQueryImpl_GetParent,
|
||||
IWineD3DQueryImpl_GetDevice,
|
||||
IWineD3DQueryImpl_GetData,
|
||||
IWineD3DQueryImpl_GetDataSize,
|
||||
IWineD3DQueryImpl_GetType,
|
||||
IWineD3DQueryImpl_Issue
|
||||
};
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* IWineD3DResource Implementation
|
||||
*
|
||||
* Copyright 2002-2004 Jason Edmeades
|
||||
* Copyright 2003-2004 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
|
||||
|
||||
/* IWineD3DResource IUnknown parts follow: */
|
||||
HRESULT WINAPI IWineD3DResourceImpl_QueryInterface(IWineD3DResource *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG WINAPI IWineD3DResourceImpl_AddRef(IWineD3DResource *iface) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->resource.ref);
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG WINAPI IWineD3DResourceImpl_Release(IWineD3DResource *iface) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->resource.ref);
|
||||
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
|
||||
if (ref == 0) {
|
||||
IWineD3DResourceImpl_CleanUp(iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* class static (not in vtable) */
|
||||
void IWineD3DResourceImpl_CleanUp(IWineD3DResource *iface){
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
struct list *e1, *e2;
|
||||
PrivateData *data;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p) Cleaning up resource\n", This);
|
||||
if (This->resource.pool == WINED3DPOOL_DEFAULT) {
|
||||
TRACE("Decrementing device memory pool by %u\n", This->resource.size);
|
||||
globalChangeGlRam(-This->resource.size);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_SAFE(e1, e2, &This->resource.privateData) {
|
||||
data = LIST_ENTRY(e1, PrivateData, entry);
|
||||
hr = IWineD3DResourceImpl_FreePrivateData(iface, &data->tag);
|
||||
if(hr != WINED3D_OK) {
|
||||
ERR("Failed to free private data when destroying resource %p, hr = %08x\n", This, hr);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This->resource.allocatedMemory);
|
||||
This->resource.allocatedMemory = 0;
|
||||
|
||||
if (This->resource.wineD3DDevice != NULL) {
|
||||
IWineD3DDevice_ResourceReleased((IWineD3DDevice *)This->resource.wineD3DDevice, iface);
|
||||
}/* NOTE: this is not really an error for systemmem resoruces */
|
||||
return;
|
||||
}
|
||||
|
||||
/* IWineD3DResource Interface follow: */
|
||||
HRESULT WINAPI IWineD3DResourceImpl_GetDevice(IWineD3DResource *iface, IWineD3DDevice** ppDevice) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
TRACE("(%p) : returning %p\n", This, This->resource.wineD3DDevice);
|
||||
*ppDevice = (IWineD3DDevice *) This->resource.wineD3DDevice;
|
||||
IWineD3DDevice_AddRef(*ppDevice);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static PrivateData* IWineD3DResourceImpl_FindPrivateData(IWineD3DResourceImpl *This,
|
||||
REFGUID tag)
|
||||
{
|
||||
PrivateData *data;
|
||||
struct list *entry;
|
||||
|
||||
TRACE("Searching for private data %s\n", debugstr_guid(tag));
|
||||
LIST_FOR_EACH(entry, &This->resource.privateData)
|
||||
{
|
||||
data = LIST_ENTRY(entry, PrivateData, entry);
|
||||
if (IsEqualGUID(&data->tag, tag)) {
|
||||
TRACE("Found %p\n", data);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
TRACE("Not found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DResourceImpl_SetPrivateData(IWineD3DResource *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
PrivateData *data;
|
||||
|
||||
TRACE("(%p) : %s %p %d %d\n", This, debugstr_guid(refguid), pData, SizeOfData, Flags);
|
||||
IWineD3DResourceImpl_FreePrivateData(iface, refguid);
|
||||
|
||||
data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data));
|
||||
if (NULL == data) return E_OUTOFMEMORY;
|
||||
|
||||
data->tag = *refguid;
|
||||
data->flags = Flags;
|
||||
#if 0
|
||||
(*data)->uniquenessValue = This->uniquenessValue;
|
||||
#endif
|
||||
if (Flags & WINED3DSPD_IUNKNOWN) {
|
||||
if(SizeOfData != sizeof(IUnknown *)) {
|
||||
WARN("IUnknown data with size %d, returning WINED3DERR_INVALIDCALL\n", SizeOfData);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
data->ptr.object = (LPUNKNOWN)pData;
|
||||
data->size = sizeof(LPUNKNOWN);
|
||||
IUnknown_AddRef(data->ptr.object);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->ptr.data = HeapAlloc(GetProcessHeap(), 0, SizeOfData);
|
||||
if (NULL == data->ptr.data) {
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
data->size = SizeOfData;
|
||||
memcpy(data->ptr.data, pData, SizeOfData);
|
||||
}
|
||||
list_add_tail(&This->resource.privateData, &data->entry);
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DResourceImpl_GetPrivateData(IWineD3DResource *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
PrivateData *data;
|
||||
|
||||
TRACE("(%p) : %p %p %p\n", This, refguid, pData, pSizeOfData);
|
||||
data = IWineD3DResourceImpl_FindPrivateData(This, refguid);
|
||||
if (data == NULL) return WINED3DERR_NOTFOUND;
|
||||
|
||||
|
||||
#if 0 /* This may not be right. */
|
||||
if (((*data)->flags & WINED3DSPD_VOLATILE)
|
||||
&& (*data)->uniquenessValue != This->uniquenessValue)
|
||||
return DDERR_EXPIRED;
|
||||
#endif
|
||||
if (*pSizeOfData < data->size) {
|
||||
*pSizeOfData = data->size;
|
||||
return WINED3DERR_MOREDATA;
|
||||
}
|
||||
|
||||
if (data->flags & WINED3DSPD_IUNKNOWN) {
|
||||
*(LPUNKNOWN *)pData = data->ptr.object;
|
||||
if(((IWineD3DImpl *) This->resource.wineD3DDevice->wineD3D)->dxVersion != 7) {
|
||||
/* D3D8 and D3D9 addref the private data, DDraw does not. This can't be handled in
|
||||
* ddraw because it doesn't know if the pointer returned is an IUnknown * or just a
|
||||
* Blob
|
||||
*/
|
||||
IUnknown_AddRef(data->ptr.object);
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(pData, data->ptr.data, data->size);
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
HRESULT WINAPI IWineD3DResourceImpl_FreePrivateData(IWineD3DResource *iface, REFGUID refguid) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
PrivateData *data;
|
||||
|
||||
TRACE("(%p) : %s\n", This, debugstr_guid(refguid));
|
||||
data = IWineD3DResourceImpl_FindPrivateData(This, refguid);
|
||||
if (data == NULL) return WINED3DERR_NOTFOUND;
|
||||
|
||||
if (data->flags & WINED3DSPD_IUNKNOWN)
|
||||
{
|
||||
if (data->ptr.object != NULL)
|
||||
IUnknown_Release(data->ptr.object);
|
||||
} else {
|
||||
HeapFree(GetProcessHeap(), 0, data->ptr.data);
|
||||
}
|
||||
list_remove(&data->entry);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* Priority support is not implemented yet */
|
||||
DWORD WINAPI IWineD3DResourceImpl_SetPriority(IWineD3DResource *iface, DWORD PriorityNew) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
FIXME("(%p) : stub\n", This);
|
||||
return 0;
|
||||
}
|
||||
DWORD WINAPI IWineD3DResourceImpl_GetPriority(IWineD3DResource *iface) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
FIXME("(%p) : stub\n", This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Preloading of resources is not supported yet */
|
||||
void WINAPI IWineD3DResourceImpl_PreLoad(IWineD3DResource *iface) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
FIXME("(%p) : stub\n", This);
|
||||
}
|
||||
|
||||
WINED3DRESOURCETYPE WINAPI IWineD3DResourceImpl_GetType(IWineD3DResource *iface) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
TRACE("(%p) : returning %d\n", This, This->resource.resourceType);
|
||||
return This->resource.resourceType;
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DResourceImpl_GetParent(IWineD3DResource *iface, IUnknown **pParent) {
|
||||
IWineD3DResourceImpl *This = (IWineD3DResourceImpl *)iface;
|
||||
IUnknown_AddRef(This->resource.parent);
|
||||
*pParent = This->resource.parent;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
void dumpResources(ResourceList *resources) {
|
||||
ResourceList *iterator = resources;
|
||||
|
||||
while(iterator) {
|
||||
FIXME("Leftover resource %p with type %d,%s\n", iterator->resource, IWineD3DResource_GetType(iterator->resource), debug_d3dresourcetype(IWineD3DResource_GetType(iterator->resource)));
|
||||
iterator = iterator->next;
|
||||
}
|
||||
}
|
||||
|
||||
static const IWineD3DResourceVtbl IWineD3DResource_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DResourceImpl_QueryInterface,
|
||||
IWineD3DResourceImpl_AddRef,
|
||||
IWineD3DResourceImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DResourceImpl_GetParent,
|
||||
IWineD3DResourceImpl_GetDevice,
|
||||
IWineD3DResourceImpl_SetPrivateData,
|
||||
IWineD3DResourceImpl_GetPrivateData,
|
||||
IWineD3DResourceImpl_FreePrivateData,
|
||||
IWineD3DResourceImpl_SetPriority,
|
||||
IWineD3DResourceImpl_GetPriority,
|
||||
IWineD3DResourceImpl_PreLoad,
|
||||
IWineD3DResourceImpl_GetType
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
*IDirect3DSwapChain9 implementation
|
||||
*
|
||||
*Copyright 2002-2003 Jason Edmeades
|
||||
*Copyright 2002-2003 Raphael Junqueira
|
||||
*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
|
||||
*License as published by the Free Software Foundation; either
|
||||
*version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*This library is distributed in the hope that it will be useful,
|
||||
*but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
*Lesser General Public License for more details.
|
||||
*
|
||||
*You should have received a copy of the GNU Lesser General Public
|
||||
*License along with this library; if not, write to the Free Software
|
||||
*Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
|
||||
/*TODO: some of the additional parameters may be required to
|
||||
set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
|
||||
but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/
|
||||
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(fps);
|
||||
|
||||
#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* IDirect3DSwapChain IUnknown parts follow: */
|
||||
static ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
DWORD refCount = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
|
||||
IWineD3DSwapChainImpl_AddRef(iface);
|
||||
if(ppobj == NULL){
|
||||
ERR("Query interface called but now data allocated\n");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
*ppobj = This;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
static ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
DWORD refCount;
|
||||
refCount = InterlockedDecrement(&This->ref);
|
||||
TRACE("(%p) : ReleaseRef to %d\n", This, refCount);
|
||||
if (refCount == 0) {
|
||||
IWineD3DSwapChain_Destroy(iface, D3DCB_DefaultDestroySurface);
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
*ppParent = This->parent;
|
||||
IUnknown_AddRef(*ppParent);
|
||||
TRACE("(%p) returning %p\n", This , *ppParent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/*IWineD3DSwapChain parts follow: */
|
||||
static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
WINED3DDISPLAYMODE mode;
|
||||
int i;
|
||||
|
||||
/* release the ref to the front and back buffer parents */
|
||||
if(This->frontBuffer) {
|
||||
IWineD3DSurface_SetContainer(This->frontBuffer, 0);
|
||||
if(D3DCB_DestroyRenderTarget(This->frontBuffer) > 0) {
|
||||
FIXME("(%p) Something's still holding the front buffer\n",This);
|
||||
}
|
||||
}
|
||||
|
||||
if(This->backBuffer) {
|
||||
int i;
|
||||
for(i = 0; i < This->presentParms.BackBufferCount; i++) {
|
||||
IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
|
||||
if(D3DCB_DestroyRenderTarget(This->backBuffer[i]) > 0) {
|
||||
FIXME("(%p) Something's still holding the back buffer\n",This);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the screen resolution if we rendered in fullscreen
|
||||
* This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9
|
||||
* this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution
|
||||
* before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params
|
||||
*/
|
||||
if(This->presentParms.Windowed == FALSE) {
|
||||
mode.Width = This->orig_width;
|
||||
mode.Height = This->orig_height;
|
||||
mode.RefreshRate = 0;
|
||||
mode.Format = This->orig_fmt;
|
||||
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode);
|
||||
}
|
||||
for(i = 0; i < This->num_contexts; i++) {
|
||||
DestroyContext(This->wineD3DDevice, This->context[i]);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->context);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
unsigned int sync;
|
||||
int retval;
|
||||
|
||||
|
||||
ActivateContext(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
|
||||
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
|
||||
if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) {
|
||||
IWineD3DSurfaceImpl cursor;
|
||||
RECT destRect = {This->wineD3DDevice->xScreenSpace - This->wineD3DDevice->xHotSpot,
|
||||
This->wineD3DDevice->yScreenSpace - This->wineD3DDevice->yHotSpot,
|
||||
This->wineD3DDevice->xScreenSpace + This->wineD3DDevice->cursorWidth - This->wineD3DDevice->xHotSpot,
|
||||
This->wineD3DDevice->yScreenSpace + This->wineD3DDevice->cursorHeight - This->wineD3DDevice->yHotSpot};
|
||||
TRACE("Rendering the cursor. Creating fake surface at %p\n", &cursor);
|
||||
/* Build a fake surface to call the Blitting code. It is not possible to use the interface passed by
|
||||
* the application because we are only supposed to copy the information out. Using a fake surface
|
||||
* allows to use the Blitting engine and avoid copying the whole texture -> render target blitting code.
|
||||
*/
|
||||
memset(&cursor, 0, sizeof(cursor));
|
||||
cursor.lpVtbl = &IWineD3DSurface_Vtbl;
|
||||
cursor.resource.ref = 1;
|
||||
cursor.resource.wineD3DDevice = This->wineD3DDevice;
|
||||
cursor.resource.pool = WINED3DPOOL_SCRATCH;
|
||||
cursor.resource.format = WINED3DFMT_A8R8G8B8;
|
||||
cursor.resource.resourceType = WINED3DRTYPE_SURFACE;
|
||||
cursor.glDescription.textureName = This->wineD3DDevice->cursorTexture;
|
||||
cursor.glDescription.target = GL_TEXTURE_2D;
|
||||
cursor.glDescription.level = 0;
|
||||
cursor.currentDesc.Width = This->wineD3DDevice->cursorWidth;
|
||||
cursor.currentDesc.Height = This->wineD3DDevice->cursorHeight;
|
||||
cursor.glRect.left = 0;
|
||||
cursor.glRect.top = 0;
|
||||
cursor.glRect.right = cursor.currentDesc.Width;
|
||||
cursor.glRect.bottom = cursor.currentDesc.Height;
|
||||
/* The cursor must have pow2 sizes */
|
||||
cursor.pow2Width = cursor.currentDesc.Width;
|
||||
cursor.pow2Height = cursor.currentDesc.Height;
|
||||
/* The surface is in the texture */
|
||||
cursor.Flags |= SFLAG_INTEXTURE;
|
||||
/* DDBLT_KEYSRC will cause BltOverride to enable the alpha test with GL_NOTEQUAL, 0.0,
|
||||
* which is exactly what we want :-)
|
||||
*/
|
||||
if (This->presentParms.Windowed) {
|
||||
MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
|
||||
}
|
||||
IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *) &cursor, NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_NONE);
|
||||
}
|
||||
|
||||
if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
|
||||
/* TODO: If only source rect or dest rect are supplied then clip the window to match */
|
||||
TRACE("preseting HDC %p\n", This->context[0]->hdc);
|
||||
|
||||
/* Don't call checkGLcall, as glGetError is not applicable here */
|
||||
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
|
||||
WINED3DLOCKED_RECT r;
|
||||
BYTE *mem;
|
||||
|
||||
TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride);
|
||||
if(This->context[0] == This->wineD3DDevice->contexts[0]) {
|
||||
/* The primary context 'owns' all the opengl resources. Destroying and recreating that context would require downloading
|
||||
* all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
|
||||
* and reload the resources
|
||||
*/
|
||||
ERR("Cannot change the destination window of the owner of the primary context\n");
|
||||
} else {
|
||||
This->win_handle = hDestWindowOverride;
|
||||
|
||||
/* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect
|
||||
* would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code
|
||||
* So lock read only, copy the surface out, then lock with the discard flag and write back
|
||||
*/
|
||||
IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY);
|
||||
mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
||||
memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
||||
IWineD3DSurface_UnlockRect(This->backBuffer[0]);
|
||||
|
||||
DestroyContext(This->wineD3DDevice, This->context[0]);
|
||||
This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms);
|
||||
|
||||
IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
|
||||
memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
|
||||
HeapFree(GetProcessHeap(), 0, mem);
|
||||
IWineD3DSurface_UnlockRect(This->backBuffer[0]);
|
||||
}
|
||||
}
|
||||
|
||||
SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */
|
||||
|
||||
TRACE("SwapBuffers called, Starting new frame\n");
|
||||
/* FPS support */
|
||||
if (TRACE_ON(fps))
|
||||
{
|
||||
DWORD time = GetTickCount();
|
||||
This->frames++;
|
||||
/* every 1.5 seconds */
|
||||
if (time - This->prev_time > 1500) {
|
||||
TRACE_(fps)("%p @ approx %.2ffps\n", This, 1000.0*This->frames/(time - This->prev_time));
|
||||
This->prev_time = time;
|
||||
This->frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FRAME_DEBUGGING)
|
||||
{
|
||||
if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
|
||||
if (!isOn) {
|
||||
isOn = TRUE;
|
||||
FIXME("Enabling D3D Trace\n");
|
||||
__WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
|
||||
#if defined(SHOW_FRAME_MAKEUP)
|
||||
FIXME("Singe Frame snapshots Starting\n");
|
||||
isDumpingFrames = TRUE;
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
#endif
|
||||
|
||||
#if defined(SINGLE_FRAME_DEBUGGING)
|
||||
} else {
|
||||
#if defined(SHOW_FRAME_MAKEUP)
|
||||
FIXME("Singe Frame snapshots Finishing\n");
|
||||
isDumpingFrames = FALSE;
|
||||
#endif
|
||||
FIXME("Singe Frame trace complete\n");
|
||||
DeleteFileA("C:\\D3DTRACE");
|
||||
__WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (isOn) {
|
||||
isOn = FALSE;
|
||||
#if defined(SHOW_FRAME_MAKEUP)
|
||||
FIXME("Single Frame snapshots Finishing\n");
|
||||
isDumpingFrames = FALSE;
|
||||
#endif
|
||||
FIXME("Disabling D3D Trace\n");
|
||||
__WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LEAVE_GL();
|
||||
|
||||
if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
|
||||
TRACE("Clearing the color buffer with pink color\n");
|
||||
|
||||
IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL,
|
||||
WINED3DCLEAR_TARGET, 0xff00ffff, 1.0, 0);
|
||||
}
|
||||
|
||||
if(((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM ||
|
||||
((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) {
|
||||
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */
|
||||
IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
|
||||
IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
|
||||
BOOL frontuptodate = front->Flags & SFLAG_INSYSMEM;
|
||||
BOOL backuptodate = back->Flags & SFLAG_INSYSMEM;
|
||||
|
||||
if(front->resource.size == back->resource.size) {
|
||||
/* Flip the DC */
|
||||
{
|
||||
HDC tmp;
|
||||
tmp = front->hDC;
|
||||
front->hDC = back->hDC;
|
||||
back->hDC = tmp;
|
||||
}
|
||||
|
||||
/* Flip the DIBsection */
|
||||
{
|
||||
HBITMAP tmp;
|
||||
BOOL hasDib = front->Flags & SFLAG_DIBSECTION;
|
||||
tmp = front->dib.DIBsection;
|
||||
front->dib.DIBsection = back->dib.DIBsection;
|
||||
back->dib.DIBsection = tmp;
|
||||
|
||||
if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION;
|
||||
else front->Flags &= ~SFLAG_DIBSECTION;
|
||||
if(hasDib) back->Flags |= SFLAG_DIBSECTION;
|
||||
else back->Flags &= ~SFLAG_DIBSECTION;
|
||||
}
|
||||
|
||||
/* Flip the surface data */
|
||||
{
|
||||
void* tmp;
|
||||
|
||||
tmp = front->dib.bitmap_data;
|
||||
front->dib.bitmap_data = back->dib.bitmap_data;
|
||||
back->dib.bitmap_data = tmp;
|
||||
|
||||
tmp = front->resource.allocatedMemory;
|
||||
front->resource.allocatedMemory = back->resource.allocatedMemory;
|
||||
back->resource.allocatedMemory = tmp;
|
||||
}
|
||||
|
||||
/* client_memory should not be different, but just in case */
|
||||
{
|
||||
BOOL tmp;
|
||||
tmp = front->dib.client_memory;
|
||||
front->dib.client_memory = back->dib.client_memory;
|
||||
back->dib.client_memory = tmp;
|
||||
}
|
||||
if(frontuptodate) back->Flags |= SFLAG_INSYSMEM;
|
||||
else back->Flags &= ~SFLAG_INSYSMEM;
|
||||
if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
|
||||
else front->Flags &= ~SFLAG_INSYSMEM;
|
||||
} else {
|
||||
back->Flags &= ~SFLAG_INSYSMEM;
|
||||
front->Flags &= ~SFLAG_INSYSMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if(This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE && GL_SUPPORT(SGI_VIDEO_SYNC)) {
|
||||
retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync));
|
||||
if(retval != 0) {
|
||||
ERR("glXGetVideoSyncSGI failed(retval = %d\n", retval);
|
||||
}
|
||||
|
||||
switch(This->presentParms.PresentationInterval) {
|
||||
case WINED3DPRESENT_INTERVAL_DEFAULT:
|
||||
case WINED3DPRESENT_INTERVAL_ONE:
|
||||
if(sync <= This->vSyncCounter) {
|
||||
retval = GL_EXTCALL(glXWaitVideoSyncSGI(1, 0, &This->vSyncCounter));
|
||||
} else {
|
||||
This->vSyncCounter = sync;
|
||||
}
|
||||
break;
|
||||
case WINED3DPRESENT_INTERVAL_TWO:
|
||||
if(sync <= This->vSyncCounter + 1) {
|
||||
retval = GL_EXTCALL(glXWaitVideoSyncSGI(2, This->vSyncCounter & 0x1, &This->vSyncCounter));
|
||||
} else {
|
||||
This->vSyncCounter = sync;
|
||||
}
|
||||
break;
|
||||
case WINED3DPRESENT_INTERVAL_THREE:
|
||||
if(sync <= This->vSyncCounter + 2) {
|
||||
retval = GL_EXTCALL(glXWaitVideoSyncSGI(3, This->vSyncCounter % 0x3, &This->vSyncCounter));
|
||||
} else {
|
||||
This->vSyncCounter = sync;
|
||||
}
|
||||
break;
|
||||
case WINED3DPRESENT_INTERVAL_FOUR:
|
||||
if(sync <= This->vSyncCounter + 3) {
|
||||
retval = GL_EXTCALL(glXWaitVideoSyncSGI(4, This->vSyncCounter & 0x3, &This->vSyncCounter));
|
||||
} else {
|
||||
This->vSyncCounter = sync;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown presentation interval %08x\n", This->presentParms.PresentationInterval);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("returning\n");
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
POINT start;
|
||||
|
||||
TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
|
||||
|
||||
start.x = 0;
|
||||
start.y = 0;
|
||||
|
||||
if (This->presentParms.Windowed) {
|
||||
MapWindowPoints(This->win_handle, NULL, &start, 1);
|
||||
}
|
||||
|
||||
IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
|
||||
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
|
||||
if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
|
||||
TRACE("Back buffer count out of range\n");
|
||||
/* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here
|
||||
* in wined3d to avoid problems in other libs
|
||||
*/
|
||||
*ppBackBuffer = NULL;
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
*ppBackBuffer = This->backBuffer[iBackBuffer];
|
||||
TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
|
||||
|
||||
/* Note inc ref on returned surface */
|
||||
if(*ppBackBuffer) IWineD3DSurface_AddRef(*ppBackBuffer);
|
||||
return WINED3D_OK;
|
||||
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
static BOOL showFixmes = TRUE;
|
||||
pRasterStatus->InVBlank = TRUE;
|
||||
pRasterStatus->ScanLine = 0;
|
||||
/* No openGL equivalent */
|
||||
if(showFixmes) {
|
||||
FIXME("(%p) : stub (once)\n", This);
|
||||
showFixmes = FALSE;
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
HDC hdc;
|
||||
int bpp = 0;
|
||||
|
||||
pMode->Width = GetSystemMetrics(SM_CXSCREEN);
|
||||
pMode->Height = GetSystemMetrics(SM_CYSCREEN);
|
||||
pMode->RefreshRate = 85; /* FIXME: How to identify? */
|
||||
|
||||
hdc = GetDC(0);
|
||||
bpp = GetDeviceCaps(hdc, BITSPIXEL);
|
||||
ReleaseDC(0, hdc);
|
||||
|
||||
switch (bpp) {
|
||||
case 8: pMode->Format = WINED3DFMT_R8G8B8; break;
|
||||
case 16: pMode->Format = WINED3DFMT_R5G6B5; break;
|
||||
case 24: /*pMode->Format = WINED3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
|
||||
case 32: pMode->Format = WINED3DFMT_A8R8G8B8; break;
|
||||
default:
|
||||
FIXME("Unrecognized display mode format\n");
|
||||
pMode->Format = WINED3DFMT_UNKNOWN;
|
||||
}
|
||||
|
||||
TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
|
||||
pMode->Format, debug_d3dformat(pMode->Format));
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
|
||||
*ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
|
||||
|
||||
/* Note Calling this method will increase the internal reference count
|
||||
on the IDirect3DDevice9 interface. */
|
||||
IWineD3DDevice_AddRef(*ppDevice);
|
||||
TRACE("(%p) : returning %p\n", This, *ppDevice);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
*pPresentationParameters = This->presentParms;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){
|
||||
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
HDC hDC;
|
||||
TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags);
|
||||
hDC = GetDC(This->win_handle);
|
||||
SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
|
||||
ReleaseDC(This->win_handle, hDC);
|
||||
return WINED3D_OK;
|
||||
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
|
||||
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||
HDC hDC;
|
||||
TRACE("(%p) : pRamp@%p\n", This, pRamp);
|
||||
hDC = GetDC(This->win_handle);
|
||||
GetDeviceGammaRamp(hDC, pRamp);
|
||||
ReleaseDC(This->win_handle, hDC);
|
||||
return WINED3D_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DSwapChainImpl_QueryInterface,
|
||||
IWineD3DSwapChainImpl_AddRef,
|
||||
IWineD3DSwapChainImpl_Release,
|
||||
/* IWineD3DSwapChain */
|
||||
IWineD3DSwapChainImpl_GetParent,
|
||||
IWineD3DSwapChainImpl_Destroy,
|
||||
IWineD3DSwapChainImpl_GetDevice,
|
||||
IWineD3DSwapChainImpl_Present,
|
||||
IWineD3DSwapChainImpl_GetFrontBufferData,
|
||||
IWineD3DSwapChainImpl_GetBackBuffer,
|
||||
IWineD3DSwapChainImpl_GetRasterStatus,
|
||||
IWineD3DSwapChainImpl_GetDisplayMode,
|
||||
IWineD3DSwapChainImpl_GetPresentParameters,
|
||||
IWineD3DSwapChainImpl_SetGammaRamp,
|
||||
IWineD3DSwapChainImpl_GetGammaRamp
|
||||
};
|
||||
|
||||
WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface) {
|
||||
WineD3DContext *ctx;
|
||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
|
||||
WineD3DContext **newArray;
|
||||
|
||||
TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
|
||||
|
||||
ctx = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer,
|
||||
This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms);
|
||||
if(!ctx) {
|
||||
ERR("Failed to create a new context for the swapchain\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * This->num_contexts + 1);
|
||||
if(!newArray) {
|
||||
ERR("Out of memory when trying to allocate a new context array\n");
|
||||
DestroyContext(This->wineD3DDevice, ctx);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(newArray, This->context, sizeof(*newArray) * This->num_contexts);
|
||||
HeapFree(GetProcessHeap(), 0, This->context);
|
||||
newArray[This->num_contexts] = ctx;
|
||||
This->context = newArray;
|
||||
This->num_contexts++;
|
||||
|
||||
TRACE("Returning context %p\n", ctx);
|
||||
return ctx;
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* IWineD3DTexture implementation
|
||||
*
|
||||
* Copyright 2002-2005 Jason Edmeades
|
||||
* Copyright 2002-2005 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_texture);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DTexture IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_QueryInterface(IWineD3DTexture *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseTexture)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DTexture)){
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DTextureImpl_AddRef(IWineD3DTexture *iface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref);
|
||||
return InterlockedIncrement(&This->resource.ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
|
||||
ref = InterlockedDecrement(&This->resource.ref);
|
||||
if (ref == 0) {
|
||||
IWineD3DTexture_Destroy(iface, D3DCB_DefaultDestroySurface);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DTexture IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_GetDevice(IWineD3DTexture *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_SetPrivateData(IWineD3DTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_GetPrivateData(IWineD3DTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_FreePrivateData(IWineD3DTexture *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DTextureImpl_SetPriority(IWineD3DTexture *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DTextureImpl_GetPriority(IWineD3DTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
|
||||
|
||||
/* Override the IWineD3DResource PreLoad method */
|
||||
unsigned int i;
|
||||
BOOL setGlTextureDesc = FALSE;
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
BOOL srgb_mode = This->baseTexture.is_srgb;
|
||||
BOOL srgb_was_toggled = FALSE;
|
||||
|
||||
TRACE("(%p) : About to load texture\n", This);
|
||||
|
||||
if (This->baseTexture.textureName == 0) setGlTextureDesc = TRUE;
|
||||
|
||||
if(!device->isInDraw) {
|
||||
/* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture, thus no danger of
|
||||
* recursive calls
|
||||
*/
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
|
||||
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
|
||||
srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
|
||||
This->baseTexture.is_srgb = srgb_mode;
|
||||
}
|
||||
|
||||
IWineD3DTexture_BindTexture(iface);
|
||||
ENTER_GL();
|
||||
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
|
||||
if (This->baseTexture.dirty) {
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
if(setGlTextureDesc)
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
|
||||
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
|
||||
}
|
||||
} else if (srgb_was_toggled) {
|
||||
if (This->baseTexture.srgb_mode_change_count < 20)
|
||||
++This->baseTexture.srgb_mode_change_count;
|
||||
else
|
||||
FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
|
||||
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[i], NULL);
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
|
||||
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
|
||||
}
|
||||
} else {
|
||||
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
|
||||
}
|
||||
LEAVE_GL();
|
||||
|
||||
/* No longer dirty */
|
||||
This->baseTexture.dirty = FALSE;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DTextureImpl_GetType(IWineD3DTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_GetParent(IWineD3DTexture *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DTexture IWineD3DBaseTexture parts follow
|
||||
****************************************************** */
|
||||
static DWORD WINAPI IWineD3DTextureImpl_SetLOD(IWineD3DTexture *iface, DWORD LODNew) {
|
||||
return IWineD3DBaseTextureImpl_SetLOD((IWineD3DBaseTexture *)iface, LODNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DTextureImpl_GetLOD(IWineD3DTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLOD((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DTextureImpl_GetLevelCount(IWineD3DTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLevelCount((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_SetAutoGenFilterType(IWineD3DTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
|
||||
return IWineD3DBaseTextureImpl_SetAutoGenFilterType((IWineD3DBaseTexture *)iface, FilterType);
|
||||
}
|
||||
|
||||
static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DTextureImpl_GetAutoGenFilterType(IWineD3DTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetAutoGenFilterType((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DTextureImpl_GenerateMipSubLevels(IWineD3DTexture *iface) {
|
||||
IWineD3DBaseTextureImpl_GenerateMipSubLevels((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
/* Internal function, No d3d mapping */
|
||||
static BOOL WINAPI IWineD3DTextureImpl_SetDirty(IWineD3DTexture *iface, BOOL dirty) {
|
||||
return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty);
|
||||
}
|
||||
|
||||
static BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_BindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_UnBindTexture(IWineD3DTexture *iface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_UnBindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *iface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface,
|
||||
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
|
||||
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
float matrix[16];
|
||||
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
|
||||
|
||||
/** non-power2 fixups using texture matrix **/
|
||||
if(This->pow2scalingFactorX != 1.0f || This->pow2scalingFactorY != 1.0f) {
|
||||
/* Apply non-power2 mappings and texture offsets so long as the texture coords aren't projected or generated */
|
||||
if(((textureStates[WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) == WINED3DTSS_TCI_PASSTHRU) &&
|
||||
(~textureStates[WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)) {
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
memset(matrix, 0 , sizeof(matrix));
|
||||
matrix[0] = This->pow2scalingFactorX;
|
||||
matrix[5] = This->pow2scalingFactorY;
|
||||
#if 0 /* this isn't needed any more, I changed the translation in drawprim.c to 0.9/width instead of 1/width and everything lines up ok. left here as a reminder */
|
||||
matrix[12] = -0.25f / (float)This->width;
|
||||
matrix[13] = -0.75f / (float)This->height;
|
||||
#endif
|
||||
matrix[10] = 1;
|
||||
matrix[15] = 1;
|
||||
TRACE("(%p) Setup Matrix:\n", This);
|
||||
TRACE(" %f %f %f %f\n", matrix[0], matrix[1], matrix[2], matrix[3]);
|
||||
TRACE(" %f %f %f %f\n", matrix[4], matrix[5], matrix[6], matrix[7]);
|
||||
TRACE(" %f %f %f %f\n", matrix[8], matrix[9], matrix[10], matrix[11]);
|
||||
TRACE(" %f %f %f %f\n", matrix[12], matrix[13], matrix[14], matrix[15]);
|
||||
TRACE("\n");
|
||||
|
||||
glMultMatrixf(matrix);
|
||||
} else {
|
||||
/* I don't expect nonpower 2 textures to be used with generated texture coordinates, but if they are present a fixme. */
|
||||
FIXME("Non-power2 texture being used with generated texture coords\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DTexture IWineD3DTexture parts follow
|
||||
******************************************* */
|
||||
static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroySurface) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
int i;
|
||||
|
||||
TRACE("(%p) : Cleaning up\n",This);
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
if (This->surfaces[i] != NULL) {
|
||||
/* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
|
||||
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], 0, 0);
|
||||
IWineD3DSurface_SetContainer(This->surfaces[i], 0);
|
||||
D3DCB_DestroySurface(This->surfaces[i]);
|
||||
}
|
||||
}
|
||||
TRACE("(%p) : cleaning up base texture\n", This);
|
||||
IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *)iface);
|
||||
/* free the object */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_GetLevelDesc(IWineD3DTexture *iface, UINT Level, WINED3DSURFACE_DESC* pDesc) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
TRACE("(%p) Level (%d)\n", This, Level);
|
||||
return IWineD3DSurface_GetDesc(This->surfaces[Level], pDesc);
|
||||
}
|
||||
FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_GetSurfaceLevel(IWineD3DTexture *iface, UINT Level, IWineD3DSurface** ppSurfaceLevel) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
*ppSurfaceLevel = This->surfaces[Level];
|
||||
IWineD3DSurface_AddRef((IWineD3DSurface*) This->surfaces[Level]);
|
||||
hr = WINED3D_OK;
|
||||
TRACE("(%p) : returning %p for level %d\n", This, *ppSurfaceLevel, Level);
|
||||
}
|
||||
if (WINED3D_OK != hr) {
|
||||
WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
*ppSurfaceLevel = NULL; /* Just to be on the safe side.. */
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_LockRect(IWineD3DTexture *iface, UINT Level, WINED3DLOCKED_RECT *pLockedRect,
|
||||
CONST RECT *pRect, DWORD Flags) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
hr = IWineD3DSurface_LockRect(This->surfaces[Level], pLockedRect, pRect, Flags);
|
||||
}
|
||||
if (WINED3D_OK == hr) {
|
||||
TRACE("(%p) Level (%d) success\n", This, Level);
|
||||
} else {
|
||||
WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UINT Level) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
HRESULT hr = WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
hr = IWineD3DSurface_UnlockRect(This->surfaces[Level]);
|
||||
}
|
||||
if ( WINED3D_OK == hr) {
|
||||
TRACE("(%p) Level (%d) success\n", This, Level);
|
||||
} else {
|
||||
WARN("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) {
|
||||
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
|
||||
This->baseTexture.dirty = TRUE;
|
||||
TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
|
||||
return IWineD3DSurface_AddDirtyRect(This->surfaces[0], pDirtyRect);
|
||||
}
|
||||
|
||||
const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DTextureImpl_QueryInterface,
|
||||
IWineD3DTextureImpl_AddRef,
|
||||
IWineD3DTextureImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DTextureImpl_GetParent,
|
||||
IWineD3DTextureImpl_GetDevice,
|
||||
IWineD3DTextureImpl_SetPrivateData,
|
||||
IWineD3DTextureImpl_GetPrivateData,
|
||||
IWineD3DTextureImpl_FreePrivateData,
|
||||
IWineD3DTextureImpl_SetPriority,
|
||||
IWineD3DTextureImpl_GetPriority,
|
||||
IWineD3DTextureImpl_PreLoad,
|
||||
IWineD3DTextureImpl_GetType,
|
||||
/* IWineD3DBaseTexture */
|
||||
IWineD3DTextureImpl_SetLOD,
|
||||
IWineD3DTextureImpl_GetLOD,
|
||||
IWineD3DTextureImpl_GetLevelCount,
|
||||
IWineD3DTextureImpl_SetAutoGenFilterType,
|
||||
IWineD3DTextureImpl_GetAutoGenFilterType,
|
||||
IWineD3DTextureImpl_GenerateMipSubLevels,
|
||||
IWineD3DTextureImpl_SetDirty,
|
||||
IWineD3DTextureImpl_GetDirty,
|
||||
IWineD3DTextureImpl_BindTexture,
|
||||
IWineD3DTextureImpl_UnBindTexture,
|
||||
IWineD3DTextureImpl_GetTextureDimensions,
|
||||
IWineD3DTextureImpl_ApplyStateChanges,
|
||||
/* IWineD3DTexture */
|
||||
IWineD3DTextureImpl_Destroy,
|
||||
IWineD3DTextureImpl_GetLevelDesc,
|
||||
IWineD3DTextureImpl_GetSurfaceLevel,
|
||||
IWineD3DTextureImpl_LockRect,
|
||||
IWineD3DTextureImpl_UnlockRect,
|
||||
IWineD3DTextureImpl_AddDirtyRect
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2001 Ove Kaaven
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WINE_OLESELFREGISTER
|
||||
#define WINE_FILEDESCRIPTION_STR "Wine WineD3D OpenGL (Licen LGPL)"
|
||||
#define WINE_FILENAME_STR "wined3d.dll"
|
||||
#define WINE_FILEVERSION 5,3,1,904
|
||||
#define WINE_FILEVERSION_STR "5.3.1.904"
|
||||
#define WINE_PRODUCTVERSION 5,3,1,904
|
||||
#define WINE_PRODUCTVERSION_STR "5.3.1.904"
|
||||
|
||||
#include "wine/wine_common_ver.rc"
|
||||
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* IWineD3DVertexBuffer Implementation
|
||||
*
|
||||
* Copyright 2002-2005 Jason Edmeades
|
||||
* Raphael Junqueira
|
||||
* Copyright 2004 Christian Costa
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
#define VB_MAXDECLCHANGES 100 /* After that number we stop converting */
|
||||
#define VB_RESETDECLCHANGE 1000 /* Reset the changecount after that number of draws */
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVertexBuffer IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_QueryInterface(IWineD3DVertexBuffer *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DVertexBuffer)){
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexBufferImpl_AddRef(IWineD3DVertexBuffer *iface) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
ULONG ref = InterlockedIncrement(&This->resource.ref);
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, ref - 1);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexBufferImpl_Release(IWineD3DVertexBuffer *iface) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
ULONG ref = InterlockedDecrement(&This->resource.ref);
|
||||
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
|
||||
if (ref == 0) {
|
||||
|
||||
if(This->vbo) {
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
|
||||
checkGLcall("glDeleteBuffersARB");
|
||||
LEAVE_GL();
|
||||
}
|
||||
|
||||
IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DVertexBuffer IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_GetDevice(IWineD3DVertexBuffer *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_SetPrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_GetPrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_FreePrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVertexBufferImpl_SetPriority(IWineD3DVertexBuffer *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVertexBufferImpl_GetPriority(IWineD3DVertexBuffer *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void fixup_vertices(
|
||||
BYTE *src, BYTE *dst,
|
||||
int stride,
|
||||
int num,
|
||||
int pos, BOOL haspos,
|
||||
int diffuse, BOOL hasdiffuse,
|
||||
int specular, BOOL hasspecular
|
||||
) {
|
||||
int i;
|
||||
float x, y, z, w;
|
||||
|
||||
for(i = num - 1; i >= 0; i--) {
|
||||
if(haspos) {
|
||||
float *p = (float *) ((src + pos) + i * stride);
|
||||
|
||||
/* rhw conversion like in drawStridedSlow */
|
||||
if(p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps))) {
|
||||
x = p[0];
|
||||
y = p[1];
|
||||
z = p[2];
|
||||
w = 1.0;
|
||||
} else {
|
||||
w = 1.0 / p[3];
|
||||
x = p[0] * w;
|
||||
y = p[1] * w;
|
||||
z = p[2] * w;
|
||||
}
|
||||
p = (float *) (dst + i * stride + pos);
|
||||
p[0] = x;
|
||||
p[1] = y;
|
||||
p[2] = z;
|
||||
p[3] = w;
|
||||
}
|
||||
if(hasdiffuse) {
|
||||
DWORD srcColor, *dstColor = (DWORD *) (dst + i * stride + diffuse);
|
||||
srcColor = * (DWORD *) ( (src + diffuse) + i * stride);
|
||||
|
||||
/* Color conversion like in drawStridedSlow. watch out for little endianity
|
||||
* If we want that stuff to work on big endian machines too we have to consider more things
|
||||
*
|
||||
* 0xff000000: Alpha mask
|
||||
* 0x00ff0000: Blue mask
|
||||
* 0x0000ff00: Green mask
|
||||
* 0x000000ff: Red mask
|
||||
*/
|
||||
|
||||
*dstColor = 0;
|
||||
*dstColor |= (srcColor & 0xff00ff00) ; /* Alpha Green */
|
||||
*dstColor |= (srcColor & 0x00ff0000) >> 16; /* Red */
|
||||
*dstColor |= (srcColor & 0x000000ff) << 16; /* Blue */
|
||||
}
|
||||
if(hasspecular) {
|
||||
DWORD srcColor, *dstColor = (DWORD *) (dst + i * stride + specular);
|
||||
srcColor = * (DWORD *) ( (src + specular) + i * stride);
|
||||
|
||||
/* Similar to diffuse
|
||||
* TODO: Write the alpha value out for fog coords
|
||||
*/
|
||||
*dstColor = 0;
|
||||
*dstColor |= (srcColor & 0xff00ff00) ; /* Alpha Green */
|
||||
*dstColor |= (srcColor & 0x00ff0000) >> 16; /* Red */
|
||||
*dstColor |= (srcColor & 0x000000ff) << 16; /* Blue */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *This)
|
||||
{
|
||||
WineDirect3DVertexStridedData strided;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
|
||||
/* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
|
||||
* Once we have our declaration there is no need to look it up again.
|
||||
*/
|
||||
if(((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->Flags & VBFLAG_HASDESC) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* There are certain vertex data types that need to be fixed up. The Vertex Buffers FVF doesn't
|
||||
* help finding them, only the vertex declaration or the device FVF can determine that at drawPrim
|
||||
* time. Rules are as follows:
|
||||
*
|
||||
* -> No modification when Vertex Shaders are used
|
||||
* -> Fix up position1 and position 2 if they are XYZRHW
|
||||
* -> Fix up diffuse color
|
||||
* -> Fix up specular color
|
||||
*
|
||||
* The Declaration is only known at drawing time, and it can change from draw to draw. If any converted values
|
||||
* are changed, the whole buffer has to be reconverted and reloaded. (Converting is SLOW, so if this happens too
|
||||
* often PreLoad stops converting entirely and falls back to drawStridedSlow).
|
||||
*
|
||||
* Reconvert if:
|
||||
* -> New semantics that have to be converted appear
|
||||
* -> The position of semantics that have to be converted changes
|
||||
* -> The stride of the vertex changed AND there is stuff that needs conversion
|
||||
* -> (If a vertex shader is bound and in use assume that nothing that needs conversion is there)
|
||||
*
|
||||
* Return values:
|
||||
* TRUE: Reload is needed
|
||||
* FALSE: otherwise
|
||||
*/
|
||||
|
||||
if (use_vs(device)) {
|
||||
/* Assume no conversion */
|
||||
memset(&strided, 0, sizeof(strided));
|
||||
} else {
|
||||
/* we need a copy because we modify some params */
|
||||
memcpy(&strided, &device->strided_streams, sizeof(strided));
|
||||
|
||||
/* Filter out data that does not come from this VBO */
|
||||
if(strided.u.s.position.VBO != This->vbo) memset(&strided.u.s.position, 0, sizeof(strided.u.s.position));
|
||||
if(strided.u.s.diffuse.VBO != This->vbo) memset(&strided.u.s.diffuse, 0, sizeof(strided.u.s.diffuse));
|
||||
if(strided.u.s.specular.VBO != This->vbo) memset(&strided.u.s.specular, 0, sizeof(strided.u.s.specular));
|
||||
if(strided.u.s.position2.VBO != This->vbo) memset(&strided.u.s.position2, 0, sizeof(strided.u.s.position2));
|
||||
}
|
||||
|
||||
/* We have a declaration now in the buffer */
|
||||
This->Flags |= VBFLAG_HASDESC;
|
||||
|
||||
/* Find out if reload is needed
|
||||
* Position of the semantic in the vertex and the stride must be equal to the stored type. Don't mind if only unconverted stuff changed.
|
||||
*
|
||||
* If some stuff does not exist in the buffer, then lpData, dwStride and dwType are memsetted to 0. So if the semantic didn't exist before
|
||||
* and does not exist now all 3 values will be equal(=0).
|
||||
*
|
||||
* Checking the lpData field alone is not enough, because data may appear at offset 0 in the buffer. This is the same location as nonexistent
|
||||
* data uses, so we have to check the type and stride too. Colors can be at offset 0 too, because it is perfectly fine to render from 2 or more
|
||||
* buffers at the same time and get the position from one and the color from the other buffer.
|
||||
*/
|
||||
if( /* Position transformed vs untransformed */
|
||||
((This->strided.u.s.position_transformed || strided.u.s.position_transformed) &&
|
||||
(This->strided.u.s.position.lpData != strided.u.s.position.lpData ||
|
||||
This->strided.u.s.position.dwType != strided.u.s.position.dwType)) ||
|
||||
/* Diffuse position and data type */
|
||||
This->strided.u.s.diffuse.lpData != strided.u.s.diffuse.lpData || This->strided.u.s.diffuse.dwStride != strided.u.s.diffuse.dwStride ||
|
||||
This->strided.u.s.diffuse.dwType != strided.u.s.diffuse.dwType ||
|
||||
/* Specular position and data type */
|
||||
This->strided.u.s.specular.lpData != strided.u.s.specular.lpData || This->strided.u.s.specular.dwStride != strided.u.s.specular.dwStride ||
|
||||
This->strided.u.s.specular.dwType != strided.u.s.specular.dwType) {
|
||||
|
||||
TRACE("Declaration changed, reloading buffer\n");
|
||||
/* Set the new description */
|
||||
memcpy(&This->strided, &strided, sizeof(strided));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
BYTE *data;
|
||||
UINT start = 0, end = 0, stride = 0;
|
||||
BOOL declChanged = FALSE;
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
if(This->Flags & VBFLAG_LOAD) {
|
||||
return; /* Already doing that stuff */
|
||||
}
|
||||
|
||||
if(!This->vbo) {
|
||||
/* TODO: Make converting independent from VBOs */
|
||||
return; /* Not doing any conversion */
|
||||
}
|
||||
|
||||
/* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */
|
||||
if(device->isInDraw && This->bindCount > 0) {
|
||||
declChanged = IWineD3DVertexBufferImpl_FindDecl(This);
|
||||
} else if(This->Flags & VBFLAG_HASDESC) {
|
||||
/* Reuse the declaration stored in the buffer. It will most likely not change, and if it does
|
||||
* the stream source state handler will call PreLoad again and the change will be cought
|
||||
*/
|
||||
} else {
|
||||
/* Cannot get a declaration, and no declaration is stored in the buffer. It is pointless to preload
|
||||
* now. When the buffer is used, PreLoad will be called by the stream source state handler and a valid
|
||||
* declaration for the buffer can be found
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* If applications change the declaration over and over, reconverting all the time is a huge
|
||||
* performance hit. So count the declaration changes and release the VBO if there are too much
|
||||
* of them(and thus stop converting)
|
||||
*/
|
||||
if(declChanged) {
|
||||
This->declChanges++;
|
||||
This->draws = 0;
|
||||
|
||||
if(This->declChanges > VB_MAXDECLCHANGES) {
|
||||
FIXME("Too much declaration changes, stopping converting\n");
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
|
||||
checkGLcall("glDeleteBuffersARB");
|
||||
LEAVE_GL();
|
||||
This->vbo = 0;
|
||||
|
||||
/* The stream source state handler might have read the memory of the vertex buffer already
|
||||
* and got the memory in the vbo which is not valid any longer. Dirtify the stream source
|
||||
* to force a reload. This happens only once per changed vertexbuffer and should occur rather
|
||||
* rarely
|
||||
*/
|
||||
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
|
||||
* changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without
|
||||
* decl changes and reset the decl change count after a specific number of them
|
||||
*/
|
||||
This->draws++;
|
||||
if(This->draws > VB_RESETDECLCHANGE) This->declChanges = 0;
|
||||
}
|
||||
|
||||
if(declChanged) {
|
||||
/* The declaration changed, reload the whole buffer */
|
||||
WARN("Reloading buffer because of decl change\n");
|
||||
start = 0;
|
||||
end = This->resource.size;
|
||||
} else if(This->Flags & VBFLAG_DIRTY) {
|
||||
/* No decl change, but dirty data, reload the changed stuff */
|
||||
start = This->dirtystart;
|
||||
end = This->dirtyend;
|
||||
} else {
|
||||
/* Desc not changed, buffer not dirty, nothing to do :-) */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark the buffer clean */
|
||||
This->Flags &= ~VBFLAG_DIRTY;
|
||||
This->dirtystart = 0;
|
||||
This->dirtyend = 0;
|
||||
|
||||
if (This->strided.u.s.position.dwStride) stride = This->strided.u.s.position.dwStride;
|
||||
else if(This->strided.u.s.specular.dwStride) stride = This->strided.u.s.specular.dwStride;
|
||||
else if(This->strided.u.s.diffuse.dwStride) stride = This->strided.u.s.diffuse.dwStride;
|
||||
else {
|
||||
/* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory
|
||||
* directly into the vbo. Do not free the system memory copy because drawPrimitive may need it if
|
||||
* the stride is 0, for instancing emulation, vertex blending emulation or shader emulation.
|
||||
*/
|
||||
TRACE("No conversion needed, locking directly into the VBO in future\n");
|
||||
|
||||
if(!device->isInDraw) {
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
}
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
|
||||
checkGLcall("glBindBufferARB");
|
||||
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start));
|
||||
checkGLcall("glBufferSubDataARB");
|
||||
LEAVE_GL();
|
||||
return;
|
||||
}
|
||||
|
||||
/* OK, we have the original data from the app, the description of the buffer and the dirty area.
|
||||
* so convert the stuff
|
||||
*/
|
||||
data = HeapAlloc(GetProcessHeap(), 0, end-start);
|
||||
if(!data) {
|
||||
ERR("Out of memory\n");
|
||||
return;
|
||||
}
|
||||
memcpy(data, This->resource.allocatedMemory + start, end - start);
|
||||
|
||||
fixup_vertices(data, data, stride, ( end - start) / stride,
|
||||
/* Position */
|
||||
(int)This->strided.u.s.position.lpData, /* Data location */
|
||||
This->strided.u.s.position_transformed, /* Do convert? */
|
||||
/* Diffuse color */
|
||||
(int)This->strided.u.s.diffuse.lpData, /* Location */
|
||||
This->strided.u.s.diffuse.dwType == WINED3DDECLTYPE_SHORT4 || This->strided.u.s.diffuse.dwType == WINED3DDECLTYPE_D3DCOLOR, /* Convert? */
|
||||
/* specular color */
|
||||
(int)This->strided.u.s.specular.lpData, /* location */
|
||||
This->strided.u.s.specular.dwType == WINED3DDECLTYPE_SHORT4 || This->strided.u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR);
|
||||
|
||||
if(!device->isInDraw) {
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
}
|
||||
ENTER_GL();
|
||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
|
||||
checkGLcall("glBindBufferARB");
|
||||
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data));
|
||||
checkGLcall("glBufferSubDataARB");
|
||||
LEAVE_GL();
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DVertexBufferImpl_GetType(IWineD3DVertexBuffer *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_GetParent(IWineD3DVertexBuffer *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DVertexBuffer IWineD3DVertexBuffer parts follow
|
||||
****************************************************** */
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface, UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
BYTE *data;
|
||||
TRACE("(%p)->%d, %d, %p, %08x\n", This, OffsetToLock, SizeToLock, ppbData, Flags);
|
||||
|
||||
InterlockedIncrement(&This->lockcount);
|
||||
|
||||
if(This->Flags & VBFLAG_DIRTY) {
|
||||
if(This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
|
||||
if(SizeToLock) {
|
||||
if(This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
|
||||
} else {
|
||||
This->dirtyend = This->resource.size;
|
||||
}
|
||||
} else {
|
||||
This->dirtystart = OffsetToLock;
|
||||
if(SizeToLock)
|
||||
This->dirtyend = OffsetToLock + SizeToLock;
|
||||
else
|
||||
This->dirtyend = This->resource.size;
|
||||
}
|
||||
|
||||
data = This->resource.allocatedMemory;
|
||||
This->Flags |= VBFLAG_DIRTY;
|
||||
*ppbData = data + OffsetToLock;
|
||||
|
||||
TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, data + OffsetToLock, data, OffsetToLock);
|
||||
/* TODO: check Flags compatibility with This->currentDesc.Usage (see MSDN) */
|
||||
return WINED3D_OK;
|
||||
}
|
||||
HRESULT WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
|
||||
LONG lockcount;
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
lockcount = InterlockedDecrement(&This->lockcount);
|
||||
if(lockcount > 0) {
|
||||
/* Delay loading the buffer until everything is unlocked */
|
||||
TRACE("Ignoring the unlock\n");
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
if(This->Flags & VBFLAG_HASDESC) {
|
||||
IWineD3DVertexBufferImpl_PreLoad(iface);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
static HRESULT WINAPI IWineD3DVertexBufferImpl_GetDesc(IWineD3DVertexBuffer *iface, WINED3DVERTEXBUFFER_DESC *pDesc) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
pDesc->Format = This->resource.format;
|
||||
pDesc->Type = This->resource.resourceType;
|
||||
pDesc->Usage = This->resource.usage;
|
||||
pDesc->Pool = This->resource.pool;
|
||||
pDesc->Size = This->resource.size;
|
||||
pDesc->FVF = This->fvf;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DVertexBufferImpl_QueryInterface,
|
||||
IWineD3DVertexBufferImpl_AddRef,
|
||||
IWineD3DVertexBufferImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DVertexBufferImpl_GetParent,
|
||||
IWineD3DVertexBufferImpl_GetDevice,
|
||||
IWineD3DVertexBufferImpl_SetPrivateData,
|
||||
IWineD3DVertexBufferImpl_GetPrivateData,
|
||||
IWineD3DVertexBufferImpl_FreePrivateData,
|
||||
IWineD3DVertexBufferImpl_SetPriority,
|
||||
IWineD3DVertexBufferImpl_GetPriority,
|
||||
IWineD3DVertexBufferImpl_PreLoad,
|
||||
IWineD3DVertexBufferImpl_GetType,
|
||||
/* IWineD3DVertexBuffer */
|
||||
IWineD3DVertexBufferImpl_Lock,
|
||||
IWineD3DVertexBufferImpl_Unlock,
|
||||
IWineD3DVertexBufferImpl_GetDesc
|
||||
};
|
||||
|
||||
BYTE* WINAPI IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer* iface, DWORD iOffset, GLint *vbo) {
|
||||
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
|
||||
|
||||
*vbo = This->vbo;
|
||||
if(This->vbo == 0) {
|
||||
return This->resource.allocatedMemory + iOffset;
|
||||
} else {
|
||||
return (BYTE *) iOffset;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WINAPI IWineD3DVertexBufferImpl_ReleaseMemory(IWineD3DVertexBuffer* iface) {
|
||||
return WINED3D_OK;
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* vertex declaration implementation
|
||||
*
|
||||
* Copyright 2002-2005 Raphael Junqueira
|
||||
* Copyright 2004 Jason Edmeades
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_decl);
|
||||
|
||||
static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT *element) {
|
||||
TRACE(" Stream: %d\n", element->Stream);
|
||||
TRACE(" Offset: %d\n", element->Offset);
|
||||
TRACE(" Type: %s (%#x)\n", debug_d3ddecltype(element->Type), element->Type);
|
||||
TRACE(" Method: %s (%#x)\n", debug_d3ddeclmethod(element->Method), element->Method);
|
||||
TRACE(" Usage: %s (%#x)\n", debug_d3ddeclusage(element->Usage), element->Usage);
|
||||
TRACE("Usage index: %d\n", element->UsageIndex);
|
||||
TRACE(" Register: %d\n", element->Reg);
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVertexDeclaration IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_QueryInterface(IWineD3DVertexDeclaration *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DVertexDeclaration)){
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexDeclarationImpl_AddRef(IWineD3DVertexDeclaration *iface) {
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *iface) {
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0) {
|
||||
if(iface == This->wineD3DDevice->stateBlock->vertexDecl) {
|
||||
/* See comment in PixelShader::Release */
|
||||
IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVertexDeclaration parts follow
|
||||
******************************************* */
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration *iface, IUnknown** parent){
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
|
||||
*parent= This->parent;
|
||||
IUnknown_AddRef(*parent);
|
||||
TRACE("(%p) : returning %p\n", This, *parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) {
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
TRACE("(%p) : returning %p\n", This, This->wineD3DDevice);
|
||||
|
||||
*ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
|
||||
IWineD3DDevice_AddRef(*ppDevice);
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface,
|
||||
WINED3DVERTEXELEMENT *elements, size_t *element_count) {
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
HRESULT hr = WINED3D_OK;
|
||||
|
||||
TRACE("(%p) : d3d version %d, elements %p, element_count %p\n",
|
||||
This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion, elements, element_count);
|
||||
|
||||
*element_count = This->declarationWNumElements;
|
||||
if (elements) {
|
||||
CopyMemory(elements, This->pDeclarationWine, This->declarationWNumElements * sizeof(WINED3DVERTEXELEMENT));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface,
|
||||
const WINED3DVERTEXELEMENT *elements, size_t element_count) {
|
||||
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
|
||||
HRESULT hr = WINED3D_OK;
|
||||
int i;
|
||||
char isPreLoaded[MAX_STREAMS];
|
||||
|
||||
TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
|
||||
memset(isPreLoaded, 0, sizeof(isPreLoaded));
|
||||
|
||||
if (TRACE_ON(d3d_decl)) {
|
||||
for (i = 0; i < element_count; ++i) {
|
||||
dump_wined3dvertexelement(elements+i);
|
||||
}
|
||||
}
|
||||
|
||||
This->declarationWNumElements = element_count;
|
||||
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count);
|
||||
if (!This->pDeclarationWine) {
|
||||
ERR("Memory allocation failed\n");
|
||||
hr = WINED3DERR_OUTOFVIDEOMEMORY;
|
||||
} else {
|
||||
CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count);
|
||||
}
|
||||
|
||||
/* Do some static analysis on the elements to make reading the declaration more comfortable
|
||||
* for the drawing code
|
||||
*/
|
||||
This->num_streams = 0;
|
||||
This->position_transformed = FALSE;
|
||||
for (i = 0; i < element_count; ++i) {
|
||||
|
||||
if(This->pDeclarationWine[i].Usage == WINED3DDECLUSAGE_POSITIONT) {
|
||||
This->position_transformed = TRUE;
|
||||
}
|
||||
|
||||
/* Find the Streams used in the declaration. The vertex buffers have to be loaded
|
||||
* when drawing, but filter tesselation pseudo streams
|
||||
*/
|
||||
if(This->pDeclarationWine[i].Stream >= MAX_STREAMS) continue;
|
||||
|
||||
if(!isPreLoaded[This->pDeclarationWine[i].Stream]) {
|
||||
This->streams[This->num_streams] = This->pDeclarationWine[i].Stream;
|
||||
This->num_streams++;
|
||||
isPreLoaded[This->pDeclarationWine[i].Stream] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Returning\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DVertexDeclarationImpl_QueryInterface,
|
||||
IWineD3DVertexDeclarationImpl_AddRef,
|
||||
IWineD3DVertexDeclarationImpl_Release,
|
||||
/* IWineD3DVertexDeclaration */
|
||||
IWineD3DVertexDeclarationImpl_GetParent,
|
||||
IWineD3DVertexDeclarationImpl_GetDevice,
|
||||
IWineD3DVertexDeclarationImpl_GetDeclaration,
|
||||
IWineD3DVertexDeclarationImpl_SetDeclaration
|
||||
};
|
||||
@@ -0,0 +1,663 @@
|
||||
/*
|
||||
* shaders implementation
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* Copyright 2004 Christian Costa
|
||||
* Copyright 2005 Oliver Stieber
|
||||
* Copyright 2006 Ivan Gyurdiev
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||
|
||||
#define GLINFO_LOCATION ((IWineD3DDeviceImpl *)This->baseShader.device)->adapter->gl_info
|
||||
|
||||
/* Shader debugging - Change the following line to enable debugging of software
|
||||
vertex shaders */
|
||||
#if 0 /* Musxt not be 1 in cvs version */
|
||||
# define VSTRACE(A) TRACE A
|
||||
# define TRACE_VSVECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
|
||||
#else
|
||||
# define VSTRACE(A)
|
||||
# define TRACE_VSVECTOR(name)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DirectX9 SDK download
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp
|
||||
*
|
||||
* Exploring D3DX
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp
|
||||
*
|
||||
* Using Vertex Shaders
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp
|
||||
*
|
||||
* Dx9 New
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp
|
||||
*
|
||||
* Dx9 Shaders
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp
|
||||
*
|
||||
* Dx9 D3DX
|
||||
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp
|
||||
*
|
||||
* FVF
|
||||
* http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp
|
||||
*
|
||||
* NVIDIA: DX8 Vertex Shader to NV Vertex Program
|
||||
* http://developer.nvidia.com/view.asp?IO=vstovp
|
||||
*
|
||||
* NVIDIA: Memory Management with VAR
|
||||
* http://developer.nvidia.com/view.asp?IO=var_memory_management
|
||||
*/
|
||||
|
||||
/* TODO: Vertex and Pixel shaders are almost identicle, the only exception being the way that some of the data is looked up or the availablity of some of the data i.e. some instructions are only valid for pshaders and some for vshaders
|
||||
because of this the bulk of the software pipeline can be shared between pixel and vertex shaders... and it wouldn't supprise me if the programes can be cross compiled using a large body body shared code */
|
||||
|
||||
#define GLNAME_REQUIRE_GLSL ((const char *)1)
|
||||
|
||||
CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
|
||||
/* This table is not order or position dependent. */
|
||||
|
||||
/* Arithmetic */
|
||||
{WINED3DSIO_NOP, "nop", "NOP", 0, 0, vshader_hw_map2gl, NULL, 0, 0},
|
||||
{WINED3DSIO_MOV, "mov", "MOV", 1, 2, vshader_hw_map2gl, shader_glsl_mov, 0, 0},
|
||||
{WINED3DSIO_MOVA, "mova", NULL, 1, 2, vshader_hw_map2gl, shader_glsl_mov, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_ADD, "add", "ADD", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_SUB, "sub", "SUB", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_MAD, "mad", "MAD", 1, 4, vshader_hw_map2gl, shader_glsl_mad, 0, 0},
|
||||
{WINED3DSIO_MUL, "mul", "MUL", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0},
|
||||
{WINED3DSIO_RCP, "rcp", "RCP", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rcp, 0, 0},
|
||||
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rsq, 0, 0},
|
||||
{WINED3DSIO_DP3, "dp3", "DP3", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0},
|
||||
{WINED3DSIO_DP4, "dp4", "DP4", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0},
|
||||
{WINED3DSIO_MIN, "min", "MIN", 1, 3, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_MAX, "max", "MAX", 1, 3, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_SLT, "slt", "SLT", 1, 3, vshader_hw_map2gl, shader_glsl_compare, 0, 0},
|
||||
{WINED3DSIO_SGE, "sge", "SGE", 1, 3, vshader_hw_map2gl, shader_glsl_compare, 0, 0},
|
||||
{WINED3DSIO_ABS, "abs", "ABS", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_EXP, "exp", "EX2", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_LOG, "log", "LG2", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_EXPP, "expp", "EXP", 1, 2, vshader_hw_map2gl, shader_glsl_expp, 0, 0},
|
||||
{WINED3DSIO_LOGP, "logp", "LOG", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_LIT, "lit", "LIT", 1, 2, vshader_hw_map2gl, shader_glsl_lit, 0, 0},
|
||||
{WINED3DSIO_DST, "dst", "DST", 1, 3, vshader_hw_map2gl, shader_glsl_dst, 0, 0},
|
||||
{WINED3DSIO_LRP, "lrp", "LRP", 1, 4, NULL, shader_glsl_lrp, 0, 0},
|
||||
{WINED3DSIO_FRC, "frc", "FRC", 1, 2, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_POW, "pow", "POW", 1, 3, NULL, shader_glsl_pow, 0, 0},
|
||||
{WINED3DSIO_CRS, "crs", "XPS", 1, 3, NULL, shader_glsl_cross, 0, 0},
|
||||
/* TODO: sng can possibly be performed a s
|
||||
RCP tmp, vec
|
||||
MUL out, tmp, vec*/
|
||||
{WINED3DSIO_SGN, "sgn", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
|
||||
/* TODO: xyz normalise can be performed as VS_ARB using one temporary register,
|
||||
DP3 tmp , vec, vec;
|
||||
RSQ tmp, tmp.x;
|
||||
MUL vec.xyz, vec, tmp;
|
||||
but I think this is better because it accounts for w properly.
|
||||
DP3 tmp , vec, vec;
|
||||
RSQ tmp, tmp.x;
|
||||
MUL vec, vec, tmp;
|
||||
*/
|
||||
{WINED3DSIO_NRM, "nrm", NULL, 1, 2, NULL, shader_glsl_map2gl, 0, 0},
|
||||
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 4, NULL, shader_glsl_sincos, WINED3DVS_VERSION(2,0), WINED3DVS_VERSION(2,1)},
|
||||
{WINED3DSIO_SINCOS, "sincos", NULL, 1, 2, NULL, shader_glsl_sincos, WINED3DVS_VERSION(3,0), -1},
|
||||
/* Matrix */
|
||||
{WINED3DSIO_M4x4, "m4x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M4x3, "m4x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x4, "m3x4", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x3, "m3x3", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
{WINED3DSIO_M3x2, "m3x2", "undefined", 1, 3, vshader_hw_mnxn, shader_glsl_mnxn, 0, 0},
|
||||
/* Declare registers */
|
||||
{WINED3DSIO_DCL, "dcl", NULL, 0, 2, NULL, NULL, 0, 0},
|
||||
/* Constant definitions */
|
||||
{WINED3DSIO_DEF, "def", NULL, 1, 5, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_DEFB, "defb", GLNAME_REQUIRE_GLSL, 1, 2, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_DEFI, "defi", GLNAME_REQUIRE_GLSL, 1, 5, NULL, NULL, 0, 0},
|
||||
/* Flow control - requires GLSL or software shaders */
|
||||
{WINED3DSIO_REP , "rep", NULL, 0, 1, NULL, shader_glsl_rep, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_ENDREP, "endrep", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_IF, "if", NULL, 0, 1, NULL, shader_glsl_if, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_IFC, "ifc", NULL, 0, 2, NULL, shader_glsl_ifc, WINED3DVS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_ELSE, "else", NULL, 0, 0, NULL, shader_glsl_else, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_ENDIF, "endif", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_BREAK, "break", NULL, 0, 0, NULL, shader_glsl_break, WINED3DVS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_BREAKC, "breakc", NULL, 0, 2, NULL, shader_glsl_breakc, WINED3DVS_VERSION(2,1), -1},
|
||||
{WINED3DSIO_BREAKP, "breakp", GLNAME_REQUIRE_GLSL, 0, 1, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_CALL, "call", NULL, 0, 1, NULL, shader_glsl_call, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_CALLNZ, "callnz", NULL, 0, 2, NULL, shader_glsl_callnz, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_LOOP, "loop", NULL, 0, 2, NULL, shader_glsl_loop, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_RET, "ret", NULL, 0, 0, NULL, NULL, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_ENDLOOP,"endloop", NULL, 0, 0, NULL, shader_glsl_end, WINED3DVS_VERSION(2,0), -1},
|
||||
{WINED3DSIO_LABEL, "label", NULL, 0, 1, NULL, shader_glsl_label, WINED3DVS_VERSION(2,0), -1},
|
||||
|
||||
{WINED3DSIO_SETP, "setp", GLNAME_REQUIRE_GLSL, 1, 3, NULL, NULL, 0, 0},
|
||||
{WINED3DSIO_TEXLDL, "texldl", NULL, 1, 3, NULL, shader_glsl_texldl, WINED3DVS_VERSION(3,0), -1},
|
||||
{0, NULL, NULL, 0, 0, NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
static void vshader_set_limits(
|
||||
IWineD3DVertexShaderImpl *This) {
|
||||
|
||||
This->baseShader.limits.texcoord = 0;
|
||||
This->baseShader.limits.attributes = 16;
|
||||
This->baseShader.limits.packed_input = 0;
|
||||
|
||||
/* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
|
||||
This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
|
||||
|
||||
switch (This->baseShader.hex_version) {
|
||||
case WINED3DVS_VERSION(1,0):
|
||||
case WINED3DVS_VERSION(1,1):
|
||||
This->baseShader.limits.temporary = 12;
|
||||
This->baseShader.limits.constant_bool = 0;
|
||||
This->baseShader.limits.constant_int = 0;
|
||||
This->baseShader.limits.address = 1;
|
||||
This->baseShader.limits.packed_output = 0;
|
||||
This->baseShader.limits.sampler = 0;
|
||||
This->baseShader.limits.label = 0;
|
||||
break;
|
||||
|
||||
case WINED3DVS_VERSION(2,0):
|
||||
case WINED3DVS_VERSION(2,1):
|
||||
This->baseShader.limits.temporary = 12;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.address = 1;
|
||||
This->baseShader.limits.packed_output = 0;
|
||||
This->baseShader.limits.sampler = 0;
|
||||
This->baseShader.limits.label = 16;
|
||||
break;
|
||||
|
||||
case WINED3DVS_VERSION(3,0):
|
||||
This->baseShader.limits.temporary = 32;
|
||||
This->baseShader.limits.constant_bool = 32;
|
||||
This->baseShader.limits.constant_int = 32;
|
||||
This->baseShader.limits.address = 1;
|
||||
This->baseShader.limits.packed_output = 12;
|
||||
This->baseShader.limits.sampler = 4;
|
||||
This->baseShader.limits.label = 16; /* FIXME: 2048 */
|
||||
break;
|
||||
|
||||
default: This->baseShader.limits.temporary = 12;
|
||||
This->baseShader.limits.constant_bool = 16;
|
||||
This->baseShader.limits.constant_int = 16;
|
||||
This->baseShader.limits.address = 1;
|
||||
This->baseShader.limits.packed_output = 0;
|
||||
This->baseShader.limits.sampler = 0;
|
||||
This->baseShader.limits.label = 16;
|
||||
FIXME("Unrecognized vertex shader version %#x\n",
|
||||
This->baseShader.hex_version);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is an internal function,
|
||||
* used to create fake semantics for shaders
|
||||
* that don't have them - d3d8 shaders where the declaration
|
||||
* stores the register for each input
|
||||
*/
|
||||
static void vshader_set_input(
|
||||
IWineD3DVertexShaderImpl* This,
|
||||
unsigned int regnum,
|
||||
BYTE usage, BYTE usage_idx) {
|
||||
|
||||
/* Fake usage: set reserved bit, usage, usage_idx */
|
||||
DWORD usage_token = (0x1 << 31) |
|
||||
(usage << WINED3DSP_DCL_USAGE_SHIFT) | (usage_idx << WINED3DSP_DCL_USAGEINDEX_SHIFT);
|
||||
|
||||
/* Fake register; set reserved bit, regnum, type: input, wmask: all */
|
||||
DWORD reg_token = (0x1 << 31) |
|
||||
WINED3DSP_WRITEMASK_ALL | (WINED3DSPR_INPUT << WINED3DSP_REGTYPE_SHIFT) | regnum;
|
||||
|
||||
This->semantics_in[regnum].usage = usage_token;
|
||||
This->semantics_in[regnum].reg = reg_token;
|
||||
}
|
||||
|
||||
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
|
||||
if (usage_idx1 != usage_idx2) return FALSE;
|
||||
if (usage1 == usage2) return TRUE;
|
||||
if (usage1 == WINED3DDECLUSAGE_POSITION && usage2 == WINED3DDECLUSAGE_POSITIONT) return TRUE;
|
||||
if (usage2 == WINED3DDECLUSAGE_POSITION && usage1 == WINED3DDECLUSAGE_POSITIONT) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL vshader_get_input(
|
||||
IWineD3DVertexShader* iface,
|
||||
BYTE usage_req, BYTE usage_idx_req,
|
||||
unsigned int* regnum) {
|
||||
|
||||
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_ATTRIBS; i++) {
|
||||
DWORD usage_token = This->semantics_in[i].usage;
|
||||
DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
|
||||
DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
|
||||
if (usage_token && match_usage(usage, usage_idx, usage_req, usage_idx_req)) {
|
||||
*regnum = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL vshader_input_is_color(
|
||||
IWineD3DVertexShader* iface,
|
||||
unsigned int regnum) {
|
||||
|
||||
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
|
||||
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
|
||||
IWineD3DVertexDeclarationImpl *vertexDeclaration = (IWineD3DVertexDeclarationImpl *)deviceImpl->stateBlock->vertexDecl;
|
||||
|
||||
DWORD usage_token = This->semantics_in[regnum].usage;
|
||||
DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
|
||||
DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
|
||||
if (vertexDeclaration) {
|
||||
int i;
|
||||
/* Find the declaration element that matches our register, then check
|
||||
* if it has D3DCOLOR as it's type. This works for both d3d8 and d3d9. */
|
||||
for (i = 0; i < vertexDeclaration->declarationWNumElements-1; ++i) {
|
||||
WINED3DVERTEXELEMENT *element = vertexDeclaration->pDeclarationWine + i;
|
||||
if (match_usage(element->Usage, element->UsageIndex, usage, usage_idx)) {
|
||||
return element->Type == WINED3DDECLTYPE_D3DCOLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERR("Either no vertexdeclaration present, or register not matched. This should never happen.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
|
||||
or GLSL and send it to the card */
|
||||
static VOID IWineD3DVertexShaderImpl_GenerateShader(
|
||||
IWineD3DVertexShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
SHADER_BUFFER buffer;
|
||||
|
||||
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
|
||||
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
|
||||
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
|
||||
HeapFree(GetProcessHeap(), 0, This->fixupVertexBuffer);
|
||||
This->fixupVertexBuffer = HeapAlloc(GetProcessHeap() , 0, SHADER_PGMSIZE);
|
||||
This->fixupVertexBufferSize = PGMSIZE;
|
||||
This->fixupVertexBuffer[0] = 0;
|
||||
}
|
||||
buffer.buffer = This->device->fixupVertexBuffer;
|
||||
#else
|
||||
buffer.buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SHADER_PGMSIZE);
|
||||
#endif
|
||||
buffer.bsize = 0;
|
||||
buffer.lineNo = 0;
|
||||
buffer.newline = TRUE;
|
||||
|
||||
if (This->baseShader.shader_mode == SHADER_GLSL) {
|
||||
|
||||
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */
|
||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
|
||||
|
||||
/* Base Declarations */
|
||||
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
|
||||
|
||||
/* Unpack 3.0 outputs */
|
||||
if (This->baseShader.hex_version >= WINED3DVS_VERSION(3,0))
|
||||
vshader_glsl_output_unpack(&buffer, This->semantics_out);
|
||||
|
||||
/* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
|
||||
if (!reg_maps->fog)
|
||||
shader_addline(&buffer, "gl_FogFragCoord = gl_Position.z;\n");
|
||||
|
||||
/* Write the final position.
|
||||
*
|
||||
* OpenGL coordinates specify the center of the pixel while d3d coords specify
|
||||
* the corner. The offsets are stored in z and w in the 2nd row of the projection
|
||||
* matrix to avoid wasting a free shader constant. Add them to the w and z coord
|
||||
* of the 2nd row
|
||||
*/
|
||||
shader_addline(&buffer, "gl_Position.x = gl_Position.x + posFixup[2];\n");
|
||||
shader_addline(&buffer, "gl_Position.y = gl_Position.y + posFixup[3];\n");
|
||||
/* Account for any inverted textures (render to texture case) by reversing the y coordinate
|
||||
* (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
|
||||
*/
|
||||
shader_addline(&buffer, "gl_Position.y = gl_Position.y * posFixup[1];\n");
|
||||
|
||||
shader_addline(&buffer, "}\n");
|
||||
|
||||
TRACE("Compiling shader object %u\n", shader_obj);
|
||||
GL_EXTCALL(glShaderSourceARB(shader_obj, 1, (const char**)&buffer.buffer, NULL));
|
||||
GL_EXTCALL(glCompileShaderARB(shader_obj));
|
||||
print_glsl_info_log(&GLINFO_LOCATION, shader_obj);
|
||||
|
||||
/* Store the shader object */
|
||||
This->baseShader.prgId = shader_obj;
|
||||
|
||||
} else if (This->baseShader.shader_mode == SHADER_ARB) {
|
||||
|
||||
/* Create the hw ARB shader */
|
||||
shader_addline(&buffer, "!!ARBvp1.0\n");
|
||||
|
||||
/* Mesa supports only 95 constants */
|
||||
if (GL_VEND(MESA) || GL_VEND(WINE))
|
||||
This->baseShader.limits.constant_float =
|
||||
min(95, This->baseShader.limits.constant_float);
|
||||
|
||||
/* Base Declarations */
|
||||
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer, &GLINFO_LOCATION);
|
||||
|
||||
/* We need a constant to fixup the final position */
|
||||
shader_addline(&buffer, "PARAM posFixup = program.env[%d];\n", ARB_SHADER_PRIVCONST_POS);
|
||||
|
||||
/* Base Shader Body */
|
||||
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
|
||||
|
||||
/* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
|
||||
if (!reg_maps->fog)
|
||||
shader_addline(&buffer, "MOV result.fogcoord, TMP_OUT.z;\n");
|
||||
|
||||
/* Write the final position.
|
||||
*
|
||||
* OpenGL coordinates specify the center of the pixel while d3d coords specify
|
||||
* the corner. The offsets are stored in the 2nd row of the projection matrix,
|
||||
* the x offset in z and the y offset in w. Add them to the resulting position
|
||||
*/
|
||||
shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;\n");
|
||||
shader_addline(&buffer, "ADD TMP_OUT.y, TMP_OUT.y, posFixup.w;\n");
|
||||
/* Account for any inverted textures (render to texture case) by reversing the y coordinate
|
||||
* (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
|
||||
*/
|
||||
shader_addline(&buffer, "MUL TMP_OUT.y, TMP_OUT.y, posFixup.y;\n");
|
||||
|
||||
shader_addline(&buffer, "MOV result.position, TMP_OUT;\n");
|
||||
|
||||
shader_addline(&buffer, "END\n");
|
||||
|
||||
/* TODO: change to resource.glObjectHandle or something like that */
|
||||
GL_EXTCALL(glGenProgramsARB(1, &This->baseShader.prgId));
|
||||
|
||||
TRACE("Creating a hw vertex shader, prg=%d\n", This->baseShader.prgId);
|
||||
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, This->baseShader.prgId));
|
||||
|
||||
TRACE("Created hw vertex shader, prg=%d\n", This->baseShader.prgId);
|
||||
/* Create the program and check for errors */
|
||||
GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||
buffer.bsize, buffer.buffer));
|
||||
|
||||
if (glGetError() == GL_INVALID_OPERATION) {
|
||||
GLint errPos;
|
||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
|
||||
FIXME("HW VertexShader Error at position %d: %s\n",
|
||||
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
|
||||
This->baseShader.prgId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if 1 /* if were using the data buffer of device then we don't need to free it */
|
||||
HeapFree(GetProcessHeap(), 0, buffer.buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVertexShader IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_QueryInterface(IWineD3DVertexShader *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseShader)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DVertexShader)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexShaderImpl_AddRef(IWineD3DVertexShader *iface) {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->ref);
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||
ref = InterlockedDecrement(&This->ref);
|
||||
if (ref == 0) {
|
||||
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->vertexShader) {
|
||||
/* See comment in PixelShader::Release */
|
||||
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_VSHADER);
|
||||
}
|
||||
|
||||
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||
struct list *linked_programs = &This->baseShader.linked_programs;
|
||||
|
||||
TRACE("Deleting linked programs\n");
|
||||
if (linked_programs->next) {
|
||||
struct glsl_shader_prog_link *entry, *entry2;
|
||||
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, linked_programs, struct glsl_shader_prog_link, vshader_entry) {
|
||||
delete_glsl_program_entry(This->baseShader.device, entry);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
||||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||
checkGLcall("glDeleteObjectARB");
|
||||
}
|
||||
shader_delete_constant_list(&This->baseShader.constantsF);
|
||||
shader_delete_constant_list(&This->baseShader.constantsB);
|
||||
shader_delete_constant_list(&This->baseShader.constantsI);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVertexShader IWineD3DVertexShader parts follow
|
||||
******************************************* */
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_GetParent(IWineD3DVertexShader *iface, IUnknown** parent){
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
|
||||
*parent = This->parent;
|
||||
IUnknown_AddRef(*parent);
|
||||
TRACE("(%p) : returning %p\n", This, *parent);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_GetDevice(IWineD3DVertexShader* iface, IWineD3DDevice **pDevice){
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
IWineD3DDevice_AddRef(This->baseShader.device);
|
||||
*pDevice = This->baseShader.device;
|
||||
TRACE("(%p) returning %p\n", This, *pDevice);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader* impl, VOID* pData, UINT* pSizeOfData) {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)impl;
|
||||
TRACE("(%p) : pData(%p), pSizeOfData(%p)\n", This, pData, pSizeOfData);
|
||||
|
||||
if (NULL == pData) {
|
||||
*pSizeOfData = This->baseShader.functionLength;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
if (*pSizeOfData < This->baseShader.functionLength) {
|
||||
/* MSDN claims (for d3d8 at least) that if *pSizeOfData is smaller
|
||||
* than the required size we should write the required size and
|
||||
* return D3DERR_MOREDATA. That's not actually true. */
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
if (NULL == This->baseShader.function) { /* no function defined */
|
||||
TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
|
||||
(*(DWORD **) pData) = NULL;
|
||||
} else {
|
||||
if(This->baseShader.functionLength == 0){
|
||||
|
||||
}
|
||||
TRACE("(%p) : GetFunction copying to %p\n", This, pData);
|
||||
memcpy(pData, This->baseShader.function, This->baseShader.functionLength);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* Note that for vertex shaders CompileShader isn't called until the
|
||||
* shader is first used. The reason for this is that we need the vertex
|
||||
* declaration the shader will be used with in order to determine if
|
||||
* the data in a register is of type D3DCOLOR, and needs swizzling. */
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
|
||||
|
||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
|
||||
HRESULT hr;
|
||||
shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
|
||||
|
||||
TRACE("(%p) : pFunction %p\n", iface, pFunction);
|
||||
|
||||
/* First pass: trace shader */
|
||||
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
|
||||
vshader_set_limits(This);
|
||||
|
||||
/* Initialize immediate constant lists */
|
||||
list_init(&This->baseShader.constantsF);
|
||||
list_init(&This->baseShader.constantsB);
|
||||
list_init(&This->baseShader.constantsI);
|
||||
|
||||
/* Second pass: figure out registers used, semantics, etc.. */
|
||||
memset(reg_maps, 0, sizeof(shader_reg_maps));
|
||||
hr = shader_get_registers_used((IWineD3DBaseShader*) This, reg_maps,
|
||||
This->semantics_in, This->semantics_out, pFunction, NULL);
|
||||
if (hr != WINED3D_OK) return hr;
|
||||
|
||||
This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
|
||||
|
||||
/* copy the function ... because it will certainly be released by application */
|
||||
if (NULL != pFunction) {
|
||||
void *function;
|
||||
|
||||
function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
|
||||
if (!function) return E_OUTOFMEMORY;
|
||||
memcpy(function, pFunction, This->baseShader.functionLength);
|
||||
This->baseShader.function = function;
|
||||
} else {
|
||||
This->baseShader.function = NULL;
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* Preload semantics for d3d8 shaders */
|
||||
static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader *iface, IWineD3DVertexDeclaration *vertex_declaration) {
|
||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||
IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < vdecl->declarationWNumElements - 1; ++i) {
|
||||
WINED3DVERTEXELEMENT* element = vdecl->pDeclarationWine + i;
|
||||
vshader_set_input(This, element->Reg, element->Usage, element->UsageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set local constants for d3d8 shaders */
|
||||
static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertexShader *iface,
|
||||
UINT start_idx, const float *src_data, UINT count) {
|
||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||
UINT i, end_idx;
|
||||
|
||||
TRACE("(%p) : start_idx %u, src_data %p, count %u\n", This, start_idx, src_data, count);
|
||||
|
||||
end_idx = start_idx + count;
|
||||
if (end_idx > GL_LIMITS(vshader_constantsF)) {
|
||||
WARN("end_idx %u > float constants limit %u\n", end_idx, GL_LIMITS(vshader_constantsF));
|
||||
end_idx = GL_LIMITS(vshader_constantsF);
|
||||
}
|
||||
|
||||
for (i = start_idx; i < end_idx; ++i) {
|
||||
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
|
||||
if (!lconst) return E_OUTOFMEMORY;
|
||||
|
||||
lconst->idx = i;
|
||||
memcpy(lconst->value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
|
||||
list_add_head(&This->baseShader.constantsF, &lconst->entry);
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
CONST DWORD *function = This->baseShader.function;
|
||||
|
||||
TRACE("(%p) : function %p\n", iface, function);
|
||||
|
||||
/* We're already compiled. */
|
||||
if (This->baseShader.is_compiled) return WINED3D_OK;
|
||||
|
||||
/* We don't need to compile */
|
||||
if (!function) {
|
||||
This->baseShader.is_compiled = TRUE;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* Generate the HW shader */
|
||||
TRACE("(%p) : Generating hardware program\n", This);
|
||||
IWineD3DVertexShaderImpl_GenerateShader(iface, &This->baseShader.reg_maps, function);
|
||||
|
||||
This->baseShader.is_compiled = TRUE;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
|
||||
{
|
||||
/*** IUnknown methods ***/
|
||||
IWineD3DVertexShaderImpl_QueryInterface,
|
||||
IWineD3DVertexShaderImpl_AddRef,
|
||||
IWineD3DVertexShaderImpl_Release,
|
||||
/*** IWineD3DBase methods ***/
|
||||
IWineD3DVertexShaderImpl_GetParent,
|
||||
/*** IWineD3DBaseShader methods ***/
|
||||
IWineD3DVertexShaderImpl_SetFunction,
|
||||
IWineD3DVertexShaderImpl_CompileShader,
|
||||
/*** IWineD3DVertexShader methods ***/
|
||||
IWineD3DVertexShaderImpl_GetDevice,
|
||||
IWineD3DVertexShaderImpl_GetFunction,
|
||||
IWineD3DVertexShaderImpl_FakeSemantics,
|
||||
IWIneD3DVertexShaderImpl_SetLocalConstantsF
|
||||
};
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* IWineD3DVolume implementation
|
||||
*
|
||||
* Copyright 2002-2005 Jason Edmeades
|
||||
* Copyright 2002-2005 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVolume IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_QueryInterface(IWineD3DVolume *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DVolume)){
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVolumeImpl_AddRef(IWineD3DVolume *iface) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref);
|
||||
return InterlockedIncrement(&This->resource.ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVolumeImpl_Release(IWineD3DVolume *iface) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
|
||||
ref = InterlockedDecrement(&This->resource.ref);
|
||||
if (ref == 0) {
|
||||
IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DVolume IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_GetParent(IWineD3DVolume *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_GetDevice(IWineD3DVolume *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_SetPrivateData(IWineD3DVolume *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_GetPrivateData(IWineD3DVolume *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_FreePrivateData(IWineD3DVolume *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeImpl_SetPriority(IWineD3DVolume *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeImpl_GetPriority(IWineD3DVolume *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DVolumeImpl_PreLoad(IWineD3DVolume *iface) {
|
||||
IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeImpl_GetType(IWineD3DVolume *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVolume parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_GetContainer(IWineD3DVolume *iface, REFIID riid, void** ppContainer) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
|
||||
TRACE("(This %p, riid %s, ppContainer %p)\n", This, debugstr_guid(riid), ppContainer);
|
||||
|
||||
if (!ppContainer) {
|
||||
ERR("Called without a valid ppContainer.\n");
|
||||
}
|
||||
|
||||
/* Although surfaces can be standalone, volumes can't */
|
||||
if (!This->container) {
|
||||
ERR("Volume without an container. Should not happen.\n");
|
||||
}
|
||||
|
||||
TRACE("Relaying to QueryInterface\n");
|
||||
return IUnknown_QueryInterface(This->container, riid, ppContainer);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_GetDesc(IWineD3DVolume *iface, WINED3DVOLUME_DESC* pDesc) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
TRACE("(%p) : copying into %p\n", This, pDesc);
|
||||
|
||||
*(pDesc->Format) = This->resource.format;
|
||||
*(pDesc->Type) = This->resource.resourceType;
|
||||
*(pDesc->Usage) = This->resource.usage;
|
||||
*(pDesc->Pool) = This->resource.pool;
|
||||
*(pDesc->Size) = This->resource.size; /* dx8 only */
|
||||
*(pDesc->Width) = This->currentDesc.Width;
|
||||
*(pDesc->Height) = This->currentDesc.Height;
|
||||
*(pDesc->Depth) = This->currentDesc.Depth;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_LockBox(IWineD3DVolume *iface, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
FIXME("(%p) : pBox=%p stub\n", This, pBox);
|
||||
|
||||
if(!This->resource.allocatedMemory) {
|
||||
This->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size);
|
||||
}
|
||||
|
||||
/* fixme: should we really lock as such? */
|
||||
TRACE("(%p) : box=%p, output pbox=%p, allMem=%p\n", This, pBox, pLockedVolume, This->resource.allocatedMemory);
|
||||
|
||||
pLockedVolume->RowPitch = This->bytesPerPixel * This->currentDesc.Width; /* Bytes / row */
|
||||
pLockedVolume->SlicePitch = This->bytesPerPixel * This->currentDesc.Width * This->currentDesc.Height; /* Bytes / slice */
|
||||
if (!pBox) {
|
||||
TRACE("No box supplied - all is ok\n");
|
||||
pLockedVolume->pBits = This->resource.allocatedMemory;
|
||||
This->lockedBox.Left = 0;
|
||||
This->lockedBox.Top = 0;
|
||||
This->lockedBox.Front = 0;
|
||||
This->lockedBox.Right = This->currentDesc.Width;
|
||||
This->lockedBox.Bottom = This->currentDesc.Height;
|
||||
This->lockedBox.Back = This->currentDesc.Depth;
|
||||
} else {
|
||||
TRACE("Lock Box (%p) = l %d, t %d, r %d, b %d, fr %d, ba %d\n", pBox, pBox->Left, pBox->Top, pBox->Right, pBox->Bottom, pBox->Front, pBox->Back);
|
||||
pLockedVolume->pBits = This->resource.allocatedMemory +
|
||||
(pLockedVolume->SlicePitch * pBox->Front) + /* FIXME: is front < back or vica versa? */
|
||||
(pLockedVolume->RowPitch * pBox->Top) +
|
||||
(pBox->Left * This->bytesPerPixel);
|
||||
This->lockedBox.Left = pBox->Left;
|
||||
This->lockedBox.Top = pBox->Top;
|
||||
This->lockedBox.Front = pBox->Front;
|
||||
This->lockedBox.Right = pBox->Right;
|
||||
This->lockedBox.Bottom = pBox->Bottom;
|
||||
This->lockedBox.Back = pBox->Back;
|
||||
}
|
||||
|
||||
if (Flags & (WINED3DLOCK_NO_DIRTY_UPDATE | WINED3DLOCK_READONLY)) {
|
||||
/* Don't dirtify */
|
||||
} else {
|
||||
/**
|
||||
* Dirtify on lock
|
||||
* as seen in msdn docs
|
||||
*/
|
||||
IWineD3DVolume_AddDirtyBox(iface, &This->lockedBox);
|
||||
|
||||
/** Dirtify Container if needed */
|
||||
if (NULL != This->container) {
|
||||
|
||||
IWineD3DVolumeTexture *cont = (IWineD3DVolumeTexture*) This->container;
|
||||
WINED3DRESOURCETYPE containerType = IWineD3DBaseTexture_GetType((IWineD3DBaseTexture *) cont);
|
||||
|
||||
if (containerType == WINED3DRTYPE_VOLUMETEXTURE) {
|
||||
IWineD3DBaseTextureImpl* pTexture = (IWineD3DBaseTextureImpl*) cont;
|
||||
pTexture->baseTexture.dirty = TRUE;
|
||||
} else {
|
||||
FIXME("Set dirty on container type %d\n", containerType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
This->locked = TRUE;
|
||||
TRACE("returning memory@%p rpitch(%d) spitch(%d)\n", pLockedVolume->pBits, pLockedVolume->RowPitch, pLockedVolume->SlicePitch);
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_UnlockBox(IWineD3DVolume *iface) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
if (!This->locked) {
|
||||
ERR("trying to lock unlocked volume@%p\n", This);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
TRACE("(%p) : unlocking volume\n", This);
|
||||
This->locked = FALSE;
|
||||
memset(&This->lockedBox, 0, sizeof(RECT));
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
/* Internal use functions follow : */
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_CleanDirtyBox(IWineD3DVolume *iface) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
This->dirty = FALSE;
|
||||
This->lockedBox.Left = This->currentDesc.Width;
|
||||
This->lockedBox.Top = This->currentDesc.Height;
|
||||
This->lockedBox.Front = This->currentDesc.Depth;
|
||||
This->lockedBox.Right = 0;
|
||||
This->lockedBox.Bottom = 0;
|
||||
This->lockedBox.Back = 0;
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_AddDirtyBox(IWineD3DVolume *iface, CONST WINED3DBOX* pDirtyBox) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
This->dirty = TRUE;
|
||||
if (NULL != pDirtyBox) {
|
||||
This->lockedBox.Left = min(This->lockedBox.Left, pDirtyBox->Left);
|
||||
This->lockedBox.Top = min(This->lockedBox.Top, pDirtyBox->Top);
|
||||
This->lockedBox.Front = min(This->lockedBox.Front, pDirtyBox->Front);
|
||||
This->lockedBox.Right = max(This->lockedBox.Right, pDirtyBox->Right);
|
||||
This->lockedBox.Bottom = max(This->lockedBox.Bottom, pDirtyBox->Bottom);
|
||||
This->lockedBox.Back = max(This->lockedBox.Back, pDirtyBox->Back);
|
||||
} else {
|
||||
This->lockedBox.Left = 0;
|
||||
This->lockedBox.Top = 0;
|
||||
This->lockedBox.Front = 0;
|
||||
This->lockedBox.Right = This->currentDesc.Width;
|
||||
This->lockedBox.Bottom = This->currentDesc.Height;
|
||||
This->lockedBox.Back = This->currentDesc.Depth;
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IWineD3DBase* container) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
|
||||
TRACE("This %p, container %p\n", This, container);
|
||||
|
||||
/* We can't keep a reference to the container, since the container already keeps a reference to us. */
|
||||
|
||||
TRACE("Setting container to %p from %p\n", container, This->container);
|
||||
This->container = container;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, int gl_level, BOOL srgb_mode) {
|
||||
IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface;
|
||||
WINED3DFORMAT format = This->resource.format;
|
||||
const GlPixelFormatDesc *glDesc;
|
||||
getFormatDescEntry(format, &GLINFO_LOCATION, &glDesc);
|
||||
|
||||
TRACE("(%p) : level %u, format %s (0x%08x)\n", This, gl_level, debug_d3dformat(format), format);
|
||||
|
||||
if(GL_SUPPORT(EXT_TEXTURE3D)) {
|
||||
TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n",
|
||||
GL_TEXTURE_3D,
|
||||
gl_level,
|
||||
glDesc->glInternal,
|
||||
This->currentDesc.Width,
|
||||
This->currentDesc.Height,
|
||||
This->currentDesc.Depth,
|
||||
0,
|
||||
glDesc->glFormat,
|
||||
glDesc->glType,
|
||||
This->resource.allocatedMemory);
|
||||
GL_EXTCALL(glTexImage3DEXT(GL_TEXTURE_3D,
|
||||
gl_level,
|
||||
glDesc->glInternal,
|
||||
This->currentDesc.Width,
|
||||
This->currentDesc.Height,
|
||||
This->currentDesc.Depth,
|
||||
0,
|
||||
glDesc->glFormat,
|
||||
glDesc->glType,
|
||||
This->resource.allocatedMemory));
|
||||
checkGLcall("glTexImage3D");
|
||||
} else
|
||||
WARN("This OpenGL implementation doesn't support 3D textures\n");
|
||||
|
||||
/* When adding code releasing This->resource.allocatedMemory to save data keep in mind that
|
||||
* GL_UNPACK_CLIENT_STORAGE_APPLE is enabled by default if supported(GL_APPLE_client_storage).
|
||||
* Thus do not release This->resource.allocatedMemory if GL_APPLE_client_storage is supported.
|
||||
*/
|
||||
return WINED3D_OK;
|
||||
|
||||
}
|
||||
|
||||
const IWineD3DVolumeVtbl IWineD3DVolume_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DVolumeImpl_QueryInterface,
|
||||
IWineD3DVolumeImpl_AddRef,
|
||||
IWineD3DVolumeImpl_Release,
|
||||
/* IWineD3DResource */
|
||||
IWineD3DVolumeImpl_GetParent,
|
||||
IWineD3DVolumeImpl_GetDevice,
|
||||
IWineD3DVolumeImpl_SetPrivateData,
|
||||
IWineD3DVolumeImpl_GetPrivateData,
|
||||
IWineD3DVolumeImpl_FreePrivateData,
|
||||
IWineD3DVolumeImpl_SetPriority,
|
||||
IWineD3DVolumeImpl_GetPriority,
|
||||
IWineD3DVolumeImpl_PreLoad,
|
||||
IWineD3DVolumeImpl_GetType,
|
||||
/* IWineD3DVolume */
|
||||
IWineD3DVolumeImpl_GetContainer,
|
||||
IWineD3DVolumeImpl_GetDesc,
|
||||
IWineD3DVolumeImpl_LockBox,
|
||||
IWineD3DVolumeImpl_UnlockBox,
|
||||
/* Internal interface */
|
||||
IWineD3DVolumeImpl_AddDirtyBox,
|
||||
IWineD3DVolumeImpl_CleanDirtyBox,
|
||||
IWineD3DVolumeImpl_LoadTexture,
|
||||
IWineD3DVolumeImpl_SetContainer
|
||||
};
|
||||
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* IWineD3DVolumeTexture implementation
|
||||
*
|
||||
* Copyright 2002-2005 Jason Edmeades
|
||||
* Copyright 2002-2005 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
#define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DTexture IUnknown parts follow
|
||||
******************************************* */
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_QueryInterface(IWineD3DVolumeTexture *iface, REFIID riid, LPVOID *ppobj)
|
||||
{
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if (IsEqualGUID(riid, &IID_IUnknown)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DBaseTexture)
|
||||
|| IsEqualGUID(riid, &IID_IWineD3DVolumeTexture)) {
|
||||
IUnknown_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVolumeTextureImpl_AddRef(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref);
|
||||
return InterlockedIncrement(&This->resource.ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
ULONG ref;
|
||||
TRACE("(%p) : Releasing from %d\n", This, This->resource.ref);
|
||||
ref = InterlockedDecrement(&This->resource.ref);
|
||||
if (ref == 0) {
|
||||
IWineD3DVolumeTexture_Destroy(iface, D3DCB_DefaultDestroyVolume);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
/* ****************************************************
|
||||
IWineD3DVolumeTexture IWineD3DResource parts follow
|
||||
**************************************************** */
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetDevice(IWineD3DVolumeTexture *iface, IWineD3DDevice** ppDevice) {
|
||||
return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetPrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
|
||||
return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetPrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
|
||||
return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_FreePrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid) {
|
||||
return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeTextureImpl_SetPriority(IWineD3DVolumeTexture *iface, DWORD PriorityNew) {
|
||||
return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) {
|
||||
/* Overrider the IWineD3DResource Preload method */
|
||||
int i;
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||
BOOL srgb_mode = This->baseTexture.is_srgb;
|
||||
BOOL srgb_was_toggled = FALSE;
|
||||
|
||||
TRACE("(%p) : About to load texture\n", This);
|
||||
|
||||
IWineD3DVolumeTexture_BindTexture(iface);
|
||||
|
||||
if(!device->isInDraw) {
|
||||
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
|
||||
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
|
||||
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
|
||||
srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
|
||||
This->baseTexture.is_srgb = srgb_mode;
|
||||
}
|
||||
ENTER_GL();
|
||||
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
|
||||
if (This->baseTexture.dirty) {
|
||||
for (i = 0; i < This->baseTexture.levels; i++)
|
||||
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
|
||||
} else if (srgb_was_toggled) {
|
||||
if (This->baseTexture.srgb_mode_change_count < 20)
|
||||
++This->baseTexture.srgb_mode_change_count;
|
||||
else
|
||||
FIXME("Volumetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
|
||||
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
IWineD3DVolume_AddDirtyBox(This->volumes[i], NULL);
|
||||
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
|
||||
}
|
||||
} else {
|
||||
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
|
||||
}
|
||||
LEAVE_GL();
|
||||
|
||||
/* No longer dirty */
|
||||
This->baseTexture.dirty = FALSE;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeTextureImpl_GetType(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetParent(IWineD3DVolumeTexture *iface, IUnknown **pParent) {
|
||||
return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
|
||||
}
|
||||
|
||||
/* ******************************************************
|
||||
IWineD3DVolumeTexture IWineD3DBaseTexture parts follow
|
||||
****************************************************** */
|
||||
static DWORD WINAPI IWineD3DVolumeTextureImpl_SetLOD(IWineD3DVolumeTexture *iface, DWORD LODNew) {
|
||||
return IWineD3DBaseTextureImpl_SetLOD((IWineD3DBaseTexture *)iface, LODNew);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeTextureImpl_GetLOD(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLOD((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static DWORD WINAPI IWineD3DVolumeTextureImpl_GetLevelCount(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetLevelCount((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetAutoGenFilterType(IWineD3DVolumeTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) {
|
||||
return IWineD3DBaseTextureImpl_SetAutoGenFilterType((IWineD3DBaseTexture *)iface, FilterType);
|
||||
}
|
||||
|
||||
static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DVolumeTextureImpl_GetAutoGenFilterType(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetAutoGenFilterType((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DVolumeTextureImpl_GenerateMipSubLevels(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DBaseTextureImpl_GenerateMipSubLevels((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
/* Internal function, No d3d mapping */
|
||||
static BOOL WINAPI IWineD3DVolumeTextureImpl_SetDirty(IWineD3DVolumeTexture *iface, BOOL dirty) {
|
||||
return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty);
|
||||
}
|
||||
|
||||
static BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *iface) {
|
||||
return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_BindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnBindTexture(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p) : relay to BaseTexture\n", This);
|
||||
return IWineD3DBaseTextureImpl_UnBindTexture((IWineD3DBaseTexture *)iface);
|
||||
}
|
||||
|
||||
static UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture *iface) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p)\n", This);
|
||||
return GL_TEXTURE_3D;
|
||||
}
|
||||
|
||||
static void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface,
|
||||
const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],
|
||||
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
TRACE("(%p) : nothing to do, passing to base texture\n", This);
|
||||
IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates);
|
||||
}
|
||||
|
||||
|
||||
/* *******************************************
|
||||
IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow
|
||||
******************************************* */
|
||||
static void WINAPI IWineD3DVolumeTextureImpl_Destroy(IWineD3DVolumeTexture *iface, D3DCB_DESTROYVOLUMEFN D3DCB_DestroyVolume) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
int i;
|
||||
TRACE("(%p) : Cleaning up\n",This);
|
||||
for (i = 0; i < This->baseTexture.levels; i++) {
|
||||
if (This->volumes[i] != NULL) {
|
||||
/* Cleanup the container */
|
||||
IWineD3DVolume_SetContainer(This->volumes[i], 0);
|
||||
D3DCB_DestroyVolume(This->volumes[i]);
|
||||
}
|
||||
}
|
||||
IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
if (Level < This->baseTexture.levels) {
|
||||
TRACE("(%p) Level (%d)\n", This, Level);
|
||||
return IWineD3DVolume_GetDesc((IWineD3DVolume *) This->volumes[Level], pDesc);
|
||||
} else {
|
||||
FIXME("(%p) Level (%d)\n", This, Level);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, UINT Level, IWineD3DVolume** ppVolumeLevel) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
if (Level < This->baseTexture.levels) {
|
||||
*ppVolumeLevel = (IWineD3DVolume *)This->volumes[Level];
|
||||
IWineD3DVolume_AddRef((IWineD3DVolume *) *ppVolumeLevel);
|
||||
TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel);
|
||||
} else {
|
||||
FIXME("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
return WINED3D_OK;
|
||||
|
||||
}
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) {
|
||||
HRESULT hr;
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
hr = IWineD3DVolume_LockBox((IWineD3DVolume *)This->volumes[Level], pLockedVolume, pBox, Flags);
|
||||
TRACE("(%p) Level (%d) success(%u)\n", This, Level, hr);
|
||||
|
||||
} else {
|
||||
FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT Level) {
|
||||
HRESULT hr;
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
|
||||
if (Level < This->baseTexture.levels) {
|
||||
hr = IWineD3DVolume_UnlockBox((IWineD3DVolume*) This->volumes[Level]);
|
||||
TRACE("(%p) -> level(%d) success(%u)\n", This, Level, hr);
|
||||
|
||||
} else {
|
||||
FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, CONST WINED3DBOX* pDirtyBox) {
|
||||
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
|
||||
This->baseTexture.dirty = TRUE;
|
||||
TRACE("(%p) : dirtyfication of volume Level (0)\n", This);
|
||||
return IWineD3DVolume_AddDirtyBox((IWineD3DVolume *) This->volumes[0], pDirtyBox);
|
||||
}
|
||||
|
||||
const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl =
|
||||
{
|
||||
/* IUnknown */
|
||||
IWineD3DVolumeTextureImpl_QueryInterface,
|
||||
IWineD3DVolumeTextureImpl_AddRef,
|
||||
IWineD3DVolumeTextureImpl_Release,
|
||||
/* resource */
|
||||
IWineD3DVolumeTextureImpl_GetParent,
|
||||
IWineD3DVolumeTextureImpl_GetDevice,
|
||||
IWineD3DVolumeTextureImpl_SetPrivateData,
|
||||
IWineD3DVolumeTextureImpl_GetPrivateData,
|
||||
IWineD3DVolumeTextureImpl_FreePrivateData,
|
||||
IWineD3DVolumeTextureImpl_SetPriority,
|
||||
IWineD3DVolumeTextureImpl_GetPriority,
|
||||
IWineD3DVolumeTextureImpl_PreLoad,
|
||||
IWineD3DVolumeTextureImpl_GetType,
|
||||
/* BaseTexture */
|
||||
IWineD3DVolumeTextureImpl_SetLOD,
|
||||
IWineD3DVolumeTextureImpl_GetLOD,
|
||||
IWineD3DVolumeTextureImpl_GetLevelCount,
|
||||
IWineD3DVolumeTextureImpl_SetAutoGenFilterType,
|
||||
IWineD3DVolumeTextureImpl_GetAutoGenFilterType,
|
||||
IWineD3DVolumeTextureImpl_GenerateMipSubLevels,
|
||||
IWineD3DVolumeTextureImpl_SetDirty,
|
||||
IWineD3DVolumeTextureImpl_GetDirty,
|
||||
/* not in d3d */
|
||||
IWineD3DVolumeTextureImpl_BindTexture,
|
||||
IWineD3DVolumeTextureImpl_UnBindTexture,
|
||||
IWineD3DVolumeTextureImpl_GetTextureDimensions,
|
||||
IWineD3DVolumeTextureImpl_ApplyStateChanges,
|
||||
/* volume texture */
|
||||
IWineD3DVolumeTextureImpl_Destroy,
|
||||
IWineD3DVolumeTextureImpl_GetLevelDesc,
|
||||
IWineD3DVolumeTextureImpl_GetVolumeLevel,
|
||||
IWineD3DVolumeTextureImpl_LockBox,
|
||||
IWineD3DVolumeTextureImpl_UnlockBox,
|
||||
IWineD3DVolumeTextureImpl_AddDirtyBox
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
WineDirect3DCreate@12
|
||||
WineDirect3DCreateClipper@4
|
||||
@@ -0,0 +1,51 @@
|
||||
<module name="wined3d" type="win32dll" installbase="system32" installname="wined3d.dll" allowwarnings ="true">
|
||||
<importlibrary definition="wined3d.def" />
|
||||
<include base="wined3d">.</include>
|
||||
<include base="ReactOS">include/reactos/wine</include>
|
||||
<define name="__REACTOS__" />
|
||||
<define name="__USE_W32API" />
|
||||
<define name="_WIN32_IE">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x501</define>
|
||||
<define name="WINVER">0x501</define>
|
||||
<define name="__WINESRC__" />
|
||||
<define name="USE_WIN32_OPENGL" />
|
||||
|
||||
<library>wine</library>
|
||||
<library>user32</library>
|
||||
<library>opengl32</library>
|
||||
<library>gdi32</library>
|
||||
<library>advapi32 </library>
|
||||
<library>kernel32</library>
|
||||
<library>uuid</library>
|
||||
<library>msvcrt</library>
|
||||
|
||||
<file>arb_program_shader.c</file>
|
||||
<file>baseshader.c</file>
|
||||
<file>basetexture.c</file>
|
||||
<file>clipper.c</file>
|
||||
<file>context.c</file>
|
||||
<file>cubetexture.c</file>
|
||||
<file>device.c</file>
|
||||
<file>directx.c</file>
|
||||
<file>drawprim.c</file>
|
||||
<file>glsl_shader.c</file>
|
||||
<file>indexbuffer.c</file>
|
||||
<file>palette.c</file>
|
||||
<file>pixelshader.c</file>
|
||||
<file>query.c</file>
|
||||
<file>resource.c</file>
|
||||
<file>state.c</file>
|
||||
<file>stateblock.c</file>
|
||||
<file>surface.c</file>
|
||||
<file>surface_gdi.c </file>
|
||||
<file>swapchain.c</file>
|
||||
<file>texture.c</file>
|
||||
<file>utils.c</file>
|
||||
<file>vertexbuffer.c</file>
|
||||
<file>vertexdeclaration.c</file>
|
||||
<file>vertexshader.c</file>
|
||||
<file>volume.c</file>
|
||||
<file>volumetexture.c</file>
|
||||
<file>wined3d_main.c</file>
|
||||
<file>version.rc</file>
|
||||
</module>
|
||||
@@ -0,0 +1,2 @@
|
||||
@ stdcall WineDirect3DCreate(long long ptr)
|
||||
@ stdcall WineDirect3DCreateClipper(ptr)
|
||||
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Direct3D wine internal interface main
|
||||
*
|
||||
* Copyright 2002-2003 The wine-d3d team
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* Copyright 2004 Jason Edmeades
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wine_d3d);
|
||||
|
||||
int num_lock = 0;
|
||||
void (*wine_tsx11_lock_ptr)(void) = NULL;
|
||||
void (*wine_tsx11_unlock_ptr)(void) = NULL;
|
||||
|
||||
|
||||
/* When updating default value here, make sure to update winecfg as well,
|
||||
* where appropriate. */
|
||||
wined3d_settings_t wined3d_settings =
|
||||
{
|
||||
VS_HW, /* Hardware by default */
|
||||
PS_HW, /* Hardware by default */
|
||||
VBO_HW, /* Hardware by default */
|
||||
FALSE, /* Use of GLSL disabled by default */
|
||||
ORM_BACKBUFFER, /* Use the backbuffer to do offscreen rendering */
|
||||
RTL_AUTO, /* Automatically determine best locking method */
|
||||
64*1024*1024 /* 64MB texture memory by default */
|
||||
};
|
||||
|
||||
WineD3DGlobalStatistics *wineD3DGlobalStatistics = NULL;
|
||||
|
||||
long globalChangeGlRam(long glram){
|
||||
/* FIXME: replace this function with object tracking */
|
||||
int result;
|
||||
|
||||
wineD3DGlobalStatistics->glsurfaceram += glram;
|
||||
TRACE("Adjusted gl ram by %ld to %d\n", glram, wineD3DGlobalStatistics->glsurfaceram);
|
||||
result = wineD3DGlobalStatistics->glsurfaceram;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
IWineD3D* WINAPI WineDirect3DCreate(UINT SDKVersion, UINT dxVersion, IUnknown *parent) {
|
||||
IWineD3DImpl* object;
|
||||
|
||||
if (!InitAdapters()) {
|
||||
WARN("Failed to initialize direct3d adapters, Direct3D will not be available\n");
|
||||
if(dxVersion > 7) {
|
||||
ERR("Direct3D%d is not available without opengl\n", dxVersion);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DImpl));
|
||||
object->lpVtbl = &IWineD3D_Vtbl;
|
||||
object->dxVersion = dxVersion;
|
||||
object->ref = 1;
|
||||
object->parent = parent;
|
||||
|
||||
/*Create a structure for storing global data in*/
|
||||
if(wineD3DGlobalStatistics == NULL){
|
||||
TRACE("Creating global statistics store\n");
|
||||
wineD3DGlobalStatistics = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wineD3DGlobalStatistics));
|
||||
|
||||
}
|
||||
|
||||
TRACE("Created WineD3D object @ %p for d3d%d support\n", object, dxVersion);
|
||||
|
||||
return (IWineD3D *)object;
|
||||
}
|
||||
|
||||
static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, char* buffer, DWORD size)
|
||||
{
|
||||
if (0 != appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
|
||||
if (0 != defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0;
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
static void wined3d_do_nothing(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* At process attach */
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
||||
{
|
||||
TRACE("WineD3D DLLMain Reason=%d\n", fdwReason);
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
HMODULE mod;
|
||||
char buffer[MAX_PATH+10];
|
||||
DWORD size = sizeof(buffer);
|
||||
HKEY hkey = 0;
|
||||
HKEY appkey = 0;
|
||||
DWORD len;
|
||||
WNDCLASSA wc;
|
||||
|
||||
wined3d_settings.emulated_textureram = 64*1024*1024;
|
||||
|
||||
/* We need our own window class for a fake window which we use to retrieve GL capabilities */
|
||||
/* We might need CS_OWNDC in the future if we notice strange things on Windows.
|
||||
* Various articles/posts about OpenGL problems on Windows recommend this. */
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = DefWindowProcA;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstDLL;
|
||||
wc.hIcon = LoadIconA(NULL, (LPCSTR)IDI_WINLOGO);
|
||||
wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "WineD3D_OpenGL";
|
||||
|
||||
if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
|
||||
{
|
||||
ERR("Failed to register window class 'WineD3D_OpenGL'!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
|
||||
mod = GetModuleHandleA( "winex11.drv" );
|
||||
if (mod)
|
||||
{
|
||||
wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
|
||||
wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
|
||||
}
|
||||
else /* We are most likely on Windows */
|
||||
{
|
||||
wine_tsx11_lock_ptr = wined3d_do_nothing;
|
||||
wine_tsx11_unlock_ptr = wined3d_do_nothing;
|
||||
}
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\Direct3D */
|
||||
if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0;
|
||||
|
||||
len = GetModuleFileNameA( 0, buffer, MAX_PATH );
|
||||
if (len && len < MAX_PATH)
|
||||
{
|
||||
HKEY tmpkey;
|
||||
/* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */
|
||||
if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
|
||||
{
|
||||
char *p, *appname = buffer;
|
||||
if ((p = strrchr( appname, '/' ))) appname = p + 1;
|
||||
if ((p = strrchr( appname, '\\' ))) appname = p + 1;
|
||||
strcat( appname, "\\Direct3D" );
|
||||
TRACE("appname = [%s]\n", appname);
|
||||
if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
|
||||
RegCloseKey( tmpkey );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 != hkey || 0 != appkey )
|
||||
{
|
||||
if ( !get_config_key( hkey, appkey, "VertexShaderMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"none"))
|
||||
{
|
||||
TRACE("Disable vertex shaders\n");
|
||||
wined3d_settings.vs_mode = VS_NONE;
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "PixelShaderMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"enabled"))
|
||||
{
|
||||
TRACE("Allow pixel shaders\n");
|
||||
wined3d_settings.ps_mode = PS_HW;
|
||||
}
|
||||
if (!strcmp(buffer,"disabled"))
|
||||
{
|
||||
TRACE("Disable pixel shaders\n");
|
||||
wined3d_settings.ps_mode = PS_NONE;
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "VertexBufferMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"none"))
|
||||
{
|
||||
TRACE("Disable Vertex Buffer Hardware support\n");
|
||||
wined3d_settings.vbo_mode = VBO_NONE;
|
||||
}
|
||||
else if (!strcmp(buffer,"hardware"))
|
||||
{
|
||||
TRACE("Allow Vertex Buffer Hardware support\n");
|
||||
wined3d_settings.vbo_mode = VBO_HW;
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"enabled"))
|
||||
{
|
||||
TRACE("Use of GL Shading Language enabled for systems that support it\n");
|
||||
wined3d_settings.glslRequested = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Use of GL Shading Language disabled\n");
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "OffscreenRenderingMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"backbuffer"))
|
||||
{
|
||||
TRACE("Using the backbuffer for offscreen rendering\n");
|
||||
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
|
||||
}
|
||||
else if (!strcmp(buffer,"pbuffer"))
|
||||
{
|
||||
TRACE("Using PBuffers for offscreen rendering\n");
|
||||
wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
|
||||
}
|
||||
else if (!strcmp(buffer,"fbo"))
|
||||
{
|
||||
TRACE("Using FBOs for offscreen rendering\n");
|
||||
wined3d_settings.offscreen_rendering_mode = ORM_FBO;
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "RenderTargetLockMode", buffer, size) )
|
||||
{
|
||||
if (!strcmp(buffer,"disabled"))
|
||||
{
|
||||
TRACE("Disabling render target locking\n");
|
||||
wined3d_settings.rendertargetlock_mode = RTL_DISABLE;
|
||||
}
|
||||
else if (!strcmp(buffer,"readdraw"))
|
||||
{
|
||||
TRACE("Using glReadPixels for render target reading and glDrawPixels for writing\n");
|
||||
wined3d_settings.rendertargetlock_mode = RTL_READDRAW;
|
||||
}
|
||||
else if (!strcmp(buffer,"readtex"))
|
||||
{
|
||||
TRACE("Using glReadPixels for render target reading and textures for writing\n");
|
||||
wined3d_settings.rendertargetlock_mode = RTL_READTEX;
|
||||
}
|
||||
else if (!strcmp(buffer,"texdraw"))
|
||||
{
|
||||
TRACE("Using textures for render target reading and glDrawPixels for writing\n");
|
||||
wined3d_settings.rendertargetlock_mode = RTL_TEXDRAW;
|
||||
}
|
||||
else if (!strcmp(buffer,"textex"))
|
||||
{
|
||||
TRACE("Reading render targets via textures and writing via textures\n");
|
||||
wined3d_settings.rendertargetlock_mode = RTL_TEXTEX;
|
||||
}
|
||||
}
|
||||
if ( !get_config_key( hkey, appkey, "VideoMemorySize", buffer, size) )
|
||||
{
|
||||
int TmpVideoMemorySize = atoi(buffer);
|
||||
if(TmpVideoMemorySize > 0)
|
||||
{
|
||||
wined3d_settings.emulated_textureram = TmpVideoMemorySize *1024*1024;
|
||||
TRACE("Use %iMB = %d byte for emulated_textureram\n",
|
||||
TmpVideoMemorySize,
|
||||
wined3d_settings.emulated_textureram);
|
||||
}
|
||||
else
|
||||
ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize);
|
||||
}
|
||||
}
|
||||
if (wined3d_settings.vs_mode == VS_HW)
|
||||
TRACE("Allow HW vertex shaders\n");
|
||||
if (wined3d_settings.ps_mode == PS_NONE)
|
||||
TRACE("Disable pixel shaders\n");
|
||||
if (wined3d_settings.vbo_mode == VBO_NONE)
|
||||
TRACE("Disable Vertex Buffer Hardware support\n");
|
||||
if (wined3d_settings.glslRequested)
|
||||
TRACE("If supported by your system, GL Shading Language will be used\n");
|
||||
|
||||
if (appkey) RegCloseKey( appkey );
|
||||
if (hkey) RegCloseKey( hkey );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Direct3D wine internal header: D3D equivalent types
|
||||
*
|
||||
* Copyright 2002-2003 Jason Edmeades
|
||||
* Copyright 2002-2003 Raphael Junqueira
|
||||
* 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
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_WINED3D_TYPES_INTERNAL_H
|
||||
#define __WINE_WINED3D_TYPES_INTERNAL_H
|
||||
|
||||
/* Depth copy state */
|
||||
typedef enum {
|
||||
WINED3D_DCS_INITIAL = 0,
|
||||
WINED3D_DCS_COPY = 1,
|
||||
WINED3D_DCS_NO_COPY = 2
|
||||
} WINED3D_DEPTHCOPYSTATE;
|
||||
|
||||
/** DCL usage masks **/
|
||||
#define WINED3DSP_DCL_USAGE_SHIFT 0
|
||||
#define WINED3DSP_DCL_USAGE_MASK 0x0000000f
|
||||
#define WINED3DSP_DCL_USAGEINDEX_SHIFT 16
|
||||
#define WINED3DSP_DCL_USAGEINDEX_MASK 0x000f0000
|
||||
|
||||
/** DCL sampler texture type **/
|
||||
#define WINED3DSP_TEXTURETYPE_SHIFT 27
|
||||
#define WINED3DSP_TEXTURETYPE_MASK 0x78000000
|
||||
|
||||
typedef enum _WINED3DSAMPLER_TEXTURE_TYPE {
|
||||
WINED3DSTT_UNKNOWN = 0 << WINED3DSP_TEXTURETYPE_SHIFT,
|
||||
WINED3DSTT_1D = 1 << WINED3DSP_TEXTURETYPE_SHIFT,
|
||||
WINED3DSTT_2D = 2 << WINED3DSP_TEXTURETYPE_SHIFT,
|
||||
WINED3DSTT_CUBE = 3 << WINED3DSP_TEXTURETYPE_SHIFT,
|
||||
WINED3DSTT_VOLUME = 4 << WINED3DSP_TEXTURETYPE_SHIFT,
|
||||
|
||||
WINED3DSTT_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DSAMPLER_TEXTURE_TYPE;
|
||||
|
||||
/** Register number mask **/
|
||||
#define WINED3DSP_REGNUM_MASK 0x000007FF
|
||||
|
||||
/** Register type masks **/
|
||||
#define WINED3DSP_REGTYPE_SHIFT 28
|
||||
#define WINED3DSP_REGTYPE_SHIFT2 8
|
||||
#define WINED3DSP_REGTYPE_MASK (0x7 << WINED3DSP_REGTYPE_SHIFT)
|
||||
#define WINED3DSP_REGTYPE_MASK2 0x00001800
|
||||
|
||||
/** Register types **/
|
||||
typedef enum _WINED3DSHADER_PARAM_REGISTER_TYPE {
|
||||
WINED3DSPR_TEMP = 0,
|
||||
WINED3DSPR_INPUT = 1,
|
||||
WINED3DSPR_CONST = 2,
|
||||
WINED3DSPR_ADDR = 3,
|
||||
WINED3DSPR_TEXTURE = 3,
|
||||
WINED3DSPR_RASTOUT = 4,
|
||||
WINED3DSPR_ATTROUT = 5,
|
||||
WINED3DSPR_TEXCRDOUT = 6,
|
||||
WINED3DSPR_OUTPUT = 6,
|
||||
WINED3DSPR_CONSTINT = 7,
|
||||
WINED3DSPR_COLOROUT = 8,
|
||||
WINED3DSPR_DEPTHOUT = 9,
|
||||
WINED3DSPR_SAMPLER = 10,
|
||||
WINED3DSPR_CONST2 = 11,
|
||||
WINED3DSPR_CONST3 = 12,
|
||||
WINED3DSPR_CONST4 = 13,
|
||||
WINED3DSPR_CONSTBOOL = 14,
|
||||
WINED3DSPR_LOOP = 15,
|
||||
WINED3DSPR_TEMPFLOAT16 = 16,
|
||||
WINED3DSPR_MISCTYPE = 17,
|
||||
WINED3DSPR_LABEL = 18,
|
||||
WINED3DSPR_PREDICATE = 19,
|
||||
|
||||
WINED3DSPR_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DSHADER_PARAM_REGISTER_TYPE;
|
||||
|
||||
/* RASTOUT register offsets */
|
||||
typedef enum _WINED3DVS_RASTOUT_OFFSETS {
|
||||
WINED3DSRO_POSITION = 0,
|
||||
WINED3DSRO_FOG = 1,
|
||||
WINED3DSRO_POINT_SIZE = 2,
|
||||
|
||||
WINED3DSRO_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DVS_RASTOUT_OFFSETS;
|
||||
|
||||
/** Source register modifiers **/
|
||||
#define WINED3DVS_SWIZZLE_SHIFT 16
|
||||
#define WINED3DVS_SWIZZLE_MASK (0xFF << WINED3DVS_SWIZZLE_SHIFT)
|
||||
#define WINED3DSP_SWIZZLE_SHIFT 16
|
||||
#define WINED3DSP_SWIZZLE_MASK (0xFF << WINED3DSP_SWIZZLE_SHIFT)
|
||||
|
||||
#define WINED3DVS_X_X (0 << WINED3DVS_SWIZZLE_SHIFT)
|
||||
#define WINED3DVS_X_Y (1 << WINED3DVS_SWIZZLE_SHIFT)
|
||||
#define WINED3DVS_X_Z (2 << WINED3DVS_SWIZZLE_SHIFT)
|
||||
#define WINED3DVS_X_W (3 << WINED3DVS_SWIZZLE_SHIFT)
|
||||
|
||||
#define WINED3DVS_Y_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 2))
|
||||
#define WINED3DVS_Y_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 2))
|
||||
#define WINED3DVS_Y_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 2))
|
||||
#define WINED3DVS_Y_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 2))
|
||||
|
||||
#define WINED3DVS_Z_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 4))
|
||||
#define WINED3DVS_Z_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 4))
|
||||
#define WINED3DVS_Z_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 4))
|
||||
#define WINED3DVS_Z_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 4))
|
||||
|
||||
#define WINED3DVS_W_X (0 << (WINED3DVS_SWIZZLE_SHIFT + 6))
|
||||
#define WINED3DVS_W_Y (1 << (WINED3DVS_SWIZZLE_SHIFT + 6))
|
||||
#define WINED3DVS_W_Z (2 << (WINED3DVS_SWIZZLE_SHIFT + 6))
|
||||
#define WINED3DVS_W_W (3 << (WINED3DVS_SWIZZLE_SHIFT + 6))
|
||||
|
||||
#define WINED3DVS_NOSWIZZLE (WINED3DVS_X_X | WINED3DVS_Y_Y | WINED3DVS_Z_Z | WINED3DVS_W_W)
|
||||
|
||||
#define WINED3DSP_NOSWIZZLE \
|
||||
((0 << (WINED3DSP_SWIZZLE_SHIFT + 0)) | (1 << (WINED3DSP_SWIZZLE_SHIFT + 2)) | \
|
||||
(2 << (WINED3DSP_SWIZZLE_SHIFT + 4)) | (3 << (WINED3DSP_SWIZZLE_SHIFT + 6)))
|
||||
|
||||
#define WINED3DSP_SRCMOD_SHIFT 24
|
||||
#define WINED3DSP_SRCMOD_MASK (0xF << WINED3DSP_SRCMOD_SHIFT)
|
||||
|
||||
typedef enum _WINED3DSHADER_PARAM_SRCMOD_TYPE {
|
||||
WINED3DSPSM_NONE = 0 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_NEG = 1 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_BIAS = 2 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_BIASNEG = 3 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_SIGN = 4 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_SIGNNEG = 5 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_COMP = 6 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_X2 = 7 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_X2NEG = 8 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_DZ = 9 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_DW = 10 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_ABS = 11 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_ABSNEG = 12 << WINED3DSP_SRCMOD_SHIFT,
|
||||
WINED3DSPSM_NOT = 13 << WINED3DSP_SRCMOD_SHIFT,
|
||||
|
||||
WINED3DSPSM_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DSHADER_PARAM_SRCMOD_TYPE;
|
||||
|
||||
/** Destination register modifiers **/
|
||||
#define WINED3DSP_WRITEMASK_0 0x00010000 /* .x r */
|
||||
#define WINED3DSP_WRITEMASK_1 0x00020000 /* .y g */
|
||||
#define WINED3DSP_WRITEMASK_2 0x00040000 /* .z b */
|
||||
#define WINED3DSP_WRITEMASK_3 0x00080000 /* .w a */
|
||||
#define WINED3DSP_WRITEMASK_ALL 0x000F0000 /* all */
|
||||
|
||||
#define WINED3DSP_DSTMOD_SHIFT 20
|
||||
#define WINED3DSP_DSTMOD_MASK (0xF << WINED3DSP_DSTMOD_SHIFT)
|
||||
|
||||
typedef enum _WINED3DSHADER_PARAM_DSTMOD_TYPE {
|
||||
WINED3DSPDM_NONE = 0 << WINED3DSP_DSTMOD_SHIFT,
|
||||
WINED3DSPDM_SATURATE = 1 << WINED3DSP_DSTMOD_SHIFT,
|
||||
WINED3DSPDM_PARTIALPRECISION = 2 << WINED3DSP_DSTMOD_SHIFT,
|
||||
WINED3DSPDM_MSAMPCENTROID = 4 << WINED3DSP_DSTMOD_SHIFT,
|
||||
|
||||
WINED3DSPDM_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DSHADER_PARAM_DSTMOD_TYPE;
|
||||
|
||||
#define WINED3DSP_DSTSHIFT_SHIFT 24
|
||||
#define WINED3DSP_DSTSHIFT_MASK (0xF << WINED3DSP_DSTSHIFT_SHIFT)
|
||||
|
||||
/** Register addressing modes **/
|
||||
#define WINED3DSHADER_ADDRESSMODE_SHIFT 13
|
||||
#define WINED3DSHADER_ADDRESSMODE_MASK (1 << WINED3DSHADER_ADDRESSMODE_SHIFT)
|
||||
|
||||
typedef enum _WINED3DSHADER_ADDRESSMODE_TYPE {
|
||||
WINED3DSHADER_ADDRMODE_ABSOLUTE = 0 << WINED3DSHADER_ADDRESSMODE_SHIFT,
|
||||
WINED3DSHADER_ADDRMODE_RELATIVE = 1 << WINED3DSHADER_ADDRESSMODE_SHIFT,
|
||||
|
||||
WINED3DSHADER_ADDRMODE_FORCE_DWORD = 0x7FFFFFFF
|
||||
} WINED3DSHADER_ADDRESSMODE_TYPE;
|
||||
|
||||
/** Opcode types */
|
||||
typedef enum _WINED3DSHADER_INSTRUCTION_OPCODE_TYPE {
|
||||
WINED3DSIO_NOP = 0,
|
||||
WINED3DSIO_MOV = 1,
|
||||
WINED3DSIO_ADD = 2,
|
||||
WINED3DSIO_SUB = 3,
|
||||
WINED3DSIO_MAD = 4,
|
||||
WINED3DSIO_MUL = 5,
|
||||
WINED3DSIO_RCP = 6,
|
||||
WINED3DSIO_RSQ = 7,
|
||||
WINED3DSIO_DP3 = 8,
|
||||
WINED3DSIO_DP4 = 9,
|
||||
WINED3DSIO_MIN = 10,
|
||||
WINED3DSIO_MAX = 11,
|
||||
WINED3DSIO_SLT = 12,
|
||||
WINED3DSIO_SGE = 13,
|
||||
WINED3DSIO_EXP = 14,
|
||||
WINED3DSIO_LOG = 15,
|
||||
WINED3DSIO_LIT = 16,
|
||||
WINED3DSIO_DST = 17,
|
||||
WINED3DSIO_LRP = 18,
|
||||
WINED3DSIO_FRC = 19,
|
||||
WINED3DSIO_M4x4 = 20,
|
||||
WINED3DSIO_M4x3 = 21,
|
||||
WINED3DSIO_M3x4 = 22,
|
||||
WINED3DSIO_M3x3 = 23,
|
||||
WINED3DSIO_M3x2 = 24,
|
||||
WINED3DSIO_CALL = 25,
|
||||
WINED3DSIO_CALLNZ = 26,
|
||||
WINED3DSIO_LOOP = 27,
|
||||
WINED3DSIO_RET = 28,
|
||||
WINED3DSIO_ENDLOOP = 29,
|
||||
WINED3DSIO_LABEL = 30,
|
||||
WINED3DSIO_DCL = 31,
|
||||
WINED3DSIO_POW = 32,
|
||||
WINED3DSIO_CRS = 33,
|
||||
WINED3DSIO_SGN = 34,
|
||||
WINED3DSIO_ABS = 35,
|
||||
WINED3DSIO_NRM = 36,
|
||||
WINED3DSIO_SINCOS = 37,
|
||||
WINED3DSIO_REP = 38,
|
||||
WINED3DSIO_ENDREP = 39,
|
||||
WINED3DSIO_IF = 40,
|
||||
WINED3DSIO_IFC = 41,
|
||||
WINED3DSIO_ELSE = 42,
|
||||
WINED3DSIO_ENDIF = 43,
|
||||
WINED3DSIO_BREAK = 44,
|
||||
WINED3DSIO_BREAKC = 45,
|
||||
WINED3DSIO_MOVA = 46,
|
||||
WINED3DSIO_DEFB = 47,
|
||||
WINED3DSIO_DEFI = 48,
|
||||
|
||||
WINED3DSIO_TEXCOORD = 64,
|
||||
WINED3DSIO_TEXKILL = 65,
|
||||
WINED3DSIO_TEX = 66,
|
||||
WINED3DSIO_TEXBEM = 67,
|
||||
WINED3DSIO_TEXBEML = 68,
|
||||
WINED3DSIO_TEXREG2AR = 69,
|
||||
WINED3DSIO_TEXREG2GB = 70,
|
||||
WINED3DSIO_TEXM3x2PAD = 71,
|
||||
WINED3DSIO_TEXM3x2TEX = 72,
|
||||
WINED3DSIO_TEXM3x3PAD = 73,
|
||||
WINED3DSIO_TEXM3x3TEX = 74,
|
||||
WINED3DSIO_TEXM3x3DIFF = 75,
|
||||
WINED3DSIO_TEXM3x3SPEC = 76,
|
||||
WINED3DSIO_TEXM3x3VSPEC = 77,
|
||||
WINED3DSIO_EXPP = 78,
|
||||
WINED3DSIO_LOGP = 79,
|
||||
WINED3DSIO_CND = 80,
|
||||
WINED3DSIO_DEF = 81,
|
||||
WINED3DSIO_TEXREG2RGB = 82,
|
||||
WINED3DSIO_TEXDP3TEX = 83,
|
||||
WINED3DSIO_TEXM3x2DEPTH = 84,
|
||||
WINED3DSIO_TEXDP3 = 85,
|
||||
WINED3DSIO_TEXM3x3 = 86,
|
||||
WINED3DSIO_TEXDEPTH = 87,
|
||||
WINED3DSIO_CMP = 88,
|
||||
WINED3DSIO_BEM = 89,
|
||||
WINED3DSIO_DP2ADD = 90,
|
||||
WINED3DSIO_DSX = 91,
|
||||
WINED3DSIO_DSY = 92,
|
||||
WINED3DSIO_TEXLDD = 93,
|
||||
WINED3DSIO_SETP = 94,
|
||||
WINED3DSIO_TEXLDL = 95,
|
||||
WINED3DSIO_BREAKP = 96,
|
||||
|
||||
WINED3DSIO_PHASE = 0xFFFD,
|
||||
WINED3DSIO_COMMENT = 0xFFFE,
|
||||
WINED3DSIO_END = 0XFFFF,
|
||||
|
||||
WINED3DSIO_FORCE_DWORD = 0X7FFFFFFF /** for 32-bit alignment */
|
||||
} WINED3DSHADER_INSTRUCTION_OPCODE_TYPE;
|
||||
|
||||
/** opcode-related masks **/
|
||||
|
||||
#define WINED3DSI_OPCODE_MASK 0x0000FFFF
|
||||
#define WINED3DSI_INSTLENGTH_MASK 0x0F000000
|
||||
#define WINED3DSI_INSTLENGTH_SHIFT 24
|
||||
|
||||
#define WINED3DSI_COISSUE 0x40000000
|
||||
|
||||
#define WINED3DSI_COMMENTSIZE_SHIFT 16
|
||||
#define WINED3DSI_COMMENTSIZE_MASK (0x7FFF << WINED3DSI_COMMENTSIZE_SHIFT)
|
||||
#define WINED3DSHADER_COMMENT(commentSize) \
|
||||
((((commentSize) << WINED3DSI_COMMENTSIZE_SHIFT) & WINED3DSI_COMMENTSIZE_MASK) | WINED3DSIO_COMMENT)
|
||||
|
||||
#define WINED3DSHADER_INSTRUCTION_PREDICATED (1 << 28)
|
||||
|
||||
/* Undocumented opcode control to identify projective texture lookups in ps 2.0 and later */
|
||||
#define WINED3DSI_TEXLD_PROJECT 0x00010000
|
||||
|
||||
/** Shader version tokens, and shader end tokens **/
|
||||
|
||||
#define WINED3DPS_VERSION(major, minor) (0xFFFF0000 | ((major) << 8) | (minor))
|
||||
#define WINED3DVS_VERSION(major, minor) (0xFFFE0000 | ((major) << 8) | (minor))
|
||||
#define WINED3DSHADER_VERSION_MAJOR(version) (((version) >> 8) & 0xFF)
|
||||
#define WINED3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
|
||||
#define WINED3DPS_END() 0x0000FFFF
|
||||
#define WINED3DVS_END() 0x0000FFFF
|
||||
|
||||
/* Multithreaded flag. Removed from the public header to signal that IWineD3D::CreateDevice ignores it */
|
||||
#define WINED3DCREATE_MULTITHREADED 0x00000004
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user