- sync wined3d, ddraw, d3d8 and d3d9 with Wine 1.1.40

svn path=/trunk/; revision=45947
This commit is contained in:
Kamil Hornicek 2010-03-06 14:49:14 +00:00
parent 7632ce84a0
commit b7fbeda3eb
37 changed files with 6908 additions and 5661 deletions

View file

@ -35,7 +35,7 @@ void WINAPI DebugSetMute(void) {
/* nothing to do */
}
IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion) {
IDirect3D8* WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT SDKVersion) {
IDirect3D8Impl* object;
TRACE("SDKVersion = %x\n", SDKVersion);
@ -79,7 +79,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
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);
static BOOL warned;
if (TRACE_ON(d3d8) || !warned) {
FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, bool, toto);
warned = TRUE;
}
if (!vertexshader)
return E_FAIL;
@ -109,7 +114,12 @@ HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD
HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL bool, DWORD* toto)
{
HRESULT ret;
FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
static BOOL warned;
if (TRACE_ON(d3d8) || !warned) {
FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, bool, toto);
warned = TRUE;
}
if (!pixelshader)
return E_FAIL;

View file

@ -275,18 +275,6 @@ HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *devic
UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level,
DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) DECLSPEC_HIDDEN;
/* ------------------ */
/* IDirect3DResource8 */
/* ------------------ */
/*****************************************************************************
* Predeclare the interface implementation structures
*/
extern const IDirect3DResource8Vtbl Direct3DResource8_Vtbl DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirect3DResource8 implementation structure
*/
struct IDirect3DResource8Impl
{
/* IUnknown fields */

View file

@ -1047,7 +1047,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_BeginScene(LPDIRECT3DDEVICE8 iface) {
return hr;
}
static HRESULT WINAPI IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice8Impl_EndScene(LPDIRECT3DDEVICE8 iface) {
IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
HRESULT hr;

View file

@ -33,7 +33,7 @@ void WINAPI DebugSetMute(void) {
/* nothing to do */
}
IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) {
IDirect3D9* WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT SDKVersion) {
IDirect3D9Impl* object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3D9Impl));
object->lpVtbl = &Direct3D9_Vtbl;
@ -53,7 +53,7 @@ IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion) {
return (IDirect3D9*) object;
}
HRESULT WINAPI Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **direct3d9ex) {
HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **direct3d9ex) {
IDirect3D9 *ret;
IDirect3D9Impl* object;

View file

@ -187,11 +187,6 @@ HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapte
extern HRESULT WINAPI IDirect3DDevice9Impl_GetSwapChain(IDirect3DDevice9Ex *iface,
UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain) DECLSPEC_HIDDEN;
extern UINT WINAPI IDirect3DDevice9Impl_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9 **ppSB) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface,
IDirect3DStateBlock9 **ppSB) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_SetVertexDeclaration(IDirect3DDevice9Ex *iface,
IDirect3DVertexDeclaration9 *pDecl) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_GetVertexDeclaration(IDirect3DDevice9Ex *iface,
@ -228,9 +223,6 @@ extern HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantB(IDirect3DDevi
UINT StartRegister, const BOOL *pConstantData, UINT BoolCount) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
UINT StartRegister, BOOL *pConstantData, UINT BoolCount) DECLSPEC_HIDDEN;
extern HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface,
D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery) DECLSPEC_HIDDEN;
/* ---------------- */
/* IDirect3DVolume9 */
@ -470,6 +462,8 @@ typedef struct IDirect3DStateBlock9Impl {
LPDIRECT3DDEVICE9EX parentDevice;
} IDirect3DStateBlock9Impl;
HRESULT stateblock_init(IDirect3DStateBlock9Impl *stateblock, IDirect3DDevice9Impl *device,
D3DSTATEBLOCKTYPE type, IWineD3DStateBlock *wined3d_stateblock) DECLSPEC_HIDDEN;
/* --------------------------- */
/* IDirect3DVertexDeclaration9 */
@ -564,4 +558,7 @@ typedef struct IDirect3DQuery9Impl {
LPDIRECT3DDEVICE9EX parentDevice;
} IDirect3DQuery9Impl;
HRESULT query_init(IDirect3DQuery9Impl *query, IDirect3DDevice9Impl *device,
D3DQUERYTYPE type) DECLSPEC_HIDDEN;
#endif /* __WINE_D3D9_PRIVATE_H */

View file

@ -248,7 +248,7 @@ static ULONG WINAPI IDirect3DDevice9Impl_AddRef(LPDIRECT3DDEVICE9EX iface) {
return ref;
}
static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
ULONG ref;
@ -452,7 +452,7 @@ static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX ifac
return ret;
}
static HRESULT WINAPI IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
@ -541,7 +541,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
return ret;
}
static HRESULT WINAPI IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
WINED3DPRESENT_PARAMETERS localParameters;
HRESULT hr;
@ -619,7 +619,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3DP
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA*
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA*
pDirtyRegion) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
@ -1182,7 +1182,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX ifac
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
@ -1388,7 +1388,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX if
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD Value) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD Value) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
@ -1414,6 +1414,97 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DStateBlock9Impl *object;
HRESULT hr;
TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
{
WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
return D3DERR_INVALIDCALL;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate stateblock memory.\n");
return E_OUTOFMEMORY;
}
hr = stateblock_init(object, This, type, NULL);
if (FAILED(hr))
{
WARN("Failed to initialize stateblock, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created stateblock %p.\n", object);
*stateblock = (IDirect3DStateBlock9 *)object;
return D3D_OK;
}
static HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
TRACE("iface %p.\n", iface);
wined3d_mutex_lock();
hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
wined3d_mutex_unlock();
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **stateblock)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IWineD3DStateBlock *wined3d_stateblock;
IDirect3DStateBlock9Impl *object;
HRESULT hr;
TRACE("iface %p, stateblock %p.\n", iface, stateblock);
wined3d_mutex_lock();
hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice, &wined3d_stateblock);
wined3d_mutex_unlock();
if (FAILED(hr))
{
WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
return hr;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate stateblock memory.\n");
IWineD3DStateBlock_Release(wined3d_stateblock);
return E_OUTOFMEMORY;
}
hr = stateblock_init(object, This, 0, wined3d_stateblock);
if (FAILED(hr))
{
WARN("Failed to initialize stateblock, hr %#x.\n", hr);
IWineD3DStateBlock_Release(wined3d_stateblock);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created stateblock %p.\n", object);
*stateblock = (IDirect3DStateBlock9 *)object;
return D3D_OK;
}
static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX iface, CONST D3DCLIPSTATUS9* pClipStatus) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
@ -1559,7 +1650,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *i
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
@ -2178,6 +2269,37 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX ifa
return hr;
}
static HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface,
D3DQUERYTYPE type, IDirect3DQuery9 **query)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DQuery9Impl *object;
HRESULT hr;
TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate query memory.\n");
return E_OUTOFMEMORY;
}
hr = query_init(object, This, type);
if (FAILED(hr))
{
WARN("Failed to initialize query, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
TRACE("Created query %p.\n", object);
if (query) *query = (IDirect3DQuery9 *)object;
else IDirect3DQuery9_Release((IDirect3DQuery9 *)object);
return D3D_OK;
}
static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
UINT width, UINT height, float *rows, float *columns)
{

View file

@ -407,7 +407,7 @@ static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9EX iface, UIN
return ret;
}
static HRESULT WINAPI IDirect3D9Impl_CreateDevice(IDirect3D9Ex *iface, UINT adapter,
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9Impl_CreateDevice(IDirect3D9Ex *iface, UINT adapter,
D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters,
IDirect3DDevice9 **device)
{
@ -465,7 +465,7 @@ static HRESULT WINAPI IDirect3D9ExImpl_GetAdapterDisplayModeEx(IDirect3D9Ex *ifa
return D3DERR_DRIVERINTERNALERROR;
}
static HRESULT WINAPI IDirect3D9ExImpl_CreateDeviceEx(IDirect3D9Ex *iface,
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3D9ExImpl_CreateDeviceEx(IDirect3D9Ex *iface,
UINT adapter, D3DDEVTYPE device_type, HWND focus_window, DWORD flags,
D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode, IDirect3DDevice9Ex **device)
{

View file

@ -150,49 +150,24 @@ static const IDirect3DQuery9Vtbl Direct3DQuery9_Vtbl =
IDirect3DQuery9Impl_GetData
};
HRESULT query_init(IDirect3DQuery9Impl *query, IDirect3DDevice9Impl *device, D3DQUERYTYPE type)
{
HRESULT hr;
/* IDirect3DDevice9 IDirect3DQuery9 Methods follow: */
HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(LPDIRECT3DDEVICE9EX iface, D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DQuery9Impl *object = NULL;
HRESULT hr = D3D_OK;
query->lpVtbl = &Direct3DQuery9_Vtbl;
query->ref = 1;
TRACE("iface %p, type %#x, query %p.\n", iface, Type, ppQuery);
if (!ppQuery)
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateQuery(device->WineD3DDevice, type, &query->wineD3DQuery, (IUnknown *)query);
wined3d_mutex_unlock();
if (FAILED(hr))
{
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, NULL, NULL);
wined3d_mutex_unlock();
WARN("Failed to create wined3d query, hr %#x.\n", hr);
return hr;
}
/* Allocate the storage for the device */
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DQuery9Impl));
if (NULL == object) {
ERR("Allocation of memory failed, returning D3DERR_OUTOFVIDEOMEMORY\n");
return D3DERR_OUTOFVIDEOMEMORY;
}
query->parentDevice = (IDirect3DDevice9Ex *)device;
IDirect3DDevice9Ex_AddRef(query->parentDevice);
object->lpVtbl = &Direct3DQuery9_Vtbl;
object->ref = 1;
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateQuery(This->WineD3DDevice, Type, &object->wineD3DQuery, (IUnknown *)object);
wined3d_mutex_unlock();
if (FAILED(hr)) {
/* free up object */
WARN("(%p) call to IWineD3DDevice_CreateQuery failed\n", This);
HeapFree(GetProcessHeap(), 0, object);
} else {
IDirect3DDevice9Ex_AddRef(iface);
object->parentDevice = iface;
*ppQuery = (LPDIRECT3DQUERY9) object;
TRACE("(%p) : Created query %p\n", This , object);
}
TRACE("(%p) : returning %x\n", This, hr);
return hr;
return D3D_OK;
}

View file

@ -123,87 +123,33 @@ static const IDirect3DStateBlock9Vtbl Direct3DStateBlock9_Vtbl =
IDirect3DStateBlock9Impl_Apply
};
/* IDirect3DDevice9 IDirect3DStateBlock9 Methods follow: */
HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(LPDIRECT3DDEVICE9EX iface, D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppStateBlock) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DStateBlock9Impl* object;
HRESULT hrc = D3D_OK;
TRACE("iface %p, type %#x, stateblock %p.\n", iface, Type, ppStateBlock);
if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
Type != D3DSBT_VERTEXSTATE ) {
WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL\n");
return D3DERR_INVALIDCALL;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock9Impl));
if (NULL == object) return E_OUTOFMEMORY;
object->lpVtbl = &Direct3DStateBlock9_Vtbl;
object->ref = 1;
wined3d_mutex_lock();
hrc = IWineD3DDevice_CreateStateBlock(This->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)Type, &object->wineD3DStateBlock, (IUnknown*)object);
wined3d_mutex_unlock();
if(hrc != D3D_OK){
FIXME("(%p) Call to IWineD3DDevice_CreateStateBlock failed.\n", This);
HeapFree(GetProcessHeap(), 0, object);
} else {
IDirect3DDevice9Ex_AddRef(iface);
object->parentDevice = iface;
*ppStateBlock = (IDirect3DStateBlock9*)object;
TRACE("(%p) : Created stateblock %p\n", This, object);
}
TRACE("(%p) returning token (ptr to stateblock) of %p\n", This, object);
return hrc;
}
HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
HRESULT stateblock_init(IDirect3DStateBlock9Impl *stateblock, IDirect3DDevice9Impl *device,
D3DSTATEBLOCKTYPE type, IWineD3DStateBlock *wined3d_stateblock)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hr;
TRACE("iface %p.\n", iface);
stateblock->lpVtbl = &Direct3DStateBlock9_Vtbl;
stateblock->ref = 1;
wined3d_mutex_lock();
hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
wined3d_mutex_unlock();
return hr;
}
HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **ppSB)
{
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IWineD3DStateBlock *wineD3DStateBlock;
IDirect3DStateBlock9Impl *object;
HRESULT hr;
TRACE("iface %p, stateblock %p.\n", iface, ppSB);
/* Tell wineD3D to endstateblock before anything else (in case we run out
* of memory later and cause locking problems) */
wined3d_mutex_lock();
hr=IWineD3DDevice_EndStateBlock(This->WineD3DDevice,&wineD3DStateBlock);
wined3d_mutex_unlock();
if (hr!= D3D_OK)
if (wined3d_stateblock)
{
WARN("IWineD3DDevice_EndStateBlock returned an error\n");
return hr;
stateblock->wineD3DStateBlock = wined3d_stateblock;
}
else
{
wined3d_mutex_lock();
hr = IWineD3DDevice_CreateStateBlock(device->WineD3DDevice, (WINED3DSTATEBLOCKTYPE)type,
&stateblock->wineD3DStateBlock, (IUnknown *)stateblock);
wined3d_mutex_unlock();
if (FAILED(hr))
{
WARN("Failed to create wined3d stateblock, hr %#x.\n", hr);
return hr;
}
}
/* allocate a new IDirectD3DStateBlock */
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DStateBlock9Impl));
if (!object) return E_OUTOFMEMORY;
object->ref = 1;
object->lpVtbl = &Direct3DStateBlock9_Vtbl;
object->wineD3DStateBlock = wineD3DStateBlock;
IDirect3DDevice9Ex_AddRef(iface);
object->parentDevice = iface;
*ppSB=(IDirect3DStateBlock9*)object;
TRACE("(%p) Returning *ppSB %p, wineD3DStateBlock %p\n", This, *ppSB, wineD3DStateBlock);
stateblock->parentDevice = (IDirect3DDevice9Ex *)device;
IDirect3DDevice9Ex_AddRef(stateblock->parentDevice);
return D3D_OK;
}

View file

@ -79,7 +79,7 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface)
}
/* IDirect3DSwapChain9 parts follow: */
static HRESULT WINAPI IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) {
static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DSwapChain9Impl_Present(LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) {
IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface;
HRESULT hr;
@ -269,7 +269,7 @@ HRESULT swapchain_init(IDirect3DSwapChain9Impl *swapchain, IDirect3DDevice9Impl
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) {
HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_GetSwapChain(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
HRESULT hrc = D3D_OK;
IWineD3DSwapChain *swapchain = NULL;

View file

@ -1705,13 +1705,13 @@ IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
else return D3DERR_SCENE_NOT_IN_SCENE;
}
static HRESULT WINAPI
static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
{
return IDirect3DDeviceImpl_7_EndScene(iface);
}
static HRESULT WINAPI
static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
{
HRESULT hr;
@ -1724,7 +1724,7 @@ IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
return hr;
}
static HRESULT WINAPI
static HRESULT WINAPI DECLSPEC_HOTPATCH
Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
{
IDirect3DDeviceImpl *This = device_from_device3(iface);
@ -1732,7 +1732,7 @@ Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
}
static HRESULT WINAPI
static HRESULT WINAPI DECLSPEC_HOTPATCH
Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
{
IDirect3DDeviceImpl *This = device_from_device2(iface);
@ -1740,7 +1740,7 @@ Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
}
static HRESULT WINAPI
static HRESULT WINAPI DECLSPEC_HOTPATCH
Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
{
IDirect3DDeviceImpl *This = device_from_device1(iface);
@ -2580,7 +2580,8 @@ IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
}
if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
{
ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
}
@ -2852,16 +2853,12 @@ IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
IWineD3DBaseTexture_Release(tex);
}
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
if (tex_alpha)
{
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
}
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
else
{
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
}
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
@ -4664,15 +4661,11 @@ IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
IWineD3DBaseTexture_Release(tex);
}
/* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
/* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
if (tex_alpha)
{
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
}
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
else
{
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
}
IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
}
LeaveCriticalSection(&ddraw_cs);

View file

@ -302,7 +302,7 @@ err_out:
* Arguments, return values: See DDRAW_Create
*
***********************************************************************/
HRESULT WINAPI
HRESULT WINAPI DECLSPEC_HOTPATCH
DirectDrawCreate(GUID *GUID,
LPDIRECTDRAW *DD,
IUnknown *UnkOuter)
@ -325,7 +325,7 @@ DirectDrawCreate(GUID *GUID,
* Arguments, return values: See DDRAW_Create
*
***********************************************************************/
HRESULT WINAPI
HRESULT WINAPI DECLSPEC_HOTPATCH
DirectDrawCreateEx(GUID *GUID,
LPVOID *DD,
REFIID iid,
@ -742,14 +742,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
HRESULT hr;
FIXME("(void): stub\n");
EnterCriticalSection(&ddraw_cs);
hr = S_FALSE;
LeaveCriticalSection(&ddraw_cs);
return hr;
return S_FALSE;
}
/*******************************************************************************

View file

@ -236,8 +236,17 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface;
WINED3DBUFFER_DESC Desc;
HRESULT hr;
DWORD wined3d_flags = 0;
TRACE("(%p)->(%08x,%p,%p)\n", This, Flags, Data, Size);
/* Writeonly: Pointless. Event: Unsupported by native according to the sdk
* nosyslock: Not applicable
*/
if(!(Flags & DDLOCK_WAIT)) wined3d_flags |= WINED3DLOCK_DONOTWAIT;
if(Flags & DDLOCK_READONLY) wined3d_flags |= WINED3DLOCK_READONLY;
if(Flags & DDLOCK_NOOVERWRITE) wined3d_flags |= WINED3DLOCK_NOOVERWRITE;
if(Flags & DDLOCK_DISCARDCONTENTS) wined3d_flags |= WINED3DLOCK_DISCARD;
EnterCriticalSection(&ddraw_cs);
if(Size)
{
@ -253,7 +262,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
}
hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, 0 /* OffsetToLock */,
0 /* SizeToLock, 0 == Full lock */, (BYTE **)Data, Flags);
0 /* SizeToLock, 0 == Full lock */, (BYTE **)Data, wined3d_flags);
LeaveCriticalSection(&ddraw_cs);
return hr;
}

View file

@ -255,14 +255,25 @@ IDirect3DViewportImpl_GetViewport(IDirect3DViewport3 *iface,
TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
EnterCriticalSection(&ddraw_cs);
if (This->use_vp2 != 0) {
ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
dwSize = lpData->dwSize;
memset(lpData, 0, dwSize);
memcpy(lpData, &(This->viewports.vp1), dwSize);
if (!This->use_vp2)
memcpy(lpData, &(This->viewports.vp1), dwSize);
else {
D3DVIEWPORT vp1;
vp1.dwSize = sizeof(vp1);
vp1.dwX = This->viewports.vp2.dwX;
vp1.dwY = This->viewports.vp2.dwY;
vp1.dwWidth = This->viewports.vp2.dwWidth;
vp1.dwHeight = This->viewports.vp2.dwHeight;
vp1.dvMaxX = 0.0;
vp1.dvMaxY = 0.0;
vp1.dvScaleX = 0.0;
vp1.dvScaleY = 0.0;
vp1.dvMinZ = This->viewports.vp2.dvMinZ;
vp1.dvMaxZ = This->viewports.vp2.dvMaxZ;
memcpy(lpData, &vp1, dwSize);
}
if (TRACE_ON(d3d7)) {
TRACE(" returning D3DVIEWPORT :\n");
@ -908,14 +919,25 @@ IDirect3DViewportImpl_GetViewport2(IDirect3DViewport3 *iface,
TRACE("(%p)->(%p)\n", This, lpData);
EnterCriticalSection(&ddraw_cs);
if (This->use_vp2 != 1) {
ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
dwSize = lpData->dwSize;
memset(lpData, 0, dwSize);
memcpy(lpData, &(This->viewports.vp2), dwSize);
if (This->use_vp2)
memcpy(lpData, &(This->viewports.vp2), dwSize);
else {
D3DVIEWPORT2 vp2;
vp2.dwSize = sizeof(vp2);
vp2.dwX = This->viewports.vp1.dwX;
vp2.dwY = This->viewports.vp1.dwY;
vp2.dwWidth = This->viewports.vp1.dwWidth;
vp2.dwHeight = This->viewports.vp1.dwHeight;
vp2.dvClipX = 0.0;
vp2.dvClipY = 0.0;
vp2.dvClipWidth = 0.0;
vp2.dvClipHeight = 0.0;
vp2.dvMinZ = This->viewports.vp1.dvMinZ;
vp2.dvMaxZ = This->viewports.vp1.dvMaxZ;
memcpy(lpData, &vp2, dwSize);
}
if (TRACE_ON(d3d7)) {
TRACE(" returning D3DVIEWPORT2 :\n");

View file

@ -41,6 +41,45 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION (*gl_info)
/* Extract a line. Note that this modifies the source string. */
static char *get_line(char **ptr)
{
char *p, *q;
p = *ptr;
if (!(q = strstr(p, "\n")))
{
if (!*p) return NULL;
*ptr += strlen(p);
return p;
}
*q = '\0';
*ptr = q + 1;
return p;
}
static void shader_arb_dump_program_source(const char *source)
{
unsigned long source_size;
char *ptr, *line, *tmp;
source_size = strlen(source) + 1;
tmp = HeapAlloc(GetProcessHeap(), 0, source_size);
if (!tmp)
{
ERR("Failed to allocate %lu bytes for shader source.\n", source_size);
return;
}
memcpy(tmp, source, source_size);
ptr = tmp;
while ((line = get_line(&ptr))) FIXME(" %s\n", line);
FIXME("\n");
HeapFree(GetProcessHeap(), 0, tmp);
}
/* GL locking for state handlers is done by the caller. */
static BOOL need_mova_const(IWineD3DBaseShader *shader, const struct wined3d_gl_info *gl_info)
{
@ -1122,10 +1161,10 @@ static void gen_color_correction(struct wined3d_shader_buffer *buffer, const cha
{
DWORD mask;
if (is_yuv_fixup(fixup))
if (is_complex_fixup(fixup))
{
enum yuv_fixup yuv_fixup = get_yuv_fixup(fixup);
FIXME("YUV fixup (%#x) not supported\n", yuv_fixup);
enum complex_fixup complex_fixup = get_complex_fixup(fixup);
FIXME("Complex fixup (%#x) not supported\n", complex_fixup);
return;
}
@ -1761,8 +1800,8 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
ins->ctx->reg_maps->shader_version.minor);
@ -1856,8 +1895,8 @@ static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins)
{
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
DWORD flags;
DWORD reg1 = ins->dst[0].reg.idx;
@ -1904,7 +1943,8 @@ static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)shader->baseShader.device;
const struct wined3d_shader_dst_param *dst = &ins->dst[0];
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
char reg_coord[40], dst_reg[50], src_reg[50];
@ -1936,8 +1976,8 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
/* with projective textures, texbem only divides the static texture coord, not the displacement,
* so we can't let the GL handle this.
*/
if (((IWineD3DDeviceImpl*) This->baseShader.device)->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]
& WINED3DTTFF_PROJECTED) {
if (device->stateBlock->textureState[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS] & WINED3DTTFF_PROJECTED)
{
shader_addline(buffer, "RCP TB.w, %s.w;\n", reg_coord);
shader_addline(buffer, "MUL TB.xy, %s, TB.w;\n", reg_coord);
shader_addline(buffer, "ADD TA.xy, TA, TB;\n");
@ -1975,8 +2015,8 @@ static void pshader_hw_texm3x2pad(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
DWORD flags;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
@ -1997,10 +2037,10 @@ static void pshader_hw_texm3x2tex(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char src0_name[50], dst_name[50];
struct wined3d_shader_register tmp_reg = ins->dst[0].reg;
BOOL is_color;
@ -2020,12 +2060,12 @@ static void pshader_hw_texm3x3pad(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
DWORD flags;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char dst_str[50];
char src0_name[50], dst_name[50];
BOOL is_color;
@ -2043,12 +2083,12 @@ static void pshader_hw_texm3x3tex(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
DWORD flags;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
char dst_str[50];
char src0_name[50];
char dst_reg[50];
@ -2085,11 +2125,11 @@ static void pshader_hw_texm3x3vspec(const struct wined3d_shader_instruction *ins
static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
DWORD flags;
DWORD reg = ins->dst[0].reg.idx;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
char dst_str[50];
char src0_name[50];
@ -3046,8 +3086,9 @@ static GLuint create_arb_blt_vertex_program(const struct wined3d_gl_info *gl_inf
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Vertex program error at position %d: %s\n", pos,
FIXME("Vertex program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(blt_vprogram);
}
else
{
@ -3108,8 +3149,9 @@ static GLuint create_arb_blt_fragment_program(const struct wined3d_gl_info *gl_i
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Fragment program error at position %d: %s\n", pos,
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(blt_fprograms[tex_type]);
}
else
{
@ -3564,8 +3606,9 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
if (errPos != -1)
{
FIXME("HW PixelShader Error at position %d: %s\n",
FIXME("HW PixelShader Error at position %d: %s\n\n",
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer->buffer);
retval = 0;
}
else
@ -3974,8 +4017,9 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShaderImpl *This, struct
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
if (errPos != -1)
{
FIXME("HW VertexShader Error at position %d: %s\n",
FIXME("HW VertexShader Error at position %d: %s\n\n",
errPos, debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer->buffer);
ret = -1;
}
else
@ -4448,8 +4492,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
if (shader_is_pshader_version(baseShader->baseShader.reg_maps.shader_version.type))
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
struct arb_pshader_private *shader_data = This->baseShader.backend_data;
struct arb_pshader_private *shader_data = baseShader->baseShader.backend_data;
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
@ -4471,10 +4514,11 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
This->baseShader.backend_data = NULL;
} else {
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *) iface;
struct arb_vshader_private *shader_data = This->baseShader.backend_data;
baseShader->baseShader.backend_data = NULL;
}
else
{
struct arb_vshader_private *shader_data = baseShader->baseShader.backend_data;
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
@ -4496,7 +4540,7 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
This->baseShader.backend_data = NULL;
baseShader->baseShader.backend_data = NULL;
}
}
@ -4565,8 +4609,7 @@ static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) {
return TRUE;
}
static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info,
struct shader_caps *pCaps)
static void shader_arb_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
{
DWORD vs_consts = min(gl_info->limits.arb_vs_float_constants, gl_info->limits.arb_vs_native_constants);
DWORD ps_consts = min(gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_native_constants);
@ -4574,7 +4617,7 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_
/* We don't have an ARB fixed function pipeline yet, so let the none backend set its caps,
* then overwrite the shader specific ones
*/
none_shader_backend.shader_get_caps(devtype, gl_info, pCaps);
none_shader_backend.shader_get_caps(gl_info, pCaps);
if (gl_info->supported[ARB_VERTEX_PROGRAM])
{
@ -4630,8 +4673,8 @@ static BOOL shader_arb_color_fixup_supported(struct color_fixup_desc fixup)
dump_color_fixup_desc(fixup);
}
/* We support everything except YUV conversions. */
if (!is_yuv_fixup(fixup))
/* We support everything except complex conversions. */
if (!is_complex_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
@ -4678,6 +4721,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_CMP */ pshader_hw_cmp,
/* WINED3DSIH_CND */ pshader_hw_cnd,
/* WINED3DSIH_CRS */ shader_hw_map2gl,
/* WINED3DSIH_CUT */ NULL,
/* WINED3DSIH_DCL */ NULL,
/* WINED3DSIH_DEF */ NULL,
/* WINED3DSIH_DEFB */ NULL,
@ -4689,20 +4733,24 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_DSX */ shader_hw_map2gl,
/* WINED3DSIH_DSY */ shader_hw_dsy,
/* WINED3DSIH_ELSE */ shader_hw_else,
/* WINED3DSIH_EMIT */ NULL,
/* WINED3DSIH_ENDIF */ shader_hw_endif,
/* WINED3DSIH_ENDLOOP */ shader_hw_endloop,
/* WINED3DSIH_ENDREP */ shader_hw_endrep,
/* WINED3DSIH_EXP */ shader_hw_scalar_op,
/* WINED3DSIH_EXPP */ shader_hw_scalar_op,
/* WINED3DSIH_FRC */ shader_hw_map2gl,
/* WINED3DSIH_IADD */ NULL,
/* WINED3DSIH_IF */ NULL /* Hardcoded into the shader */,
/* WINED3DSIH_IFC */ shader_hw_ifc,
/* WINED3DSIH_IGE */ NULL,
/* WINED3DSIH_LABEL */ shader_hw_label,
/* WINED3DSIH_LIT */ shader_hw_map2gl,
/* WINED3DSIH_LOG */ shader_hw_log_pow,
/* WINED3DSIH_LOGP */ shader_hw_log_pow,
/* WINED3DSIH_LOOP */ shader_hw_loop,
/* WINED3DSIH_LRP */ shader_hw_lrp,
/* WINED3DSIH_LT */ NULL,
/* WINED3DSIH_M3x2 */ shader_hw_mnxn,
/* WINED3DSIH_M3x3 */ shader_hw_mnxn,
/* WINED3DSIH_M3x4 */ shader_hw_mnxn,
@ -5229,7 +5277,7 @@ static void arbfp_free(IWineD3DDevice *iface) {
}
}
static void arbfp_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
static void arbfp_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |
@ -5858,8 +5906,9 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, IWi
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Fragment program error at position %d: %s\n", pos,
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer.buffer);
}
else
{
@ -6180,6 +6229,7 @@ struct arbfp_blit_priv {
GLenum yuy2_rect_shader, yuy2_2d_shader;
GLenum uyvy_rect_shader, uyvy_2d_shader;
GLenum yv12_rect_shader, yv12_2d_shader;
GLenum p8_rect_shader, p8_2d_shader;
};
static HRESULT arbfp_blit_alloc(IWineD3DDevice *iface) {
@ -6204,20 +6254,22 @@ static void arbfp_blit_free(IWineD3DDevice *iface) {
GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader));
checkGLcall("Delete yuv programs");
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader));
GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader));
checkGLcall("Delete yuv and p8 programs");
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, device->blit_priv);
device->blit_priv = NULL;
}
static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum yuv_fixup yuv_fixup,
static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum complex_fixup fixup,
GLenum textype, char *luminance)
{
char chroma;
const char *tex, *texinstr;
if (yuv_fixup == YUV_FIXUP_UYVY) {
if (fixup == COMPLEX_FIXUP_UYVY) {
chroma = 'x';
*luminance = 'w';
} else {
@ -6445,8 +6497,74 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
return TRUE;
}
static GLuint gen_p8_shader(IWineD3DDeviceImpl *device, GLenum textype)
{
GLenum shader;
struct wined3d_shader_buffer buffer;
struct arbfp_blit_priv *priv = device->blit_priv;
GLint pos;
/* Shader header */
if (!shader_buffer_init(&buffer))
{
ERR("Failed to initialize shader buffer.\n");
return 0;
}
ENTER_GL();
GL_EXTCALL(glGenProgramsARB(1, &shader));
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shader));
LEAVE_GL();
if(!shader) {
shader_buffer_free(&buffer);
return 0;
}
shader_addline(&buffer, "!!ARBfp1.0\n");
shader_addline(&buffer, "TEMP index;\n");
/* { 255/256, 0.5/255*255/256, 0, 0 } */
shader_addline(&buffer, "PARAM constants = { 0.996, 0.00195, 0, 0 };\n");
/* The alpha-component contains the palette index */
if(textype == GL_TEXTURE_RECTANGLE_ARB)
shader_addline(&buffer, "TXP index, fragment.texcoord[0], texture[0], RECT;\n");
else
shader_addline(&buffer, "TEX index, fragment.texcoord[0], texture[0], 2D;\n");
/* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
shader_addline(&buffer, "MAD index.a, index.a, constants.x, constants.y;\n");
/* Use the alpha-component as an index in the palette to get the final color */
shader_addline(&buffer, "TEX result.color, index.a, texture[1], 1D;\n");
shader_addline(&buffer, "END\n");
ENTER_GL();
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(buffer.buffer), buffer.buffer));
checkGLcall("glProgramStringARB()");
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer.buffer);
}
if (textype == GL_TEXTURE_RECTANGLE_ARB)
priv->p8_rect_shader = shader;
else
priv->p8_2d_shader = shader;
shader_buffer_free(&buffer);
LEAVE_GL();
return shader;
}
/* Context activation is done by the caller. */
static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixup, GLenum textype)
static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum complex_fixup yuv_fixup, GLenum textype)
{
GLenum shader;
struct wined3d_shader_buffer buffer;
@ -6519,8 +6637,8 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
switch (yuv_fixup)
{
case YUV_FIXUP_UYVY:
case YUV_FIXUP_YUY2:
case COMPLEX_FIXUP_UYVY:
case COMPLEX_FIXUP_YUY2:
if (!gen_planar_yuv_read(&buffer, yuv_fixup, textype, &luminance_component))
{
shader_buffer_free(&buffer);
@ -6528,7 +6646,7 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
}
break;
case YUV_FIXUP_YV12:
case COMPLEX_FIXUP_YV12:
if (!gen_yv12_read(&buffer, textype, &luminance_component))
{
shader_buffer_free(&buffer);
@ -6562,8 +6680,9 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
if (pos != -1)
{
FIXME("Fragment program error at position %d: %s\n", pos,
FIXME("Fragment program error at position %d: %s\n\n", pos,
debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
shader_arb_dump_program_source(buffer.buffer);
}
else
{
@ -6579,20 +6698,22 @@ static GLuint gen_yuv_shader(IWineD3DDeviceImpl *device, enum yuv_fixup yuv_fixu
switch (yuv_fixup)
{
case YUV_FIXUP_YUY2:
case COMPLEX_FIXUP_YUY2:
if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yuy2_rect_shader = shader;
else priv->yuy2_2d_shader = shader;
break;
case YUV_FIXUP_UYVY:
case COMPLEX_FIXUP_UYVY:
if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->uyvy_rect_shader = shader;
else priv->uyvy_2d_shader = shader;
break;
case YUV_FIXUP_YV12:
case COMPLEX_FIXUP_YV12:
if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader;
else priv->yv12_2d_shader = shader;
break;
default:
ERR("Unsupported complex fixup: %d\n", yuv_fixup);
}
return shader;
@ -6606,9 +6727,9 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *) iface;
float size[4] = {width, height, 1, 1};
struct arbfp_blit_priv *priv = device->blit_priv;
enum yuv_fixup yuv_fixup;
enum complex_fixup fixup;
if (!is_yuv_fixup(format_desc->color_fixup))
if (!is_complex_fixup(format_desc->color_fixup))
{
TRACE("Fixup:\n");
dump_color_fixup_desc(format_desc->color_fixup);
@ -6620,24 +6741,29 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD
return WINED3D_OK;
}
yuv_fixup = get_yuv_fixup(format_desc->color_fixup);
fixup = get_complex_fixup(format_desc->color_fixup);
switch(yuv_fixup)
switch(fixup)
{
case YUV_FIXUP_YUY2:
case COMPLEX_FIXUP_YUY2:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yuy2_rect_shader : priv->yuy2_2d_shader;
break;
case YUV_FIXUP_UYVY:
case COMPLEX_FIXUP_UYVY:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->uyvy_rect_shader : priv->uyvy_2d_shader;
break;
case YUV_FIXUP_YV12:
case COMPLEX_FIXUP_YV12:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader : priv->yv12_2d_shader;
break;
case COMPLEX_FIXUP_P8:
shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader;
if (!shader) shader = gen_p8_shader(device, textype);
break;
default:
FIXME("Unsupported YUV fixup %#x, not setting a shader\n", yuv_fixup);
FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup);
ENTER_GL();
glEnable(textype);
checkGLcall("glEnable(textype)");
@ -6645,7 +6771,7 @@ static HRESULT arbfp_blit_set(IWineD3DDevice *iface, const struct GlPixelFormatD
return E_NOTIMPL;
}
if (!shader) shader = gen_yuv_shader(device, yuv_fixup, textype);
if (!shader) shader = gen_yuv_shader(device, fixup, textype);
ENTER_GL();
glEnable(GL_FRAGMENT_PROGRAM_ARB);
@ -6684,7 +6810,7 @@ static void arbfp_blit_unset(IWineD3DDevice *iface) {
static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup)
{
enum yuv_fixup yuv_fixup;
enum complex_fixup complex_fixup;
if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
{
@ -6699,23 +6825,24 @@ static BOOL arbfp_blit_color_fixup_supported(struct color_fixup_desc fixup)
}
/* We only support YUV conversions. */
if (!is_yuv_fixup(fixup))
if (!is_complex_fixup(fixup))
{
TRACE("[FAILED]\n");
return FALSE;
}
yuv_fixup = get_yuv_fixup(fixup);
switch(yuv_fixup)
complex_fixup = get_complex_fixup(fixup);
switch(complex_fixup)
{
case YUV_FIXUP_YUY2:
case YUV_FIXUP_UYVY:
case YUV_FIXUP_YV12:
case COMPLEX_FIXUP_YUY2:
case COMPLEX_FIXUP_UYVY:
case COMPLEX_FIXUP_YV12:
case COMPLEX_FIXUP_P8:
TRACE("[OK]\n");
return TRUE;
default:
FIXME("Unsupported YUV fixup %#x\n", yuv_fixup);
FIXME("Unsupported YUV fixup %#x\n", complex_fixup);
TRACE("[FAILED]\n");
return FALSE;
}

View file

@ -1061,7 +1061,7 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
LEAVE_GL();
}
static void atifs_get_caps(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
static void atifs_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
{
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
* Copyright 2002-2005 Raphael Junqueira
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
* Copyright 2007 Stefan Dösinger for CodeWeavers
* Copyright 2007-2010 Stefan Dösinger for CodeWeavers
* Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
@ -56,7 +56,13 @@ static inline BOOL buffer_add_dirty_area(struct wined3d_buffer *This, UINT offse
}
}
if(!offset && !size)
if(offset > This->resource.size || offset + size > This->resource.size)
{
WARN("Invalid range dirtified, marking entire buffer dirty\n");
offset = 0;
size = This->resource.size;
}
else if(!offset && !size)
{
size = This->resource.size;
}
@ -145,11 +151,6 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
{
TRACE("Gl usage = GL_STREAM_DRAW_ARB\n");
gl_usage = GL_STREAM_DRAW_ARB;
}
else
{
TRACE("Gl usage = GL_DYNAMIC_DRAW_ARB\n");
gl_usage = GL_DYNAMIC_DRAW_ARB;
if(gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
{
@ -157,6 +158,12 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
checkGLcall("glBufferParameteriAPPLE(This->buffer_type_hint, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE)");
This->flags |= WINED3D_BUFFER_FLUSH;
}
/* No setup is needed here for GL_ARB_map_buffer_range */
}
else
{
TRACE("Gl usage = GL_DYNAMIC_DRAW_ARB\n");
gl_usage = GL_DYNAMIC_DRAW_ARB;
}
/* Reserve memory for the buffer. The amount of data won't change
@ -483,7 +490,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
* FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all
* the attributes that our current fixed function pipeline implementation cares for.
*/
BOOL support_d3dcolor = gl_info->supported[EXT_VERTEX_ARRAY_BGRA];
BOOL support_d3dcolor = gl_info->supported[ARB_VERTEX_ARRAY_BGRA];
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
@ -1026,6 +1033,51 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac
/* IWineD3DBuffer methods */
static DWORD buffer_sanitize_flags(DWORD flags)
{
/* Not all flags make sense together, but Windows never returns an error. Catch the
* cases that could cause issues */
if(flags & WINED3DLOCK_READONLY)
{
if(flags & WINED3DLOCK_DISCARD)
{
WARN("WINED3DLOCK_READONLY combined with WINED3DLOCK_DISCARD, ignoring flags\n");
return 0;
}
if(flags & WINED3DLOCK_NOOVERWRITE)
{
WARN("WINED3DLOCK_READONLY combined with WINED3DLOCK_NOOVERWRITE, ignoring flags\n");
return 0;
}
}
else if((flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE)) == (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE))
{
WARN("WINED3DLOCK_DISCARD and WINED3DLOCK_NOOVERWRITE used together, ignoring\n");
return 0;
}
return flags;
}
static GLbitfield buffer_gl_map_flags(DWORD d3d_flags)
{
GLbitfield ret = 0;
if (!(d3d_flags & WINED3DLOCK_READONLY)) ret = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
if (d3d_flags & (WINED3DLOCK_DISCARD | WINED3DLOCK_NOOVERWRITE))
{
if(d3d_flags & WINED3DLOCK_DISCARD) ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
ret |= GL_MAP_UNSYNCHRONIZED_BIT;
}
else
{
ret |= GL_MAP_READ_BIT;
}
return ret;
}
static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags)
{
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
@ -1033,7 +1085,11 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags);
if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY;
flags = buffer_sanitize_flags(flags);
if (!(flags & WINED3DLOCK_READONLY))
{
if (!buffer_add_dirty_area(This, offset, size)) return E_OUTOFMEMORY;
}
count = InterlockedIncrement(&This->lock_count);
@ -1043,6 +1099,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
{
IWineD3DDeviceImpl *device = This->resource.device;
struct wined3d_context *context;
const struct wined3d_gl_info *gl_info;
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
@ -1050,9 +1107,20 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
}
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
gl_info = context->gl_info;
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
GLbitfield mapflags = buffer_gl_map_flags(flags);
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferRange(This->buffer_type_hint, 0,
This->resource.size, mapflags));
}
else
{
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
}
LEAVE_GL();
context_release(context);
}
@ -1093,6 +1161,7 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
{
IWineD3DDeviceImpl *device = This->resource.device;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
@ -1101,10 +1170,21 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
}
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
gl_info = context->gl_info;
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
if(This->flags & WINED3D_BUFFER_FLUSH)
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
for(i = 0; i < This->modified_areas; i++)
{
GL_EXTCALL(glFlushMappedBufferRange(This->buffer_type_hint,
This->maps[i].offset,
This->maps[i].size));
checkGLcall("glFlushMappedBufferRange");
}
}
else if (This->flags & WINED3D_BUFFER_FLUSH)
{
for(i = 0; i < This->modified_areas; i++)
{
@ -1196,8 +1276,7 @@ HRESULT buffer_init(struct wined3d_buffer *buffer, IWineD3DDeviceImpl *device,
TRACE("size %#x, usage %#x, format %s, memory @ %p, iface @ %p.\n", buffer->resource.size, buffer->resource.usage,
debug_d3dformat(buffer->resource.format_desc->format), buffer->resource.allocatedMemory, buffer);
/* TODO: GL_ARB_map_buffer_range */
dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE];
dynamic_buffer_ok = gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] || gl_info->supported[ARB_MAP_BUFFER_RANGE];
/* Observations show that drawStridedSlow is faster on dynamic VBs than converting +
* drawStridedFast (half-life 2 and others).

View file

@ -114,7 +114,7 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
}
/* GL locking is done by the caller */
static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOOL force_preload)
static void context_apply_attachment_filter_states(IWineD3DSurface *surface)
{
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
IWineD3DDeviceImpl *device = surface_impl->resource.device;
@ -148,7 +148,7 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
}
if (update_minfilter || update_magfilter || force_preload)
if (update_minfilter || update_magfilter)
{
GLenum target, bind_target;
GLint old_binding;
@ -166,8 +166,6 @@ static void context_apply_attachment_filter_states(IWineD3DSurface *surface, BOO
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
}
surface_internal_preload(surface, SRGB_RGB);
glBindTexture(bind_target, surface_impl->texture_name);
if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -208,7 +206,8 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
}
else
{
context_apply_attachment_filter_states(depth_stencil, TRUE);
surface_prepare_texture(depth_stencil_impl, FALSE);
context_apply_attachment_filter_states(depth_stencil);
if (format_flags & WINED3DFMT_FLAG_DEPTH)
{
@ -253,14 +252,15 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
void context_attach_surface_fbo(const struct wined3d_context *context,
GLenum fbo_target, DWORD idx, IWineD3DSurface *surface)
{
const IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
IWineD3DSurfaceImpl *surface_impl = (IWineD3DSurfaceImpl *)surface;
const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("Attach surface %p to %u\n", surface, idx);
if (surface)
{
context_apply_attachment_filter_states(surface, TRUE);
surface_prepare_texture(surface_impl, FALSE);
context_apply_attachment_filter_states(surface);
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface_impl->texture_target,
surface_impl->texture_name, surface_impl->texture_level);
@ -431,10 +431,10 @@ static void context_apply_fbo_entry(struct wined3d_context *context, struct fbo_
for (i = 0; i < gl_info->limits.buffers; ++i)
{
if (device->render_targets[i])
context_apply_attachment_filter_states(device->render_targets[i], FALSE);
context_apply_attachment_filter_states(device->render_targets[i]);
}
if (device->stencilBufferTarget)
context_apply_attachment_filter_states(device->stencilBufferTarget, FALSE);
context_apply_attachment_filter_states(device->stencilBufferTarget);
}
for (i = 0; i < gl_info->limits.buffers; ++i)
@ -532,32 +532,38 @@ void context_alloc_event_query(struct wined3d_context *context, struct wined3d_e
if (context->free_event_query_count)
{
query->id = context->free_event_queries[--context->free_event_query_count];
query->object = context->free_event_queries[--context->free_event_query_count];
}
else
{
if (gl_info->supported[APPLE_FENCE])
if (gl_info->supported[ARB_SYNC])
{
/* Using ARB_sync, not much to do here. */
query->object.sync = NULL;
TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
}
else if (gl_info->supported[APPLE_FENCE])
{
ENTER_GL();
GL_EXTCALL(glGenFencesAPPLE(1, &query->id));
GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
checkGLcall("glGenFencesAPPLE");
LEAVE_GL();
TRACE("Allocated event query %u in context %p.\n", query->id, context);
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
}
else if(gl_info->supported[NV_FENCE])
{
ENTER_GL();
GL_EXTCALL(glGenFencesNV(1, &query->id));
GL_EXTCALL(glGenFencesNV(1, &query->object.id));
checkGLcall("glGenFencesNV");
LEAVE_GL();
TRACE("Allocated event query %u in context %p.\n", query->id, context);
TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
}
else
{
WARN("Event queries not supported, not allocating query id.\n");
query->id = 0;
query->object.id = 0;
}
}
@ -575,12 +581,12 @@ void context_free_event_query(struct wined3d_event_query *query)
if (context->free_event_query_count >= context->free_event_query_size - 1)
{
UINT new_size = context->free_event_query_size << 1;
GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
union wined3d_gl_query_object *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
new_size * sizeof(*context->free_event_queries));
if (!new_data)
{
ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
return;
}
@ -588,7 +594,7 @@ void context_free_event_query(struct wined3d_event_query *query)
context->free_event_queries = new_data;
}
context->free_event_queries[context->free_event_query_count++] = query->id;
context->free_event_queries[context->free_event_query_count++] = query->object;
}
void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
@ -661,6 +667,7 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
struct fbo_entry *entry, *entry2;
HGLRC restore_ctx;
HDC restore_dc;
unsigned int i;
restore_ctx = pwglGetCurrentContext();
restore_dc = pwglGetCurrentDC();
@ -682,8 +689,12 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
{
if (context->valid)
{
if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->id));
else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->id));
if (gl_info->supported[ARB_SYNC])
{
if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
}
else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
}
event_query->context = NULL;
}
@ -720,10 +731,24 @@ static void context_destroy_gl_resources(struct wined3d_context *context)
if (gl_info->supported[ARB_OCCLUSION_QUERY])
GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
if (gl_info->supported[APPLE_FENCE])
GL_EXTCALL(glDeleteFencesAPPLE(context->free_event_query_count, context->free_event_queries));
if (gl_info->supported[ARB_SYNC])
{
if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
}
else if (gl_info->supported[APPLE_FENCE])
{
for (i = 0; i < context->free_event_query_count; ++i)
{
GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
}
}
else if (gl_info->supported[NV_FENCE])
GL_EXTCALL(glDeleteFencesNV(context->free_event_query_count, context->free_event_queries));
{
for (i = 0; i < context->free_event_query_count; ++i)
{
GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
}
}
checkGLcall("context cleanup");
}
@ -2131,6 +2156,8 @@ static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceI
if (context->render_offscreen)
{
FIXME("Activating for CTXUSAGE_BLIT for an offscreen target with ORM_FBO. This should be avoided.\n");
surface_internal_preload(context->current_rt, SRGB_RGB);
ENTER_GL();
context_bind_fbo(context, GL_FRAMEBUFFER, &context->dst_fbo);
context_attach_surface_fbo(context, GL_FRAMEBUFFER, 0, context->current_rt);
@ -2189,6 +2216,9 @@ static void context_apply_state(struct wined3d_context *context, IWineD3DDeviceI
}
IWineD3DDeviceImpl_FindTexUnitMap(device);
device_preload_textures(device);
if (isStateDirty(context, STATE_VDECL))
device_update_stream_info(device, context->gl_info);
ENTER_GL();
for (i = 0; i < context->numDirtyEntries; ++i)

View file

@ -179,8 +179,6 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
{
/* We need to deal with frequency data! */
IWineD3DVertexDeclarationImpl *declaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl;
UINT stream_count = This->stateBlock->streamIsUP ? 0 : declaration->num_streams;
const DWORD *streams = declaration->streams;
unsigned int i;
stream_info->use_map = 0;
@ -298,7 +296,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
stream_info->elements[idx].stream_idx = element->input_slot;
stream_info->elements[idx].buffer_object = buffer_object;
if (!This->adapter->gl_info.supported[EXT_VERTEX_ARRAY_BGRA]
if (!This->adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA]
&& element->format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
{
stream_info->swizzle_map |= 1 << idx;
@ -307,17 +305,29 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
}
}
/* Now call PreLoad on all the vertex buffers. In the very rare case
* that the buffers stopps converting PreLoad will dirtify the VDECL again.
* The vertex buffer can now use the strided structure in the device instead of finding its
* own again.
*
* NULL streams won't be recorded in the array, UP streams won't be either. A stream is only
* once in there. */
for (i = 0; i < stream_count; ++i)
if (!This->stateBlock->streamIsUP)
{
IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]];
if (vb) IWineD3DBuffer_PreLoad(vb);
WORD map = stream_info->use_map;
/* PreLoad all the vertex buffers. */
for (i = 0; map; map >>= 1, ++i)
{
struct wined3d_stream_info_element *element;
struct wined3d_buffer *buffer;
if (!(map & 1)) continue;
element = &stream_info->elements[i];
buffer = (struct wined3d_buffer *)This->stateBlock->streamSource[element->stream_idx];
IWineD3DBuffer_PreLoad((IWineD3DBuffer *)buffer);
/* If PreLoad dropped the buffer object, update the stream info. */
if (buffer->buffer_object != element->buffer_object)
{
element->buffer_object = 0;
element->data = buffer_get_sysmem(buffer) + (ptrdiff_t)element->data;
}
}
}
}
@ -332,7 +342,7 @@ static void stream_info_element_from_strided(const struct wined3d_gl_info *gl_in
e->buffer_object = 0;
}
void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
static void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info)
{
unsigned int i;
@ -361,7 +371,7 @@ void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
{
if (!stream_info->elements[i].format_desc) continue;
if (!gl_info->supported[EXT_VERTEX_ARRAY_BGRA]
if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
&& stream_info->elements[i].format_desc->format == WINED3DFMT_B8G8R8A8_UNORM)
{
stream_info->swizzle_map |= 1 << i;
@ -370,6 +380,120 @@ void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
}
}
static void device_trace_strided_stream_info(const struct wined3d_stream_info *stream_info)
{
TRACE("Strided Data:\n");
TRACE_STRIDED(stream_info, WINED3D_FFP_POSITION);
TRACE_STRIDED(stream_info, WINED3D_FFP_BLENDWEIGHT);
TRACE_STRIDED(stream_info, WINED3D_FFP_BLENDINDICES);
TRACE_STRIDED(stream_info, WINED3D_FFP_NORMAL);
TRACE_STRIDED(stream_info, WINED3D_FFP_PSIZE);
TRACE_STRIDED(stream_info, WINED3D_FFP_DIFFUSE);
TRACE_STRIDED(stream_info, WINED3D_FFP_SPECULAR);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD0);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD1);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD2);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD3);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD4);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD5);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD6);
TRACE_STRIDED(stream_info, WINED3D_FFP_TEXCOORD7);
}
/* Context activation is done by the caller. */
void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info)
{
struct wined3d_stream_info *stream_info = &device->strided_streams;
IWineD3DStateBlockImpl *stateblock = device->stateBlock;
BOOL vs = stateblock->vertexShader && device->vs_selected_mode != SHADER_NONE;
BOOL fixup = FALSE;
if (device->up_strided)
{
/* Note: this is a ddraw fixed-function code path. */
TRACE("=============================== Strided Input ================================\n");
device_stream_info_from_strided(gl_info, device->up_strided, stream_info);
if (TRACE_ON(d3d)) device_trace_strided_stream_info(stream_info);
}
else
{
TRACE("============================= Vertex Declaration =============================\n");
device_stream_info_from_declaration(device, vs, stream_info, &fixup);
}
if (vs && !stream_info->position_transformed)
{
if (((IWineD3DVertexDeclarationImpl *)stateblock->vertexDecl)->half_float_conv_needed && !fixup)
{
TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion.\n");
device->useDrawStridedSlow = TRUE;
}
else
{
device->useDrawStridedSlow = FALSE;
}
}
else
{
WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
& ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
if ((stream_info->position_transformed || (stream_info->use_map & slow_mask)) && !fixup)
{
device->useDrawStridedSlow = TRUE;
}
else
{
device->useDrawStridedSlow = FALSE;
}
}
}
static void device_preload_texture(IWineD3DStateBlockImpl *stateblock, unsigned int idx)
{
IWineD3DBaseTextureImpl *texture;
enum WINED3DSRGB srgb;
if (!(texture = (IWineD3DBaseTextureImpl *)stateblock->textures[idx])) return;
srgb = stateblock->samplerState[idx][WINED3DSAMP_SRGBTEXTURE] ? SRGB_SRGB : SRGB_RGB;
texture->baseTexture.internal_preload((IWineD3DBaseTexture *)texture, srgb);
}
void device_preload_textures(IWineD3DDeviceImpl *device)
{
IWineD3DStateBlockImpl *stateblock = device->stateBlock;
unsigned int i;
if (use_vs(stateblock))
{
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
if (((IWineD3DBaseShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.sampler_type[i])
device_preload_texture(stateblock, MAX_FRAGMENT_SAMPLERS + i);
}
}
if (use_ps(stateblock))
{
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (((IWineD3DBaseShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.sampler_type[i])
device_preload_texture(stateblock, i);
}
}
else
{
WORD ffu_map = device->fixed_function_usage_map;
for (i = 0; ffu_map; ffu_map >>= 1, ++i)
{
if (ffu_map & 1)
device_preload_texture(stateblock, i);
}
}
}
/**********************************************************
* IUnknown parts follows
**********************************************************/
@ -596,7 +720,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSurface(IWineD3DDevice *iface, UI
IWineD3DSurfaceImpl *object;
HRESULT hr;
TRACE("(%p) Create surface\n",This);
TRACE("iface %p, width %u, height %u, format %s (%#x), lockable %#x, discard %#x, level %u\n",
iface, Width, Height, debug_d3dformat(Format), Format, Lockable, Discard, Level);
TRACE("surface %p, usage %s (%#x), pool %s (%#x), multisample_type %#x, multisample_quality %u\n",
ppSurface, debug_d3dusage(Usage), Usage, debug_d3dpool(Pool), Pool, MultiSample, MultisampleQuality);
TRACE("surface_type %#x, parent %p, parent_ops %p.\n", Impl, parent, parent_ops);
if (Impl == SURFACE_OPENGL && !This->adapter)
{
@ -784,104 +912,33 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
return WINED3D_OK;
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface, WINED3DQUERYTYPE Type, IWineD3DQuery **ppQuery, IUnknown* parent) {
static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface,
WINED3DQUERYTYPE type, IWineD3DQuery **query, IUnknown *parent)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
IWineD3DQueryImpl *object; /*NOTE: impl ref allowed since this is a create function */
HRESULT hr = WINED3DERR_NOTAVAILABLE;
const IWineD3DQueryVtbl *vtable;
IWineD3DQueryImpl *object;
HRESULT hr;
/* Just a check to see if we support this type of query */
switch(Type) {
case WINED3DQUERYTYPE_OCCLUSION:
TRACE("(%p) occlusion query\n", This);
if (gl_info->supported[ARB_OCCLUSION_QUERY])
hr = WINED3D_OK;
else
WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY/NV_OCCLUSION_QUERY\n");
TRACE("iface %p, type %#x, query %p, parent %p.\n", iface, type, query, parent);
vtable = &IWineD3DOcclusionQuery_Vtbl;
break;
case WINED3DQUERYTYPE_EVENT:
if (!gl_info->supported[NV_FENCE] && !gl_info->supported[APPLE_FENCE])
{
/* Half-Life 2 needs this query. It does not render the main menu correctly otherwise
* Pretend to support it, faking this query does not do much harm except potentially lowering performance
*/
FIXME("(%p) Event query: Unimplemented, but pretending to be supported\n", This);
}
vtable = &IWineD3DEventQuery_Vtbl;
hr = WINED3D_OK;
break;
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
case WINED3DQUERYTYPE_PIXELTIMINGS:
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
case WINED3DQUERYTYPE_CACHEUTILIZATION:
default:
/* Use the base Query vtable until we have a special one for each query */
vtable = &IWineD3DQuery_Vtbl;
FIXME("(%p) Unhandled query type %d\n", This, Type);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
{
ERR("Failed to allocate query memory.\n");
return E_OUTOFMEMORY;
}
if(NULL == ppQuery || hr != WINED3D_OK) {
hr = query_init(object, This, type, parent);
if (FAILED(hr))
{
WARN("Failed to initialize query, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if(!object)
{
ERR("Out of memory\n");
*ppQuery = NULL;
return WINED3DERR_OUTOFVIDEOMEMORY;
}
TRACE("Created query %p.\n", object);
*query = (IWineD3DQuery *)object;
object->lpVtbl = vtable;
object->type = Type;
object->state = QUERY_CREATED;
object->device = This;
object->parent = parent;
object->ref = 1;
*ppQuery = (IWineD3DQuery *)object;
/* allocated the 'extended' data based on the type of query requested */
switch(Type){
case WINED3DQUERYTYPE_OCCLUSION:
object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
((struct wined3d_occlusion_query *)object->extendedData)->context = NULL;
break;
case WINED3DQUERYTYPE_EVENT:
object->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_event_query));
((struct wined3d_event_query *)object->extendedData)->context = NULL;
break;
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
case WINED3DQUERYTYPE_PIXELTIMINGS:
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
case WINED3DQUERYTYPE_CACHEUTILIZATION:
default:
object->extendedData = 0;
FIXME("(%p) Unhandled query type %d\n",This , Type);
}
TRACE("(%p) : Created Query %p\n", This, object);
return WINED3D_OK;
}
@ -1663,14 +1720,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface,
}
}
/* Delete the palette conversion shader if it is around */
if(This->paletteConversionShader) {
ENTER_GL();
GL_EXTCALL(glDeleteProgramsARB(1, &This->paletteConversionShader));
LEAVE_GL();
This->paletteConversionShader = 0;
}
/* Delete the pbuffer context if there is any */
if(This->pbufferContext) context_destroy(This, This->pbufferContext);
@ -3054,15 +3103,17 @@ static void device_update_fixed_function_usage_map(IWineD3DDeviceImpl *This) {
}
}
static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info)
{
unsigned int i, tex;
WORD ffu_map;
device_update_fixed_function_usage_map(This);
ffu_map = This->fixed_function_usage_map;
if (This->max_ffp_textures == This->max_ffp_texture_stages ||
This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures) {
if (This->max_ffp_textures == gl_info->limits.texture_stages
|| This->stateBlock->lowest_disabled_stage <= This->max_ffp_textures)
{
for (i = 0; ffu_map; ffu_map >>= 1, ++i)
{
if (!(ffu_map & 1)) continue;
@ -3092,7 +3143,8 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This) {
}
}
static void device_map_psamplers(IWineD3DDeviceImpl *This) {
static void device_map_psamplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info)
{
const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type =
((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.reg_maps.sampler_type;
unsigned int i;
@ -3102,7 +3154,8 @@ static void device_map_psamplers(IWineD3DDeviceImpl *This) {
{
device_map_stage(This, i, i);
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_SAMPLER(i));
if (i < MAX_TEXTURES) {
if (i < gl_info->limits.texture_stages)
{
markTextureStagesDirty(This, i);
}
}
@ -3133,11 +3186,12 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const DWORD *pshad
return !vshader_sampler_tokens[current_mapping - MAX_FRAGMENT_SAMPLERS];
}
static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct wined3d_gl_info *gl_info)
{
const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.reg_maps.sampler_type;
const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
int start = min(MAX_COMBINED_SAMPLERS, This->adapter->gl_info.limits.combined_samplers) - 1;
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
if (ps) {
@ -3174,7 +3228,9 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps) {
}
}
void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This)
{
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
BOOL vs = use_vs(This->stateBlock);
BOOL ps = use_ps(This->stateBlock);
/*
@ -3184,15 +3240,10 @@ void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) {
* -> When the mapping of a stage is changed, sampler and ALL texture stage states have
* to be reset. Because of that try to work with a 1:1 mapping as much as possible
*/
if (ps) {
device_map_psamplers(This);
} else {
device_map_fixed_function_samplers(This);
}
if (ps) device_map_psamplers(This, gl_info);
else device_map_fixed_function_samplers(This, gl_info);
if (vs) {
device_map_vsamplers(This, ps);
}
if (vs) device_map_vsamplers(This, ps, gl_info);
}
static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, IWineD3DPixelShader *pShader) {
@ -3806,11 +3857,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
static HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *iface, DWORD Stage, WINED3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD oldValue = This->updateStateBlock->textureState[Stage][Type];
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
TRACE("(%p) : Stage=%d, Type=%s(%d), Value=%d\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
if (Stage >= MAX_TEXTURES) {
WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring\n", Stage, MAX_TEXTURES - 1);
if (Stage >= gl_info->limits.texture_stages)
{
WARN("Attempting to set stage %u which is higher than the max stage %u, ignoring.\n",
Stage, gl_info->limits.texture_stages - 1);
return WINED3D_OK;
}
@ -3891,6 +3945,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface,
DWORD stage, IWineD3DBaseTexture *texture)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct wined3d_gl_info *gl_info = &This->adapter->gl_info;
IWineD3DBaseTexture *prev;
TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
@ -3949,7 +4004,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface,
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_PIXELSHADER);
}
if (!prev && stage < MAX_TEXTURES)
if (!prev && stage < gl_info->limits.texture_stages)
{
/* The source arguments for color and alpha ops have different
* meanings when a NULL texture is bound, so the COLOROP and
@ -3968,7 +4023,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface,
IWineD3DBaseTexture_Release(prev);
if (!texture && stage < MAX_TEXTURES)
if (!texture && stage < gl_info->limits.texture_stages)
{
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, WINED3DTSS_COLOROP));
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TEXTURESTAGE(stage, WINED3DTSS_ALPHAOP));
@ -4206,7 +4261,6 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
const WINED3DVIEWPORT *vp = &This->stateBlock->viewport;
UINT drawable_width, drawable_height;
IWineD3DSurfaceImpl *depth_stencil = (IWineD3DSurfaceImpl *) This->stencilBufferTarget;
IWineD3DSwapChainImpl *swapchain = NULL;
struct wined3d_context *context;
/* When we're clearing parts of the drawable, make sure that the target surface is well up to date in the
@ -4376,12 +4430,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfa
LEAVE_GL();
if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)target, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
if (target == (IWineD3DSurfaceImpl*) swapchain->frontBuffer) {
wglFlush();
}
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
}
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
@ -5340,6 +5389,9 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
struct wined3d_context *context;
if (rect) IWineD3DSurface_LoadLocation(surface, SFLAG_INDRAWABLE, NULL);
IWineD3DSurface_ModifyLocation(surface, SFLAG_INDRAWABLE, TRUE);
if (!surface_is_offscreen(surface))
{
TRACE("Surface %p is onscreen\n", surface);
@ -5386,6 +5438,9 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
checkGLcall("glClear");
LEAVE_GL();
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
}
@ -5685,6 +5740,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
if(Swapchain->backBuffer[0]) {
IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain);
((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN;
Swapchain->presentParms.BackBufferWidth = BackImpl->currentDesc.Width;
Swapchain->presentParms.BackBufferHeight = BackImpl->currentDesc.Height;
Swapchain->presentParms.BackBufferFormat = BackImpl->resource.format_desc->format;
} else {
HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer);
Swapchain->backBuffer = NULL;
@ -5738,6 +5796,12 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
break;
}
/* Make sure the drawables are up-to-date. Note that loading the
* destination surface isn't strictly required if we overwrite the
* entire surface. */
IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
/* Attach src surface to src fbo */
src_swapchain = get_swapchain(src_surface);
dst_swapchain = get_swapchain(dst_surface);
@ -5753,9 +5817,6 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
GLenum buffer = surface_get_gl_buffer(src_surface);
TRACE("Source surface %p is onscreen\n", src_surface);
/* Make sure the drawable is up to date. In the offscreen case
* attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(src_surface, SFLAG_INDRAWABLE, NULL);
if(buffer == GL_FRONT) {
RECT windowsize;
@ -5792,9 +5853,6 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
GLenum buffer = surface_get_gl_buffer(dst_surface);
TRACE("Destination surface %p is onscreen\n", dst_surface);
/* Make sure the drawable is up to date. In the offscreen case
* attach_surface_fbo() implicitly takes care of this. */
IWineD3DSurface_LoadLocation(dst_surface, SFLAG_INDRAWABLE, NULL);
if(buffer == GL_FRONT) {
RECT windowsize;
@ -5839,6 +5897,9 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, WINED
}
LEAVE_GL();
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
IWineD3DSurface_ModifyLocation(dst_surface, SFLAG_INDRAWABLE, TRUE);
@ -6982,20 +7043,19 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
for (i = 0; i < PATCHMAP_SIZE; ++i) list_init(&device->patches[i]);
select_shader_mode(&adapter->gl_info, &device->ps_selected_mode, &device->vs_selected_mode);
device->shader_backend = select_shader_backend(adapter, device_type);
device->shader_backend = adapter->shader_backend;
memset(&shader_caps, 0, sizeof(shader_caps));
device->shader_backend->shader_get_caps(device_type, &adapter->gl_info, &shader_caps);
device->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
device->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
device->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
device->vs_clipping = shader_caps.VSClipping;
memset(&ffp_caps, 0, sizeof(ffp_caps));
fragment_pipeline = select_fragment_implementation(adapter, device_type);
fragment_pipeline = adapter->fragment_pipe;
device->frag_pipe = fragment_pipeline;
fragment_pipeline->get_caps(device_type, &adapter->gl_info, &ffp_caps);
fragment_pipeline->get_caps(&adapter->gl_info, &ffp_caps);
device->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
device->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
hr = compile_state_table(device->StateTable, device->multistate_funcs, &adapter->gl_info,
ffp_vertexstate_template, fragment_pipeline, misc_state_template);
@ -7006,7 +7066,7 @@ HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
return hr;
}
device->blitter = select_blit_implementation(adapter, device_type);
device->blitter = adapter->blitter;
return WINED3D_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -334,7 +334,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, WINED3DFORMAT format
GL_EXTCALL(glVertexAttrib4ubvARB(index, ptr));
break;
case WINED3DFMT_B8G8R8A8_UNORM:
if (gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
const DWORD *src = ptr;
DWORD c = *src & 0xff00ff00;
@ -690,6 +690,9 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
/* Finished updating the screen, restore lock */
LEAVE_GL();
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
TRACE("Done all gl drawing\n");
@ -1100,7 +1103,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
if(patch->has_texcoords) {
vtxStride += 4 * sizeof(float);
}
memset(&patch->strided, 0, sizeof(&patch->strided));
memset(&patch->strided, 0, sizeof(patch->strided));
patch->strided.position.format = WINED3DFMT_R32G32B32_FLOAT;
patch->strided.position.lpData = (BYTE *) patch->mem;
patch->strided.position.dwStride = vtxStride;

View file

@ -156,6 +156,20 @@ struct glsl_vshader_private
UINT num_gl_shaders, shader_array_size;
};
static const char *debug_gl_shader_type(GLenum type)
{
switch (type)
{
#define WINED3D_TO_STR(u) case u: return #u
WINED3D_TO_STR(GL_VERTEX_SHADER_ARB);
WINED3D_TO_STR(GL_GEOMETRY_SHADER_ARB);
WINED3D_TO_STR(GL_FRAGMENT_SHADER_ARB);
#undef WINED3D_TO_STR
default:
return wine_dbg_sprintf("UNKNOWN(%#x)", type);
}
}
/* Extract a line from the info log.
* Note that this modifies the source string. */
static char *get_info_log_line(char **ptr)
@ -238,6 +252,81 @@ static void print_glsl_info_log(const struct wined3d_gl_info *gl_info, GLhandleA
}
}
/* GL locking is done by the caller. */
static void shader_glsl_dump_program_source(const struct wined3d_gl_info *gl_info, GLhandleARB program)
{
GLint i, object_count, source_size;
GLhandleARB *objects;
char *source = NULL;
GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_ATTACHED_OBJECTS_ARB, &object_count));
objects = HeapAlloc(GetProcessHeap(), 0, object_count * sizeof(*objects));
if (!objects)
{
ERR("Failed to allocate object array memory.\n");
return;
}
GL_EXTCALL(glGetAttachedObjectsARB(program, object_count, NULL, objects));
for (i = 0; i < object_count; ++i)
{
char *ptr, *line;
GLint tmp;
GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &tmp));
if (!source || source_size < tmp)
{
HeapFree(GetProcessHeap(), 0, source);
source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, tmp);
if (!source)
{
ERR("Failed to allocate %d bytes for shader source.\n", tmp);
HeapFree(GetProcessHeap(), 0, objects);
return;
}
source_size = tmp;
}
FIXME("Object %u:\n", objects[i]);
GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_SUBTYPE_ARB, &tmp));
FIXME(" GL_OBJECT_SUBTYPE_ARB: %s.\n", debug_gl_shader_type(tmp));
GL_EXTCALL(glGetObjectParameterivARB(objects[i], GL_OBJECT_COMPILE_STATUS_ARB, &tmp));
FIXME(" GL_OBJECT_COMPILE_STATUS_ARB: %d.\n", tmp);
FIXME("\n");
ptr = source;
GL_EXTCALL(glGetShaderSourceARB(objects[i], source_size, NULL, source));
while ((line = get_info_log_line(&ptr))) FIXME(" %s\n", line);
FIXME("\n");
}
HeapFree(GetProcessHeap(), 0, source);
HeapFree(GetProcessHeap(), 0, objects);
}
/* GL locking is done by the caller. */
static void shader_glsl_validate_link(const struct wined3d_gl_info *gl_info, GLhandleARB program)
{
GLint tmp;
if (!TRACE_ON(d3d_shader) && !FIXME_ON(d3d_shader)) return;
GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_TYPE_ARB, &tmp));
if (tmp == GL_PROGRAM_OBJECT_ARB)
{
GL_EXTCALL(glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &tmp));
if (!tmp)
{
FIXME("Program %u link status invalid.\n", program);
shader_glsl_dump_program_source(gl_info, program);
}
}
print_glsl_info_log(gl_info, program);
}
/**
* Loads (pixel shader) samplers
*/
@ -1083,6 +1172,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
}
shader_addline(buffer, "const float FLT_MAX = 1e38;\n");
/* Start the main program */
shader_addline(buffer, "void main() {\n");
if(pshader && reg_maps->vpos) {
@ -1194,8 +1285,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
char pshader = shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type);
*is_color = FALSE;
@ -1552,7 +1642,8 @@ static inline const char *shader_get_comp_op(DWORD op)
}
}
static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function)
static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_info,
DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function)
{
BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
@ -1564,9 +1655,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
case WINED3DSTT_1D:
if(lod) {
sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
} else if(grad) {
sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
} else {
}
else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
else
{
FIXME("Unsupported 1D grad function.\n");
sample_function->name = "unsupported1DGrad";
}
}
else
{
sample_function->name = projected ? "texture1DProj" : "texture1D";
}
sample_function->coord_mask = WINED3DSP_WRITEMASK_0;
@ -1575,20 +1678,41 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
if(texrect) {
if(lod) {
sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
} else if(grad) {
/* What good are texrect grad functions? I don't know, but GL_EXT_gpu_shader4 defines them.
* There is no GL_ARB_shader_texture_lod spec yet, so I don't know if they're defined there
*/
sample_function->name = projected ? "shadow2DRectProjGradARB" : "shadow2DRectGradARB";
} else {
}
else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
else
{
FIXME("Unsupported RECT grad function.\n");
sample_function->name = "unsupported2DRectGrad";
}
}
else
{
sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
}
} else {
if(lod) {
sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
} else if(grad) {
sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
} else {
}
else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
else
{
FIXME("Unsupported 2D grad function.\n");
sample_function->name = "unsupported2DGrad";
}
}
else
{
sample_function->name = projected ? "texture2DProj" : "texture2D";
}
}
@ -1597,9 +1721,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
case WINED3DSTT_CUBE:
if(lod) {
sample_function->name = "textureCubeLod";
} else if(grad) {
sample_function->name = "textureCubeGradARB";
} else {
}
else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
sample_function->name = "textureCubeGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
sample_function->name = "textureCubeGradARB";
else
{
FIXME("Unsupported Cube grad function.\n");
sample_function->name = "unsupportedCubeGrad";
}
}
else
{
sample_function->name = "textureCube";
}
sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@ -1607,9 +1743,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
case WINED3DSTT_VOLUME:
if(lod) {
sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
} else if(grad) {
sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
} else {
}
else if (grad)
{
if (gl_info->supported[EXT_GPU_SHADER4])
sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
else
{
FIXME("Unsupported 3D grad function.\n");
sample_function->name = "unsupported3DGrad";
}
}
else
{
sample_function->name = projected ? "texture3DProj" : "texture3D";
}
sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@ -1681,10 +1829,10 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction
if (!mask) return; /* Nothing to do */
if (is_yuv_fixup(fixup))
if (is_complex_fixup(fixup))
{
enum yuv_fixup yuv_fixup = get_yuv_fixup(fixup);
FIXME("YUV fixup (%#x) not supported\n", yuv_fixup);
enum complex_fixup complex_fixup = get_complex_fixup(fixup);
FIXME("Complex fixup (%#x) not supported\n",complex_fixup);
return;
}
@ -1822,6 +1970,7 @@ static void shader_glsl_arith(const struct wined3d_shader_instruction *ins)
/* Process the WINED3DSIO_MOV opcode using GLSL (dst = src) */
static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
glsl_src_param_t src0_param;
DWORD write_mask;
@ -1847,12 +1996,26 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
{
/* We need to *round* to the nearest int here. */
unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
if (mask_size > 1) {
shader_addline(buffer, "ivec%d(floor(abs(%s) + vec%d(0.5)) * sign(%s)));\n", mask_size, src0_param.param_str, mask_size, src0_param.param_str);
} else {
shader_addline(buffer, "int(floor(abs(%s) + 0.5) * sign(%s)));\n", src0_param.param_str, src0_param.param_str);
if (gl_info->supported[EXT_GPU_SHADER4])
{
if (mask_size > 1)
shader_addline(buffer, "ivec%d(round(%s)));\n", mask_size, src0_param.param_str);
else
shader_addline(buffer, "int(round(%s)));\n", src0_param.param_str);
}
} else {
else
{
if (mask_size > 1)
shader_addline(buffer, "ivec%d(floor(abs(%s) + vec%d(0.5)) * sign(%s)));\n",
mask_size, src0_param.param_str, mask_size, src0_param.param_str);
else
shader_addline(buffer, "int(floor(abs(%s) + 0.5) * sign(%s)));\n",
src0_param.param_str, src0_param.param_str);
}
}
else
{
shader_addline(buffer, "%s);\n", src0_param.param_str);
}
}
@ -1942,10 +2105,15 @@ static void shader_glsl_log(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0, &src0_param);
if (dst_size > 1) {
shader_addline(buffer, "vec%d(log2(abs(%s))));\n", dst_size, src0_param.param_str);
} else {
shader_addline(buffer, "log2(abs(%s)));\n", src0_param.param_str);
if (dst_size > 1)
{
shader_addline(buffer, "vec%d(%s == 0.0 ? -FLT_MAX : log2(abs(%s))));\n",
dst_size, src0_param.param_str, src0_param.param_str);
}
else
{
shader_addline(buffer, "%s == 0.0 ? -FLT_MAX : log2(abs(%s)));\n",
src0_param.param_str, src0_param.param_str);
}
}
@ -1966,7 +2134,6 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
case WINED3DSIH_MAX: instruction = "max"; break;
case WINED3DSIH_ABS: instruction = "abs"; break;
case WINED3DSIH_FRC: instruction = "fract"; break;
case WINED3DSIH_NRM: instruction = "normalize"; break;
case WINED3DSIH_EXP: instruction = "exp2"; break;
case WINED3DSIH_DSX: instruction = "dFdx"; break;
case WINED3DSIH_DSY: instruction = "ycorrection.y * dFdy"; break;
@ -1993,6 +2160,22 @@ static void shader_glsl_map2gl(const struct wined3d_shader_instruction *ins)
shader_addline(buffer, "));\n");
}
static void shader_glsl_nrm(const struct wined3d_shader_instruction *ins)
{
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
glsl_src_param_t src_param;
DWORD write_mask;
char dst_mask[6];
write_mask = shader_glsl_get_write_mask(ins->dst, dst_mask);
shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src_param);
shader_addline(buffer, "tmp0.x = length(%s);\n", src_param.param_str);
shader_glsl_append_dst(buffer, ins);
shader_addline(buffer, "tmp0.x == 0.0 ? (%s * FLT_MAX) : (%s / tmp0.x));",
src_param.param_str, src_param.param_str);
}
/** Process the WINED3DSIO_EXPP instruction in GLSL:
* For shader model 1.x, do the following (and honor the writemask, so use a temporary variable):
* dst.x = 2^(floor(src))
@ -2046,10 +2229,15 @@ static void shader_glsl_rcp(const struct wined3d_shader_instruction *ins)
mask_size = shader_glsl_get_write_mask_size(write_mask);
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
shader_addline(ins->ctx->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
} else {
shader_addline(ins->ctx->buffer, "1.0 / %s);\n", src_param.param_str);
if (mask_size > 1)
{
shader_addline(ins->ctx->buffer, "vec%d(%s == 0.0 ? FLT_MAX : 1.0 / %s));\n",
mask_size, src_param.param_str, src_param.param_str);
}
else
{
shader_addline(ins->ctx->buffer, "%s == 0.0 ? FLT_MAX : 1.0 / %s);\n",
src_param.param_str, src_param.param_str);
}
}
@ -2065,10 +2253,15 @@ static void shader_glsl_rsq(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
shader_addline(buffer, "vec%d(inversesqrt(%s)));\n", mask_size, src_param.param_str);
} else {
shader_addline(buffer, "inversesqrt(%s));\n", src_param.param_str);
if (mask_size > 1)
{
shader_addline(buffer, "vec%d(%s == 0.0 ? FLT_MAX : inversesqrt(abs(%s))));\n",
mask_size, src_param.param_str, src_param.param_str);
}
else
{
shader_addline(buffer, "%s == 0.0 ? FLT_MAX : inversesqrt(abs(%s)));\n",
src_param.param_str, src_param.param_str);
}
}
@ -2671,10 +2864,11 @@ static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
********************************************/
static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
ins->ctx->reg_maps->shader_version.minor);
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
DWORD sample_flags = 0;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
@ -2728,7 +2922,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
mask |= sample_function.coord_mask;
if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
@ -2762,7 +2956,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
{
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, dx_param, dy_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_GRAD;
@ -2770,7 +2964,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
DWORD sampler_idx;
DWORD swizzle = ins->src[1].swizzle;
if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD])
if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4])
{
FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
return shader_glsl_tex(ins);
@ -2783,7 +2977,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
@ -2796,7 +2990,7 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
{
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
const struct wined3d_gl_info *gl_info = &deviceImpl->adapter->gl_info;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, lod_param;
DWORD sample_flags = WINED3D_GLSL_SAMPLE_LOD;
@ -2810,12 +3004,12 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
}
shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD]
if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4]
&& shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
{
/* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
@ -2877,6 +3071,7 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
* then perform a 1D texture lookup from stage dstregnum, place into dst. */
static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
glsl_sample_function_t sample_function;
DWORD sampler_idx = ins->dst[0].reg.idx;
@ -2891,7 +3086,7 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
*
* It is a dependent read - not valid with conditional NP2 textures
*/
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
switch(mask_size)
@ -2990,7 +3185,7 @@ static void shader_glsl_texm3x2pad(const struct wined3d_shader_instruction *ins)
* Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
@ -3004,6 +3199,7 @@ static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
@ -3014,7 +3210,7 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
@ -3025,10 +3221,11 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD reg = ins->dst[0].reg.idx;
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[reg];
glsl_sample_function_t sample_function;
@ -3036,7 +3233,7 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@ -3049,11 +3246,11 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
{
DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE *current_state = &shader->baseShader.parse_state;
glsl_src_param_t src0_param;
char dst_mask[6];
DWORD reg = ins->dst[0].reg.idx;
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
@ -3068,7 +3265,8 @@ static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
* Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD reg = ins->dst[0].reg.idx;
glsl_src_param_t src0_param;
glsl_src_param_t src1_param;
@ -3087,7 +3285,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str);
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(stype, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, stype, 0, &sample_function);
/* Sample the texture */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@ -3099,7 +3297,8 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
* Perform the final texture lookup based on the previous 2 3x3 matrix multiplies */
static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
DWORD reg = ins->dst[0].reg.idx;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
@ -3119,7 +3318,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@ -3133,8 +3332,9 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
*/
static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
{
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
@ -3148,7 +3348,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
mask = sample_function.coord_mask;
shader_glsl_write_mask_to_str(mask, coord_mask);
@ -3207,6 +3407,7 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
* Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
@ -3214,7 +3415,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.wx", src0_param.reg_name);
}
@ -3223,6 +3424,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
* Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
@ -3230,7 +3432,7 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
"%s.yz", src0_param.reg_name);
}
@ -3239,13 +3441,14 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
* Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_src_param_t src0_param;
DWORD sampler_idx = ins->dst[0].reg.idx;
WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
glsl_sample_function_t sample_function;
/* Dependent read, not valid with conditional NP2 */
shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
@ -3759,6 +3962,10 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
*/
shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
}
if (gl_info->supported[EXT_GPU_SHADER4])
{
shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
}
/* Base Declarations */
shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShader *)This, reg_maps, &priv_ctx);
@ -3846,6 +4053,11 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
shader_addline(buffer, "#version 120\n");
if (gl_info->supported[EXT_GPU_SHADER4])
{
shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n");
}
memset(&priv_ctx, 0, sizeof(priv_ctx));
priv_ctx.cur_vs_args = args;
@ -4149,7 +4361,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
/* Link the program */
TRACE("Linking GLSL shader program %u\n", programId);
GL_EXTCALL(glLinkProgramARB(programId));
print_glsl_info_log(gl_info, programId);
shader_glsl_validate_link(gl_info, programId);
entry->vuniformF_locations = HeapAlloc(GetProcessHeap(), 0,
sizeof(GLhandleARB) * gl_info->limits.glsl_vs_float_constants);
@ -4230,10 +4442,12 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
* load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
* later
*/
if(pshader && !((IWineD3DPixelShaderImpl*)pshader)->baseShader.load_local_constsF) {
if (pshader && !((IWineD3DBaseShaderImpl *)pshader)->baseShader.load_local_constsF)
{
hardcode_local_constants((IWineD3DBaseShaderImpl *) pshader, gl_info, programId, 'P');
}
if(vshader && !((IWineD3DVertexShaderImpl*)vshader)->baseShader.load_local_constsF) {
if (vshader && !((IWineD3DBaseShaderImpl *)vshader)->baseShader.load_local_constsF)
{
hardcode_local_constants((IWineD3DBaseShaderImpl *) vshader, gl_info, programId, 'V');
}
}
@ -4303,7 +4517,7 @@ static GLhandleARB create_glsl_blt_shader(const struct wined3d_gl_info *gl_info,
GL_EXTCALL(glAttachObjectARB(program_id, pshader_id));
GL_EXTCALL(glLinkProgramARB(program_id));
print_glsl_info_log(gl_info, program_id);
shader_glsl_validate_link(gl_info, program_id);
/* Once linked we can mark the shaders for deletion. They will be deleted once the program
* is destroyed
@ -4394,8 +4608,6 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
struct shader_glsl_priv *priv = device->shader_priv;
const struct wined3d_gl_info *gl_info;
IWineD3DPixelShaderImpl *ps = NULL;
IWineD3DVertexShaderImpl *vs = NULL;
struct wined3d_context *context;
/* Note: Do not use QueryInterface here to find out which shader type this is because this code
@ -4405,12 +4617,11 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
if(pshader) {
struct glsl_pshader_private *shader_data;
ps = (IWineD3DPixelShaderImpl *) This;
shader_data = ps->baseShader.backend_data;
shader_data = This->baseShader.backend_data;
if(!shader_data || shader_data->num_gl_shaders == 0)
{
HeapFree(GetProcessHeap(), 0, shader_data);
ps->baseShader.backend_data = NULL;
This->baseShader.backend_data = NULL;
return;
}
@ -4425,12 +4636,11 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
}
} else {
struct glsl_vshader_private *shader_data;
vs = (IWineD3DVertexShaderImpl *) This;
shader_data = vs->baseShader.backend_data;
shader_data = This->baseShader.backend_data;
if(!shader_data || shader_data->num_gl_shaders == 0)
{
HeapFree(GetProcessHeap(), 0, shader_data);
vs->baseShader.backend_data = NULL;
This->baseShader.backend_data = NULL;
return;
}
@ -4466,7 +4676,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
if(pshader) {
UINT i;
struct glsl_pshader_private *shader_data = ps->baseShader.backend_data;
struct glsl_pshader_private *shader_data = This->baseShader.backend_data;
ENTER_GL();
for(i = 0; i < shader_data->num_gl_shaders; i++) {
@ -4476,11 +4686,11 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
}
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
ps->baseShader.backend_data = NULL;
} else {
}
else
{
UINT i;
struct glsl_vshader_private *shader_data = vs->baseShader.backend_data;
struct glsl_vshader_private *shader_data = This->baseShader.backend_data;
ENTER_GL();
for(i = 0; i < shader_data->num_gl_shaders; i++) {
@ -4490,10 +4700,11 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
}
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
vs->baseShader.backend_data = NULL;
}
HeapFree(GetProcessHeap(), 0, This->baseShader.backend_data);
This->baseShader.backend_data = NULL;
context_release(context);
}
@ -4632,8 +4843,7 @@ static BOOL shader_glsl_dirty_const(IWineD3DDevice *iface) {
return FALSE;
}
static void shader_glsl_get_caps(WINED3DDEVTYPE devtype,
const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
static void shader_glsl_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *pCaps)
{
/* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
* models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support based
@ -4697,7 +4907,7 @@ static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup)
}
/* We support everything except YUV conversions. */
if (!is_yuv_fixup(fixup))
if (!is_complex_fixup(fixup))
{
TRACE("[OK]\n");
return TRUE;
@ -4720,6 +4930,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
/* WINED3DSIH_CMP */ shader_glsl_cmp,
/* WINED3DSIH_CND */ shader_glsl_cnd,
/* WINED3DSIH_CRS */ shader_glsl_cross,
/* WINED3DSIH_CUT */ NULL,
/* WINED3DSIH_DCL */ NULL,
/* WINED3DSIH_DEF */ NULL,
/* WINED3DSIH_DEFB */ NULL,
@ -4731,20 +4942,24 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
/* WINED3DSIH_DSX */ shader_glsl_map2gl,
/* WINED3DSIH_DSY */ shader_glsl_map2gl,
/* WINED3DSIH_ELSE */ shader_glsl_else,
/* WINED3DSIH_EMIT */ NULL,
/* WINED3DSIH_ENDIF */ shader_glsl_end,
/* WINED3DSIH_ENDLOOP */ shader_glsl_end,
/* WINED3DSIH_ENDREP */ shader_glsl_end,
/* WINED3DSIH_EXP */ shader_glsl_map2gl,
/* WINED3DSIH_EXPP */ shader_glsl_expp,
/* WINED3DSIH_FRC */ shader_glsl_map2gl,
/* WINED3DSIH_IADD */ NULL,
/* WINED3DSIH_IF */ shader_glsl_if,
/* WINED3DSIH_IFC */ shader_glsl_ifc,
/* WINED3DSIH_IGE */ NULL,
/* WINED3DSIH_LABEL */ shader_glsl_label,
/* WINED3DSIH_LIT */ shader_glsl_lit,
/* WINED3DSIH_LOG */ shader_glsl_log,
/* WINED3DSIH_LOGP */ shader_glsl_log,
/* WINED3DSIH_LOOP */ shader_glsl_loop,
/* WINED3DSIH_LRP */ shader_glsl_lrp,
/* WINED3DSIH_LT */ NULL,
/* WINED3DSIH_M3x2 */ shader_glsl_mnxn,
/* WINED3DSIH_M3x3 */ shader_glsl_mnxn,
/* WINED3DSIH_M3x4 */ shader_glsl_mnxn,
@ -4757,7 +4972,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
/* WINED3DSIH_MOVA */ shader_glsl_mov,
/* WINED3DSIH_MUL */ shader_glsl_arith,
/* WINED3DSIH_NOP */ NULL,
/* WINED3DSIH_NRM */ shader_glsl_map2gl,
/* WINED3DSIH_NRM */ shader_glsl_nrm,
/* WINED3DSIH_PHASE */ NULL,
/* WINED3DSIH_POW */ shader_glsl_pow,
/* WINED3DSIH_RCP */ shader_glsl_rcp,

View file

@ -627,8 +627,7 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
LEAVE_GL();
}
static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype,
const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
static void nvrc_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
{
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
@ -671,7 +670,7 @@ static void nvrc_fragment_get_caps(WINED3DDEVTYPE devtype,
WINED3DTEXOPCAPS_PREMODULATE */
#endif
pCaps->MaxTextureBlendStages = gl_info->limits.texture_stages;
pCaps->MaxTextureBlendStages = min(MAX_TEXTURES, gl_info->limits.general_combiners);
pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;

View file

@ -24,15 +24,164 @@
#include "config.h"
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION (*gl_info)
static HRESULT wined3d_event_query_init(const struct wined3d_gl_info *gl_info, struct wined3d_event_query **query)
{
struct wined3d_event_query *ret;
*query = NULL;
if (!gl_info->supported[ARB_SYNC] && !gl_info->supported[NV_FENCE]
&& !gl_info->supported[APPLE_FENCE]) return E_NOTIMPL;
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
if (!ret)
{
ERR("Failed to allocate a wined3d event query structure.\n");
return E_OUTOFMEMORY;
}
ret->context = NULL;
*query = ret;
return WINED3D_OK;
}
static void wined3d_event_query_destroy(struct wined3d_event_query *query)
{
if (query->context) context_free_event_query(query);
HeapFree(GetProcessHeap(), 0, query);
}
static enum wined3d_event_query_result wined3d_event_query_test(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
struct wined3d_context *context;
const struct wined3d_gl_info *gl_info;
enum wined3d_event_query_result ret;
BOOL fence_result;
TRACE("(%p) : device %p\n", query, device);
if (query->context == NULL)
{
TRACE("Query not started\n");
return WINED3D_EVENT_QUERY_NOT_STARTED;
}
if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
{
WARN("Event query tested from wrong thread\n");
return WINED3D_EVENT_QUERY_WRONG_THREAD;
}
context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
gl_info = context->gl_info;
ENTER_GL();
if (gl_info->supported[ARB_SYNC])
{
GLenum gl_ret = GL_EXTCALL(glClientWaitSync(query->object.sync, 0, 0));
checkGLcall("glClientWaitSync");
switch (gl_ret)
{
case GL_ALREADY_SIGNALED:
case GL_CONDITION_SATISFIED:
ret = WINED3D_EVENT_QUERY_OK;
break;
case GL_TIMEOUT_EXPIRED:
ret = WINED3D_EVENT_QUERY_WAITING;
break;
case GL_WAIT_FAILED:
default:
ERR("glClientWaitSync returned %#x.\n", gl_ret);
ret = WINED3D_EVENT_QUERY_ERROR;
}
}
else if (gl_info->supported[APPLE_FENCE])
{
fence_result = GL_EXTCALL(glTestFenceAPPLE(query->object.id));
checkGLcall("glTestFenceAPPLE");
if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
else ret = WINED3D_EVENT_QUERY_WAITING;
}
else if (gl_info->supported[NV_FENCE])
{
fence_result = GL_EXTCALL(glTestFenceNV(query->object.id));
checkGLcall("glTestFenceNV");
if (fence_result) ret = WINED3D_EVENT_QUERY_OK;
else ret = WINED3D_EVENT_QUERY_WAITING;
}
else
{
ERR("Event query created despite lack of GL support\n");
ret = WINED3D_EVENT_QUERY_ERROR;
}
LEAVE_GL();
context_release(context);
return ret;
}
static void wined3d_event_query_issue(struct wined3d_event_query *query, IWineD3DDeviceImpl *device)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
if (query->context)
{
if (!query->context->gl_info->supported[ARB_SYNC] && query->context->tid != GetCurrentThreadId())
{
context_free_event_query(query);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
else
{
context = context_acquire(device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
}
}
else
{
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
gl_info = context->gl_info;
ENTER_GL();
if (gl_info->supported[ARB_SYNC])
{
if (query->object.sync) GL_EXTCALL(glDeleteSync(query->object.sync));
checkGLcall("glDeleteSync");
query->object.sync = GL_EXTCALL(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
checkGLcall("glFenceSync");
}
else if (gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glSetFenceAPPLE(query->object.id));
checkGLcall("glSetFenceAPPLE");
}
else if (gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glSetFenceNV(query->object.id, GL_ALL_COMPLETED_NV));
checkGLcall("glSetFenceNV");
}
LEAVE_GL();
context_release(context);
}
/*
* 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->device->adapter->gl_info
/* *******************************************
IWineD3DQuery IUnknown parts follow
******************************************* */
@ -70,17 +219,16 @@ static ULONG WINAPI IWineD3DQueryImpl_Release(IWineD3DQuery *iface) {
if (This->type == WINED3DQUERYTYPE_EVENT)
{
struct wined3d_event_query *query = This->extendedData;
if (query->context) context_free_event_query(query);
if (query) wined3d_event_query_destroy(query);
}
else if (This->type == WINED3DQUERYTYPE_OCCLUSION)
{
struct wined3d_occlusion_query *query = This->extendedData;
if (query->context) context_free_occlusion_query(query);
HeapFree(GetProcessHeap(), 0, This->extendedData);
}
HeapFree(GetProcessHeap(), 0, This->extendedData);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@ -101,168 +249,6 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetParent(IWineD3DQuery *iface, IUnknown
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);
switch (This->type){
case WINED3DQUERYTYPE_VCACHE:
{
WINED3DDEVINFO_VCACHE *data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VCACHE\n", This);
if(pData == NULL || dwSize == 0) break;
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 = pData;
int i;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_RESOURCEMANAGER\n", This);
if(pData == NULL || dwSize == 0) break;
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 information */
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 = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXSTATS\n", This);
if(pData == NULL || dwSize == 0) break;
data->NumRenderedTriangles = 1;
data->NumExtraClippingTriangles = 1;
}
break;
case WINED3DQUERYTYPE_TIMESTAMP:
{
UINT64* data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_TIMESTAMP\n", This);
if(pData == NULL || dwSize == 0) break;
*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);
if(pData == NULL || dwSize == 0) break;
*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);
if(pData == NULL || dwSize == 0) break;
*data = 1; /*Don't know what this is supposed to be*/
}
break;
case WINED3DQUERYTYPE_PIPELINETIMINGS:
{
WINED3DDEVINFO_PIPELINETIMINGS *data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIPELINETIMINGS\n", This);
if(pData == NULL || dwSize == 0) break;
data->VertexProcessingTimePercent = 1.0f;
data->PixelProcessingTimePercent = 1.0f;
data->OtherGPUProcessingTimePercent = 97.0f;
data->GPUIdleTimePercent = 1.0f;
}
break;
case WINED3DQUERYTYPE_INTERFACETIMINGS:
{
WINED3DDEVINFO_INTERFACETIMINGS *data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_INTERFACETIMINGS\n", This);
if(pData == NULL || dwSize == 0) break;
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 = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_VERTEXTIMINGS\n", This);
if(pData == NULL || dwSize == 0) break;
data->MemoryProcessingPercent = 50.0f;
data->ComputationProcessingPercent = 50.0f;
}
break;
case WINED3DQUERYTYPE_PIXELTIMINGS:
{
WINED3DDEVINFO_STAGETIMINGS *data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_PIXELTIMINGS\n", This);
if(pData == NULL || dwSize == 0) break;
data->MemoryProcessingPercent = 50.0f;
data->ComputationProcessingPercent = 50.0f;
}
break;
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
{
WINED3DDEVINFO_BANDWIDTHTIMINGS *data = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_BANDWIDTHTIMINGS\n", This);
if(pData == NULL || dwSize == 0) break;
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 = pData;
FIXME("(%p): Unimplemented query WINED3DQUERYTYPE_CACHEUTILIZATION\n", This);
if(pData == NULL || dwSize == 0) break;
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 HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
struct wined3d_occlusion_query *query = This->extendedData;
@ -341,108 +327,44 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
struct wined3d_event_query *query = This->extendedData;
struct wined3d_context *context;
BOOL *data = pData;
enum wined3d_event_query_result ret;
TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
if (!pData || !dwSize) return S_OK;
if (!query->context)
if (!query)
{
TRACE("Query not started, returning TRUE.\n");
WARN("(%p): Event query not supported by GL, reporting GPU idle\n", This);
*data = TRUE;
return S_OK;
}
if (query->context->tid != GetCurrentThreadId())
ret = wined3d_event_query_test(query, This->device);
switch(ret)
{
/* See comment in IWineD3DQuery::Issue, event query codeblock */
FIXME("Wrong thread, reporting GPU idle.\n");
*data = TRUE;
case WINED3D_EVENT_QUERY_OK:
case WINED3D_EVENT_QUERY_NOT_STARTED:
*data = TRUE;
break;
return S_OK;
case WINED3D_EVENT_QUERY_WAITING:
*data = FALSE;
break;
case WINED3D_EVENT_QUERY_WRONG_THREAD:
FIXME("(%p) Wrong thread, reporting GPU idle.\n", This);
*data = TRUE;
break;
case WINED3D_EVENT_QUERY_ERROR:
ERR("The GL event query failed, returning D3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
if (context->gl_info->supported[APPLE_FENCE])
{
*data = GL_EXTCALL(glTestFenceAPPLE(query->id));
checkGLcall("glTestFenceAPPLE");
}
else if (context->gl_info->supported[NV_FENCE])
{
*data = GL_EXTCALL(glTestFenceNV(query->id));
checkGLcall("glTestFenceNV");
}
else
{
WARN("(%p): reporting GPU idle\n", This);
*data = TRUE;
}
LEAVE_GL();
context_release(context);
return S_OK;
}
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_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 DWORD WINAPI IWineD3DEventQueryImpl_GetDataSize(IWineD3DQuery* iface){
TRACE("(%p) : type D3DQUERY_EVENT\n", iface);
@ -460,7 +382,6 @@ static WINED3DQUERYTYPE WINAPI IWineD3DQueryImpl_GetType(IWineD3DQuery* iface){
return This->type;
}
static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
@ -468,43 +389,11 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
if (dwIssueFlags & WINED3DISSUE_END)
{
struct wined3d_event_query *query = This->extendedData;
struct wined3d_context *context;
if (query->context)
{
if (query->context->tid != GetCurrentThreadId())
{
context_free_event_query(query);
context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
else
{
context = context_acquire(This->device, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
}
}
else
{
context = context_acquire(This->device, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
/* Faked event query support */
if (!query) return WINED3D_OK;
ENTER_GL();
if (context->gl_info->supported[APPLE_FENCE])
{
GL_EXTCALL(glSetFenceAPPLE(query->id));
checkGLcall("glSetFenceAPPLE");
}
else if (context->gl_info->supported[NV_FENCE])
{
GL_EXTCALL(glSetFenceNV(query->id, GL_ALL_COMPLETED_NV));
checkGLcall("glSetFenceNV");
}
LEAVE_GL();
context_release(context);
wined3d_event_query_issue(query, This->device);
}
else if(dwIssueFlags & WINED3DISSUE_BEGIN)
{
@ -604,43 +493,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
return WINED3D_OK; /* can be WINED3DERR_INVALIDCALL. */
}
static HRESULT WINAPI IWineD3DQueryImpl_Issue(IWineD3DQuery* iface, DWORD dwIssueFlags){
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *)iface;
TRACE("(%p) : dwIssueFlags %#x, type %#x\n", This, dwIssueFlags, This->type);
/* The fixme is printed when the app asks for the resulting data */
WARN("(%p) : Unhandled query type %#x\n", This, This->type);
if(dwIssueFlags & WINED3DISSUE_BEGIN) {
This->state = QUERY_BUILDING;
} else {
This->state = QUERY_SIGNALLED;
}
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_GetData,
IWineD3DQueryImpl_GetDataSize,
IWineD3DQueryImpl_GetType,
IWineD3DQueryImpl_Issue
};
const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
static const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
{
/*** IUnknown methods ***/
IWineD3DQueryImpl_QueryInterface,
@ -654,7 +507,7 @@ const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl =
IWineD3DEventQueryImpl_Issue
};
const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
static const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
{
/*** IUnknown methods ***/
IWineD3DQueryImpl_QueryInterface,
@ -667,3 +520,72 @@ const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl =
IWineD3DQueryImpl_GetType,
IWineD3DOcclusionQueryImpl_Issue
};
HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device,
WINED3DQUERYTYPE type, IUnknown *parent)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
HRESULT hr;
switch (type)
{
case WINED3DQUERYTYPE_OCCLUSION:
TRACE("Occlusion query.\n");
if (!gl_info->supported[ARB_OCCLUSION_QUERY])
{
WARN("Unsupported in local OpenGL implementation: ARB_OCCLUSION_QUERY.\n");
return WINED3DERR_NOTAVAILABLE;
}
query->lpVtbl = &IWineD3DOcclusionQuery_Vtbl;
query->extendedData = HeapAlloc(GetProcessHeap(), 0, sizeof(struct wined3d_occlusion_query));
if (!query->extendedData)
{
ERR("Failed to allocate occlusion query extended data.\n");
return E_OUTOFMEMORY;
}
((struct wined3d_occlusion_query *)query->extendedData)->context = NULL;
break;
case WINED3DQUERYTYPE_EVENT:
TRACE("Event query.\n");
query->lpVtbl = &IWineD3DEventQuery_Vtbl;
hr = wined3d_event_query_init(gl_info, (struct wined3d_event_query **) &query->extendedData);
if (hr == E_NOTIMPL)
{
/* Half-Life 2 needs this query. It does not render the main
* menu correctly otherwise. Pretend to support it, faking
* this query does not do much harm except potentially
* lowering performance. */
FIXME("Event query: Unimplemented, but pretending to be supported.\n");
}
else if(FAILED(hr))
{
return hr;
}
break;
case WINED3DQUERYTYPE_VCACHE:
case WINED3DQUERYTYPE_RESOURCEMANAGER:
case WINED3DQUERYTYPE_VERTEXSTATS:
case WINED3DQUERYTYPE_TIMESTAMP:
case WINED3DQUERYTYPE_TIMESTAMPDISJOINT:
case WINED3DQUERYTYPE_TIMESTAMPFREQ:
case WINED3DQUERYTYPE_PIPELINETIMINGS:
case WINED3DQUERYTYPE_INTERFACETIMINGS:
case WINED3DQUERYTYPE_VERTEXTIMINGS:
case WINED3DQUERYTYPE_PIXELTIMINGS:
case WINED3DQUERYTYPE_BANDWIDTHTIMINGS:
case WINED3DQUERYTYPE_CACHEUTILIZATION:
default:
FIXME("Unhandled query type %#x.\n", type);
return WINED3DERR_NOTAVAILABLE;
}
query->type = type;
query->state = QUERY_CREATED;
query->device = device;
query->parent = parent;
query->ref = 1;
return WINED3D_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -641,9 +641,10 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}
static void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
static void shader_sm1_read_comment(const DWORD **ptr, const char **comment, UINT *comment_size)
{
DWORD token = **ptr;
UINT size;
if ((token & WINED3DSI_OPCODE_MASK) != WINED3D_SM1_OP_COMMENT)
{
@ -651,8 +652,10 @@ static void shader_sm1_read_comment(const DWORD **ptr, const char **comment)
return;
}
size = (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
*comment = (const char *)++(*ptr);
*ptr += (token & WINED3DSI_COMMENTSIZE_MASK) >> WINED3DSI_COMMENTSIZE_SHIFT;
*comment_size = size * sizeof(DWORD);
*ptr += size;
}
static BOOL shader_sm1_is_end(void *data, const DWORD **ptr)

View file

@ -49,10 +49,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
enum wined3d_sm4_opcode
{
WINED3D_SM4_OP_ADD = 0x00,
WINED3D_SM4_OP_BREAK = 0x02,
WINED3D_SM4_OP_BREAKC = 0x03,
WINED3D_SM4_OP_CUT = 0x09,
WINED3D_SM4_OP_DP3 = 0x10,
WINED3D_SM4_OP_DP4 = 0x11,
WINED3D_SM4_OP_EMIT = 0x13,
WINED3D_SM4_OP_ENDIF = 0x15,
WINED3D_SM4_OP_ENDLOOP = 0x16,
WINED3D_SM4_OP_EXP = 0x19,
WINED3D_SM4_OP_IADD = 0x1e,
WINED3D_SM4_OP_IF = 0x1f,
WINED3D_SM4_OP_IGE = 0x21,
WINED3D_SM4_OP_LOG = 0x2f,
WINED3D_SM4_OP_LT = 0x31,
WINED3D_SM4_OP_MIN = 0x33,
WINED3D_SM4_OP_MAX = 0x34,
WINED3D_SM4_OP_MOV = 0x36,
@ -102,10 +112,20 @@ struct sysval_map
static const struct wined3d_sm4_opcode_info opcode_table[] =
{
{WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, 1, 2},
{WINED3D_SM4_OP_BREAK, WINED3DSIH_BREAK, 0, 0},
{WINED3D_SM4_OP_BREAKC, WINED3DSIH_BREAKP, 0, 1},
{WINED3D_SM4_OP_CUT, WINED3DSIH_CUT, 0, 0},
{WINED3D_SM4_OP_DP3, WINED3DSIH_DP3, 1, 2},
{WINED3D_SM4_OP_DP4, WINED3DSIH_DP4, 1, 2},
{WINED3D_SM4_OP_EMIT, WINED3DSIH_EMIT, 0, 0},
{WINED3D_SM4_OP_ENDIF, WINED3DSIH_ENDIF, 0, 0},
{WINED3D_SM4_OP_ENDLOOP,WINED3DSIH_ENDLOOP, 0, 0},
{WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, 1, 1},
{WINED3D_SM4_OP_IADD, WINED3DSIH_IADD, 1, 2},
{WINED3D_SM4_OP_IF, WINED3DSIH_IF, 0, 1},
{WINED3D_SM4_OP_IGE, WINED3DSIH_IGE, 1, 2},
{WINED3D_SM4_OP_LOG, WINED3DSIH_LOG, 1, 1},
{WINED3D_SM4_OP_LT, WINED3DSIH_LT, 1, 2},
{WINED3D_SM4_OP_MIN, WINED3DSIH_MIN, 1, 2},
{WINED3D_SM4_OP_MAX, WINED3DSIH_MAX, 1, 2},
{WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, 1, 1},
@ -386,9 +406,9 @@ static void shader_sm4_read_semantic(const DWORD **ptr, struct wined3d_shader_se
FIXME("ptr %p, semantic %p stub!\n", ptr, semantic);
}
static void shader_sm4_read_comment(const DWORD **ptr, const char **comment)
static void shader_sm4_read_comment(const DWORD **ptr, const char **comment, UINT *comment_size)
{
FIXME("ptr %p, comment %p stub!\n", ptr, comment);
FIXME("ptr %p, comment %p, comment_size %p stub!\n", ptr, comment, comment_size);
*comment = NULL;
}

View file

@ -584,6 +584,10 @@ static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, stru
glEnable(GL_DEPTH_CLAMP);
checkGLcall("glEnable(GL_DEPTH_CLAMP)");
}
else
{
FIXME("Clipping disabled, but ARB_depth_clamp isn't supported.\n");
}
}
if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
@ -3523,7 +3527,6 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wine
if(stateblock->textures[sampler]) {
BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE];
IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB);
IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
basetexture_apply_state_changes(stateblock->textures[sampler],
stateblock->textureState[sampler], stateblock->samplerState[sampler], gl_info);
@ -3597,9 +3600,9 @@ void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct w
}
} else {
/* Disabled the pixel shader - color ops weren't applied
* while it was enabled, so re-apply them.
*/
for(i=0; i < MAX_TEXTURES; i++) {
* while it was enabled, so re-apply them. */
for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
{
if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply
(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
@ -3880,62 +3883,18 @@ static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock
glLoadIdentity();
checkGLcall("glLoadIdentity");
if(context->last_was_rhw) {
double X, Y, height, width, minZ, maxZ;
if (context->last_was_rhw)
{
double x = stateblock->viewport.X;
double y = stateblock->viewport.Y;
double w = stateblock->viewport.Width;
double h = stateblock->viewport.Height;
X = stateblock->viewport.X;
Y = stateblock->viewport.Y;
height = stateblock->viewport.Height;
width = stateblock->viewport.Width;
minZ = stateblock->viewport.MinZ;
maxZ = stateblock->viewport.MaxZ;
if (!stateblock->device->untransformed)
{
/* Transformed vertices are supposed to bypass the whole transform pipeline including
* frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
* suppress depth clipping. This can be done because it is an orthogonal projection and
* the Z coordinate does not affect the size of the primitives. Half Life 1 and Prince of
* Persia 3D need this.
*
* Note that using minZ and maxZ here doesn't entirely fix the problem, since view frustum
* clipping is still enabled, but it seems to fix it for all apps tested so far. A minor
* problem can be witnessed in half-life 1 engine based games, the weapon is clipped close
* to the viewer.
*
* Also note that this breaks z comparison against z values filled in with clear,
* but no app depending on that and disabled clipping has been found yet. Comparing
* primitives against themselves works, so the Z buffer is still intact for normal hidden
* surface removal.
*
* We could disable clipping entirely by setting the near to infinity and far to -infinity,
* but this would break Z buffer operation. Raising the range to something less than
* infinity would help a bit at the cost of Z precision, but it wouldn't eliminate the
* problem either.
*/
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
if (context->render_offscreen)
{
glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
} else {
glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
}
} else {
/* If the app mixes transformed and untransformed primitives we can't use the coordinate system
* trick above because this would mess up transformed and untransformed Z order. Pass the z position
* unmodified to opengl.
*
* If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
* replacement shader.
*/
TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
if (context->render_offscreen)
{
glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
} else {
glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
}
}
TRACE("Calling glOrtho with x %.8e, y %.8e, w %.8e, h %.8e.\n", x, y, w, h);
if (context->render_offscreen)
glOrtho(x, x + w, -y, -y - h, 0.0, -1.0);
else
glOrtho(x, x + w, y + h, y, 0.0, -1.0);
checkGLcall("glOrtho");
/* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
@ -4167,7 +4126,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
break;
case WINED3DFMT_B8G8R8A8_UNORM:
if (gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
const DWORD *src = (const DWORD *)ptr;
DWORD c = *src & 0xff00ff00;
@ -4479,87 +4438,11 @@ static void loadVertexData(const struct wined3d_context *context, IWineD3DStateB
loadTexCoords(context, stateblock, si, &curVBO);
}
static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
{
/* Dump out what parts we have supplied */
TRACE("Strided Data:\n");
TRACE_STRIDED((dataLocations), WINED3D_FFP_POSITION);
TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDWEIGHT);
TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDINDICES);
TRACE_STRIDED((dataLocations), WINED3D_FFP_NORMAL);
TRACE_STRIDED((dataLocations), WINED3D_FFP_PSIZE);
TRACE_STRIDED((dataLocations), WINED3D_FFP_DIFFUSE);
TRACE_STRIDED((dataLocations), WINED3D_FFP_SPECULAR);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD0);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD1);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD2);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD3);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD4);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD5);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD6);
TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD7);
}
static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
IWineD3DDeviceImpl *device = stateblock->device;
BOOL fixup = FALSE;
struct wined3d_stream_info *dataLocations = &device->strided_streams;
BOOL useVertexShaderFunction;
BOOL load_numbered = FALSE;
BOOL load_named = FALSE;
useVertexShaderFunction = (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader) ? TRUE : FALSE;
if(device->up_strided) {
/* Note: this is a ddraw fixed-function code path */
TRACE("================ Strided Input ===================\n");
device_stream_info_from_strided(gl_info, device->up_strided, dataLocations);
if(TRACE_ON(d3d)) {
drawPrimitiveTraceDataLocations(dataLocations);
}
} else {
/* Note: This is a fixed function or shader codepath.
* This means it must handle both types of strided data.
* Shaders must go through here to zero the strided data, even if they
* don't set any declaration at all
*/
TRACE("================ Vertex Declaration ===================\n");
device_stream_info_from_declaration(device, useVertexShaderFunction, dataLocations, &fixup);
}
if (dataLocations->position_transformed) useVertexShaderFunction = FALSE;
if(useVertexShaderFunction) {
if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion\n");
device->useDrawStridedSlow = TRUE;
} else {
load_numbered = TRUE;
device->useDrawStridedSlow = FALSE;
}
}
else
{
WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
slow_mask |= -!gl_info->supported[EXT_VERTEX_ARRAY_BGRA]
& ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
if (fixup || (!dataLocations->position_transformed
&& !(dataLocations->use_map & slow_mask)))
{
/* Load the vertex data using named arrays */
load_named = TRUE;
device->useDrawStridedSlow = FALSE;
}
else
{
TRACE("Not loading vertex data\n");
device->useDrawStridedSlow = TRUE;
}
}
BOOL load_numbered = use_vs(stateblock) && !device->useDrawStridedSlow;
BOOL load_named = !use_vs(stateblock) && !device->useDrawStridedSlow;
if (context->numberedArraysLoaded && !load_numbered)
{
@ -4576,13 +4459,13 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wi
if (load_numbered)
{
TRACE("Loading numbered arrays\n");
loadNumberedArrays(stateblock, dataLocations, context);
loadNumberedArrays(stateblock, &device->strided_streams, context);
context->numberedArraysLoaded = TRUE;
}
else if (load_named)
{
TRACE("Loading vertex data\n");
loadVertexData(context, stateblock, dataLocations);
loadVertexData(context, stateblock, &device->strided_streams);
context->namedArraysLoaded = TRUE;
}
}
@ -5634,8 +5517,7 @@ static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
/* Context activation is done by the caller. */
static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype,
const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
{
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
@ -5670,7 +5552,7 @@ static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype,
if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
pCaps->MaxTextureBlendStages = gl_info->limits.texture_stages;
pCaps->MaxTextureBlendStages = gl_info->limits.textures;
pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
}
@ -5725,6 +5607,43 @@ static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock,
stateblock->device->multistate_funcs[state][2](state, stateblock, context);
}
static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
{
unsigned int start, last, i;
start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
for (i = start; i <= last; ++i)
{
state_table[i].representative = 0;
state_table[i].apply = state_undefined;
}
start = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + gl_info->limits.texture_stages);
last = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + MAX_TEXTURES - 1);
for (i = start; i <= last; ++i)
{
state_table[i].representative = 0;
state_table[i].apply = state_undefined;
}
}
static void validate_state_table(struct StateEntry *state_table)
{
unsigned int i;
for (i = 0; i < STATE_HIGHEST + 1; ++i)
{
DWORD rep = state_table[i].representative;
if (rep && !state_table[rep].representative)
{
ERR("State %s (%#x) has invalid representative %s (%#x).\n",
debug_d3dstate(i), i, debug_d3dstate(rep), rep);
state_table[i].representative = 0;
}
}
}
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
@ -5824,6 +5743,9 @@ HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_
}
}
prune_invalid_states(StateTable, gl_info);
validate_state_table(StateTable);
return WINED3D_OK;
out_of_mem:

View file

@ -1253,6 +1253,37 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb)
TRACE("Updated target %d\n", This->texture_target);
}
/* Context activation is done by the caller. */
void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb)
{
DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
GLenum format, internal, type;
GLsizei width, height;
CONVERT_TYPES convert;
int bpp;
if (surface->Flags & alloc_flag) return;
d3dfmt_get_conv(surface, TRUE, TRUE, &format, &internal, &type, &convert, &bpp, srgb);
if(convert != NO_CONVERSION) surface->Flags |= SFLAG_CONVERTED;
else surface->Flags &= ~SFLAG_CONVERTED;
if ((surface->Flags & SFLAG_NONPOW2) && !(surface->Flags & SFLAG_OVERSIZE))
{
width = surface->pow2Width;
height = surface->pow2Height;
}
else
{
width = surface->glRect.right - surface->glRect.left;
height = surface->glRect.bottom - surface->glRect.top;
}
surface_bind_and_dirtify(surface, srgb);
surface_allocate_surface(surface, internal, width, height, format, type);
surface->Flags |= alloc_flag;
}
static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This)
{
IWineD3DDeviceImpl *device = This->resource.device;
@ -1822,7 +1853,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
* in which the main render target uses p8. Some games like GTA Vice City use P8 for texturing which
* conflicts with this.
*/
if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (gl_info->supported[ARB_FRAGMENT_PROGRAM]
if (!(gl_info->supported[EXT_PALETTED_TEXTURE] || (device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)
&& device->render_targets && This == (IWineD3DSurfaceImpl*)device->render_targets[0]))
|| colorkey_active || !use_texturing)
{
@ -1836,7 +1867,7 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*convert = CONVERT_PALETTED;
}
}
else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && gl_info->supported[ARB_FRAGMENT_PROGRAM])
else if (!gl_info->supported[EXT_PALETTED_TEXTURE] && device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup))
{
*format = GL_ALPHA;
*type = GL_UNSIGNED_BYTE;
@ -2553,34 +2584,10 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
* The 8bit pixel data will be used as an index in this palette texture to retrieve the final color. */
TRACE("Using fragment shaders for emulating 8-bit paletted texture support\n");
device->blitter->set_shader((IWineD3DDevice *) device, This->resource.format_desc,
This->texture_target, This->pow2Width, This->pow2Height);
ENTER_GL();
/* Create the fragment program if we don't have it */
if(!device->paletteConversionShader)
{
const char *fragment_palette_conversion =
"!!ARBfp1.0\n"
"TEMP index;\n"
/* { 255/256, 0.5/255*255/256, 0, 0 } */
"PARAM constants = { 0.996, 0.00195, 0, 0 };\n"
/* The alpha-component contains the palette index */
"TEX index, fragment.texcoord[0], texture[0], 2D;\n"
/* Scale the index by 255/256 and add a bias of '0.5' in order to sample in the middle */
"MAD index.a, index.a, constants.x, constants.y;\n"
/* Use the alpha-component as an index in the palette to get the final color */
"TEX result.color, index.a, texture[1], 1D;\n"
"END";
glEnable(GL_FRAGMENT_PROGRAM_ARB);
GL_EXTCALL(glGenProgramsARB(1, &device->paletteConversionShader));
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(fragment_palette_conversion), fragment_palette_conversion));
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
glEnable(GL_FRAGMENT_PROGRAM_ARB);
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, device->paletteConversionShader));
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE1));
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -2594,7 +2601,6 @@ static void d3dfmt_p8_upload_palette(IWineD3DSurface *iface, CONVERT_TYPES conve
/* Rebind the texture because it isn't bound anymore */
glBindTexture(This->texture_target, This->texture_name);
LEAVE_GL();
}
}
@ -2700,7 +2706,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
/* TODO: check for locks */
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.device;
IWineD3DBaseTexture *baseTexture = NULL;
TRACE("(%p)Checking to see if the container is a base texture\n", This);
@ -2711,13 +2716,11 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL
}
else
{
struct wined3d_context *context = NULL;
GLuint *name;
TRACE("(%p) : Binding surface\n", This);
name = srgb ? &This->texture_name_srgb : &This->texture_name;
if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
@ -2751,8 +2754,6 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL
checkGLcall("glBindTexture");
LEAVE_GL();
if (context) context_release(context);
}
}
@ -3447,6 +3448,9 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
}
LEAVE_GL();
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
/* The texture is now most up to date - If the surface is a render target and has a drawable, this
@ -3921,9 +3925,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
/* Leave the opengl state valid for blitting */
myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);
/* Flush in case the drawable is used by multiple GL contexts */
if(dstSwapchain && (This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer || dstSwapchain->num_contexts >= 2))
wglFlush();
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
@ -4552,7 +4554,11 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
else context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
LEAVE_GL();
} else {
wglFlush(); /* Flush to ensure ordering across contexts. */
}
else
{
FIXME("No up to date depth stencil location\n");
}
} else if (location == SFLAG_DS_ONSCREEN) {
@ -4569,7 +4575,11 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
if (context->current_fbo) context_bind_fbo(context, GL_FRAMEBUFFER, &context->current_fbo->id);
LEAVE_GL();
} else {
wglFlush(); /* Flush to ensure ordering across contexts. */
}
else
{
FIXME("No up to date depth stencil location\n");
}
} else {
@ -4656,11 +4666,10 @@ static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct float
static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
{
IWineD3DDeviceImpl *device = This->resource.device;
IWineD3DBaseTextureImpl *texture;
struct wined3d_context *context;
struct coords coords[4];
RECT rect;
IWineD3DSwapChain *swapchain;
IWineD3DBaseTexture *texture;
GLenum bind_target;
struct float_rect f;
@ -4802,25 +4811,16 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
LEAVE_GL();
if(SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface*)This, &IID_IWineD3DSwapChain, (void **) &swapchain)))
{
/* Make sure to flush the buffers. This is needed in apps like Red Alert II and Tiberian SUN that use multiple WGL contexts. */
if(((IWineD3DSwapChainImpl*)swapchain)->frontBuffer == (IWineD3DSurface*)This ||
((IWineD3DSwapChainImpl*)swapchain)->num_contexts >= 2)
wglFlush();
wglFlush(); /* Flush to ensure ordering across contexts. */
IWineD3DSwapChain_Release(swapchain);
} else {
/* We changed the filtering settings on the texture. Inform the container about this to get the filters
* reset properly next draw
*/
if(SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface*)This, &IID_IWineD3DBaseTexture, (void **) &texture)))
{
((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
((IWineD3DBaseTextureImpl *) texture)->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
IWineD3DBaseTexture_Release(texture);
}
/* We changed the filtering settings on the texture. Inform the
* container about this to get the filters reset properly next draw. */
if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)This, &IID_IWineD3DBaseTexture, (void **)&texture)))
{
texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
texture->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture);
}
context_release(context);
@ -4977,7 +4977,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
{
/* Upload from system memory */
BOOL srgb = flag == SFLAG_INSRGBTEX;
DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
struct wined3d_context *context = NULL;
d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */,
@ -5004,6 +5003,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
}
if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
surface_prepare_texture(This, srgb);
surface_bind_and_dirtify(This, srgb);
if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
@ -5037,17 +5038,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
return WINED3DERR_OUTOFVIDEOMEMORY;
}
d3dfmt_convert_surface(This->resource.allocatedMemory, mem, pitch, width, height, outpitch, convert, This);
This->Flags |= SFLAG_CONVERTED;
}
else if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
&& (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM]))
&& (gl_info->supported[EXT_PALETTED_TEXTURE] || device->blitter->color_fixup_supported(This->resource.format_desc->color_fixup)))
{
d3dfmt_p8_upload_palette(iface, convert);
This->Flags &= ~SFLAG_CONVERTED;
mem = This->resource.allocatedMemory;
} else {
This->Flags &= ~SFLAG_CONVERTED;
mem = This->resource.allocatedMemory;
}
@ -5058,10 +5055,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
TRACE("non power of two support\n");
if(!(This->Flags & alloc_flag)) {
surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type);
This->Flags |= alloc_flag;
}
if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
}
@ -5069,10 +5062,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
/* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory
* changed. So also keep track of memory changes. In this case the texture has to be reallocated
*/
if(!(This->Flags & alloc_flag)) {
surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
This->Flags |= alloc_flag;
}
if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem);
}

View file

@ -217,6 +217,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
unsigned int sync;
int retval;
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
context = context_acquire(This->device, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
@ -272,12 +274,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
}
TRACE("presetting HDC %p\n", This->context[0]->hdc);
/* Don't call checkGLcall, as glGetError is not applicable here */
if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
}
TRACE("Presenting HDC %p.\n", context->hdc);
render_to_fbo = This->render_to_fbo;
@ -343,7 +340,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
swapchain_blit(This, context, &src_rect, &dst_rect);
}
SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */
if (This->num_contexts > 1) wglFinish();
SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
TRACE("SwapBuffers called, Starting new frame\n");
/* FPS support */
@ -521,7 +519,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapCh
WINED3DLOCKED_RECT r;
BYTE *mem;
if(window == This->win_handle) return WINED3D_OK;
if (!window || window == This->win_handle) return WINED3D_OK;
TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window);
if (This->context[0] == This->device->contexts[0])
@ -913,10 +911,15 @@ err:
HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
}
if (swapchain->context && swapchain->context[0])
if (swapchain->context)
{
context_release(swapchain->context[0]);
context_destroy(device, swapchain->context[0]);
if (swapchain->context[0])
{
context_release(swapchain->context[0]);
context_destroy(device, swapchain->context[0]);
swapchain->num_contexts = 0;
}
HeapFree(GetProcessHeap(), 0, swapchain->context);
}
if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);

View file

@ -387,7 +387,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE},
{WINED3DFMT_R16G16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
{WINED3DFMT_R16G16_UNORM, GL_RGB16, GL_RGB16, GL_RGBA16,
GL_RGB, GL_UNSIGNED_SHORT,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE},
@ -395,7 +395,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE},
{WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, 0,
{WINED3DFMT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA16, 0,
GL_RGBA, GL_UNSIGNED_SHORT,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
WINED3D_GL_EXT_NONE},
@ -445,7 +445,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
GL_RGBA, GL_BYTE,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
NV_TEXTURE_SHADER},
{WINED3DFMT_R16G16_SNORM, GL_RGB16_EXT, GL_RGB16_EXT, 0,
{WINED3DFMT_R16G16_SNORM, GL_RGB16, GL_RGB16, 0,
GL_BGR, GL_UNSIGNED_SHORT,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE},
@ -506,7 +506,7 @@ static const GlPixelFormatDescTemplate gl_formats_template[] = {
GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH,
ARB_DEPTH_TEXTURE},
{WINED3DFMT_L16_UNORM, GL_LUMINANCE16_EXT, GL_LUMINANCE16_EXT, 0,
{WINED3DFMT_L16_UNORM, GL_LUMINANCE16, GL_LUMINANCE16, 0,
GL_LUMINANCE, GL_UNSIGNED_SHORT,
WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
WINED3D_GL_EXT_NONE},
@ -950,7 +950,7 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
{
WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
if (vendor == VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
{
TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
filtered = TRUE;
@ -1088,17 +1088,20 @@ static void apply_format_fixups(struct wined3d_gl_info *gl_info)
if (!gl_info->supported[APPLE_YCBCR_422])
{
idx = getFmtIdx(WINED3DFMT_YUY2);
gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YUY2);
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
idx = getFmtIdx(WINED3DFMT_UYVY);
gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_UYVY);
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
}
idx = getFmtIdx(WINED3DFMT_YV12);
gl_info->gl_formats[idx].heightscale = 1.5f;
gl_info->gl_formats[idx].color_fixup = create_yuv_fixup_desc(YUV_FIXUP_YV12);
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
if (gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
idx = getFmtIdx(WINED3DFMT_P8_UINT);
gl_info->gl_formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
gl_info->gl_formats[idx].gl_vtx_format = GL_BGRA;
@ -1786,6 +1789,51 @@ const char* debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) {
}
}
const char *debug_d3dstate(DWORD state)
{
if (STATE_IS_RENDER(state))
return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
if (STATE_IS_TEXTURESTAGE(state))
{
DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
texture_stage, debug_d3dtexturestate(texture_state));
}
if (STATE_IS_SAMPLER(state))
return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
if (STATE_IS_PIXELSHADER(state))
return "STATE_PIXELSHADER";
if (STATE_IS_TRANSFORM(state))
return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
if (STATE_IS_STREAMSRC(state))
return "STATE_STREAMSRC";
if (STATE_IS_INDEXBUFFER(state))
return "STATE_INDEXBUFFER";
if (STATE_IS_VDECL(state))
return "STATE_VDECL";
if (STATE_IS_VSHADER(state))
return "STATE_VSHADER";
if (STATE_IS_VIEWPORT(state))
return "STATE_VIEWPORT";
if (STATE_IS_VERTEXSHADERCONSTANT(state))
return "STATE_VERTEXSHADERCONSTANT";
if (STATE_IS_PIXELSHADERCONSTANT(state))
return "STATE_PIXELSHADERCONSTANT";
if (STATE_IS_ACTIVELIGHT(state))
return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
if (STATE_IS_SCISSORRECT(state))
return "STATE_SCISSORRECT";
if (STATE_IS_CLIPPLANE(state))
return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
if (STATE_IS_MATERIAL(state))
return "STATE_MATERIAL";
if (STATE_IS_FRONTFACE(state))
return "STATE_FRONTFACE";
return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
}
const char* debug_d3dpool(WINED3DPOOL Pool) {
switch (Pool) {
#define POOL_TO_STR(p) case p: return #p
@ -1868,8 +1916,8 @@ static const char *debug_fixup_channel_source(enum fixup_channel_source source)
WINED3D_TO_STR(CHANNEL_SOURCE_Y);
WINED3D_TO_STR(CHANNEL_SOURCE_Z);
WINED3D_TO_STR(CHANNEL_SOURCE_W);
WINED3D_TO_STR(CHANNEL_SOURCE_YUV0);
WINED3D_TO_STR(CHANNEL_SOURCE_YUV1);
WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
#undef WINED3D_TO_STR
default:
FIXME("Unrecognized fixup_channel_source %#x\n", source);
@ -1877,26 +1925,27 @@ static const char *debug_fixup_channel_source(enum fixup_channel_source source)
}
}
static const char *debug_yuv_fixup(enum yuv_fixup yuv_fixup)
static const char *debug_complex_fixup(enum complex_fixup fixup)
{
switch(yuv_fixup)
switch(fixup)
{
#define WINED3D_TO_STR(x) case x: return #x
WINED3D_TO_STR(YUV_FIXUP_YUY2);
WINED3D_TO_STR(YUV_FIXUP_UYVY);
WINED3D_TO_STR(YUV_FIXUP_YV12);
WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
WINED3D_TO_STR(COMPLEX_FIXUP_P8);
#undef WINED3D_TO_STR
default:
FIXME("Unrecognized YUV fixup %#x\n", yuv_fixup);
FIXME("Unrecognized complex fixup %#x\n", fixup);
return "unrecognized";
}
}
void dump_color_fixup_desc(struct color_fixup_desc fixup)
{
if (is_yuv_fixup(fixup))
if (is_complex_fixup(fixup))
{
TRACE("\tYUV: %s\n", debug_yuv_fixup(get_yuv_fixup(fixup)));
TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
return;
}
@ -2795,40 +2844,3 @@ void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected,
else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
else *ps_selected = SHADER_NONE;
}
const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter, WINED3DDEVTYPE device_type)
{
int vs_selected_mode, ps_selected_mode;
select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
return &none_shader_backend;
}
const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter,
WINED3DDEVTYPE device_type)
{
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
int vs_selected_mode, ps_selected_mode;
select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
&& gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
else if (gl_info->supported[NV_REGISTER_COMBINERS]
&& gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
else return &ffp_fragment_pipeline;
}
const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter, WINED3DDEVTYPE device_type)
{
const struct wined3d_gl_info *gl_info = &adapter->gl_info;
int vs_selected_mode, ps_selected_mode;
select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
&& gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
else return &ffp_blit;
}

View file

@ -16,7 +16,6 @@
<file>ati_fragment_shader.c</file>
<file>arb_program_shader.c</file>
<file>baseshader.c</file>
<file>basetexture.c</file>
<file>buffer.c</file>
<file>clipper.c</file>

File diff suppressed because it is too large Load diff

View file

@ -61,15 +61,16 @@ enum fixup_channel_source
CHANNEL_SOURCE_Y = 3,
CHANNEL_SOURCE_Z = 4,
CHANNEL_SOURCE_W = 5,
CHANNEL_SOURCE_YUV0 = 6,
CHANNEL_SOURCE_YUV1 = 7,
CHANNEL_SOURCE_COMPLEX0 = 6,
CHANNEL_SOURCE_COMPLEX1 = 7,
};
enum yuv_fixup
enum complex_fixup
{
YUV_FIXUP_YUY2 = 0,
YUV_FIXUP_UYVY = 1,
YUV_FIXUP_YV12 = 2,
COMPLEX_FIXUP_YUY2 = 0,
COMPLEX_FIXUP_UYVY = 1,
COMPLEX_FIXUP_YV12 = 2,
COMPLEX_FIXUP_P8 = 3,
};
#include <pshpack2.h>
@ -103,14 +104,14 @@ static inline struct color_fixup_desc create_color_fixup_desc(
return fixup;
}
static inline struct color_fixup_desc create_yuv_fixup_desc(enum yuv_fixup yuv_fixup)
static inline struct color_fixup_desc create_complex_fixup_desc(enum complex_fixup complex_fixup)
{
struct color_fixup_desc fixup =
{
0, yuv_fixup & (1 << 0) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 1) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 2) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, yuv_fixup & (1 << 3) ? CHANNEL_SOURCE_YUV1 : CHANNEL_SOURCE_YUV0,
0, complex_fixup & (1 << 0) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
0, complex_fixup & (1 << 1) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
0, complex_fixup & (1 << 2) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
0, complex_fixup & (1 << 3) ? CHANNEL_SOURCE_COMPLEX1 : CHANNEL_SOURCE_COMPLEX0,
};
return fixup;
}
@ -120,19 +121,19 @@ static inline BOOL is_identity_fixup(struct color_fixup_desc fixup)
return !memcmp(&fixup, &COLOR_FIXUP_IDENTITY, sizeof(fixup));
}
static inline BOOL is_yuv_fixup(struct color_fixup_desc fixup)
static inline BOOL is_complex_fixup(struct color_fixup_desc fixup)
{
return fixup.x_source == CHANNEL_SOURCE_YUV0 || fixup.x_source == CHANNEL_SOURCE_YUV1;
return fixup.x_source == CHANNEL_SOURCE_COMPLEX0 || fixup.x_source == CHANNEL_SOURCE_COMPLEX1;
}
static inline enum yuv_fixup get_yuv_fixup(struct color_fixup_desc fixup)
static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup)
{
enum yuv_fixup yuv_fixup = 0;
if (fixup.x_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 0);
if (fixup.y_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 1);
if (fixup.z_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 2);
if (fixup.w_source == CHANNEL_SOURCE_YUV1) yuv_fixup |= (1 << 3);
return yuv_fixup;
enum complex_fixup complex_fixup = 0;
if (fixup.x_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 0);
if (fixup.y_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 1);
if (fixup.z_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 2);
if (fixup.w_source == CHANNEL_SOURCE_COMPLEX1) complex_fixup |= (1 << 3);
return complex_fixup;
}
void *wined3d_rb_alloc(size_t size) DECLSPEC_HIDDEN;
@ -410,6 +411,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
WINED3DSIH_CMP,
WINED3DSIH_CND,
WINED3DSIH_CRS,
WINED3DSIH_CUT,
WINED3DSIH_DCL,
WINED3DSIH_DEF,
WINED3DSIH_DEFB,
@ -421,20 +423,24 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
WINED3DSIH_DSX,
WINED3DSIH_DSY,
WINED3DSIH_ELSE,
WINED3DSIH_EMIT,
WINED3DSIH_ENDIF,
WINED3DSIH_ENDLOOP,
WINED3DSIH_ENDREP,
WINED3DSIH_EXP,
WINED3DSIH_EXPP,
WINED3DSIH_FRC,
WINED3DSIH_IADD,
WINED3DSIH_IF,
WINED3DSIH_IFC,
WINED3DSIH_IGE,
WINED3DSIH_LABEL,
WINED3DSIH_LIT,
WINED3DSIH_LOG,
WINED3DSIH_LOGP,
WINED3DSIH_LOOP,
WINED3DSIH_LRP,
WINED3DSIH_LT,
WINED3DSIH_M3x2,
WINED3DSIH_M3x3,
WINED3DSIH_M3x4,
@ -544,6 +550,7 @@ typedef struct shader_reg_maps
struct wined3d_shader_context
{
IWineD3DBaseShader *shader;
const struct wined3d_gl_info *gl_info;
const struct shader_reg_maps *reg_maps;
struct wined3d_shader_buffer *buffer;
void *backend_data;
@ -619,7 +626,7 @@ struct wined3d_shader_frontend
void (*shader_read_dst_param)(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
struct wined3d_shader_src_param *dst_rel_addr);
void (*shader_read_semantic)(const DWORD **ptr, struct wined3d_shader_semantic *semantic);
void (*shader_read_comment)(const DWORD **ptr, const char **comment);
void (*shader_read_comment)(const DWORD **ptr, const char **comment, UINT *comment_size);
BOOL (*shader_is_end)(void *data, const DWORD **ptr);
};
@ -714,7 +721,7 @@ typedef struct {
HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
void (*shader_free_private)(IWineD3DDevice *iface);
BOOL (*shader_dirtifyable_constants)(IWineD3DDevice *iface);
void (*shader_get_caps)(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
void (*shader_get_caps)(const struct wined3d_gl_info *gl_info, struct shader_caps *caps);
BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
void (*shader_add_instruction_modifiers)(const struct wined3d_shader_instruction *ins);
} shader_backend_t;
@ -988,8 +995,10 @@ extern glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT] DECLSPEC
#define STATE_IS_CLIPPLANE(a) ((a) >= STATE_CLIPPLANE(0) && (a) <= STATE_CLIPPLANE(MAX_CLIPPLANES - 1))
#define STATE_MATERIAL (STATE_CLIPPLANE(MAX_CLIPPLANES))
#define STATE_IS_MATERIAL(a) ((a) == STATE_MATERIAL)
#define STATE_FRONTFACE (STATE_MATERIAL + 1)
#define STATE_IS_FRONTFACE(a) ((a) == STATE_FRONTFACE)
#define STATE_HIGHEST (STATE_FRONTFACE)
@ -1008,13 +1017,28 @@ struct wined3d_occlusion_query
struct wined3d_context *context;
};
union wined3d_gl_query_object
{
GLuint id;
GLsync sync;
};
struct wined3d_event_query
{
struct list entry;
GLuint id;
union wined3d_gl_query_object object;
struct wined3d_context *context;
};
enum wined3d_event_query_result
{
WINED3D_EVENT_QUERY_OK,
WINED3D_EVENT_QUERY_WAITING,
WINED3D_EVENT_QUERY_NOT_STARTED,
WINED3D_EVENT_QUERY_WRONG_THREAD,
WINED3D_EVENT_QUERY_ERROR
};
struct wined3d_context
{
const struct wined3d_gl_info *gl_info;
@ -1084,7 +1108,7 @@ struct wined3d_context
UINT free_occlusion_query_count;
struct list occlusion_queries;
GLuint *free_event_queries;
union wined3d_gl_query_object *free_event_queries;
UINT free_event_query_size;
UINT free_event_query_count;
struct list event_queries;
@ -1122,7 +1146,7 @@ struct fragment_caps
struct fragment_pipeline
{
void (*enable_extension)(IWineD3DDevice *iface, BOOL enable);
void (*get_caps)(WINED3DDEVTYPE devtype, const struct wined3d_gl_info *gl_info, struct fragment_caps *caps);
void (*get_caps)(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps);
HRESULT (*alloc_private)(IWineD3DDevice *iface);
void (*free_private)(IWineD3DDevice *iface);
BOOL (*color_fixup_supported)(struct color_fixup_desc fixup);
@ -1224,7 +1248,7 @@ typedef struct WineD3D_PixelFormat
{
int iPixelFormat; /* WGL pixel format */
int iPixelType; /* WGL pixel type e.g. WGL_TYPE_RGBA_ARB, WGL_TYPE_RGBA_FLOAT_ARB or WGL_TYPE_COLORINDEX_ARB */
int redSize, greenSize, blueSize, alphaSize;
int redSize, greenSize, blueSize, alphaSize, colorSize;
int depthSize, stencilSize;
BOOL windowDrawable;
BOOL pbufferDrawable;
@ -1233,13 +1257,23 @@ typedef struct WineD3D_PixelFormat
int numSamples;
} WineD3D_PixelFormat;
enum wined3d_gl_vendor
{
GL_VENDOR_WINE,
GL_VENDOR_APPLE,
GL_VENDOR_ATI,
GL_VENDOR_INTEL,
GL_VENDOR_MESA,
GL_VENDOR_NVIDIA,
};
enum wined3d_pci_vendor
{
VENDOR_WINE = 0x0000,
VENDOR_MESA = 0x0001,
VENDOR_ATI = 0x1002,
VENDOR_NVIDIA = 0x10de,
VENDOR_INTEL = 0x8086,
HW_VENDOR_WINE = 0x0000,
HW_VENDOR_ATI = 0x1002,
HW_VENDOR_NVIDIA = 0x10de,
HW_VENDOR_INTEL = 0x8086,
};
enum wined3d_pci_device
@ -1323,6 +1357,85 @@ enum wined3d_pci_device
CARD_INTEL_X3100 = 0x2a02, /* Found in Macs. Same as GMA 965? */
};
struct wined3d_fbo_ops
{
PGLFNGLISRENDERBUFFERPROC glIsRenderbuffer;
PGLFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
PGLFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
PGLFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
PGLFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
PGLFNRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
PGLFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
PGLFNGLISFRAMEBUFFERPROC glIsFramebuffer;
PGLFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PGLFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PGLFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PGLFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PGLFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
PGLFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PGLFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
PGLFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
PGLFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
PGLFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PGLFNGLGENERATEMIPMAPPROC glGenerateMipmap;
};
struct wined3d_gl_limits
{
UINT buffers;
UINT lights;
UINT textures;
UINT texture_stages;
UINT fragment_samplers;
UINT vertex_samplers;
UINT combined_samplers;
UINT general_combiners;
UINT sampler_stages;
UINT clipplanes;
UINT texture_size;
UINT texture3d_size;
float pointsize_max;
float pointsize_min;
UINT point_sprite_units;
UINT blends;
UINT anisotropy;
float shininess;
UINT glsl_varyings;
UINT glsl_vs_float_constants;
UINT glsl_ps_float_constants;
UINT arb_vs_float_constants;
UINT arb_vs_native_constants;
UINT arb_vs_instructions;
UINT arb_vs_temps;
UINT arb_ps_float_constants;
UINT arb_ps_local_constants;
UINT arb_ps_native_constants;
UINT arb_ps_instructions;
UINT arb_ps_temps;
};
struct wined3d_gl_info
{
UINT vidmem;
struct wined3d_gl_limits limits;
DWORD reserved_glsl_constants;
DWORD quirks;
BOOL supported[WINED3D_GL_EXT_COUNT];
GLint wrap_lookup[WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP + 1];
struct wined3d_fbo_ops fbo_ops;
#define USE_GL_FUNC(type, pfn, ext, replace) type pfn;
/* GL function pointers */
GL_EXT_FUNCS_GEN
/* WGL function pointers */
WGL_EXT_FUNCS_GEN
#undef USE_GL_FUNC
struct GlPixelFormatDesc *gl_formats;
};
struct wined3d_driver_info
{
enum wined3d_pci_vendor vendor;
@ -1348,6 +1461,10 @@ struct wined3d_adapter
unsigned int TextureRam; /* Amount of texture memory both video ram + AGP/TurboCache/HyperMemory/.. */
unsigned int UsedTextureRam;
LUID luid;
const struct fragment_pipeline *fragment_pipe;
const shader_backend_t *shader_backend;
const struct blit_shader *blitter;
};
BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor) DECLSPEC_HIDDEN;
@ -1497,7 +1614,7 @@ struct IWineD3DDeviceImpl
const struct fragment_pipeline *frag_pipe;
const struct blit_shader *blitter;
unsigned int max_ffp_textures, max_ffp_texture_stages;
unsigned int max_ffp_textures;
DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
DWORD vs_clipping;
@ -1547,7 +1664,6 @@ struct IWineD3DDeviceImpl
UINT NumberOfPalettes;
PALETTEENTRY **palettes;
UINT currentPalette;
UINT paletteConversionShader;
/* For rendering to a texture using glCopyTexImage */
GLenum *draw_buffers;
@ -1602,14 +1718,14 @@ struct IWineD3DDeviceImpl
HRESULT device_init(IWineD3DDeviceImpl *device, IWineD3DImpl *wined3d,
UINT adapter_idx, WINED3DDEVTYPE device_type, HWND focus_window, DWORD flags,
IUnknown *parent, IWineD3DDeviceParent *device_parent) DECLSPEC_HIDDEN;
void device_preload_textures(IWineD3DDeviceImpl *device) DECLSPEC_HIDDEN;
LRESULT device_process_message(IWineD3DDeviceImpl *device, HWND window,
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
void device_resource_add(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN;
void device_resource_released(IWineD3DDeviceImpl *This, IWineD3DResource *resource) DECLSPEC_HIDDEN;
void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) DECLSPEC_HIDDEN;
void device_stream_info_from_strided(const struct wined3d_gl_info *gl_info,
const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info) DECLSPEC_HIDDEN;
void device_update_stream_info(IWineD3DDeviceImpl *device, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count,
const WINED3DRECT *pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil) DECLSPEC_HIDDEN;
void IWineD3DDeviceImpl_FindTexUnitMap(IWineD3DDeviceImpl *This) DECLSPEC_HIDDEN;
@ -1745,6 +1861,7 @@ typedef struct IWineD3DBaseTextureClass
void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb) DECLSPEC_HIDDEN;
BOOL surface_init_sysmem(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
BOOL surface_is_offscreen(IWineD3DSurface *iface) DECLSPEC_HIDDEN;
void surface_prepare_texture(IWineD3DSurfaceImpl *surface, BOOL srgb) DECLSPEC_HIDDEN;
typedef struct IWineD3DBaseTextureImpl
{
@ -2342,9 +2459,8 @@ typedef struct IWineD3DQueryImpl
void *extendedData;
} IWineD3DQueryImpl;
extern const IWineD3DQueryVtbl IWineD3DQuery_Vtbl DECLSPEC_HIDDEN;
extern const IWineD3DQueryVtbl IWineD3DEventQuery_Vtbl DECLSPEC_HIDDEN;
extern const IWineD3DQueryVtbl IWineD3DOcclusionQuery_Vtbl DECLSPEC_HIDDEN;
HRESULT query_init(IWineD3DQueryImpl *query, IWineD3DDeviceImpl *device,
WINED3DQUERYTYPE type, IUnknown *parent) DECLSPEC_HIDDEN;
/* IWineD3DBuffer */
@ -2495,6 +2611,7 @@ const char *debug_d3ddeclusage(BYTE usage) DECLSPEC_HIDDEN;
const char *debug_d3dprimitivetype(WINED3DPRIMITIVETYPE PrimitiveType) DECLSPEC_HIDDEN;
const char *debug_d3drenderstate(DWORD state) DECLSPEC_HIDDEN;
const char *debug_d3dsamplerstate(DWORD state) DECLSPEC_HIDDEN;
const char *debug_d3dstate(DWORD state) DECLSPEC_HIDDEN;
const char *debug_d3dtexturefiltertype(WINED3DTEXTUREFILTERTYPE filter_type) DECLSPEC_HIDDEN;
const char *debug_d3dtexturestate(DWORD state) DECLSPEC_HIDDEN;
const char *debug_d3dtstype(WINED3DTRANSFORMSTATETYPE tstype) DECLSPEC_HIDDEN;
@ -2552,12 +2669,6 @@ void multiply_matrix(WINED3DMATRIX *dest, const WINED3DMATRIX *src1, const WINED
UINT wined3d_log2i(UINT32 x) DECLSPEC_HIDDEN;
unsigned int count_bits(unsigned int mask) DECLSPEC_HIDDEN;
const struct blit_shader *select_blit_implementation(struct wined3d_adapter *adapter,
WINED3DDEVTYPE device_type) DECLSPEC_HIDDEN;
const struct fragment_pipeline *select_fragment_implementation(struct wined3d_adapter *adapter,
WINED3DDEVTYPE device_type) DECLSPEC_HIDDEN;
const shader_backend_t *select_shader_backend(struct wined3d_adapter *adapter,
WINED3DDEVTYPE device_type) DECLSPEC_HIDDEN;
void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected) DECLSPEC_HIDDEN;
typedef struct local_constant {
@ -2601,8 +2712,6 @@ int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *fmt, va_li
extern BOOL vshader_get_input(IWineD3DVertexShader *iface,
BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN;
extern HRESULT allocate_shader_constants(IWineD3DStateBlockImpl* object) DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirect3DBaseShader implementation structure
*/
@ -2651,7 +2760,6 @@ typedef struct IWineD3DBaseShaderImpl {
void shader_buffer_clear(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
void shader_buffer_free(struct wined3d_shader_buffer *buffer) DECLSPEC_HIDDEN;
void shader_cleanup(IWineD3DBaseShader *iface) DECLSPEC_HIDDEN;
void shader_dump_src_param(const struct wined3d_shader_src_param *param,
const struct wined3d_shader_version *shader_version) DECLSPEC_HIDDEN;
void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
@ -2659,16 +2767,7 @@ void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
unsigned int shader_find_free_input_register(const struct shader_reg_maps *reg_maps, unsigned int max) DECLSPEC_HIDDEN;
void shader_generate_main(IWineD3DBaseShader *iface, struct wined3d_shader_buffer *buffer,
const shader_reg_maps *reg_maps, const DWORD *pFunction, void *backend_ctx) DECLSPEC_HIDDEN;
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
struct shader_reg_maps *reg_maps, struct wined3d_shader_signature_element *input_signature,
struct wined3d_shader_signature_element *output_signature,
const DWORD *byte_code, DWORD constf_size) DECLSPEC_HIDDEN;
void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDeviceImpl *device,
IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
BOOL shader_match_semantic(const char *semantic_name, WINED3DDECLUSAGE usage) DECLSPEC_HIDDEN;
const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token) DECLSPEC_HIDDEN;
void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction) DECLSPEC_HIDDEN;
WINED3DDECLUSAGE shader_usage_from_semantic_name(const char *semantic_name) DECLSPEC_HIDDEN;
static inline BOOL shader_is_pshader_version(enum wined3d_shader_type type)
{

View file

@ -5,6 +5,9 @@
#define __WINE_CONFIG_H
/* Define to a function attribute for Microsoft hotpatch assembly prefix. */
#define DECLSPEC_HOTPATCH
/* Specifies the compiler flag that forces a short wchar_t */
#define CC_FLAG_SHORT_WCHAR "-fshort-wchar"

View file

@ -26,6 +26,7 @@
import "unknwn.idl";
cpp_quote("#if 0")
typedef HANDLE HMONITOR;
typedef struct _RGNDATAHEADER
{
@ -134,6 +135,10 @@ typedef enum _WINED3DDEGREETYPE
WINED3DDEGREE_FORCE_DWORD = 0x7fffffff
} WINED3DDEGREETYPE;
#define WINEMAKEFOURCC(ch0, ch1, ch2, ch3) \
((unsigned long)(unsigned char)(ch0) | ((unsigned long)(unsigned char)(ch1) << 8) | \
((unsigned long)(unsigned char)(ch2) << 16) | ((unsigned long)(unsigned char)(ch3) << 24))
typedef enum _WINED3DFORMAT
{
WINED3DFMT_UNKNOWN,
@ -253,21 +258,21 @@ typedef enum _WINED3DFORMAT
WINED3DFMT_B8G8R8A8_UNORM,
WINED3DFMT_B8G8R8X8_UNORM,
/* FOURCC formats. */
WINED3DFMT_UYVY = 0x59565955, /* UYVY */
WINED3DFMT_YUY2 = 0x32595559, /* YUY2 */
WINED3DFMT_YV12 = 0x32315659, /* YV12 */
WINED3DFMT_DXT1 = 0x31545844, /* DXT1 */
WINED3DFMT_DXT2 = 0x32545844, /* DXT2 */
WINED3DFMT_DXT3 = 0x33545844, /* DXT3 */
WINED3DFMT_DXT4 = 0x34545844, /* DXT4 */
WINED3DFMT_DXT5 = 0x35545844, /* DXT5 */
WINED3DFMT_MULTI2_ARGB8 = 0x3154454d, /* MET1 */
WINED3DFMT_G8R8_G8B8 = 0x42475247, /* GRGB */
WINED3DFMT_R8G8_B8G8 = 0x47424752, /* RGBG */
WINED3DFMT_ATI2N = 0x32495441, /* ATI2 */
WINED3DFMT_INST = 0x54534e49, /* INST */
WINED3DFMT_NVHU = 0x5548564e, /* NVHU */
WINED3DFMT_NVHS = 0x5348564e, /* NVHS */
WINED3DFMT_UYVY = WINEMAKEFOURCC('U','Y','V','Y'),
WINED3DFMT_YUY2 = WINEMAKEFOURCC('Y','U','Y','2'),
WINED3DFMT_YV12 = WINEMAKEFOURCC('Y','V','1','2'),
WINED3DFMT_DXT1 = WINEMAKEFOURCC('D','X','T','1'),
WINED3DFMT_DXT2 = WINEMAKEFOURCC('D','X','T','2'),
WINED3DFMT_DXT3 = WINEMAKEFOURCC('D','X','T','3'),
WINED3DFMT_DXT4 = WINEMAKEFOURCC('D','X','T','4'),
WINED3DFMT_DXT5 = WINEMAKEFOURCC('D','X','T','5'),
WINED3DFMT_MULTI2_ARGB8 = WINEMAKEFOURCC('M','E','T','1'),
WINED3DFMT_G8R8_G8B8 = WINEMAKEFOURCC('G','R','G','B'),
WINED3DFMT_R8G8_B8G8 = WINEMAKEFOURCC('R','G','B','G'),
WINED3DFMT_ATI2N = WINEMAKEFOURCC('A','T','I','2'),
WINED3DFMT_INST = WINEMAKEFOURCC('I','N','S','T'),
WINED3DFMT_NVHU = WINEMAKEFOURCC('N','V','H','U'),
WINED3DFMT_NVHS = WINEMAKEFOURCC('N','V','H','S'),
WINED3DFMT_FORCE_DWORD = 0xffffffff
} WINED3DFORMAT;