diff --git a/reactos/dll/directx/wine/d3d8/d3d8_private.h b/reactos/dll/directx/wine/d3d8/d3d8_private.h index cbd6f761668..c9afe173ab9 100644 --- a/reactos/dll/directx/wine/d3d8/d3d8_private.h +++ b/reactos/dll/directx/wine/d3d8/d3d8_private.h @@ -326,6 +326,8 @@ struct IDirect3DVertexBuffer8Impl /* Parent reference */ LPDIRECT3DDEVICE8 parentDevice; + + DWORD fvf; }; /* --------------------- */ @@ -347,10 +349,12 @@ struct IDirect3DIndexBuffer8Impl LONG ref; /* IDirect3DResource8 fields */ - IWineD3DIndexBuffer *wineD3DIndexBuffer; + IWineD3DBuffer *wineD3DIndexBuffer; /* Parent reference */ LPDIRECT3DDEVICE8 parentDevice; + + WINED3DFORMAT format; }; /* --------------------- */ diff --git a/reactos/dll/directx/wine/d3d8/device.c b/reactos/dll/directx/wine/d3d8/device.c index 0e8c480700b..985557c8d78 100644 --- a/reactos/dll/directx/wine/d3d8/device.c +++ b/reactos/dll/directx/wine/d3d8/device.c @@ -737,8 +737,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8 object->lpVtbl = &Direct3DVertexBuffer8_Vtbl; object->ref = 1; EnterCriticalSection(&d3d8_cs); - hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL, (IUnknown *)object); + hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, + 0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL, + (IUnknown *)object); LeaveCriticalSection(&d3d8_cs); + object->fvf = FVF; if (D3D_OK != hrc) { @@ -770,10 +773,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i object->lpVtbl = &Direct3DIndexBuffer8_Vtbl; object->ref = 1; + object->format = wined3dformat_from_d3dformat(Format); TRACE("Calling wined3d create index buffer\n"); EnterCriticalSection(&d3d8_cs); hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK, - wined3dformat_from_d3dformat(Format), (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, + (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer, NULL, (IUnknown *)object); LeaveCriticalSection(&d3d8_cs); @@ -1661,10 +1665,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; HRESULT hr; + IDirect3DVertexBuffer8Impl *dest = (IDirect3DVertexBuffer8Impl *) pDestBuffer; TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer8Impl *)pDestBuffer)->wineD3DVertexBuffer, NULL, Flags); + hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, NULL, Flags, dest->fvf); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -2081,6 +2086,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEV static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; HRESULT hr; + IDirect3DIndexBuffer8Impl *ib = (IDirect3DIndexBuffer8Impl *)pIndexData; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); @@ -2092,14 +2098,15 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, I */ IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex); hr = IWineD3DDevice_SetIndices(This->WineD3DDevice, - pIndexData ? ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer : NULL); + ib ? ib->wineD3DIndexBuffer : NULL, + ib ? ib->format : WINED3DFMT_UNKNOWN); LeaveCriticalSection(&d3d8_cs); return hr; } static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) { IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface; - IWineD3DIndexBuffer *retIndexData = NULL; + IWineD3DBuffer *retIndexData = NULL; HRESULT rc = D3D_OK; TRACE("(%p) Relay\n", This); @@ -2113,8 +2120,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex); rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData); if (SUCCEEDED(rc) && retIndexData) { - IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); - IWineD3DIndexBuffer_Release(retIndexData); + IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); + IWineD3DBuffer_Release(retIndexData); } else { if (FAILED(rc)) FIXME("Call to GetIndices failed\n"); *ppIndexData = NULL; diff --git a/reactos/dll/directx/wine/d3d8/directx.c b/reactos/dll/directx/wine/d3d8/directx.c index 45d914b6276..64fc3605d43 100644 --- a/reactos/dll/directx/wine/d3d8/directx.c +++ b/reactos/dll/directx/wine/d3d8/directx.c @@ -188,11 +188,23 @@ static HRESULT WINAPI IDirect3D8Impl_CheckDeviceFormat (LPDIRECT3D8 i DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { IDirect3D8Impl *This = (IDirect3D8Impl *)iface; HRESULT hr; + WINED3DRESOURCETYPE WineD3DRType; TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); + switch(RType) { + case D3DRTYPE_VERTEXBUFFER: + case D3DRTYPE_INDEXBUFFER: + WineD3DRType = WINED3DRTYPE_BUFFER; + break; + + default: + WineD3DRType = RType; + break; + } + EnterCriticalSection(&d3d8_cs); hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat), - Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL); + Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL); LeaveCriticalSection(&d3d8_cs); return hr; } diff --git a/reactos/dll/directx/wine/d3d8/indexbuffer.c b/reactos/dll/directx/wine/d3d8/indexbuffer.c index 8a0a1552f24..a0de5c5caf0 100644 --- a/reactos/dll/directx/wine/d3d8/indexbuffer.c +++ b/reactos/dll/directx/wine/d3d8/indexbuffer.c @@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 ifa if (ref == 0) { EnterCriticalSection(&d3d8_cs); - IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer); + IWineD3DBuffer_Release(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d8_cs); IUnknown_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); @@ -73,7 +73,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device); + hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device); if (SUCCEEDED(hr)) { IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice); @@ -89,7 +89,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBU TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags); + hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -100,7 +100,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBU TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData); + hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -111,7 +111,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXB TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid); + hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -122,7 +122,7 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - ret = IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew); + ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew); LeaveCriticalSection(&d3d8_cs); return ret; } @@ -133,7 +133,7 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - ret = IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer); + ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d8_cs); return ret; } @@ -143,19 +143,15 @@ static void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 ifac TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer); + IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d8_cs); } static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; - D3DRESOURCETYPE type; - TRACE("(%p) Relay\n", This); + TRACE("(%p)\n", This); - EnterCriticalSection(&d3d8_cs); - type = IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer); - LeaveCriticalSection(&d3d8_cs); - return type; + return D3DRTYPE_INDEXBUFFER; } /* IDirect3DIndexBuffer8 Interface follow: */ @@ -165,7 +161,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 ifac TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); + hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -176,7 +172,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer); + hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d8_cs); return hr; } @@ -184,13 +180,20 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 iface, D3DINDEXBUFFER_DESC *pDesc) { IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface; HRESULT hr; + WINED3DBUFFER_DESC desc; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc); LeaveCriticalSection(&d3d8_cs); - if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); + if (SUCCEEDED(hr)) { + pDesc->Format = d3dformat_from_wined3dformat(This->format); + pDesc->Type = D3DRTYPE_INDEXBUFFER; + pDesc->Usage = desc.Usage; + pDesc->Pool = desc.Pool; + pDesc->Size = desc.Size; + } return hr; } diff --git a/reactos/dll/directx/wine/d3d8/vertexbuffer.c b/reactos/dll/directx/wine/d3d8/vertexbuffer.c index 74d6dca9130..a282cda6bf2 100644 --- a/reactos/dll/directx/wine/d3d8/vertexbuffer.c +++ b/reactos/dll/directx/wine/d3d8/vertexbuffer.c @@ -151,13 +151,9 @@ static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 if static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; - D3DRESOURCETYPE type; - TRACE("(%p) Relay\n", This); + TRACE("(%p)\n", This); - EnterCriticalSection(&d3d8_cs); - type = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer); - LeaveCriticalSection(&d3d8_cs); - return type; + return D3DRTYPE_VERTEXBUFFER; } /* IDirect3DVertexBuffer8 Interface follow: */ @@ -186,13 +182,21 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8 static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 iface, D3DVERTEXBUFFER_DESC *pDesc) { IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface; HRESULT hr; + WINED3DBUFFER_DESC desc; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d8_cs); - hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc); LeaveCriticalSection(&d3d8_cs); - if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); + if (SUCCEEDED(hr)) { + pDesc->Type = D3DRTYPE_VERTEXBUFFER; + pDesc->Usage = desc.Usage; + pDesc->Pool = desc.Pool; + pDesc->Size = desc.Size; + pDesc->FVF = This->fvf; + pDesc->Format = D3DFMT_VERTEXDATA; + } return hr; } diff --git a/reactos/dll/directx/wine/d3d9/Makefile.in b/reactos/dll/directx/wine/d3d9/Makefile.in deleted file mode 100644 index f581b68eb8c..00000000000 --- a/reactos/dll/directx/wine/d3d9/Makefile.in +++ /dev/null @@ -1,33 +0,0 @@ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -MODULE = d3d9.dll -IMPORTLIB = d3d9 -IMPORTS = dxguid uuid wined3d kernel32 - -C_SRCS = \ - basetexture.c \ - cubetexture.c \ - d3d9_main.c \ - device.c \ - directx.c \ - indexbuffer.c \ - pixelshader.c \ - query.c \ - resource.c \ - stateblock.c \ - surface.c \ - swapchain.c \ - texture.c \ - vertexbuffer.c \ - vertexdeclaration.c \ - vertexshader.c \ - volume.c \ - volumetexture.c - -RC_SRCS = version.rc - -@MAKE_DLL_RULES@ - -@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/reactos/dll/directx/wine/d3d9/d3d9_private.h b/reactos/dll/directx/wine/d3d9/d3d9_private.h index ac6cfaad425..25b6ae2434a 100644 --- a/reactos/dll/directx/wine/d3d9/d3d9_private.h +++ b/reactos/dll/directx/wine/d3d9/d3d9_private.h @@ -329,6 +329,8 @@ typedef struct IDirect3DVertexBuffer9Impl /* Parent reference */ LPDIRECT3DDEVICE9EX parentDevice; + + DWORD fvf; } IDirect3DVertexBuffer9Impl; /* --------------------- */ @@ -345,10 +347,11 @@ typedef struct IDirect3DIndexBuffer9Impl LONG ref; /* IDirect3DResource9 fields */ - IWineD3DIndexBuffer *wineD3DIndexBuffer; + IWineD3DBuffer *wineD3DIndexBuffer; /* Parent reference */ LPDIRECT3DDEVICE9EX parentDevice; + WINED3DFORMAT format; } IDirect3DIndexBuffer9Impl; /* --------------------- */ diff --git a/reactos/dll/directx/wine/d3d9/device.c b/reactos/dll/directx/wine/d3d9/device.c index a917884763d..8d88e5227bd 100644 --- a/reactos/dll/directx/wine/d3d9/device.c +++ b/reactos/dll/directx/wine/d3d9/device.c @@ -428,17 +428,18 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data HRESULT ret = S_OK; WINED3DSURFACE_DESC surface_desc; WINED3DVOLUME_DESC volume_desc; - WINED3DINDEXBUFFER_DESC index_desc; - WINED3DVERTEXBUFFER_DESC vertex_desc; + D3DINDEXBUFFER_DESC index_desc; + D3DVERTEXBUFFER_DESC vertex_desc; WINED3DFORMAT dummy_format; WINED3DMULTISAMPLE_TYPE dummy_multisampletype; DWORD dummy_dword; WINED3DPOOL pool = WINED3DPOOL_SCRATCH; /* a harmless pool */ - IUnknown *parent; + IDirect3DResource9 *parent; - type = IWineD3DResource_GetType(resource); + IWineD3DResource_GetParent(resource, (IUnknown **) &parent); + type = IDirect3DResource9_GetType(parent); switch(type) { - case WINED3DRTYPE_SURFACE: + case D3DRTYPE_SURFACE: surface_desc.Format = &dummy_format; surface_desc.Type = &type; surface_desc.Usage = &dummy_dword; @@ -452,7 +453,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc); break; - case WINED3DRTYPE_VOLUME: + case D3DRTYPE_VOLUME: volume_desc.Format = &dummy_format; volume_desc.Type = &type; volume_desc.Usage = &dummy_dword; @@ -464,13 +465,13 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc); break; - case WINED3DRTYPE_INDEXBUFFER: - IWineD3DIndexBuffer_GetDesc((IWineD3DIndexBuffer *) resource, &index_desc); + case D3DRTYPE_INDEXBUFFER: + IDirect3DIndexBuffer9_GetDesc((IDirect3DIndexBuffer9 *) parent, &index_desc); pool = index_desc.Pool; break; - case WINED3DRTYPE_VERTEXBUFFER: - IWineD3DBuffer_GetDesc((IWineD3DBuffer *)resource, &vertex_desc); + case D3DRTYPE_VERTEXBUFFER: + IDirect3DVertexBuffer9_GetDesc((IDirect3DVertexBuffer9 *)parent, &vertex_desc); pool = vertex_desc.Pool; break; @@ -482,7 +483,6 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data } if(pool == WINED3DPOOL_DEFAULT) { - IWineD3DResource_GetParent(resource, &parent); if(IUnknown_Release(parent) == 0) { TRACE("Parent %p is an implicit resource with ref 0\n", parent); } else { @@ -490,6 +490,8 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data ret = S_FALSE; *resources_ok = FALSE; } + } else { + IUnknown_Release(parent); } IWineD3DResource_Release(resource); @@ -514,8 +516,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3 * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls */ EnterCriticalSection(&d3d9_cs); - - IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL); + IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN); for(i = 0; i < 16; i++) { IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0); } @@ -1447,10 +1448,11 @@ static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl; HRESULT hr; + IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer; TRACE("(%p) Relay\n" , This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer9Impl *)pDestBuffer)->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags); + hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -1636,18 +1638,20 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVIC static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9* pIndexData) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; HRESULT hr; + IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); hr = IWineD3DDevice_SetIndices(This->WineD3DDevice, - pIndexData ? ((IDirect3DIndexBuffer9Impl *)pIndexData)->wineD3DIndexBuffer : NULL); + ib ? ib->wineD3DIndexBuffer : NULL, + ib ? ib->format : WINED3DFMT_UNKNOWN); LeaveCriticalSection(&d3d9_cs); return hr; } static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9 **ppIndexData) { IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface; - IWineD3DIndexBuffer *retIndexData = NULL; + IWineD3DBuffer *retIndexData = NULL; HRESULT rc = D3D_OK; TRACE("(%p) Relay\n", This); @@ -1659,8 +1663,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX ifac EnterCriticalSection(&d3d9_cs); rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData); if (SUCCEEDED(rc) && retIndexData) { - IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); - IWineD3DIndexBuffer_Release(retIndexData); + IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData); + IWineD3DBuffer_Release(retIndexData); } else { if (FAILED(rc)) FIXME("Call to GetIndices failed\n"); *ppIndexData = NULL; diff --git a/reactos/dll/directx/wine/d3d9/directx.c b/reactos/dll/directx/wine/d3d9/directx.c index 96fea01004e..229368afb80 100644 --- a/reactos/dll/directx/wine/d3d9/directx.c +++ b/reactos/dll/directx/wine/d3d9/directx.c @@ -194,11 +194,23 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { IDirect3D9Impl *This = (IDirect3D9Impl *)iface; HRESULT hr; + WINED3DRESOURCETYPE WineD3DRType; TRACE("%p\n", This); + switch(RType) { + case D3DRTYPE_VERTEXBUFFER: + case D3DRTYPE_INDEXBUFFER: + WineD3DRType = WINED3DRTYPE_BUFFER; + break; + + default: + WineD3DRType = RType; + break; + } + EnterCriticalSection(&d3d9_cs); hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat), - Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL); + Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL); LeaveCriticalSection(&d3d9_cs); return hr; } diff --git a/reactos/dll/directx/wine/d3d9/indexbuffer.c b/reactos/dll/directx/wine/d3d9/indexbuffer.c index 2f3ca644039..161ff643cd7 100644 --- a/reactos/dll/directx/wine/d3d9/indexbuffer.c +++ b/reactos/dll/directx/wine/d3d9/indexbuffer.c @@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa if (ref == 0) { EnterCriticalSection(&d3d9_cs); - IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer); + IWineD3DBuffer_Release(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d9_cs); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); @@ -74,7 +74,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDevice(LPDIRECT3DINDEXBUFFER9 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device); + hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device); if (SUCCEEDED(hr)) { IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice); @@ -90,7 +90,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_SetPrivateData(LPDIRECT3DINDEXBU TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags); + hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -101,7 +101,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetPrivateData(LPDIRECT3DINDEXBU TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData); + hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -112,7 +112,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_FreePrivateData(LPDIRECT3DINDEXB TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid); + hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -123,7 +123,7 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_SetPriority(LPDIRECT3DINDEXBUFFER9 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - ret = IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew); + ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew); LeaveCriticalSection(&d3d9_cs); return ret; } @@ -134,7 +134,7 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_GetPriority(LPDIRECT3DINDEXBUFFER9 TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - ret = IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer); + ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d9_cs); return ret; } @@ -144,19 +144,15 @@ static void WINAPI IDirect3DIndexBuffer9Impl_PreLoad(LPDIRECT3DINDEXBUFFER9 ifac TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer); + IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d9_cs); } static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) { IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface; - D3DRESOURCETYPE ret; - TRACE("(%p) Relay\n", This); + TRACE("(%p)\n", This); - EnterCriticalSection(&d3d9_cs); - ret = IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer); - LeaveCriticalSection(&d3d9_cs); - return ret; + return D3DRTYPE_INDEXBUFFER; } /* IDirect3DIndexBuffer9 Interface follow: */ @@ -166,7 +162,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Lock(LPDIRECT3DINDEXBUFFER9 ifac TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags); + hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -177,7 +173,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer); + hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer); LeaveCriticalSection(&d3d9_cs); return hr; } @@ -185,13 +181,20 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDesc(LPDIRECT3DINDEXBUFFER9 iface, D3DINDEXBUFFER_DESC *pDesc) { IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface; HRESULT hr; + WINED3DBUFFER_DESC desc; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc); LeaveCriticalSection(&d3d9_cs); - if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); + if (SUCCEEDED(hr)) { + pDesc->Format = d3dformat_from_wined3dformat(This->format); + pDesc->Usage = desc.Usage; + pDesc->Pool = desc.Pool; + pDesc->Size = desc.Size; + pDesc->Type = D3DRTYPE_INDEXBUFFER; + } return hr; } @@ -238,10 +241,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface, object->lpVtbl = &Direct3DIndexBuffer9_Vtbl; object->ref = 1; + object->format = wined3dformat_from_d3dformat(Format); TRACE("Calling wined3d create index buffer\n"); EnterCriticalSection(&d3d9_cs); hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK, - wined3dformat_from_d3dformat(Format), (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, + (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer, pSharedHandle, (IUnknown *)object); LeaveCriticalSection(&d3d9_cs); if (hrc != D3D_OK) { diff --git a/reactos/dll/directx/wine/d3d9/vertexbuffer.c b/reactos/dll/directx/wine/d3d9/vertexbuffer.c index 1a41c013c44..8c65a885df6 100644 --- a/reactos/dll/directx/wine/d3d9/vertexbuffer.c +++ b/reactos/dll/directx/wine/d3d9/vertexbuffer.c @@ -154,13 +154,9 @@ static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 if static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) { IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface; - D3DRESOURCETYPE ret; - TRACE("(%p) Relay\n", This); + TRACE("(%p)\n", This); - EnterCriticalSection(&d3d9_cs); - ret = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer); - LeaveCriticalSection(&d3d9_cs); - return ret; + return D3DRTYPE_VERTEXBUFFER; } /* IDirect3DVertexBuffer9 Interface follow: */ @@ -189,13 +185,22 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9 iface, D3DVERTEXBUFFER_DESC* pDesc) { IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface; HRESULT hr; + WINED3DBUFFER_DESC desc; TRACE("(%p) Relay\n", This); EnterCriticalSection(&d3d9_cs); - hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc); + hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc); LeaveCriticalSection(&d3d9_cs); - if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format); + if (SUCCEEDED(hr)) { + pDesc->Format = D3DFMT_VERTEXDATA; + pDesc->Usage = desc.Usage; + pDesc->Pool = desc.Pool; + pDesc->Size = desc.Size; + pDesc->Type = D3DRTYPE_VERTEXBUFFER; + pDesc->FVF = This->fvf; + } + return hr; } @@ -240,8 +245,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface object->lpVtbl = &Direct3DVertexBuffer9_Vtbl; object->ref = 1; + object->fvf = FVF; EnterCriticalSection(&d3d9_cs); - hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), pSharedHandle, (IUnknown *)object); + hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, + 0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), + pSharedHandle, (IUnknown *)object); LeaveCriticalSection(&d3d9_cs); if (hrc != D3D_OK) { diff --git a/reactos/dll/directx/wine/ddraw/ddraw_private.h b/reactos/dll/directx/wine/ddraw/ddraw_private.h index c266c687ccb..cd05e16c2ed 100644 --- a/reactos/dll/directx/wine/ddraw/ddraw_private.h +++ b/reactos/dll/directx/wine/ddraw/ddraw_private.h @@ -378,7 +378,7 @@ struct IDirect3DDeviceImpl /* Other object connections */ IWineD3DDevice *wineD3DDevice; IDirectDrawImpl *ddraw; - IWineD3DIndexBuffer *indexbuffer; + IWineD3DBuffer *indexbuffer; IDirectDrawSurfaceImpl *target; BOOL OffScreenTarget; @@ -680,6 +680,7 @@ struct IDirect3DVertexBufferImpl /*** Storage for D3D7 specific things ***/ DWORD Caps; + DWORD fvf; }; /* The Vtables */ diff --git a/reactos/dll/directx/wine/ddraw/device.c b/reactos/dll/directx/wine/ddraw/device.c index 1192e45e03a..7c8e222204e 100644 --- a/reactos/dll/directx/wine/ddraw/device.c +++ b/reactos/dll/directx/wine/ddraw/device.c @@ -316,9 +316,9 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) EnterCriticalSection(&ddraw_cs); /* Free the index buffer. */ - IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL); - IWineD3DIndexBuffer_GetParent(This->indexbuffer, - (IUnknown **) &IndexBufferParent); + IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN); + IWineD3DBuffer_GetParent(This->indexbuffer, + (IUnknown **) &IndexBufferParent); IParent_Release(IndexBufferParent); /* Once for the getParent */ if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */ { @@ -4104,7 +4104,6 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf; HRESULT hr; DWORD stride; - WINED3DVERTEXBUFFER_DESC Desc; TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); @@ -4114,18 +4113,9 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, ERR("(%p) No Vertex buffer specified\n", This); return DDERR_INVALIDPARAMS; } + stride = get_flexible_vertex_size(vb->fvf); - /* Get the FVF of the vertex buffer, and its stride */ EnterCriticalSection(&ddraw_cs); - hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc); - if(hr != D3D_OK) - { - ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr); - LeaveCriticalSection(&ddraw_cs); - return hr; - } - stride = get_flexible_vertex_size(Desc.FVF); - hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, vb->wineD3DVertexDeclaration); if(FAILED(hr)) @@ -4229,32 +4219,20 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, { IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf; - DWORD stride; + DWORD stride = get_flexible_vertex_size(vb->fvf); WORD *LockedIndices; HRESULT hr; - WINED3DVERTEXBUFFER_DESC Desc; TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags); /* Steps: - * 1) Calculate some things: stride, ... - * 2) Upload the Indices to the index buffer - * 3) Set the index source - * 4) Set the Vertex Buffer as the Stream source - * 5) Call IWineD3DDevice::DrawIndexedPrimitive + * 1) Upload the Indices to the index buffer + * 2) Set the index source + * 3) Set the Vertex Buffer as the Stream source + * 4) Call IWineD3DDevice::DrawIndexedPrimitive */ EnterCriticalSection(&ddraw_cs); - /* Get the FVF of the vertex buffer, and its stride */ - hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc); - if(hr != D3D_OK) - { - ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr); - LeaveCriticalSection(&ddraw_cs); - return hr; - } - stride = get_flexible_vertex_size(Desc.FVF); - TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride); hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, vb->wineD3DVertexDeclaration); @@ -4271,30 +4249,31 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, * or a SetData-Method for the index buffer, which * overrides the index buffer data with our pointer. */ - hr = IWineD3DIndexBuffer_Lock(This->indexbuffer, - 0 /* OffSetToLock */, - IndexCount * sizeof(WORD), - (BYTE **) &LockedIndices, - 0 /* Flags */); + hr = IWineD3DBuffer_Map(This->indexbuffer, + 0 /* OffSetToLock */, + IndexCount * sizeof(WORD), + (BYTE **) &LockedIndices, + 0 /* Flags */); assert(IndexCount < 0x100000); if(hr != D3D_OK) { - ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr); + ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr); LeaveCriticalSection(&ddraw_cs); return hr; } memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD)); - hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer); + hr = IWineD3DBuffer_Unmap(This->indexbuffer); if(hr != D3D_OK) { - ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr); + ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr); LeaveCriticalSection(&ddraw_cs); return hr; } /* Set the index stream */ IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex); - hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer); + hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer, + WINED3DFMT_R16_UINT); /* Set the vertex stream source */ hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice, diff --git a/reactos/dll/directx/wine/ddraw/direct3d.c b/reactos/dll/directx/wine/ddraw/direct3d.c index 2a051d0bcce..aeba55b5596 100644 --- a/reactos/dll/directx/wine/ddraw/direct3d.c +++ b/reactos/dll/directx/wine/ddraw/direct3d.c @@ -820,11 +820,11 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface, /* Create an Index Buffer. WineD3D needs one for Drawing indexed primitives * Create a (hopefully) long enough buffer, and copy the indices into it - * Ideally, a IWineD3DIndexBuffer::SetData method could be created, which + * Ideally, a IWineD3DBuffer::SetData method could be created, which * takes the pointer and avoids the memcpy */ hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */, - WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DFMT_R16_UINT /* Format. D3D7 uses WORDS */, WINED3DPOOL_DEFAULT, + WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &object->indexbuffer, 0 /* Handle */, (IUnknown *)IndexBufferParent); if(FAILED(hr)) @@ -1017,6 +1017,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface, object->Caps = Desc->dwCaps; object->ddraw = This; + object->fvf = Desc->dwFVF; EnterCriticalSection(&ddraw_cs); hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice, diff --git a/reactos/dll/directx/wine/ddraw/surface.c b/reactos/dll/directx/wine/ddraw/surface.c index 7254e7cf4ef..14fc721ca3e 100644 --- a/reactos/dll/directx/wine/ddraw/surface.c +++ b/reactos/dll/directx/wine/ddraw/surface.c @@ -310,7 +310,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) TRACE("(%p) Destroying the render target, uninitializing D3D\n", This); /* Unset any index buffer, just to be sure */ - IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL); + IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN); IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL); IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL); for(i = 0; i < ddraw->numConvertedDecls; i++) diff --git a/reactos/dll/directx/wine/ddraw/vertexbuffer.c b/reactos/dll/directx/wine/ddraw/vertexbuffer.c index 277591c1c78..df7528b45cb 100644 --- a/reactos/dll/directx/wine/ddraw/vertexbuffer.c +++ b/reactos/dll/directx/wine/ddraw/vertexbuffer.c @@ -234,7 +234,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, DWORD *Size) { IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface; - WINED3DVERTEXBUFFER_DESC Desc; + WINED3DBUFFER_DESC Desc; HRESULT hr; TRACE("(%p)->(%08x,%p,%p)\n", This, Flags, Data, Size); @@ -245,7 +245,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &Desc); if(hr != D3D_OK) { - ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr); + ERR("(%p) IWineD3DBuffer::GetDesc failed with hr=%08x\n", This, hr); LeaveCriticalSection(&ddraw_cs); return hr; } @@ -340,7 +340,6 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, IDirect3DDeviceImpl *D3D = (IDirect3DDeviceImpl *)D3DDevice; BOOL oldClip, doClip; HRESULT hr; - WINED3DVERTEXBUFFER_DESC Desc; TRACE("(%p)->(%08x,%d,%d,%p,%d,%p,%08x)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags); @@ -372,12 +371,11 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, doClip); } - IWineD3DBuffer_GetDesc(Src->wineD3DVertexBuffer, &Desc); IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice, 0, /* Stream No */ Src->wineD3DVertexBuffer, 0, /* Offset */ - get_flexible_vertex_size(Desc.FVF)); + get_flexible_vertex_size(Src->fvf)); IWineD3DDevice_SetVertexDeclaration(D3D->wineD3DDevice, Src->wineD3DVertexDeclaration); hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice, @@ -386,7 +384,8 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, Count, This->wineD3DVertexBuffer, NULL /* Output vdecl */, - Flags); + Flags, + This->fvf); /* Restore the states if needed */ if(doClip != oldClip) @@ -435,7 +434,7 @@ IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface, D3DVERTEXBUFFERDESC *Desc) { IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface; - WINED3DVERTEXBUFFER_DESC WDesc; + WINED3DBUFFER_DESC WDesc; HRESULT hr; TRACE("(%p)->(%p)\n", This, Desc); @@ -445,15 +444,15 @@ IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface, hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &WDesc); if(hr != D3D_OK) { - ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr); + ERR("(%p) IWineD3DBuffer::GetDesc failed with hr=%08x\n", This, hr); LeaveCriticalSection(&ddraw_cs); return hr; } /* Now fill the Desc structure */ Desc->dwCaps = This->Caps; - Desc->dwFVF = WDesc.FVF; - Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(WDesc.FVF); + Desc->dwFVF = This->fvf; + Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(This->fvf); LeaveCriticalSection(&ddraw_cs); return D3D_OK; diff --git a/reactos/dll/directx/wine/wined3d/arb_program_shader.c b/reactos/dll/directx/wine/wined3d/arb_program_shader.c index bca567d562c..b5b5ad445e0 100644 --- a/reactos/dll/directx/wine/wined3d/arb_program_shader.c +++ b/reactos/dll/directx/wine/wined3d/arb_program_shader.c @@ -40,10 +40,20 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d); #define GLINFO_LOCATION (*gl_info) +/* We have to subtract any other PARAMs that we might use in our shader programs. + * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1, + * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */ +#define ARB_SHADER_RESERVED_VS_CONSTS 3 + +/* The arb shader only loads the bump mapping environment matrix into the shader if it finds + * a free constant to do that, so only reduce the number of available constants by 2 for the fog states. + */ +#define ARB_SHADER_RESERVED_PS_CONSTS 2 + /* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1, * so upload them above that */ -#define ARB_SHADER_PRIVCONST_BASE GL_LIMITS(vshader_constantsF) +#define ARB_SHADER_PRIVCONST_BASE (GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS) #define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0 /* ARB_program_shader private data */ @@ -163,6 +173,16 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con } } +/** + * Loads the texture dimensions for NP2 fixup into the currently set ARB_[vertex/fragment]_programs. + */ +static void shader_arb_load_np2fixup_constants( + IWineD3DDevice* device, + char usePixelShader, + char useVertexShader) { + /* not implemented */ +} + /** * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs. * @@ -258,7 +278,8 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh DWORD i, cur; char pshader = shader_is_pshader_version(reg_maps->shader_version); unsigned max_constantsF = min(This->baseShader.limits.constant_float, - (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF))); + (pshader ? GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS : + GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS)); UINT extra_constants_needed = 0; const local_constant *lconst; @@ -300,13 +321,13 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh * the stateblock into the shader. If no constant is available don't load, texbem will then just sample the texture without applying * bump mapping. */ - if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) { + if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) { ps->bumpenvmatconst[cur].const_num = max_constantsF + extra_constants_needed; shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n", i, ps->bumpenvmatconst[cur].const_num); extra_constants_needed++; - if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) { + if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) { ((IWineD3DPixelShaderImpl *)This)->luminanceconst[cur].const_num = max_constantsF + extra_constants_needed; shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n", i, ps->luminanceconst[cur].const_num); @@ -383,20 +404,23 @@ static const char * const shift_tab[] = { }; static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *ins, - const DWORD param, char *write_mask) + const struct wined3d_shader_dst_param *dst, char *write_mask) { char *ptr = write_mask; char vshader = shader_is_vshader_version(ins->reg_maps->shader_version); - if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) { + if (vshader && dst->register_type == WINED3DSPR_ADDR) + { *ptr++ = '.'; *ptr++ = 'x'; - } else if ((param & WINED3DSP_WRITEMASK_ALL) != WINED3DSP_WRITEMASK_ALL) { + } + else if (dst->write_mask != WINED3DSP_WRITEMASK_ALL) + { *ptr++ = '.'; - if (param & WINED3DSP_WRITEMASK_0) *ptr++ = 'x'; - if (param & WINED3DSP_WRITEMASK_1) *ptr++ = 'y'; - if (param & WINED3DSP_WRITEMASK_2) *ptr++ = 'z'; - if (param & WINED3DSP_WRITEMASK_3) *ptr++ = 'w'; + if (dst->write_mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x'; + if (dst->write_mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y'; + if (dst->write_mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z'; + if (dst->write_mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w'; } *ptr = '\0'; @@ -433,141 +457,131 @@ static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_ *ptr = '\0'; } -static void pshader_get_register_name(IWineD3DBaseShader* iface, - const DWORD param, char* regstr) { +static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADER_PARAM_REGISTER_TYPE register_type, + UINT register_idx, BOOL rel_addr, char *register_name, BOOL *is_color) +{ + /* oPos, oFog and oPts in D3D */ + static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"}; + IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface; + DWORD shader_version = This->baseShader.reg_maps.shader_version; + BOOL pshader = shader_is_pshader_version(shader_version); - DWORD reg = param & WINED3DSP_REGNUM_MASK; - DWORD regtype = shader_get_regtype(param); - IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface; + *is_color = FALSE; - switch (regtype) { - case WINED3DSPR_TEMP: - sprintf(regstr, "R%u", reg); - break; - case WINED3DSPR_INPUT: - if (reg==0) { - strcpy(regstr, "fragment.color.primary"); - } else { - strcpy(regstr, "fragment.color.secondary"); - } - break; - case WINED3DSPR_CONST: - if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) { - sprintf(regstr, "C[%u]", reg); - } else { - sprintf(regstr, "C%u", reg); - } - break; - case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */ - sprintf(regstr,"T%u", reg); - break; - case WINED3DSPR_COLOROUT: - if (reg == 0) - sprintf(regstr, "TMP_COLOR"); - else { - /* TODO: See GL_ARB_draw_buffers */ - FIXME("Unsupported write to render target %u\n", reg); - sprintf(regstr, "unsupported_register"); - } - break; - case WINED3DSPR_DEPTHOUT: - sprintf(regstr, "result.depth"); - break; - case WINED3DSPR_ATTROUT: - sprintf(regstr, "oD[%u]", reg); - break; - case WINED3DSPR_TEXCRDOUT: - sprintf(regstr, "oT[%u]", reg); - break; - default: - FIXME("Unhandled register name Type(%d)\n", regtype); - sprintf(regstr, "unrecognized_register"); - break; + switch (register_type) + { + case WINED3DSPR_TEMP: + sprintf(register_name, "R%u", register_idx); + break; + + case WINED3DSPR_INPUT: + if (pshader) + { + if (register_idx == 0) strcpy(register_name, "fragment.color.primary"); + else strcpy(register_name, "fragment.color.secondary"); + } + else + { + if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE; + sprintf(register_name, "vertex.attrib[%u]", register_idx); + } + break; + + case WINED3DSPR_CONST: + if (!pshader && rel_addr) + { + UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset; + if (register_idx >= rel_offset) + sprintf(register_name, "C[A0.x + %u]", register_idx - rel_offset); + else + sprintf(register_name, "C[A0.x - %u]", -register_idx + rel_offset); + } + else + { + if (This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) + sprintf(register_name, "C[%u]", register_idx); + else + sprintf(register_name, "C%u", register_idx); + } + break; + + case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */ + if (pshader) sprintf(register_name, "T%u", register_idx); + else sprintf(register_name, "A%u", register_idx); + break; + + case WINED3DSPR_COLOROUT: + if (register_idx == 0) + { + strcpy(register_name, "TMP_COLOR"); + } + else + { + /* TODO: See GL_ARB_draw_buffers */ + FIXME("Unsupported write to render target %u\n", register_idx); + sprintf(register_name, "unsupported_register"); + } + break; + + case WINED3DSPR_RASTOUT: + sprintf(register_name, "%s", rastout_reg_names[register_idx]); + break; + + case WINED3DSPR_DEPTHOUT: + strcpy(register_name, "result.depth"); + break; + + case WINED3DSPR_ATTROUT: + if (pshader) sprintf(register_name, "oD[%u]", register_idx); + else if (register_idx == 0) strcpy(register_name, "result.color.primary"); + else strcpy(register_name, "result.color.secondary"); + break; + + case WINED3DSPR_TEXCRDOUT: + if (pshader) sprintf(register_name, "oT[%u]", register_idx); + else sprintf(register_name, "result.texcoord[%u]", register_idx); + break; + + default: + FIXME("Unhandled register type %#x[%u]\n", register_type, register_idx); + sprintf(register_name, "unrecognized_register[%u]", register_idx); + break; } } -/* TODO: merge with pixel shader */ -static void vshader_program_add_param(const struct wined3d_shader_instruction *ins, - const DWORD param, BOOL is_input, char *hwLine) +static void shader_arb_add_src_param(const struct wined3d_shader_instruction *ins, + DWORD param, char *str) { - IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)ins->shader; - - /* oPos, oFog and oPts in D3D */ - static const char * const hwrastout_reg_names[] = { "TMP_OUT", "result.fogcoord", "result.pointsize" }; - - DWORD reg = param & WINED3DSP_REGNUM_MASK; - DWORD regtype = shader_get_regtype(param); - char tmpReg[255]; - BOOL is_color = FALSE; - - if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) { - strcat(hwLine, " -"); - } else { - strcat(hwLine, " "); - } - - switch (regtype) { - case WINED3DSPR_TEMP: - sprintf(tmpReg, "R%u", reg); - strcat(hwLine, tmpReg); - break; - case WINED3DSPR_INPUT: - - if (This->cur_args->swizzle_map & (1 << reg)) is_color = TRUE; - - sprintf(tmpReg, "vertex.attrib[%u]", reg); - strcat(hwLine, tmpReg); - break; - case WINED3DSPR_CONST: - if(param & WINED3DSHADER_ADDRMODE_RELATIVE) { - if(reg >= This->rel_offset) { - sprintf(tmpReg, "C[A0.x + %u]", reg - This->rel_offset); - } else { - sprintf(tmpReg, "C[A0.x - %u]", -reg + This->rel_offset); - } - } else { - if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) { - sprintf(tmpReg, "C[%u]", reg); - } else { - sprintf(tmpReg, "C%u", reg); - } - } - strcat(hwLine, tmpReg); - break; - case WINED3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/ - sprintf(tmpReg, "A%u", reg); - strcat(hwLine, tmpReg); - break; - case WINED3DSPR_RASTOUT: - sprintf(tmpReg, "%s", hwrastout_reg_names[reg]); - strcat(hwLine, tmpReg); - break; - case WINED3DSPR_ATTROUT: - if (reg==0) { - strcat(hwLine, "result.color.primary"); - } else { - strcat(hwLine, "result.color.secondary"); - } - break; - case WINED3DSPR_TEXCRDOUT: - sprintf(tmpReg, "result.texcoord[%u]", reg); - strcat(hwLine, tmpReg); - break; - default: - FIXME("Unknown reg type %d %d\n", regtype, reg); - strcat(hwLine, "unrecognized_register"); - break; - } - - if (!is_input) { - char write_mask[6]; - shader_arb_get_write_mask(ins, param, write_mask); - strcat(hwLine, write_mask); - } else { + char register_name[255]; char swizzle[6]; + BOOL is_color; + + if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) strcat(str, " -"); + else strcat(str, " "); + + shader_arb_get_register_name(ins->shader, shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK, + param & WINED3DSHADER_ADDRMODE_RELATIVE, register_name, &is_color); + strcat(str, register_name); + shader_arb_get_swizzle(param, is_color, swizzle); - strcat(hwLine, swizzle); - } + strcat(str, swizzle); +} + +static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *ins, + const struct wined3d_shader_dst_param *wined3d_dst, char *str) +{ + char register_name[255]; + char write_mask[6]; + BOOL is_color; + + strcat(str, " "); + + shader_arb_get_register_name(ins->shader, wined3d_dst->register_type, + wined3d_dst->register_idx, wined3d_dst->has_rel_addr, register_name, &is_color); + strcat(str, register_name); + + shader_arb_get_write_mask(ins, wined3d_dst, write_mask); + strcat(str, write_mask); } static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channel_source) @@ -659,6 +673,12 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD } else { tex_type = "2D"; } + if(shader_is_pshader_version(ins->reg_maps->shader_version)) { + const IWineD3DPixelShaderImpl* const ps = (const IWineD3DPixelShaderImpl*)This; + if(ps->cur_args->np2_fixup & (1 << sampler_idx)) { + FIXME("NP2 texcoord fixup is currently not implemented in ARB mode (use GLSL instead).\n"); + } + } break; case WINED3DSTT_VOLUME: @@ -688,7 +708,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD if (shader_is_pshader_version(ins->reg_maps->shader_version)) { IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->shader; - gen_color_correction(buffer, dst_str, ins->dst[0].token & WINED3DSP_WRITEMASK_ALL, + gen_color_correction(buffer, dst_str, ins->dst[0].write_mask, "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]); } } @@ -701,6 +721,7 @@ static void pshader_gen_input_modifier_line ( char *outregstr) { /* Generate a line that does the input modifier computation and return the input register to use */ + BOOL is_color = FALSE; char regstr[256]; char swzstr[20]; int insert_line; @@ -709,8 +730,9 @@ static void pshader_gen_input_modifier_line ( insert_line = 1; /* Get register name */ - pshader_get_register_name(iface, instr, regstr); - shader_arb_get_swizzle(instr, FALSE, swzstr); + shader_arb_get_register_name(iface, shader_get_regtype(instr), instr & WINED3DSP_REGNUM_MASK, + instr & WINED3DSHADER_ADDRMODE_RELATIVE, regstr, &is_color); + shader_arb_get_swizzle(instr, is_color, swzstr); switch (instr & WINED3DSP_SRCMOD_MASK) { case WINED3DSPSM_NONE: @@ -771,12 +793,14 @@ static inline void pshader_gen_output_modifier_line(SHADER_BUFFER *buffer, int s static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) { IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_name[50]; char src_name[2][50]; char dst_wmask[20]; - DWORD sampler_code = ins->dst[0].register_idx; + DWORD sampler_code = dst->register_idx; BOOL has_bumpmat = FALSE; + BOOL is_color; int i; for(i = 0; i < This->numbumpenvmatconsts; i++) { @@ -788,8 +812,9 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) } } - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); strcat(dst_name, dst_wmask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]); @@ -810,18 +835,21 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins) static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE; - DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; + DWORD shift = dst->shift; + BOOL is_color; /* FIXME: support output modifiers */ /* Handle output register */ - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); /* Generate input register names (with modifiers) */ pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]); @@ -843,18 +871,21 @@ static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins) static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE; + DWORD shift = dst->shift; + BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; + BOOL is_color; /* FIXME: support output modifiers */ /* Handle output register */ - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); /* Generate input register names (with modifiers) */ pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]); @@ -872,15 +903,18 @@ static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins) * dst = dot2(src0, src1) + src2 */ static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_wmask[20]; char dst_name[50]; char src_name[3][50]; - DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE; + DWORD shift = dst->shift; + BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; + BOOL is_color; - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]); @@ -900,7 +934,6 @@ static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins) static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) { SHADER_BUFFER *buffer = ins->buffer; - DWORD dst = ins->dst[0].token; const DWORD *src = ins->src; const char *instruction; char arguments[256]; @@ -939,6 +972,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) if (shader_is_pshader_version(ins->reg_maps->shader_version)) { /* Output token related */ + const struct wined3d_shader_dst_param *dst; char output_rname[256]; char output_wmask[20]; char operands[4][100]; @@ -946,6 +980,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) BOOL centroid = FALSE; BOOL partialprecision = FALSE; const char *modifier; + BOOL is_color; DWORD shift; if (!(ins->dst_count + ins->src_count)) @@ -953,11 +988,12 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) ERR("Opcode \"%#x\" has no parameters\n", ins->handler_idx); return; } + dst = &ins->dst[0]; /* Process modifiers */ - if (dst & WINED3DSP_DSTMOD_MASK) + if (dst->modifiers) { - DWORD mask = dst & WINED3DSP_DSTMOD_MASK; + DWORD mask = dst->modifiers; saturate = mask & WINED3DSPDM_SATURATE; centroid = mask & WINED3DSPDM_MSAMPCENTROID; @@ -969,7 +1005,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) if (centroid) FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT); } - shift = (dst & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + shift = dst->shift; modifier = (saturate && !shift) ? "_SAT" : ""; /* Generate input register names (with modifiers) */ @@ -979,7 +1015,8 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) } /* Handle output register */ - pshader_get_register_name(ins->shader, dst, output_rname); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, output_rname, &is_color); strcpy(operands[0], output_rname); shader_arb_get_write_mask(ins, dst, output_wmask); strcat(operands[0], output_wmask); @@ -996,16 +1033,16 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins) /* A shift requires another line. */ if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname); } else { - /* Note that vshader_program_add_param() adds spaces. */ + /* Note that shader_arb_add_*_param() adds spaces. */ arguments[0] = '\0'; if (ins->dst_count) { - vshader_program_add_param(ins, dst, FALSE, arguments); + shader_arb_add_dst_param(ins, &ins->dst[0], arguments); for (i = 0; i < ins->src_count; ++i) { strcat(arguments, ","); - vshader_program_add_param(ins, src[i], TRUE, arguments); + shader_arb_add_src_param(ins, src[i], arguments); } } shader_addline(buffer, "%s%s;\n", instruction, arguments); @@ -1018,7 +1055,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1 && !shader_is_pshader_version(ins->reg_maps->shader_version) - && shader_get_regtype(ins->dst[0].token) == WINED3DSPR_ADDR) + && ins->dst[0].register_type == WINED3DSPR_ADDR) || ins->handler_idx == WINED3DSIH_MOVA) { SHADER_BUFFER *buffer = ins->buffer; @@ -1030,7 +1067,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) src0_param[0] = '\0'; if (((IWineD3DVertexShaderImpl *)shader)->rel_offset) { - vshader_program_add_param(ins, ins->src[0], TRUE, src0_param); + shader_arb_add_src_param(ins, ins->src[0], src0_param); shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param); shader_addline(buffer, "ARL A0.x, TMP.x;\n"); } @@ -1049,7 +1086,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) parm |= WINED3DVS_X_Y | WINED3DVS_Y_Y | WINED3DVS_Z_Y | WINED3DVS_W_Y; else if((ins->src[0] & WINED3DVS_X_X) == WINED3DVS_X_X) parm |= WINED3DVS_X_X | WINED3DVS_Y_X | WINED3DVS_Z_X | WINED3DVS_W_X; - vshader_program_add_param(ins, parm, TRUE, src0_param); + shader_arb_add_src_param(ins, parm, src0_param); shader_addline(buffer, "ARL A0.x, %s;\n", src0_param); } } @@ -1061,14 +1098,17 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins) static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; DWORD shader_version = ins->reg_maps->shader_version; SHADER_BUFFER *buffer = ins->buffer; char reg_dest[40]; + BOOL is_color; /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented, * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit) */ - pshader_get_register_name(ins->shader, ins->dst[0].token, reg_dest); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, reg_dest, &is_color); if (shader_version >= WINED3DPS_VERSION(2,0)) { @@ -1088,8 +1128,9 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) { IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; + BOOL is_color; - DWORD dst = ins->dst[0].token; const DWORD *src = ins->src; SHADER_BUFFER* buffer = ins->buffer; DWORD shader_version = ins->reg_maps->shader_version; @@ -1097,12 +1138,11 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) char reg_dest[40]; char reg_coord[40]; - DWORD reg_dest_code; DWORD reg_sampler_code; /* All versions have a destination register */ - reg_dest_code = ins->dst[0].register_idx; - pshader_get_register_name(ins->shader, dst, reg_dest); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, reg_dest, &is_color); /* 1.0-1.3: Use destination register as coordinate source. 1.4+: Use provided coordinate source register. */ @@ -1114,7 +1154,7 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) /* 1.0-1.4: Use destination register number as texture code. 2.0+: Use provided sampler number as texure code. */ if (shader_version < WINED3DPS_VERSION(2,0)) - reg_sampler_code = reg_dest_code; + reg_sampler_code = dst->register_idx; else reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK; @@ -1150,21 +1190,20 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins) { - DWORD dst = ins->dst[0].token; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char tmp[20]; shader_arb_get_write_mask(ins, dst, tmp); if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4)) { - DWORD reg = ins->dst[0].register_idx; + DWORD reg = dst->register_idx; shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg); } else { - DWORD reg1 = ins->dst[0].register_idx; char reg_src[40]; pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, reg_src); - shader_addline(buffer, "MOV R%u%s, %s;\n", reg1, tmp, reg_src); + shader_addline(buffer, "MOV R%u%s, %s;\n", dst->register_idx, tmp, reg_src); } } @@ -1217,11 +1256,12 @@ 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->shader; + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; BOOL has_bumpmat = FALSE; BOOL has_luminance = FALSE; + BOOL is_color; int i; - DWORD dst = ins->dst[0].token; DWORD src = ins->src[0] & WINED3DSP_REGNUM_MASK; SHADER_BUFFER* buffer = ins->buffer; @@ -1229,9 +1269,10 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) DWORD reg_dest_code; /* All versions have a destination register */ - reg_dest_code = ins->dst[0].register_idx; + reg_dest_code = dst->register_idx; /* Can directly use the name because texbem is only valid for <= 1.3 shaders */ - pshader_get_register_name(ins->shader, dst, reg_coord); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, reg_coord, &is_color); for(i = 0; i < This->numbumpenvmatconsts; i++) { if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED @@ -1427,15 +1468,18 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins) static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_name[50]; + BOOL is_color; /* texdepth has an implicit destination, the fragment depth value. It's only parameter, * which is essentially an input, is the destination register because it is the first * parameter. According to the msdn, this must be register r5, but let's keep it more flexible * here */ - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); /* According to the msdn, the source register(must be r5) is unusable after * the texdepth instruction, so we're free to modify it @@ -1474,18 +1518,20 @@ static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins) * Take a 3-component dot product of the TexCoord[dstreg] and src. */ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; char src0[50]; char dst_str[50]; char dst_mask[6]; - DWORD dstreg = ins->dst[0].register_idx; SHADER_BUFFER *buffer = ins->buffer; + BOOL is_color; /* Handle output register */ - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_str); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_mask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_str, &is_color); + shader_arb_get_write_mask(ins, dst, dst_mask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0); - shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dstreg, src0); + shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->register_idx, src0); /* TODO: Handle output modifiers */ } @@ -1494,17 +1540,19 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins) * Perform the 3rd row of a 3x3 matrix multiply */ static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_str[50]; char dst_mask[6]; char src0[50]; - DWORD dst_reg = ins->dst[0].register_idx; + BOOL is_color; - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_str); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_mask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_str, &is_color); + shader_arb_get_write_mask(ins, dst, dst_mask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0); - shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst_reg, src0); + shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->register_idx, src0); shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask); /* TODO: Handle output modifiers */ @@ -1583,9 +1631,9 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) break; } + tmp_dst = ins->dst[0]; for (i = 0; i < nComponents; i++) { - tmp_dst.register_idx = ins->dst[0].register_idx; - tmp_dst.token = ((ins->dst[0].token) & ~WINED3DSP_WRITEMASK_ALL) | (WINED3DSP_WRITEMASK_0 << i); + tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i; tmp_ins.src[1] = ins->src[1]+i; shader_hw_map2gl(&tmp_ins); } @@ -1594,7 +1642,6 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins) static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) { SHADER_BUFFER *buffer = ins->buffer; - DWORD dst = ins->dst[0].token; DWORD src = ins->src[0]; DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT; const char *instruction; @@ -1611,9 +1658,9 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) } strcpy(tmpLine, instruction); - vshader_program_add_param(ins, dst, FALSE, tmpLine); /* Destination */ + shader_arb_add_dst_param(ins, &ins->dst[0], tmpLine); /* Destination */ strcat(tmpLine, ","); - vshader_program_add_param(ins, src, TRUE, tmpLine); + shader_arb_add_src_param(ins, src, tmpLine); if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) == swizzle) { /* Dx sdk says .x is used if no swizzle is given, but our test shows that * .w is used @@ -1626,15 +1673,18 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins) static void shader_hw_nrm(const struct wined3d_shader_instruction *ins) { + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_name[50]; char src_name[50]; char dst_wmask[20]; - DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE; + DWORD shift = dst->shift; + BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; + BOOL is_color; - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name); shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name); @@ -1653,15 +1703,18 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins) * must contain fixed constants. So we need a separate function to filter those constants and * can't use map2gl */ + const struct wined3d_shader_dst_param *dst = &ins->dst[0]; SHADER_BUFFER *buffer = ins->buffer; char dst_name[50]; char src_name[50]; char dst_wmask[20]; - DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE; + DWORD shift = dst->shift; + BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE; + BOOL is_color; - pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name); - shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask); + shader_arb_get_register_name(ins->shader, dst->register_type, + dst->register_idx, dst->has_rel_addr, dst_name, &is_color); + shader_arb_get_write_mask(ins, dst, dst_wmask); pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name); shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask, @@ -2145,13 +2198,14 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *g if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) { pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1); TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n"); - pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); + pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS; } if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) { pCaps->PixelShaderVersion = WINED3DPS_VERSION(1,4); pCaps->PixelShader1xMaxValue = 8.0; TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n"); + pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS; } } @@ -2269,6 +2323,7 @@ const shader_backend_t arb_program_shader_backend = { shader_arb_update_float_vertex_constants, shader_arb_update_float_pixel_constants, shader_arb_load_constants, + shader_arb_load_np2fixup_constants, shader_arb_destroy, shader_arb_alloc, shader_arb_free, diff --git a/reactos/dll/directx/wine/wined3d/baseshader.c b/reactos/dll/directx/wine/wined3d/baseshader.c index 39120d40767..08415c21035 100644 --- a/reactos/dll/directx/wine/wined3d/baseshader.c +++ b/reactos/dll/directx/wine/wined3d/baseshader.c @@ -212,11 +212,24 @@ static void shader_delete_constant_list(struct list* clist) { list_init(clist); } +static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst) +{ + dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT) + | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2); + dst->register_idx = param & WINED3DSP_REGNUM_MASK; + dst->write_mask = param & WINED3DSP_WRITEMASK_ALL; + dst->modifiers = param & WINED3DSP_DSTMOD_MASK; + dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; + dst->has_rel_addr = param & WINED3DSHADER_ADDRMODE_RELATIVE; + dst->addr_token = addr_param; +} + /* Note that this does not count the loop register * as an address register. */ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps, - struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code) + struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, + const DWORD *byte_code) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins; @@ -285,14 +298,19 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m else reg_maps->packed_input[regnum] = 1; - semantics_in[regnum].usage = usage; - semantics_in[regnum].reg = param; + semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; + semantics_in[regnum].usage_idx = + (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + shader_parse_dst_param(param, 0, &semantics_in[regnum].reg); /* Vshader: mark 3.0 output registers used, save token */ } else if (WINED3DSPR_OUTPUT == regtype) { reg_maps->packed_output[regnum] = 1; - semantics_out[regnum].usage = usage; - semantics_out[regnum].reg = param; + semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; + semantics_out[regnum].usage_idx = + (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + shader_parse_dst_param(param, 0, &semantics_out[regnum].reg); + if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT)) reg_maps->fog = 1; @@ -848,9 +866,9 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer, ins.dst_count = curOpcode->dst_token ? 1 : 0; if (ins.dst_count) { - dst_param.addr_token = 0; - pToken += shader_get_param(pToken, shader_version, &dst_param.token, &dst_param.addr_token); - dst_param.register_idx = dst_param.token & WINED3DSP_REGNUM_MASK; + DWORD param, addr_param = 0; + pToken += shader_get_param(pToken, shader_version, ¶m, &addr_param); + shader_parse_dst_param(param, addr_param, &dst_param); } /* Predication token */ @@ -1075,6 +1093,7 @@ static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {} static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {} static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {} static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {} +static void shader_none_load_np2fixup_constants(IWineD3DDevice *iface, char usePS, char useVS) {} static void shader_none_destroy(IWineD3DBaseShader *iface) {} static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;} static void shader_none_free(IWineD3DDevice *iface) {} @@ -1124,6 +1143,7 @@ const shader_backend_t none_shader_backend = { shader_none_update_float_vertex_constants, shader_none_update_float_pixel_constants, shader_none_load_constants, + shader_none_load_np2fixup_constants, shader_none_destroy, shader_none_alloc, shader_none_free, diff --git a/reactos/dll/directx/wine/wined3d/buffer.c b/reactos/dll/directx/wine/wined3d/buffer.c index 9e2abeb9cab..b68dcf7c6cf 100644 --- a/reactos/dll/directx/wine/wined3d/buffer.c +++ b/reactos/dll/directx/wine/wined3d/buffer.c @@ -54,11 +54,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) while (glGetError() != GL_NO_ERROR); /* Basically the FVF parameter passed to CreateVertexBuffer is no good - * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with - * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer - * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified - * to check if the rhw and color values are in the correct format. - */ + * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with + * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer + * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified + * to check if the rhw and color values are in the correct format. + */ GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object)); error = glGetError(); @@ -68,7 +68,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) goto fail; } - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + } + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); error = glGetError(); if (error != GL_NO_ERROR) { @@ -96,10 +100,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) } /* Reserve memory for the buffer. The amount of data won't change - * so we are safe with calling glBufferData once with a NULL ptr and - * calling glBufferSubData on updates - */ - GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, This->resource.size, NULL, gl_usage)); + * so we are safe with calling glBufferData once and + * calling glBufferSubData on updates. Upload the actual data in case + * we're not double buffering, so we can release the heap mem afterwards + */ + GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.allocatedMemory, gl_usage)); error = glGetError(); if (error != GL_NO_ERROR) { @@ -113,7 +118,18 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) This->buffer_object_usage = gl_usage; This->dirty_start = 0; This->dirty_end = This->resource.size; - This->flags |= WINED3D_BUFFER_DIRTY; + + if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) + { + This->flags |= WINED3D_BUFFER_DIRTY; + } + else + { + HeapFree(GetProcessHeap(), 0, This->resource.heapMemory); + This->resource.allocatedMemory = NULL; + This->resource.heapMemory = NULL; + This->flags &= ~WINED3D_BUFFER_DIRTY; + } return; @@ -298,9 +314,14 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) unsigned int i; /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer. - * Once we have our declaration there is no need to look it up again. + * Once we have our declaration there is no need to look it up again. Index buffers also never need + * conversion, so once the (empty) conversion structure is created don't bother checking again */ - if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->flags & WINED3D_BUFFER_HASDESC) return FALSE; + if (This->flags & WINED3D_BUFFER_HASDESC) + { + if(((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 || + This->resource.format_desc->format != WINED3DFMT_VERTEXDATA) return FALSE; + } TRACE("Finding vertex buffer conversion information\n"); /* Certain declaration types need some fixups before we can pass them to @@ -308,11 +329,15 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if * GL_NV_half_float is not supported. * + * Note for d3d8 and d3d9: * The vertex buffer FVF doesn't help with finding them, we have to use * the decoded vertex declaration and pick the things that concern the * current buffer. A problem with this is that this can change between * draws, so we have to validate the information and reprocess the buffer * if it changes, and avoid false positives for performance reasons. + * WineD3D doesn't even know the vertex buffer any more, it is managed + * by the client libraries and passed to SetStreamSource and ProcessVertices + * as needed. * * We have to distinguish between vertex shaders and fixed function to * pick the way we access the strided vertex information. @@ -439,10 +464,22 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This) if (This->buffer_object_size != size) { TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size); + + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + } + + /* Rescue the data before resizing the buffer object if we do not have our backup copy */ + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) + { + buffer_get_sysmem(This); + } + ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->buffer_object_usage)); + GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, size, NULL, This->buffer_object_usage)); This->buffer_object_size = size; checkGLcall("glBufferDataARB"); LEAVE_GL(); @@ -551,21 +588,40 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface) return refcount; } +const BYTE *buffer_get_sysmem(struct wined3d_buffer *This) +{ + if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) return This->resource.allocatedMemory; + + This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT); + This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1)); + ENTER_GL(); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.allocatedMemory)); + LEAVE_GL(); + This->flags |= WINED3D_BUFFER_DOUBLEBUFFER; + + return This->resource.allocatedMemory; +} + static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; TRACE("iface %p\n", iface); - /* This is easy: The whole content is shadowed in This->resource.allocatedMemory, - * so we only have to destroy the vbo. Only do it if we have a vbo, which implies - * that vbos are supported - */ if (This->buffer_object) { IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); + + /* Download the buffer, but don't permanently enable double buffering */ + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) + { + buffer_get_sysmem(This); + This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER; + } + ENTER_GL(); GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object)); checkGLcall("glDeleteBuffersARB"); @@ -734,6 +790,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) This->dirty_start = 0; This->dirty_end = 0; + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + } + if (!This->conversion_map) { /* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory @@ -742,19 +803,27 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) */ TRACE("No conversion needed\n"); + /* Nothing to do because we locked directly into the vbo */ + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) return; + if (!device->isInDraw) { ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start)); + GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end-start, This->resource.allocatedMemory + start)); checkGLcall("glBufferSubDataARB"); LEAVE_GL(); return; } + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) + { + buffer_get_sysmem(This); + } + /* Now for each vertex in the buffer that needs conversion */ vertices = This->resource.size / This->stride; @@ -793,9 +862,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conversion_stride, data)); + GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, 0, vertices * This->conversion_stride, data)); checkGLcall("glBufferSubDataARB"); LEAVE_GL(); } @@ -832,9 +901,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) } ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data + start)); + GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end - start, data + start)); checkGLcall("glBufferSubDataARB"); LEAVE_GL(); } @@ -852,10 +921,11 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + LONG count; TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags); - InterlockedIncrement(&This->lock_count); + count = InterlockedIncrement(&This->lock_count); if (This->flags & WINED3D_BUFFER_DIRTY) { @@ -877,7 +947,22 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, else This->dirty_end = This->resource.size; } - This->flags |= WINED3D_BUFFER_DIRTY; + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) + { + if(count == 1) + { + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + } + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB)); + } + } + else + { + This->flags |= WINED3D_BUFFER_DIRTY; + } *data = This->resource.allocatedMemory + offset; @@ -900,7 +985,17 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) return WINED3D_OK; } - if (This->flags & WINED3D_BUFFER_HASDESC) + if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object) + { + if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB) + { + IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER); + } + GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object)); + GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint)); + This->resource.allocatedMemory = NULL; + } + else if (This->flags & WINED3D_BUFFER_HASDESC) { buffer_PreLoad(iface); } @@ -908,18 +1003,16 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface) return WINED3D_OK; } -static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DVERTEXBUFFER_DESC *desc) +static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DBUFFER_DESC *desc) { struct wined3d_buffer *This = (struct wined3d_buffer *)iface; TRACE("(%p)\n", This); - desc->Format = This->resource.format_desc->format; desc->Type = This->resource.resourceType; desc->Usage = This->resource.usage; desc->Pool = This->resource.pool; desc->Size = This->resource.size; - desc->FVF = This->fvf; return WINED3D_OK; } @@ -947,253 +1040,3 @@ const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = buffer_Unmap, buffer_GetDesc, }; - -/* IUnknown methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface, - REFIID riid, void **object) -{ - TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); - - if (IsEqualGUID(riid, &IID_IWineD3DIndexBuffer) - || IsEqualGUID(riid, &IID_IWineD3DResource) - || IsEqualGUID(riid, &IID_IWineD3DBase) - || IsEqualGUID(riid, &IID_IUnknown)) - { - IUnknown_AddRef(iface); - *object = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid)); - - *object = NULL; - - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_AddRef(IWineD3DIndexBuffer *iface) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface; - ULONG refcount = InterlockedIncrement(&This->resource.ref); - - TRACE("%p increasing refcount to %u\n", This, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface; - ULONG refcount = InterlockedDecrement(&This->resource.ref); - - TRACE("%p decreasing refcount to %u\n", This, refcount); - - if (!refcount) - { - if (This->vbo) - { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - /* No need to manually unset the buffer. glDeleteBuffers unsets it for the current context, - * but not for other contexts. However, because the d3d buffer is destroyed the app has to - * unset it before doing the next draw, thus dirtifying the index buffer state and forcing - * binding a new buffer - */ - GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - } - - resource_cleanup((IWineD3DResource *)iface); - HeapFree(GetProcessHeap(), 0, This); - } - - return refcount; -} - -/* IWineD3DBase methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetParent(IWineD3DIndexBuffer *iface, IUnknown **parent) -{ - return resource_get_parent((IWineD3DResource *)iface, parent); -} - -/* IWineD3DResource methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDevice(IWineD3DIndexBuffer *iface, IWineD3DDevice **device) -{ - return resource_get_device((IWineD3DResource *)iface, device); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPrivateData(IWineD3DIndexBuffer *iface, - REFGUID guid, const void *data, DWORD data_size, DWORD flags) -{ - return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPrivateData(IWineD3DIndexBuffer *iface, - REFGUID guid, void *data, DWORD *data_size) -{ - return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size); -} - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_FreePrivateData(IWineD3DIndexBuffer *iface, REFGUID guid) -{ - return resource_free_private_data((IWineD3DResource *)iface, guid); -} - -static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPriority(IWineD3DIndexBuffer *iface, DWORD priority) -{ - return resource_set_priority((IWineD3DResource *)iface, priority); -} - -static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *iface) -{ - return resource_get_priority((IWineD3DResource *)iface); -} - -static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface) -{ - TRACE("iface %p\n", iface); -} - -static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *) iface; - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - TRACE("(%p)\n", This); - - /* This is easy: The whole content is shadowed in This->resource.allocatedMemory, - * so we only have to destroy the vbo. Only do it if we have a vbo, which implies - * that vbos are supported. - * (TODO: Make a IWineD3DBuffer base class for index and vertex buffers and share - * this code. Also needed for D3D10) - */ - if (This->vbo) - { - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo)); - checkGLcall("glDeleteBuffersARB"); - LEAVE_GL(); - This->vbo = 0; - } -} - -static WINED3DRESOURCETYPE STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetType(IWineD3DIndexBuffer *iface) -{ - return resource_get_type((IWineD3DResource *)iface); -} - -/* IWineD3DIndexBuffer methods */ - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Lock(IWineD3DIndexBuffer *iface, - UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface; - - TRACE("(%p) : offset %d, size %d, Flags=%x\n", This, OffsetToLock, SizeToLock, Flags); - - InterlockedIncrement(&This->lockcount); - *ppbData = This->resource.allocatedMemory + OffsetToLock; - - if (Flags & (WINED3DLOCK_READONLY | WINED3DLOCK_NO_DIRTY_UPDATE) || !This->vbo) - { - return WINED3D_OK; - } - - if (This->dirtystart != This->dirtyend) - { - if (This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock; - if (SizeToLock) - { - if (This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock; - } - else - { - This->dirtyend = This->resource.size; - } - } - else - { - This->dirtystart = OffsetToLock; - if (SizeToLock) This->dirtyend = OffsetToLock + SizeToLock; - else This->dirtyend = This->resource.size; - } - - return WINED3D_OK; -} - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Unlock(IWineD3DIndexBuffer *iface) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface; - ULONG locks = InterlockedDecrement(&This->lockcount); - - TRACE("(%p)\n", This); - - /* For now load in unlock */ - if (!locks && This->vbo && (This->dirtyend - This->dirtystart) > 0) - { - IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - - ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - - ENTER_GL(); - GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->vbo)); - checkGLcall("glBindBufferARB"); - GL_EXTCALL(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->dirtystart, - This->dirtyend - This->dirtystart, This->resource.allocatedMemory + This->dirtystart)); - checkGLcall("glBufferSubDataARB"); - LEAVE_GL(); - This->dirtystart = 0; - This->dirtyend = 0; - /* TODO: Move loading into preload when the buffer is used, that avoids dirtifying the state */ - IWineD3DDeviceImpl_MarkStateDirty(device, STATE_INDEXBUFFER); - } - - return WINED3D_OK; -} - -static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDesc(IWineD3DIndexBuffer *iface, - WINED3DINDEXBUFFER_DESC *pDesc) -{ - IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface; - - TRACE("(%p)\n", This); - - pDesc->Format = This->resource.format_desc->format; - pDesc->Type = This->resource.resourceType; - pDesc->Usage = This->resource.usage; - pDesc->Pool = This->resource.pool; - pDesc->Size = This->resource.size; - - return WINED3D_OK; -} - -const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl = -{ - /* IUnknown methods */ - IWineD3DIndexBufferImpl_QueryInterface, - IWineD3DIndexBufferImpl_AddRef, - IWineD3DIndexBufferImpl_Release, - /* IWineD3DBase methods */ - IWineD3DIndexBufferImpl_GetParent, - /* IWineD3DResource methods */ - IWineD3DIndexBufferImpl_GetDevice, - IWineD3DIndexBufferImpl_SetPrivateData, - IWineD3DIndexBufferImpl_GetPrivateData, - IWineD3DIndexBufferImpl_FreePrivateData, - IWineD3DIndexBufferImpl_SetPriority, - IWineD3DIndexBufferImpl_GetPriority, - IWineD3DIndexBufferImpl_PreLoad, - IWineD3DIndexBufferImpl_UnLoad, - IWineD3DIndexBufferImpl_GetType, - /* IWineD3DIndexBuffer methods */ - IWineD3DIndexBufferImpl_Lock, - IWineD3DIndexBufferImpl_Unlock, - IWineD3DIndexBufferImpl_GetDesc, -}; diff --git a/reactos/dll/directx/wine/wined3d/device.c b/reactos/dll/directx/wine/wined3d/device.c index ecc00d6a685..1099872ba3b 100644 --- a/reactos/dll/directx/wine/wined3d/device.c +++ b/reactos/dll/directx/wine/wined3d/device.c @@ -352,6 +352,8 @@ void device_stream_info_from_strided(IWineD3DDeviceImpl *This, for (i = 0; i < sizeof(stream_info->elements) / sizeof(*stream_info->elements); ++i) { + if (!stream_info->elements[i].format_desc) continue; + if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && stream_info->elements[i].format_desc->format == WINED3DFMT_A8R8G8B8) { stream_info->swizzle_map |= 1 << i; @@ -463,6 +465,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, HeapFree(GetProcessHeap(), 0, object); return hr; } + object->buffer_type_hint = GL_ARRAY_BUFFER_ARB; TRACE("Created resource %p\n", object); @@ -532,7 +535,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac } object->vtbl = &wined3d_buffer_vtbl; - hr = resource_init(&object->resource, WINED3DRTYPE_VERTEXBUFFER, This, Size, Usage, format_desc, Pool, parent); + hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent); if (FAILED(hr)) { WARN("Failed to initialize resource, returning %#x\n", hr); @@ -540,6 +543,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac *ppVertexBuffer = NULL; return hr; } + object->buffer_type_hint = GL_ARRAY_BUFFER_ARB; TRACE("(%p) : Created resource %p\n", This, object); @@ -548,8 +552,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object); *ppVertexBuffer = (IWineD3DBuffer *)object; - object->fvf = FVF; - /* Observations show that drawStridedSlow is faster on dynamic VBs than converting + * drawStridedFast (half-life 2). * @@ -580,62 +582,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac return WINED3D_OK; } -static void CreateIndexBufferVBO(IWineD3DDeviceImpl *This, IWineD3DIndexBufferImpl *object) { - GLenum error, glUsage; - TRACE("Creating VBO for Index Buffer %p\n", object); - - /* The following code will modify the ELEMENT_ARRAY_BUFFER binding, make sure it is - * restored on the next draw - */ - IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); - - /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */ - ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); - ENTER_GL(); - - while(glGetError()); - - GL_EXTCALL(glGenBuffersARB(1, &object->vbo)); - error = glGetError(); - if(error != GL_NO_ERROR || object->vbo == 0) { - ERR("Creating a vbo failed with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error); - goto out; - } - - GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->vbo)); - error = glGetError(); - if(error != GL_NO_ERROR) { - ERR("Failed to bind index buffer with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error); - goto out; - } - - /* Use static write only usage for now. Dynamic index buffers stay in sysmem, and due to the sysmem - * copy no readback will be needed - */ - glUsage = GL_STATIC_DRAW_ARB; - GL_EXTCALL(glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->resource.size, NULL, glUsage)); - error = glGetError(); - if(error != GL_NO_ERROR) { - ERR("Failed to initialize the index buffer with error %s (%#x)\n", debug_glerror(error), error); - goto out; - } - LEAVE_GL(); - TRACE("Successfully created vbo %d for index buffer %p\n", object->vbo, object); - return; - -out: - GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); - GL_EXTCALL(glDeleteBuffersARB(1, &object->vbo)); - LEAVE_GL(); - object->vbo = 0; -} - -static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage, - WINED3DFORMAT Format, WINED3DPOOL Pool, IWineD3DIndexBuffer** ppIndexBuffer, +static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage, + WINED3DPOOL Pool, IWineD3DBuffer** ppIndexBuffer, HANDLE *sharedHandle, IUnknown *parent) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info); - IWineD3DIndexBufferImpl *object; + const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info); + struct wined3d_buffer *object; HRESULT hr; TRACE("(%p) Creating index buffer\n", This); @@ -649,8 +601,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface return WINED3DERR_OUTOFVIDEOMEMORY; } - object->lpVtbl = &IWineD3DIndexBuffer_Vtbl; - hr = resource_init(&object->resource, WINED3DRTYPE_INDEXBUFFER, This, Length, Usage, format_desc, Pool, parent); + object->vtbl = &wined3d_buffer_vtbl; + hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent); if (FAILED(hr)) { WARN("Failed to initialize resource, returning %#x\n", hr); @@ -658,18 +610,19 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface *ppIndexBuffer = NULL; return hr; } + object->buffer_type_hint = GL_ELEMENT_ARRAY_BUFFER_ARB; TRACE("(%p) : Created resource %p\n", This, object); IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object); if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) { - CreateIndexBufferVBO(This, object); + object->flags |= WINED3D_BUFFER_CREATEBO; } - TRACE("(%p) : Len=%d, Use=%x, Format=(%u,%s), Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage, Format, - debug_d3dformat(Format), Pool, object, object->resource.allocatedMemory); - *ppIndexBuffer = (IWineD3DIndexBuffer *) object; + TRACE("(%p) : Len=%d, Use=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage, + Pool, object, object->resource.allocatedMemory); + *ppIndexBuffer = (IWineD3DBuffer *) object; return WINED3D_OK; } @@ -799,7 +752,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, } } if(object->pIndexData) { - IWineD3DIndexBuffer_AddRef(object->pIndexData); + IWineD3DBuffer_AddRef(object->pIndexData); } if(object->vertexShader) { IWineD3DVertexShader_AddRef(object->vertexShader); @@ -3684,40 +3637,48 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetMaterial(IWineD3DDevice *iface, WINE /***** * Get / Set Indices *****/ -static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWineD3DIndexBuffer* pIndexData) { +static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWineD3DBuffer* pIndexData, WINED3DFORMAT fmt) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DIndexBuffer *oldIdxs; + IWineD3DBuffer *oldIdxs; TRACE("(%p) : Setting to %p\n", This, pIndexData); oldIdxs = This->updateStateBlock->pIndexData; This->updateStateBlock->changed.indices = TRUE; This->updateStateBlock->pIndexData = pIndexData; + This->updateStateBlock->IndexFmt = fmt; /* Handle recording of state blocks */ if (This->isRecordingState) { TRACE("Recording... not performing anything\n"); - if(pIndexData) IWineD3DIndexBuffer_AddRef(pIndexData); - if(oldIdxs) IWineD3DIndexBuffer_Release(oldIdxs); + if(pIndexData) IWineD3DBuffer_AddRef(pIndexData); + if(oldIdxs) IWineD3DBuffer_Release(oldIdxs); return WINED3D_OK; } if(oldIdxs != pIndexData) { IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); - if(pIndexData) IWineD3DIndexBuffer_AddRef(pIndexData); - if(oldIdxs) IWineD3DIndexBuffer_Release(oldIdxs); + if(pIndexData) { + InterlockedIncrement(&((struct wined3d_buffer *)pIndexData)->bind_count); + IWineD3DBuffer_AddRef(pIndexData); + } + if(oldIdxs) { + InterlockedDecrement(&((struct wined3d_buffer *)oldIdxs)->bind_count); + IWineD3DBuffer_Release(oldIdxs); + } } + return WINED3D_OK; } -static HRESULT WINAPI IWineD3DDeviceImpl_GetIndices(IWineD3DDevice *iface, IWineD3DIndexBuffer** ppIndexData) { +static HRESULT WINAPI IWineD3DDeviceImpl_GetIndices(IWineD3DDevice *iface, IWineD3DBuffer** ppIndexData) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; *ppIndexData = This->stateBlock->pIndexData; /* up ref count on ppindexdata */ if (*ppIndexData) { - IWineD3DIndexBuffer_AddRef(*ppIndexData); + IWineD3DBuffer_AddRef(*ppIndexData); TRACE("(%p) index data set to %p\n", This, ppIndexData); }else{ TRACE("(%p) No index data set\n", This); @@ -4109,7 +4070,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF( iface, srcData, start, count); /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */ - if (srcData == NULL || start + count > GL_LIMITS(vshader_constantsF) || start > GL_LIMITS(vshader_constantsF)) + if (srcData == NULL || start + count > This->d3d_vshader_constantF || start > This->d3d_vshader_constantF) return WINED3DERR_INVALIDCALL; memcpy(&This->updateStateBlock->vertexShaderConstantF[start * 4], srcData, count * sizeof(float) * 4); @@ -4138,7 +4099,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF( UINT count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - int cnt = min(count, GL_LIMITS(vshader_constantsF) - start); + int cnt = min(count, This->d3d_vshader_constantF - start); TRACE("(iface %p, dstData %p, start %d, count %d)\n", iface, dstData, start, count); @@ -4501,7 +4462,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF( iface, srcData, start, count); /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */ - if (srcData == NULL || start + count > GL_LIMITS(pshader_constantsF) || start > GL_LIMITS(pshader_constantsF)) + if (srcData == NULL || start + count > This->d3d_pshader_constantF || start > This->d3d_pshader_constantF) return WINED3DERR_INVALIDCALL; memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, count * sizeof(float) * 4); @@ -4530,7 +4491,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF( UINT count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - int cnt = min(count, GL_LIMITS(pshader_constantsF) - start); + int cnt = min(count, This->d3d_pshader_constantF - start); TRACE("(iface %p, dstData %p, start %d, count %d)\n", iface, dstData, start, count); @@ -4544,11 +4505,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF( #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, - const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags) + const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags, + DWORD DestFVF) { char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL; unsigned int i; - DWORD DestFVF = dest->fvf; WINED3DVIEWPORT vp; WINED3DMATRIX mat, proj_mat, view_mat, world_mat; BOOL doClip; @@ -4637,7 +4598,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn FIXME("Clipping is broken and disabled for now\n"); } } else doClip = FALSE; - dest_ptr = ((char *) dest->resource.allocatedMemory) + dwDestIndex * get_flexible_vertex_size(DestFVF); + dest_ptr = ((char *) buffer_get_sysmem(dest)) + dwDestIndex * get_flexible_vertex_size(DestFVF); IWineD3DDevice_GetTransform( (IWineD3DDevice *) This, WINED3DTS_VIEW, @@ -4904,7 +4865,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn #undef copy_and_next static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, - UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags) + UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags, + DWORD DestFVF) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; struct wined3d_stream_info stream_info; @@ -4939,7 +4901,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); ENTER_GL(); GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); vb->buffer_object = 0; @@ -4950,7 +4912,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, } return process_vertices_strided(This, DestIndex, VertexCount, &stream_info, - (struct wined3d_buffer *)pDestBuffer, Flags); + (struct wined3d_buffer *)pDestBuffer, Flags, DestFVF); } /***** @@ -5677,8 +5639,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; UINT idxStride = 2; - IWineD3DIndexBuffer *pIB; - WINED3DINDEXBUFFER_DESC IdxBufDsc; + IWineD3DBuffer *pIB; GLuint vbo; pIB = This->stateBlock->pIndexData; @@ -5700,13 +5661,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); This->stateBlock->streamIsUP = FALSE; } - vbo = ((IWineD3DIndexBufferImpl *) pIB)->vbo; + vbo = ((struct wined3d_buffer *) pIB)->buffer_object; TRACE("(%p) : min %u, vertex count %u, startIdx %u, index count %u\n", This, minIndex, NumVertices, startIndex, index_count); - IWineD3DIndexBuffer_GetDesc(pIB, &IdxBufDsc); - if (IdxBufDsc.Format == WINED3DFMT_R16_UINT) { + if (This->stateBlock->IndexFmt == WINED3DFMT_R16_UINT) { idxStride = 2; } else { idxStride = 4; @@ -5718,7 +5678,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if } drawPrimitive(iface, index_count, NumVertices, startIndex, idxStride, - vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex); + vbo ? NULL : ((struct wined3d_buffer *) pIB)->resource.allocatedMemory, minIndex); return WINED3D_OK; } @@ -5769,7 +5729,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice * int idxStride; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DBuffer *vb; - IWineD3DIndexBuffer *ib; + IWineD3DBuffer *ib; TRACE("(%p) : MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u\n", This, MinVertexIndex, NumVertices, index_count, pIndexData, @@ -5809,7 +5769,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice * This->stateBlock->streamStride[0] = 0; ib = This->stateBlock->pIndexData; if(ib) { - IWineD3DIndexBuffer_Release(ib); + IWineD3DBuffer_Release(ib); This->stateBlock->pIndexData = NULL; } /* No need to mark the stream source state dirty here. Either the app calls UP drawing again, or it has to call @@ -6496,7 +6456,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice *iface, UI This->currentPatch = patch; old_primitive_type = This->stateBlock->gl_primitive_type; This->stateBlock->gl_primitive_type = GL_TRIANGLES; - IWineD3DDevice_DrawPrimitiveStrided(iface, patch->numSegs[0] * patch->numSegs[1] * 2, &patch->strided); + IWineD3DDevice_DrawPrimitiveStrided(iface, patch->numSegs[0] * patch->numSegs[1] * 2 * 3, &patch->strided); This->stateBlock->gl_primitive_type = old_primitive_type; This->currentPatch = NULL; @@ -7905,7 +7865,7 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW case WINED3DRTYPE_VOLUME: /* TODO: nothing really? */ break; - case WINED3DRTYPE_VERTEXBUFFER: + case WINED3DRTYPE_BUFFER: { int streamNumber; TRACE("Cleaning up stream pointers\n"); @@ -7928,24 +7888,19 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW } } } - } - break; - case WINED3DRTYPE_INDEXBUFFER: - if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */ - if (This->updateStateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) { - This->updateStateBlock->pIndexData = NULL; - } - } - if (This->stateBlock != NULL ) { /* ==NULL when device is being destroyed */ - if (This->stateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) { - This->stateBlock->pIndexData = NULL; - } - } - break; - case WINED3DRTYPE_BUFFER: - /* Nothing to do, yet.*/ - break; + if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */ + if (This->updateStateBlock->pIndexData == (IWineD3DBuffer *)resource) { + This->updateStateBlock->pIndexData = NULL; + } + } + if (This->stateBlock != NULL ) { /* ==NULL when device is being destroyed */ + if (This->stateBlock->pIndexData == (IWineD3DBuffer *)resource) { + This->stateBlock->pIndexData = NULL; + } + } + } + break; default: FIXME("(%p) unknown resource type %p %u\n", This, resource, IWineD3DResource_GetType(resource)); diff --git a/reactos/dll/directx/wine/wined3d/directx.c b/reactos/dll/directx/wine/wined3d/directx.c index a1bb3da018b..7c6cc3bad20 100644 --- a/reactos/dll/directx/wine/wined3d/directx.c +++ b/reactos/dll/directx/wine/wined3d/directx.c @@ -425,14 +425,10 @@ static void select_shader_max_constants( switch (vs_selected_mode) { case SHADER_GLSL: - /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ - gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1; + gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF; break; case SHADER_ARB: - /* We have to subtract any other PARAMs that we might use in our shader programs. - * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1, - * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */ - gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3; + gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF; break; default: gl_info->max_vshader_constantsF = 0; @@ -441,18 +437,10 @@ static void select_shader_max_constants( switch (ps_selected_mode) { case SHADER_GLSL: - /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog. - * In theory the texbem instruction may need one more shader constant too. But lets assume - * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card, - * and lets not take away a uniform needlessly from all other shaders. - */ - gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2; + gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF; break; case SHADER_ARB: - /* The arb shader only loads the bump mapping environment matrix into the shader if it finds - * a free constant to do that, so only reduce the number of available constants by 2 for the fog states. - */ - gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2; + gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF; break; default: gl_info->max_pshader_constantsF = 0; @@ -1089,13 +1077,29 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx. */ if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) { - /* Geforce GTX - highend */ - if(strstr(gl_info->gl_renderer, "GTX 280")) { + /* Geforce 200 - highend */ + if(strstr(gl_info->gl_renderer, "GTX 280") || + strstr(gl_info->gl_renderer, "GTX 285") || + strstr(gl_info->gl_renderer, "GTX 295")) + { gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280; vidmem = 1024; } - /* Geforce9 - highend */ - else if(strstr(gl_info->gl_renderer, "9800")) { + /* Geforce 200 - midend high */ + if(strstr(gl_info->gl_renderer, "GTX 275")) { + gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX275; + vidmem = 896; + } + /* Geforce 200 - midend */ + if(strstr(gl_info->gl_renderer, "GTX 260")) { + gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX260; + vidmem = 1024; + } + /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */ + else if(strstr(gl_info->gl_renderer, "9800") || + strstr(gl_info->gl_renderer, "GTS 150") || + strstr(gl_info->gl_renderer, "GTS 250")) + { gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT; vidmem = 512; } @@ -1104,6 +1108,28 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) { gl_info->gl_card = CARD_NVIDIA_GEFORCE_9600GT; vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */ } + /* Geforce9 - midend low / Geforce 200 - low*/ + else if(strstr(gl_info->gl_renderer, "9500") || + strstr(gl_info->gl_renderer, "GT 120") || + strstr(gl_info->gl_renderer, "GT 130")) + { + gl_info->gl_card = CARD_NVIDIA_GEFORCE_9500GT; + vidmem = 256; /* The 9500GT has 256-1024MB */ + } + /* Geforce9 - lowend */ + else if(strstr(gl_info->gl_renderer, "9400")) { + gl_info->gl_card = CARD_NVIDIA_GEFORCE_9400GT; + vidmem = 256; /* The 9400GT has 256-1024MB */ + } + /* Geforce9 - lowend low */ + else if(strstr(gl_info->gl_renderer, "9100") || + strstr(gl_info->gl_renderer, "9200") || + strstr(gl_info->gl_renderer, "9300") || + strstr(gl_info->gl_renderer, "G 100")) + { + gl_info->gl_card = CARD_NVIDIA_GEFORCE_9200; + vidmem = 256; /* The 9100-9300 cards have 256MB */ + } /* Geforce8 - highend */ else if (strstr(gl_info->gl_renderer, "8800")) { gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS; @@ -1683,7 +1709,10 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad /* Return the information requested */ TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n"); strcpy(pIdentifier->Driver, This->adapters[Adapter].driver); - strcpy(pIdentifier->Description, This->adapters[Adapter].description); + if(This->adapters[Adapter].gl_info.driver_description) + strcpy(pIdentifier->Description, This->adapters[Adapter].gl_info.driver_description); + else /* Copy default description "Direct3D HAL" */ + strcpy(pIdentifier->Description, This->adapters[Adapter].description); /* Note dx8 doesn't supply a DeviceName */ if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */ @@ -3010,7 +3039,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt /* Do nothing, continue with checking the format below */ break; } - } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){ + } else if(RType == WINED3DRTYPE_BUFFER){ /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */ TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n"); return WINED3DERR_NOTAVAILABLE; @@ -3697,6 +3726,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, const struct fragment_pipeline *frag_pipeline = NULL; int i; struct fragment_caps ffp_caps; + struct shader_caps shader_caps; HRESULT hr; /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter @@ -3752,6 +3782,11 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, &object->ps_selected_mode, &object->vs_selected_mode); object->shader_backend = select_shader_backend(adapter, DeviceType); + memset(&shader_caps, 0, sizeof(shader_caps)); + object->shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps); + object->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst; + object->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst; + memset(&ffp_caps, 0, sizeof(ffp_caps)); frag_pipeline = select_fragment_implementation(adapter, DeviceType); object->frag_pipe = frag_pipeline; @@ -3913,41 +3948,59 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) { struct driver_version_information { WORD vendor; /* reported PCI card vendor ID */ WORD card; /* reported PCI card device ID */ + const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */ WORD hipart_hi, hipart_lo; /* driver hiword to report */ WORD lopart_hi, lopart_lo; /* driver loword to report */ }; static const struct driver_version_information driver_version_table[] = { - /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (177.x)*/ - /* GeforceFX support is up to 173.x, Geforce2MX/3/4 up to 96.x, TNT/Geforce1/2 up to 71.x */ - /* Note that version numbers >100 lets say 123.45 use >= x.y.11.2345 and not x.y.10.12345 */ - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, 7, 15, 11, 7341 }, - {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, 7, 15, 11, 7341 }, + /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x) + * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown + * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89 + * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86 + * + * All version numbers used below are from the Linux nvidia drivers. + */ + {VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", 7, 1, 8, 6 }, + {VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", 7, 1, 8, 6 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", 7, 1, 8, 6 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", 9, 6, 4, 3 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", 7, 1, 8, 6 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", 9, 6, 4, 3 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", 9, 6, 4, 3 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", 9, 6, 4, 3 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", 7, 15, 11, 7341 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", 7, 15, 11, 7341 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", 7, 15, 11, 7341 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", 7, 15, 11, 8044 }, + {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", 7, 15, 11, 8044 }, /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */ - {VENDOR_ATI, CARD_ATI_RADEON_9500, 6, 14, 10, 6764 }, - {VENDOR_ATI, CARD_ATI_RADEON_X700, 6, 14, 10, 6764 }, - {VENDOR_ATI, CARD_ATI_RADEON_X1600, 6, 14, 10, 6764 }, - {VENDOR_ATI, CARD_ATI_RADEON_HD2300, 6, 14, 10, 6764 }, - {VENDOR_ATI, CARD_ATI_RADEON_HD2600, 6, 14, 10, 6764 }, - {VENDOR_ATI, CARD_ATI_RADEON_HD2900, 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 6, 14, 10, 6764 }, + {VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 6, 14, 10, 6764 }, - /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */ + /* TODO: Add information about legacy ATI hardware, Intel and other cards */ }; static void fixup_extensions(WineD3D_GL_Info *gl_info) { @@ -4049,6 +4102,7 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) { driver_version_table[i].lopart_lo); gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi, driver_version_table[i].hipart_lo); + strcpy(gl_info->driver_description, driver_version_table[i].description); break; } } diff --git a/reactos/dll/directx/wine/wined3d/drawprim.c b/reactos/dll/directx/wine/wined3d/drawprim.c index 80d366a95bf..c96b97586a7 100644 --- a/reactos/dll/directx/wine/wined3d/drawprim.c +++ b/reactos/dll/directx/wine/wined3d/drawprim.c @@ -95,7 +95,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i * idxData will be != NULL */ if(idxData == NULL) { - idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory; + idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); } if (idxSize == 2) pIdxBufS = idxData; @@ -413,7 +413,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream * idxData will be != NULL */ if(idxData == NULL) { - idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory; + idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData); } if (idxSize == 2) pIdxBufS = idxData; @@ -512,7 +512,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine { struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx]; - ptr += (long) vb->resource.allocatedMemory; + ptr += (long) buffer_get_sysmem(vb); } send_attribute(This, si->elements[instancedData[j]].format_desc->format, instancedData[j], ptr); @@ -535,7 +535,7 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_i { struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; e->buffer_object = 0; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); } } } @@ -744,7 +744,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, { struct wined3d_buffer *vb; vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; - e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb)); } vtxStride = e->stride; data = e->data + diff --git a/reactos/dll/directx/wine/wined3d/glsl_shader.c b/reactos/dll/directx/wine/wined3d/glsl_shader.c index 9ea193ec4bb..61c5701f02c 100644 --- a/reactos/dll/directx/wine/wined3d/glsl_shader.c +++ b/reactos/dll/directx/wine/wined3d/glsl_shader.c @@ -100,7 +100,7 @@ struct glsl_shader_prog_link { GLint vuniformI_locations[MAX_CONST_I]; GLint puniformI_locations[MAX_CONST_I]; GLint posFixup_location; - GLint rectFixup_location[MAX_FRAGMENT_SAMPLERS]; + GLint np2Fixup_location[MAX_FRAGMENT_SAMPLERS]; GLint bumpenvmat_location[MAX_TEXTURES]; GLint luminancescale_location[MAX_TEXTURES]; GLint luminanceoffset_location[MAX_TEXTURES]; @@ -482,6 +482,48 @@ static void reset_program_constant_version(void *value, void *context) entry->constant_version = 0; } +/** + * Loads the texture dimensions for NP2 fixup into the currently set GLSL program. + */ +static void shader_glsl_load_np2fixup_constants( + IWineD3DDevice* device, + char usePixelShader, + char useVertexShader) { + + const IWineD3DDeviceImpl* deviceImpl = (const IWineD3DDeviceImpl*) device; + const struct glsl_shader_prog_link* prog = ((struct shader_glsl_priv *)(deviceImpl->shader_priv))->glsl_program; + + if (!prog) { + /* No GLSL program set - nothing to do. */ + return; + } + + if (!usePixelShader) { + /* NP2 texcoord fixup is (currently) only done for pixelshaders. */ + return; + } + + if (prog->ps_args.np2_fixup) { + UINT i; + UINT fixup = prog->ps_args.np2_fixup; + const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info; + const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock; + + for (i = 0; fixup; fixup >>= 1, ++i) { + if (-1 != prog->np2Fixup_location[i]) { + const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i]; + if (!tex) { + FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n"); + continue; + } else { + const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]}; + GL_EXTCALL(glUniform2fvARB(prog->np2Fixup_location[i], 1, tex_dim)); + } + } + } + } +} + /** * Loads the app-supplied constants into the currently set GLSL program. */ @@ -588,24 +630,6 @@ static void shader_glsl_load_constants( } GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params)); } - - /* Constant loading for texture rect coord fixup. */ - if (prog->ps_args.texrect_fixup) { - UINT fixup = prog->ps_args.texrect_fixup; - - for (i = 0; fixup; fixup >>= 1, ++i) { - if (-1 != prog->rectFixup_location[i]) { - const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i]; - if (!tex) { - FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n"); - continue; - } else { - const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]}; - GL_EXTCALL(glUniform2fvARB(prog->rectFixup_location[i], 1, tex_dim)); - } - } - } - } } if (priv->next_constant_version == UINT_MAX) @@ -698,8 +722,15 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s /* Declare the constants (aka uniforms) */ if (This->baseShader.limits.constant_float > 0) { - unsigned max_constantsF = min(This->baseShader.limits.constant_float, - (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF))); + unsigned max_constantsF; + if(pshader) { + max_constantsF = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2; + max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF); + } else { + /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ + max_constantsF = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1; + max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF); + } shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF); } @@ -794,12 +825,12 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i); } - if(ps_args->texrect_fixup & (1 << i)) { - /* RECT textures in OpenGL use texcoords in the range [0,width]x[0,height] + if(ps_args->np2_fixup & (1 << i)) { + /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height] * while D3D has them in the (normalized) [0,1]x[0,1] range. - * samplerRectFixup stores texture dimensions and is updated through - * shader_glsl_load_constants when the sampler changes. */ - shader_addline(buffer, "uniform vec2 %csamplerRectFixup%u;\n", prefix, i); + * samplerNP2Fixup stores texture dimensions and is updated through + * shader_glsl_load_np2fixup_constants when the sampler changes. */ + shader_addline(buffer, "uniform vec2 %csamplerNP2Fixup%u;\n", prefix, i); } break; case WINED3DSTT_CUBE: @@ -989,26 +1020,25 @@ static void shader_glsl_gen_modifier ( /** Writes the GLSL variable name that corresponds to the register that the * DX opcode parameter is trying to access */ -static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_token, - char *regstr, BOOL *is_color, const struct wined3d_shader_instruction *ins) +static void shader_glsl_get_register_name(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx, + BOOL rel_addr, const DWORD addr_token, char *register_name, BOOL *is_color, + const struct wined3d_shader_instruction *ins) { /* oPos, oFog and oPts in D3D */ static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" }; - DWORD reg = param & WINED3DSP_REGNUM_MASK; - DWORD regtype = shader_get_regtype(param); IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader; IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device; const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info; DWORD shader_version = This->baseShader.reg_maps.shader_version; char pshader = shader_is_pshader_version(shader_version); - char tmpStr[150]; - *is_color = FALSE; - - switch (regtype) { + *is_color = FALSE; + + switch (register_type) + { case WINED3DSPR_TEMP: - sprintf(tmpStr, "R%u", reg); + sprintf(register_name, "R%u", register_idx); break; case WINED3DSPR_INPUT: if (pshader) { @@ -1017,84 +1047,90 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to { DWORD in_count = GL_LIMITS(glsl_varyings) / 4; - if (param & WINED3DSHADER_ADDRMODE_RELATIVE) { + if (rel_addr) + { glsl_src_param_t rel_param; shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param); /* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP * operation there */ - if(((IWineD3DPixelShaderImpl *) This)->input_reg_map[reg]) { + if (((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]) + { if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) { - sprintf(tmpStr, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])", - rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg], in_count - 1, - rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg], in_count, - rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg]); + sprintf(register_name, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])", + rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count - 1, + rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count, + rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]); } else { - sprintf(tmpStr, "IN[%s + %u]", rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg]); + sprintf(register_name, "IN[%s + %u]", rel_param.param_str, + ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]); } } else { if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) { - sprintf(tmpStr, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])", + sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])", rel_param.param_str, in_count - 1, rel_param.param_str, in_count, rel_param.param_str); } else { - sprintf(tmpStr, "IN[%s]", rel_param.param_str); + sprintf(register_name, "IN[%s]", rel_param.param_str); } } } else { - DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[reg]; + DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[register_idx]; if (idx == in_count) { - sprintf(tmpStr, "gl_Color"); + sprintf(register_name, "gl_Color"); } else if (idx == in_count + 1) { - sprintf(tmpStr, "gl_SecondaryColor"); + sprintf(register_name, "gl_SecondaryColor"); } else { - sprintf(tmpStr, "IN[%u]", idx); + sprintf(register_name, "IN[%u]", idx); } } } else { - if (reg==0) - strcpy(tmpStr, "gl_Color"); + if (register_idx == 0) + strcpy(register_name, "gl_Color"); else - strcpy(tmpStr, "gl_SecondaryColor"); + strcpy(register_name, "gl_SecondaryColor"); } } else { - if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg)) *is_color = TRUE; - sprintf(tmpStr, "attrib%u", reg); - } + if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE; + sprintf(register_name, "attrib%u", register_idx); + } break; case WINED3DSPR_CONST: { const char prefix = pshader? 'P':'V'; /* Relative addressing */ - if (param & WINED3DSHADER_ADDRMODE_RELATIVE) { - + if (rel_addr) + { /* Relative addressing on shaders 2.0+ have a relative address token, * prior to that, it was hard-coded as "A0.x" because there's only 1 register */ if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2) { glsl_src_param_t rel_param; shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param); - if(reg) { - sprintf(tmpStr, "%cC[%s + %u]", prefix, rel_param.param_str, reg); + if (register_idx) + { + sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, register_idx); } else { - sprintf(tmpStr, "%cC[%s]", prefix, rel_param.param_str); + sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str); } } else { - if(reg) { - sprintf(tmpStr, "%cC[A0.x + %u]", prefix, reg); + if (register_idx) + { + sprintf(register_name, "%cC[A0.x + %u]", prefix, register_idx); } else { - sprintf(tmpStr, "%cC[A0.x]", prefix); + sprintf(register_name, "%cC[A0.x]", prefix); } } } else { - if(shader_constant_is_local(This, reg)) { - sprintf(tmpStr, "%cLC%u", prefix, reg); + if (shader_constant_is_local(This, register_idx)) + { + sprintf(register_name, "%cLC%u", prefix, register_idx); } else { - sprintf(tmpStr, "%cC[%u]", prefix, reg); + sprintf(register_name, "%cC[%u]", prefix, register_idx); } } @@ -1102,99 +1138,109 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to } case WINED3DSPR_CONSTINT: if (pshader) - sprintf(tmpStr, "PI[%u]", reg); + sprintf(register_name, "PI[%u]", register_idx); else - sprintf(tmpStr, "VI[%u]", reg); + sprintf(register_name, "VI[%u]", register_idx); break; case WINED3DSPR_CONSTBOOL: if (pshader) - sprintf(tmpStr, "PB[%u]", reg); + sprintf(register_name, "PB[%u]", register_idx); else - sprintf(tmpStr, "VB[%u]", reg); + sprintf(register_name, "VB[%u]", register_idx); break; case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */ if (pshader) { - sprintf(tmpStr, "T%u", reg); + sprintf(register_name, "T%u", register_idx); } else { - sprintf(tmpStr, "A%u", reg); + sprintf(register_name, "A%u", register_idx); } break; case WINED3DSPR_LOOP: - sprintf(tmpStr, "aL%u", This->baseShader.cur_loop_regno - 1); + sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1); break; case WINED3DSPR_SAMPLER: if (pshader) - sprintf(tmpStr, "Psampler%u", reg); + sprintf(register_name, "Psampler%u", register_idx); else - sprintf(tmpStr, "Vsampler%u", reg); + sprintf(register_name, "Vsampler%u", register_idx); break; case WINED3DSPR_COLOROUT: - if (reg >= GL_LIMITS(buffers)) { - WARN("Write to render target %u, only %d supported\n", reg, 4); - } + if (register_idx >= GL_LIMITS(buffers)) + WARN("Write to render target %u, only %d supported\n", register_idx, 4); + if (GL_SUPPORT(ARB_DRAW_BUFFERS)) { - sprintf(tmpStr, "gl_FragData[%u]", reg); + sprintf(register_name, "gl_FragData[%u]", register_idx); } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */ - sprintf(tmpStr, "gl_FragColor"); + sprintf(register_name, "gl_FragColor"); } break; case WINED3DSPR_RASTOUT: - sprintf(tmpStr, "%s", hwrastout_reg_names[reg]); + sprintf(register_name, "%s", hwrastout_reg_names[register_idx]); break; case WINED3DSPR_DEPTHOUT: - sprintf(tmpStr, "gl_FragDepth"); + sprintf(register_name, "gl_FragDepth"); break; case WINED3DSPR_ATTROUT: - if (reg == 0) { - sprintf(tmpStr, "gl_FrontColor"); + if (register_idx == 0) + { + sprintf(register_name, "gl_FrontColor"); } else { - sprintf(tmpStr, "gl_FrontSecondaryColor"); + sprintf(register_name, "gl_FrontSecondaryColor"); } break; case WINED3DSPR_TEXCRDOUT: /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */ - if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(tmpStr, "OUT[%u]", reg); - else sprintf(tmpStr, "gl_TexCoord[%u]", reg); + if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(register_name, "OUT[%u]", register_idx); + else sprintf(register_name, "gl_TexCoord[%u]", register_idx); break; case WINED3DSPR_MISCTYPE: - if (reg == 0) { + if (register_idx == 0) + { /* vPos */ - sprintf(tmpStr, "vpos"); - } else if (reg == 1){ + sprintf(register_name, "vpos"); + } + else if (register_idx == 1) + { /* Note that gl_FrontFacing is a bool, while vFace is * a float for which the sign determines front/back */ - sprintf(tmpStr, "(gl_FrontFacing ? 1.0 : -1.0)"); + sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)"); } else { - FIXME("Unhandled misctype register %d\n", reg); - sprintf(tmpStr, "unrecognized_register"); + FIXME("Unhandled misctype register %d\n", register_idx); + sprintf(register_name, "unrecognized_register"); } break; default: - FIXME("Unhandled register name Type(%d)\n", regtype); - sprintf(tmpStr, "unrecognized_register"); + FIXME("Unhandled register name Type(%d)\n", register_type); + sprintf(register_name, "unrecognized_register"); break; } +} - strcat(regstr, tmpStr); +static void shader_glsl_write_mask_to_str(DWORD write_mask, char *str) +{ + *str++ = '.'; + if (write_mask & WINED3DSP_WRITEMASK_0) *str++ = 'x'; + if (write_mask & WINED3DSP_WRITEMASK_1) *str++ = 'y'; + if (write_mask & WINED3DSP_WRITEMASK_2) *str++ = 'z'; + if (write_mask & WINED3DSP_WRITEMASK_3) *str++ = 'w'; + *str = '\0'; } /* Get the GLSL write mask for the destination register */ -static DWORD shader_glsl_get_write_mask(const DWORD param, char *write_mask) { - char *ptr = write_mask; - DWORD mask = param & WINED3DSP_WRITEMASK_ALL; +static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *param, char *write_mask) +{ + DWORD mask = param->write_mask; - if (shader_is_scalar(param)) { + if (shader_is_scalar(param->register_type, param->register_idx)) + { mask = WINED3DSP_WRITEMASK_0; - } else { - *ptr++ = '.'; - if (param & WINED3DSP_WRITEMASK_0) *ptr++ = 'x'; - if (param & WINED3DSP_WRITEMASK_1) *ptr++ = 'y'; - if (param & WINED3DSP_WRITEMASK_2) *ptr++ = 'z'; - if (param & WINED3DSP_WRITEMASK_3) *ptr++ = 'w'; + *write_mask = '\0'; + } + else + { + shader_glsl_write_mask_to_str(mask, write_mask); } - - *ptr = '\0'; return mask; } @@ -1218,7 +1264,8 @@ static void shader_glsl_get_swizzle(const DWORD param, BOOL fixup, DWORD mask, c const char *swizzle_chars = fixup ? "zyxw" : "xyzw"; char *ptr = swizzle_str; - if (!shader_is_scalar(param)) { + if (!shader_is_scalar(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK)) + { *ptr++ = '.'; /* swizzle bits fields: wwzzyyxx */ if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = swizzle_chars[swizzle & 0x03]; @@ -1243,7 +1290,8 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i src_param->param_str[0] = '\0'; swizzle_str[0] = '\0'; - shader_glsl_get_register_name(param, addr_token, src_param->reg_name, &is_color, ins); + shader_glsl_get_register_name(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK, + param & WINED3DSHADER_ADDRMODE_RELATIVE, addr_token, src_param->reg_name, &is_color, ins); shader_glsl_get_swizzle(param, is_color, mask, swizzle_str); shader_glsl_gen_modifier(param, src_param->reg_name, swizzle_str, src_param->param_str); @@ -1253,31 +1301,27 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i * Also, return the actual register name and swizzle in case the * caller needs this information as well. */ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *ins, - const DWORD param, const DWORD addr_token, glsl_dst_param_t *dst_param) + const struct wined3d_shader_dst_param *wined3d_dst, glsl_dst_param_t *glsl_dst) { BOOL is_color = FALSE; - dst_param->mask_str[0] = '\0'; - dst_param->reg_name[0] = '\0'; + glsl_dst->mask_str[0] = '\0'; + glsl_dst->reg_name[0] = '\0'; - shader_glsl_get_register_name(param, addr_token, dst_param->reg_name, &is_color, ins); - return shader_glsl_get_write_mask(param, dst_param->mask_str); + shader_glsl_get_register_name(wined3d_dst->register_type, wined3d_dst->register_idx, + wined3d_dst->has_rel_addr, wined3d_dst->addr_token, glsl_dst->reg_name, &is_color, ins); + return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str); } /* Append the destination part of the instruction to the buffer, return the effective write mask */ static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer, - const struct wined3d_shader_instruction *ins, const DWORD param) + const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst) { - glsl_dst_param_t dst_param; + glsl_dst_param_t glsl_dst; DWORD mask; - int shift; - mask = shader_glsl_add_dst_param(ins, param, ins->dst[0].addr_token, &dst_param); - - if(mask) { - shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT; - shader_addline(buffer, "%s%s = %s(", dst_param.reg_name, dst_param.mask_str, shift_glsl_tab[shift]); - } + mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst); + if (mask) shader_addline(buffer, "%s%s = %s(", glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]); return mask; } @@ -1285,35 +1329,35 @@ static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer, /* Append the destination part of the instruction to the buffer, return the effective write mask */ static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const struct wined3d_shader_instruction *ins) { - return shader_glsl_append_dst_ext(buffer, ins, ins->dst[0].token); + return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]); } /** Process GLSL instruction modifiers */ void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins) { glsl_dst_param_t dst_param; - DWORD mask; + DWORD modifiers; if (!ins->dst_count) return; - mask = ins->dst[0].token & WINED3DSP_DSTMOD_MASK; - if (!mask) return; + modifiers = ins->dst[0].modifiers; + if (!modifiers) return; - shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param); + shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param); - if (mask & WINED3DSPDM_SATURATE) + if (modifiers & WINED3DSPDM_SATURATE) { /* _SAT means to clamp the value of the register to between 0 and 1 */ shader_addline(ins->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name, dst_param.mask_str, dst_param.reg_name, dst_param.mask_str); } - if (mask & WINED3DSPDM_MSAMPCENTROID) + if (modifiers & WINED3DSPDM_MSAMPCENTROID) { FIXME("_centroid modifier not handled\n"); } - if (mask & WINED3DSPDM_PARTIALPRECISION) + if (modifiers & WINED3DSPDM_PARTIALPRECISION) { /* MSDN says this modifier can be safely ignored, so that's what we'll do. */ } @@ -1435,18 +1479,18 @@ static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name, static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup) { + struct wined3d_shader_dst_param dst; unsigned int mask_size, remaining; glsl_dst_param_t dst_param; char arguments[256]; DWORD mask; - BOOL dummy; mask = 0; if (fixup.x_sign_fixup || fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0; if (fixup.y_sign_fixup || fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1; if (fixup.z_sign_fixup || fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2; if (fixup.w_sign_fixup || fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3; - mask &= ins->dst[0].token; + mask &= ins->dst[0].write_mask; if (!mask) return; /* Nothing to do */ @@ -1459,11 +1503,9 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction mask_size = shader_glsl_get_write_mask_size(mask); - dst_param.mask_str[0] = '\0'; - shader_glsl_get_write_mask(mask, dst_param.mask_str); - - dst_param.reg_name[0] = '\0'; - shader_glsl_get_register_name(ins->dst[0].token, ins->dst[0].addr_token, dst_param.reg_name, &dummy, ins); + dst = ins->dst[0]; + dst.write_mask = mask; + shader_glsl_add_dst_param(ins, &dst, &dst_param); arguments[0] = '\0'; remaining = mask_size; @@ -1506,10 +1548,10 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s const char *sampler_base; char dst_swizzle[6]; struct color_fixup_desc fixup; - BOOL rect_fixup = FALSE; + BOOL np2_fixup = FALSE; va_list args; - shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].token, dst_swizzle); + shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle); if (shader_is_pshader_version(ins->reg_maps->shader_version)) { @@ -1517,11 +1559,11 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s fixup = This->cur_args->color_fixup[sampler]; sampler_base = "Psampler"; - if(This->cur_args->texrect_fixup & (1 << sampler)) { + if(This->cur_args->np2_fixup & (1 << sampler)) { if(bias) { - FIXME("Biased sampling from RECT textures is unsupported\n"); + FIXME("Biased sampling from NP2 textures is unsupported\n"); } else { - rect_fixup = TRUE; + np2_fixup = TRUE; } } } else { @@ -1540,8 +1582,8 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s if(bias) { shader_addline(ins->buffer, ", %s)%s);\n", bias, dst_swizzle); } else { - if (rect_fixup) { - shader_addline(ins->buffer, " * PsamplerRectFixup%u)%s);\n", sampler, dst_swizzle); + if (np2_fixup) { + shader_addline(ins->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle); } else { shader_addline(ins->buffer, ")%s);\n", dst_swizzle); } @@ -1599,7 +1641,7 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins) * shader versions WINED3DSIO_MOVA is used for this. */ if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1 && !shader_is_pshader_version(ins->reg_maps->shader_version) - && shader_get_regtype(ins->dst[0].token) == WINED3DSPR_ADDR)) + && ins->dst[0].register_type == WINED3DSPR_ADDR)) { /* This is a simple floor() */ unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask); @@ -1662,7 +1704,7 @@ static void shader_glsl_cross(const struct wined3d_shader_instruction *ins) glsl_src_param_t src1_param; char dst_mask[6]; - shader_glsl_get_write_mask(ins->dst[0].token, dst_mask); + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_glsl_append_dst(ins->buffer, ins); shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param); shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param); @@ -1785,7 +1827,7 @@ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins) shader_addline(ins->buffer, "tmp0.w = 1.0;\n"); shader_glsl_append_dst(ins->buffer, ins); - shader_glsl_get_write_mask(ins->dst[0].token, dst_mask); + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_addline(ins->buffer, "tmp0%s);\n", dst_mask); } else { DWORD write_mask; @@ -1900,7 +1942,7 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) char mask_char[6]; BOOL temp_destination = FALSE; - if (shader_is_scalar(ins->src[0])) + if (shader_is_scalar(shader_get_regtype(ins->src[0]), ins->src[0] & WINED3DSP_REGNUM_MASK)) { write_mask = shader_glsl_append_dst(ins->buffer, ins); @@ -1918,7 +1960,9 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) DWORD src1regtype = shader_get_regtype(ins->src[1]); DWORD src2regtype = shader_get_regtype(ins->src[2]); DWORD dstreg = ins->dst[0].register_idx; - DWORD dstregtype = shader_get_regtype(ins->dst[0].token); + DWORD dstregtype = ins->dst[0].register_type; + DWORD dst_mask = ins->dst[0].write_mask; + struct wined3d_shader_dst_param dst = ins->dst[0]; /* Cycle through all source0 channels */ for (i=0; i<4; i++) { @@ -1931,23 +1975,22 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) cmp_channel = WINED3DSP_WRITEMASK_0 << j; } } + dst.write_mask = dst_mask & write_mask; /* Splitting the cmp instruction up in multiple lines imposes a problem: * The first lines may overwrite source parameters of the following lines. * Deal with that by using a temporary destination register if needed */ - if((src0reg == dstreg && src0regtype == dstregtype) || - (src1reg == dstreg && src1regtype == dstregtype) || - (src2reg == dstreg && src2regtype == dstregtype)) { - - write_mask = shader_glsl_get_write_mask(ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask), - mask_char); + if ((src0reg == dstreg && src0regtype == dstregtype) + || (src1reg == dstreg && src1regtype == dstregtype) + || (src2reg == dstreg && src2regtype == dstregtype)) + { + write_mask = shader_glsl_get_write_mask(&dst, mask_char); if (!write_mask) continue; shader_addline(ins->buffer, "tmp0%s = (", mask_char); temp_destination = TRUE; } else { - write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, - ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask)); + write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst); if (!write_mask) continue; } @@ -1960,8 +2003,8 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) } if(temp_destination) { - shader_glsl_get_write_mask(ins->dst[0].token, mask_char); - shader_glsl_append_dst_ext(ins->buffer, ins, ins->dst[0].token); + shader_glsl_get_write_mask(&ins->dst[0], mask_char); + shader_glsl_append_dst(ins->buffer, ins); shader_addline(ins->buffer, "tmp0%s);\n", mask_char); } } @@ -1973,11 +2016,13 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins) * the compare is done per component of src0. */ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins) { + struct wined3d_shader_dst_param dst; glsl_src_param_t src0_param; glsl_src_param_t src1_param; glsl_src_param_t src2_param; DWORD write_mask, cmp_channel = 0; unsigned int i, j; + DWORD dst_mask; if (ins->reg_maps->shader_version < WINED3DPS_VERSION(1, 4)) { @@ -1997,6 +2042,8 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins) return; } /* Cycle through all source0 channels */ + dst_mask = ins->dst[0].write_mask; + dst = ins->dst[0]; for (i=0; i<4; i++) { write_mask = 0; /* Find the destination channels which use the current source0 channel */ @@ -2007,8 +2054,9 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins) cmp_channel = WINED3DSP_WRITEMASK_0 << j; } } - write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, - ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask)); + + dst.write_mask = dst_mask & write_mask; + write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst); if (!write_mask) continue; shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param); @@ -2084,10 +2132,10 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins) break; } + tmp_dst = ins->dst[0]; for (i = 0; i < nComponents; ++i) { - tmp_dst.register_idx = ins->dst[0].register_idx; - tmp_dst.token = ((ins->dst[0].token) & ~WINED3DSP_WRITEMASK_ALL) | (WINED3DSP_WRITEMASK_0 << i); + tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i; tmp_ins.src[1] = ins->src[1] + i; shader_glsl_dot(&tmp_ins); } @@ -2130,7 +2178,7 @@ static void shader_glsl_lit(const struct wined3d_shader_instruction *ins) char dst_mask[6]; shader_glsl_append_dst(ins->buffer, ins); - shader_glsl_get_write_mask(ins->dst[0].token, dst_mask); + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param); shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src1_param); @@ -2177,7 +2225,7 @@ static void shader_glsl_dst(const struct wined3d_shader_instruction *ins) char dst_mask[6]; shader_glsl_append_dst(ins->buffer, ins); - shader_glsl_get_write_mask(ins->dst[0].token, dst_mask); + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src0y_param); shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &src0z_param); @@ -2451,7 +2499,7 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins) if (shader_version < WINED3DPS_VERSION(1,4)) { char coord_mask[6]; - shader_glsl_get_write_mask(mask, coord_mask); + shader_glsl_write_mask_to_str(mask, coord_mask); shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, "T%u%s", sampler_idx, coord_mask); } else { @@ -2506,16 +2554,15 @@ static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins) { /* FIXME: Make this work for more than just 2D textures */ SHADER_BUFFER *buffer = ins->buffer; - DWORD write_mask; - char dst_mask[6]; - - write_mask = shader_glsl_append_dst(ins->buffer, ins); - shader_glsl_get_write_mask(write_mask, dst_mask); + DWORD write_mask = shader_glsl_append_dst(ins->buffer, ins); if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4)) { - DWORD reg = ins->dst[0].register_idx; - shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask); + char dst_mask[6]; + + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); + shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", + ins->dst[0].register_idx, dst_mask); } else { DWORD reg = ins->src[0] & WINED3DSP_REGNUM_MASK; DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK; @@ -2621,7 +2668,7 @@ static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins) { glsl_dst_param_t dst_param; - shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param); + shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param); /* Tests show that texdepth never returns anything below 0.0, and that r5.y is clamped to 1.0. * Negative input is accepted, -0.25 / -0.5 returns 0.5. GL should clamp gl_FragDepth to [0;1], but @@ -2735,7 +2782,7 @@ static void pshader_glsl_texm3x3(const struct wined3d_shader_instruction *ins) shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param); shader_glsl_append_dst(ins->buffer, ins); - shader_glsl_get_write_mask(ins->dst[0].token, dst_mask); + shader_glsl_get_write_mask(&ins->dst[0], dst_mask); shader_addline(ins->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask); current_state->current_row = 0; @@ -2828,7 +2875,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins) shader_glsl_get_sample_function(sampler_type, 0, &sample_function); mask = sample_function.coord_mask; - shader_glsl_get_write_mask(mask, coord_mask); + shader_glsl_write_mask_to_str(mask, coord_mask); /* with projective textures, texbem only divides the static texture coord, not the displacement, * so we can't let the GL handle this. @@ -2843,7 +2890,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins) case WINED3DTTFF_COUNT4: case WINED3DTTFF_DISABLE: div_mask = WINED3DSP_WRITEMASK_3; break; } - shader_glsl_get_write_mask(div_mask, coord_div_mask); + shader_glsl_write_mask_to_str(div_mask, coord_div_mask); shader_addline(ins->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask); } @@ -2860,7 +2907,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins) glsl_dst_param_t dst_param; shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &luminance_param); - shader_glsl_add_dst_param(ins, ins->dst[0].token, ins->dst[0].addr_token, &dst_param); + shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param); shader_addline(ins->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n", dst_param.reg_name, dst_param.mask_str, @@ -2939,7 +2986,7 @@ static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins) glsl_dst_param_t dst_param; /* The argument is a destination parameter, and no writemasks are allowed */ - shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param); + shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param); if ((ins->reg_maps->shader_version >= WINED3DPS_VERSION(2,0))) { /* 2.0 shaders compare all 4 components in texkill */ @@ -2982,52 +3029,52 @@ static void pshader_glsl_dp2add(const struct wined3d_shader_instruction *ins) } } -static void pshader_glsl_input_pack(SHADER_BUFFER* buffer, const struct semantic* semantics_in, - IWineD3DPixelShader *iface, enum vertexprocessing_mode vertexprocessing) +static void pshader_glsl_input_pack(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer, + const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps, + enum vertexprocessing_mode vertexprocessing) { - unsigned int i; - IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface; + unsigned int i; + IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; - for (i = 0; i < MAX_REG_INPUT; i++) { + for (i = 0; i < MAX_REG_INPUT; ++i) + { + DWORD usage, usage_idx; + char reg_mask[6]; - DWORD usage_token = semantics_in[i].usage; - DWORD register_token = semantics_in[i].reg; - DWORD usage, usage_idx; - char reg_mask[6]; + /* Unused */ + if (!reg_maps->packed_input[i]) continue; - /* Uninitialized */ - if (!usage_token) continue; - usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_glsl_get_write_mask(register_token, reg_mask); + usage = semantics_in[i].usage; + usage_idx = semantics_in[i].usage_idx; + shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask); - switch(usage) { + switch (usage) + { + case WINED3DDECLUSAGE_TEXCOORD: + if (usage_idx < 8 && vertexprocessing == pretransformed) + shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n", + This->input_reg_map[i], reg_mask, usage_idx, reg_mask); + else + shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", + This->input_reg_map[i], reg_mask, reg_mask); + break; - case WINED3DDECLUSAGE_TEXCOORD: - if(usage_idx < 8 && vertexprocessing == pretransformed) { - shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n", - This->input_reg_map[i], reg_mask, usage_idx, reg_mask); - } else { - shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", - This->input_reg_map[i], reg_mask, reg_mask); - } - break; + case WINED3DDECLUSAGE_COLOR: + if (usage_idx == 0) + shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n", + This->input_reg_map[i], reg_mask, reg_mask); + else if (usage_idx == 1) + shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n", + This->input_reg_map[i], reg_mask, reg_mask); + else + shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", + This->input_reg_map[i], reg_mask, reg_mask); + break; - case WINED3DDECLUSAGE_COLOR: - if (usage_idx == 0) - shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n", - This->input_reg_map[i], reg_mask, reg_mask); - else if (usage_idx == 1) - shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n", - This->input_reg_map[i], reg_mask, reg_mask); - else - shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", - This->input_reg_map[i], reg_mask, reg_mask); - break; - - default: - shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", - This->input_reg_map[i], reg_mask, reg_mask); + default: + shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n", + This->input_reg_map[i], reg_mask, reg_mask); + break; } } } @@ -3081,12 +3128,11 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD HeapFree(GetProcessHeap(), 0, entry); } -static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *semantics_in, - const struct semantic *semantics_out, const WineD3D_GL_Info *gl_info, const DWORD *map) +static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, const DWORD *map, + const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps_in, + const struct wined3d_shader_semantic *semantics_out, const struct shader_reg_maps *reg_maps_out) { unsigned int i, j; - DWORD usage_token, usage_token_out; - DWORD register_token, register_token_out; DWORD usage, usage_idx, usage_out, usage_idx_out; DWORD *set; DWORD in_idx; @@ -3103,8 +3149,7 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman } for(i = 0; i < MAX_REG_INPUT; i++) { - usage_token = semantics_in[i].usage; - if (!usage_token) continue; + if (!reg_maps_in->packed_input[i]) continue; in_idx = map[i]; if (in_idx >= (in_count + 2)) { @@ -3125,11 +3170,9 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman sprintf(destination, "IN[%u]", in_idx); } - register_token = semantics_in[i].reg; - - usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - set[map[i]] = shader_glsl_get_write_mask(register_token, reg_mask); + usage = semantics_in[i].usage; + usage_idx = semantics_in[i].usage_idx; + set[map[i]] = shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask); if(!semantics_out) { switch(usage) { @@ -3167,13 +3210,11 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman } else { BOOL found = FALSE; for(j = 0; j < MAX_REG_OUTPUT; j++) { - usage_token_out = semantics_out[j].usage; - if (!usage_token_out) continue; - register_token_out = semantics_out[j].reg; + if (!reg_maps_out->packed_output[j]) continue; - usage_out = (usage_token_out & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - usage_idx_out = (usage_token_out & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_glsl_get_write_mask(register_token_out, reg_mask_out); + usage_out = semantics_out[j].usage; + usage_idx_out = semantics_out[j].usage_idx; + shader_glsl_get_write_mask(&semantics_out[j].reg, reg_mask_out); if(usage == usage_out && usage_idx == usage_idx_out) { @@ -3244,11 +3285,9 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0; unsigned int i; SHADER_BUFFER buffer; - DWORD usage_token; - DWORD register_token; DWORD usage, usage_idx, writemask; char reg_mask[6]; - const struct semantic *semantics_out, *semantics_in; + const struct wined3d_shader_semantic *semantics_out; shader_buffer_init(&buffer); @@ -3278,13 +3317,11 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT); for(i = 0; i < MAX_REG_OUTPUT; i++) { - usage_token = semantics_out[i].usage; - if (!usage_token) continue; - register_token = semantics_out[i].reg; + if (!vs->baseShader.reg_maps.packed_output[i]) continue; - usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - writemask = shader_glsl_get_write_mask(register_token, reg_mask); + usage = semantics_out[i].usage; + usage_idx = semantics_out[i].usage_idx; + writemask = shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask); switch(usage) { case WINED3DDECLUSAGE_COLOR: @@ -3326,7 +3363,6 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs } else if(ps_major >= 3 && vs_major >= 3) { semantics_out = vs->semantics_out; - semantics_in = ps->semantics_in; /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */ shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4); @@ -3334,13 +3370,11 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs /* First, sort out position and point size. Those are not passed to the pixel shader */ for(i = 0; i < MAX_REG_OUTPUT; i++) { - usage_token = semantics_out[i].usage; - if (!usage_token) continue; - register_token = semantics_out[i].reg; + if (!vs->baseShader.reg_maps.packed_output[i]) continue; - usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; - shader_glsl_get_write_mask(register_token, reg_mask); + usage = semantics_out[i].usage; + usage_idx = semantics_out[i].usage_idx; + shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask); switch(usage) { case WINED3DDECLUSAGE_POSITION: @@ -3357,19 +3391,18 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs } /* Then, fix the pixel shader input */ - handle_ps3_input(&buffer, semantics_in, semantics_out, gl_info, ps->input_reg_map); + handle_ps3_input(&buffer, gl_info, ps->input_reg_map, + ps->semantics_in, &ps->baseShader.reg_maps, semantics_out, &vs->baseShader.reg_maps); shader_addline(&buffer, "}\n"); } else if(ps_major >= 3 && vs_major < 3) { - semantics_in = ps->semantics_in; - shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4); shader_addline(&buffer, "void order_ps_input() {\n"); /* The vertex shader wrote to the builtin varyings. There is no need to figure out position and * point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't * read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings */ - handle_ps3_input(&buffer, semantics_in, NULL, gl_info, ps->input_reg_map); + handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->semantics_in, &ps->baseShader.reg_maps, NULL, NULL); shader_addline(&buffer, "}\n"); } else { ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major); @@ -3557,14 +3590,14 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use } } - if (use_ps && ps_compile_args.texrect_fixup) { + if (use_ps && ps_compile_args.np2_fixup) { char name[32]; for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) { - if (ps_compile_args.texrect_fixup & (1 << i)) { - sprintf(name, "PsamplerRectFixup%u", i); - entry->rectFixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name)); + if (ps_compile_args.np2_fixup & (1 << i)) { + sprintf(name, "PsamplerNP2Fixup%u", i); + entry->np2Fixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name)); } else { - entry->rectFixup_location[i] = -1; + entry->np2Fixup_location[i] = -1; } } } @@ -3766,9 +3799,13 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) { if(pshader) { ps = (IWineD3DPixelShaderImpl *) This; if(ps->num_gl_shaders == 0) return; + if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface) + shader_glsl_select(This->baseShader.device, FALSE, FALSE); } else { vs = (IWineD3DVertexShaderImpl *) This; if(vs->num_gl_shaders == 0) return; + if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface) + shader_glsl_select(This->baseShader.device, FALSE, FALSE); } linked_programs = &This->baseShader.linked_programs; @@ -3960,7 +3997,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU /* Pack 3.0 inputs */ if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0) && args->vp_mode != vertexshader) { - pshader_glsl_input_pack(buffer, This->semantics_in, iface, args->vp_mode); + pshader_glsl_input_pack(iface, buffer, This->semantics_in, reg_maps, args->vp_mode); } /* Base Shader Body */ @@ -4107,7 +4144,8 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info * else pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0); TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff); - pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); + /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ + pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1; /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b. * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed @@ -4125,6 +4163,13 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info * else pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0); + /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog. + * In theory the texbem instruction may need one more shader constant too. But lets assume + * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card, + * and lets not take away a uniform needlessly from all other shaders. + */ + pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2; + /* FIXME: The following line is card dependent. -8.0 to 8.0 is the * Direct3D minimum requirement. * @@ -4255,6 +4300,7 @@ const shader_backend_t glsl_shader_backend = { shader_glsl_update_float_vertex_constants, shader_glsl_update_float_pixel_constants, shader_glsl_load_constants, + shader_glsl_load_np2fixup_constants, shader_glsl_destroy, shader_glsl_alloc, shader_glsl_free, diff --git a/reactos/dll/directx/wine/wined3d/pixelshader.c b/reactos/dll/directx/wine/wined3d/pixelshader.c index de609a7fc26..d1701f5c1a4 100644 --- a/reactos/dll/directx/wine/wined3d/pixelshader.c +++ b/reactos/dll/directx/wine/wined3d/pixelshader.c @@ -460,7 +460,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set */ args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0; - args->texrect_fixup = 0; + args->np2_fixup = 0; for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) { if(shader->baseShader.reg_maps.samplers[i] == 0) continue; @@ -473,7 +473,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp /* Flag samplers that need NP2 texcoord fixup. */ if(!tex->baseTexture.pow2Matrix_identity) { - args->texrect_fixup |= (1 << i); + args->np2_fixup |= (1 << i); } } if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0)) diff --git a/reactos/dll/directx/wine/wined3d/state.c b/reactos/dll/directx/wine/wined3d/state.c index 47a94a0c66b..05e52b0fbdd 100644 --- a/reactos/dll/directx/wine/wined3d/state.c +++ b/reactos/dll/directx/wine/wined3d/state.c @@ -3367,11 +3367,10 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont /* Trigger shader constant reloading (for NP2 texcoord fixup) * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */ - if (!tex_impl->baseTexture.pow2Matrix_identity && use_ps(stateblock)) { + if (!tex_impl->baseTexture.pow2Matrix_identity) { IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice; - /* FIXME: add something like shader_load_rectfixup_consts to the backend to only reload the - * constants that are used for the fixup (and not the other ones too) */ - d3ddevice->shader_backend->shader_load_constants((IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock)); + d3ddevice->shader_backend->shader_load_np2fixup_constants( + (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock)); } } else if(mapped_stage < GL_LIMITS(textures)) { if(sampler < stateblock->lowest_disabled_stage) { @@ -4631,8 +4630,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) { GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); } else { - IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData; - GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo)); + struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData; + GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object)); } } diff --git a/reactos/dll/directx/wine/wined3d/stateblock.c b/reactos/dll/directx/wine/wined3d/stateblock.c index cbf5f97bc8d..1c9b5a8db9f 100644 --- a/reactos/dll/directx/wine/wined3d/stateblock.c +++ b/reactos/dll/directx/wine/wined3d/stateblock.c @@ -195,6 +195,7 @@ void stateblock_copy( Dest->vertexShader = This->vertexShader; Dest->streamIsUP = This->streamIsUP; Dest->pIndexData = This->pIndexData; + Dest->IndexFmt = This->IndexFmt; Dest->baseVertexIndex = This->baseVertexIndex; /* Dest->lights = This->lights; */ Dest->clip_status = This->clip_status; @@ -301,7 +302,7 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { } } } - if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); + if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData); if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader); if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader); @@ -506,13 +507,15 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type; if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData) - || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) { + || (This->baseVertexIndex != targetStateBlock->baseVertexIndex) + || (This->IndexFmt != targetStateBlock->IndexFmt))) { TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n", targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex); - if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData); - if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); + if(targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData); + if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData); This->pIndexData = targetStateBlock->pIndexData; This->baseVertexIndex = targetStateBlock->baseVertexIndex; + This->IndexFmt = targetStateBlock->IndexFmt; } if(This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){ @@ -655,10 +658,12 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState)); This->scissorRect = targetStateBlock->scissorRect; - if(targetStateBlock->pIndexData != This->pIndexData) { - if (targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData); - if (This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); + if(targetStateBlock->pIndexData != This->pIndexData || + targetStateBlock->IndexFmt != This->IndexFmt) { + if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData); + if (This->pIndexData) IWineD3DBuffer_Release(This->pIndexData); This->pIndexData = targetStateBlock->pIndexData; + This->IndexFmt = targetStateBlock->IndexFmt; } for(i = 0; i < MAX_STREAMS; i++) { if(targetStateBlock->streamSource[i] != This->streamSource[i]) { @@ -841,7 +846,7 @@ should really perform a delta so that only the changes get updated*/ } if (This->changed.indices) { - IWineD3DDevice_SetIndices(pDevice, This->pIndexData); + IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->IndexFmt); IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); } @@ -1023,7 +1028,7 @@ should really perform a delta so that only the changes get updated*/ IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]); } This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type; - IWineD3DDevice_SetIndices(pDevice, This->pIndexData); + IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->IndexFmt); IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl); IWineD3DDevice_SetMaterial(pDevice, &This->material); diff --git a/reactos/dll/directx/wine/wined3d/utils.c b/reactos/dll/directx/wine/wined3d/utils.c index 02f525519d0..7eb3d595658 100644 --- a/reactos/dll/directx/wine/wined3d/utils.c +++ b/reactos/dll/directx/wine/wined3d/utils.c @@ -996,8 +996,6 @@ const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) { RES_TO_STR(WINED3DRTYPE_TEXTURE); RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE); RES_TO_STR(WINED3DRTYPE_CUBETEXTURE); - RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER); - RES_TO_STR(WINED3DRTYPE_INDEXBUFFER); RES_TO_STR(WINED3DRTYPE_BUFFER); #undef RES_TO_STR default: diff --git a/reactos/dll/directx/wine/wined3d/vertexshader.c b/reactos/dll/directx/wine/wined3d/vertexshader.c index 402d5bdfcb8..fdd8cd8b35e 100644 --- a/reactos/dll/directx/wine/wined3d/vertexshader.c +++ b/reactos/dll/directx/wine/wined3d/vertexshader.c @@ -174,16 +174,15 @@ static void vshader_set_input( unsigned int regnum, BYTE usage, BYTE usage_idx) { - /* Fake usage: set reserved bit, usage, usage_idx */ - DWORD usage_token = (0x1 << 31) | - (usage << WINED3DSP_DCL_USAGE_SHIFT) | (usage_idx << WINED3DSP_DCL_USAGEINDEX_SHIFT); - - /* Fake register; set reserved bit, regnum, type: input, wmask: all */ - DWORD reg_token = (0x1 << 31) | - WINED3DSP_WRITEMASK_ALL | (WINED3DSPR_INPUT << WINED3DSP_REGTYPE_SHIFT) | regnum; - - This->semantics_in[regnum].usage = usage_token; - This->semantics_in[regnum].reg = reg_token; + This->semantics_in[regnum].usage = usage; + This->semantics_in[regnum].usage_idx = usage_idx; + This->semantics_in[regnum].reg.register_type = WINED3DSPR_INPUT; + This->semantics_in[regnum].reg.register_idx = regnum; + This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL; + This->semantics_in[regnum].reg.modifiers = 0; + This->semantics_in[regnum].reg.shift = 0; + This->semantics_in[regnum].reg.has_rel_addr = FALSE; + This->semantics_in[regnum].reg.addr_token = 0; } static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) { @@ -204,11 +203,11 @@ BOOL vshader_get_input( int i; for (i = 0; i < MAX_ATTRIBS; i++) { - DWORD usage_token = This->semantics_in[i].usage; - DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; - DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; + if (!This->baseShader.reg_maps.attributes[i]) continue; - if (usage_token && match_usage(usage, usage_idx, usage_req, usage_idx_req)) { + if (match_usage(This->semantics_in[i].usage, + This->semantics_in[i].usage_idx, usage_req, usage_idx_req)) + { *regnum = i; return TRUE; } diff --git a/reactos/dll/directx/wine/wined3d/wined3d_gl.h b/reactos/dll/directx/wine/wined3d/wined3d_gl.h index 2b5cbab87bb..cc760351af8 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_gl.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_gl.h @@ -3320,8 +3320,13 @@ typedef enum _GL_Cards { CARD_NVIDIA_GEFORCE_8600GT = 0x0402, CARD_NVIDIA_GEFORCE_8600MGT = 0x0407, CARD_NVIDIA_GEFORCE_8800GTS = 0x0193, + CARD_NVIDIA_GEFORCE_9200 = 0x086d, + CARD_NVIDIA_GEFORCE_9400GT = 0x042c, + CARD_NVIDIA_GEFORCE_9500GT = 0x0640, CARD_NVIDIA_GEFORCE_9600GT = 0x0622, CARD_NVIDIA_GEFORCE_9800GT = 0x0614, + CARD_NVIDIA_GEFORCE_GTX260 = 0x05e2, + CARD_NVIDIA_GEFORCE_GTX275 = 0x05e6, CARD_NVIDIA_GEFORCE_GTX280 = 0x05e1, CARD_INTEL_845G = 0x2562, @@ -3903,6 +3908,7 @@ typedef struct _WineD3D_GL_Info { UINT vidmem; DWORD driver_version; DWORD driver_version_hipart; + CHAR driver_description[255]; CHAR gl_renderer[255]; /** * CAPS Constants diff --git a/reactos/dll/directx/wine/wined3d/wined3d_private.h b/reactos/dll/directx/wine/wined3d/wined3d_private.h index 8f27f2dd582..566e2a68926 100644 --- a/reactos/dll/directx/wine/wined3d/wined3d_private.h +++ b/reactos/dll/directx/wine/wined3d/wined3d_private.h @@ -408,12 +408,6 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER WINED3DSIH_TABLE_SIZE }; -typedef struct semantic -{ - DWORD usage; - DWORD reg; -} semantic; - typedef struct shader_reg_maps { DWORD shader_version; @@ -454,8 +448,12 @@ typedef struct SHADER_OPCODE struct wined3d_shader_dst_param { + WINED3DSHADER_PARAM_REGISTER_TYPE register_type; UINT register_idx; - DWORD token; + DWORD write_mask; + DWORD modifiers; + DWORD shift; + BOOL has_rel_addr; DWORD addr_token; }; @@ -475,6 +473,13 @@ struct wined3d_shader_instruction UINT src_count; }; +struct wined3d_shader_semantic +{ + WINED3DDECLUSAGE usage; + UINT usage_idx; + struct wined3d_shader_dst_param reg; +}; + typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *); struct shader_caps { @@ -483,6 +488,7 @@ struct shader_caps { DWORD PixelShaderVersion; float PixelShader1xMaxValue; + DWORD MaxPixelShaderConst; WINED3DVSHADERCAPS2_0 VS20Caps; WINED3DPSHADERCAPS2_0 PS20Caps; @@ -533,8 +539,8 @@ struct ps_compile_args { /* Projected textures(ps 1.0-1.3) */ /* Texture types(2D, Cube, 3D) in ps 1.x */ BOOL srgb_correction; - WORD texrect_fixup; - /* Bitmap for texture rect coord fixups (16 samplers max currently). + WORD np2_fixup; + /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous in D3D10 (unconditional NP2 support mandatory). */ }; @@ -557,6 +563,7 @@ typedef struct { void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count); void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count); void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS); + void (*shader_load_np2fixup_constants)(IWineD3DDevice *iface, char usePS, char useVS); void (*shader_destroy)(IWineD3DBaseShader *iface); HRESULT (*shader_alloc_private)(IWineD3DDevice *iface); void (*shader_free_private)(IWineD3DDevice *iface); @@ -1212,6 +1219,7 @@ struct IWineD3DDeviceImpl const struct blit_shader *blitter; unsigned int max_ffp_textures, max_ffp_texture_stages; + DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */ WORD view_ident : 1; /* true iff view matrix is identity */ WORD untransformed : 1; @@ -1403,24 +1411,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 32 -/***************************************************************************** - * IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl) - */ -typedef struct IWineD3DIndexBufferImpl -{ - /* IUnknown & WineD3DResource Information */ - const IWineD3DIndexBufferVtbl *lpVtbl; - IWineD3DResourceClass resource; - - GLuint vbo; - UINT dirtystart, dirtyend; - LONG lockcount; - - /* WineD3DVertexBuffer specifics */ -} IWineD3DIndexBufferImpl; - -extern const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl; - /***************************************************************************** * IWineD3DBaseTexture D3D- > openGL state map lookups */ @@ -1947,7 +1937,8 @@ struct IWineD3DStateBlockImpl UINT streamFlags[MAX_STREAMS + 1]; /*0 | WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA */ /* Indices */ - IWineD3DIndexBuffer* pIndexData; + IWineD3DBuffer* pIndexData; + WINED3DFORMAT IndexFmt; INT baseVertexIndex; INT loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */ @@ -2092,6 +2083,7 @@ enum wined3d_buffer_conversion_type #define WINED3D_BUFFER_DIRTY 0x02 /* Buffer data has been modified */ #define WINED3D_BUFFER_HASDESC 0x04 /* A vertex description has been found */ #define WINED3D_BUFFER_CREATEBO 0x08 /* Attempt to create a buffer object next PreLoad */ +#define WINED3D_BUFFER_DOUBLEBUFFER 0x10 /* Use a vbo and local allocated memory */ struct wined3d_buffer { @@ -2102,6 +2094,7 @@ struct wined3d_buffer GLuint buffer_object; GLenum buffer_object_usage; + GLenum buffer_type_hint; UINT buffer_object_size; LONG bind_count; DWORD flags; @@ -2110,9 +2103,6 @@ struct wined3d_buffer UINT dirty_end; LONG lock_count; - /* legacy vertex buffers */ - DWORD fvf; - /* conversion stuff */ UINT conversion_count; UINT draw_count; @@ -2125,6 +2115,7 @@ struct wined3d_buffer extern const IWineD3DBufferVtbl wined3d_buffer_vtbl; const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object); +const BYTE *buffer_get_sysmem(struct wined3d_buffer *This); /* IWineD3DRendertargetView */ struct wined3d_rendertarget_view @@ -2357,7 +2348,8 @@ void shader_buffer_init(struct SHADER_BUFFER *buffer); void shader_buffer_free(struct SHADER_BUFFER *buffer); void shader_cleanup(IWineD3DBaseShader *iface); HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps, - struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code); + struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, + const DWORD *byte_code); void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device, const SHADER_OPCODE *instruction_table); void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table); @@ -2386,16 +2378,13 @@ static inline BOOL shader_is_comment(DWORD token) { return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK); } -static inline BOOL shader_is_scalar(DWORD param) { - DWORD reg_type = shader_get_regtype(param); - DWORD reg_num; - - switch (reg_type) { +static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx) +{ + switch (register_type) + { case WINED3DSPR_RASTOUT: - if ((param & WINED3DSP_REGNUM_MASK) != 0) { - /* oFog & oPts */ - return TRUE; - } + /* oFog & oPts */ + if (register_idx != 0) return TRUE; /* oPos */ return FALSE; @@ -2406,8 +2395,8 @@ static inline BOOL shader_is_scalar(DWORD param) { return TRUE; case WINED3DSPR_MISCTYPE: - reg_num = param & WINED3DSP_REGNUM_MASK; - switch(reg_num) { + switch(register_idx) + { case 0: /* vPos */ return FALSE; case 1: /* vFace */ @@ -2458,8 +2447,8 @@ typedef struct IWineD3DVertexShaderImpl { UINT num_gl_shaders, shader_array_size; /* Vertex shader input and output semantics */ - semantic semantics_in [MAX_ATTRIBS]; - semantic semantics_out [MAX_REG_OUTPUT]; + struct wined3d_shader_semantic semantics_in[MAX_ATTRIBS]; + struct wined3d_shader_semantic semantics_out[MAX_REG_OUTPUT]; UINT min_rel_offset, max_rel_offset; UINT rel_offset; @@ -2493,7 +2482,7 @@ typedef struct IWineD3DPixelShaderImpl { IUnknown *parent; /* Pixel shader input semantics */ - semantic semantics_in [MAX_REG_INPUT]; + struct wined3d_shader_semantic semantics_in[MAX_REG_INPUT]; DWORD input_reg_map[MAX_REG_INPUT]; BOOL input_reg_used[MAX_REG_INPUT]; int declared_in_count; diff --git a/reactos/include/reactos/wine/wined3d.idl b/reactos/include/reactos/wine/wined3d.idl index 604781b9397..b8691a75b0c 100644 --- a/reactos/include/reactos/wine/wined3d.idl +++ b/reactos/include/reactos/wine/wined3d.idl @@ -766,12 +766,10 @@ typedef enum _WINED3DRESOURCETYPE WINED3DRTYPE_TEXTURE = 3, WINED3DRTYPE_VOLUMETEXTURE = 4, WINED3DRTYPE_CUBETEXTURE = 5, - WINED3DRTYPE_VERTEXBUFFER = 6, - WINED3DRTYPE_INDEXBUFFER = 7, - WINED3DRTYPE_BUFFER = 8, + WINED3DRTYPE_BUFFER = 6, WINED3DRTYPE_FORCE_DWORD = 0x7fffffff } WINED3DRESOURCETYPE; -const UINT WINED3DRTYPECOUNT = WINED3DRTYPE_INDEXBUFFER + 1; +const UINT WINED3DRTYPECOUNT = WINED3DRTYPE_BUFFER + 1; typedef enum _WINED3DPOOL { @@ -1864,24 +1862,13 @@ typedef struct WINED3DDEVINFO_VCACHE non user modifiable (only valid if OptMethod==1) */ } WINED3DDEVINFO_VCACHE; -typedef struct _WINED3DVERTEXBUFFER_DESC +typedef struct _WINED3DBUFFER_DESC { - WINED3DFORMAT Format; WINED3DRESOURCETYPE Type; DWORD Usage; WINED3DPOOL Pool; UINT Size; - DWORD FVF; -} WINED3DVERTEXBUFFER_DESC; - -typedef struct _WINED3DINDEXBUFFER_DESC -{ - WINED3DFORMAT Format; - WINED3DRESOURCETYPE Type; - DWORD Usage; - WINED3DPOOL Pool; - UINT Size; -} WINED3DINDEXBUFFER_DESC; +} WINED3DBUFFER_DESC; typedef struct glDescriptor { @@ -2350,26 +2337,6 @@ interface IWineD3DRendertargetView : IWineD3DBase ); } -[ - object, - local, - uuid(3a02a54e-6f30-11d9-c687-00046142c14f) -] -interface IWineD3DIndexBuffer : IWineD3DResource -{ - HRESULT Lock( - [in] UINT offset, - [in] UINT size, - [out] BYTE **data, - [in] DWORD flags - ); - HRESULT Unlock( - ); - HRESULT GetDesc( - [out] WINED3DINDEXBUFFER_DESC *desc - ); -} - [ object, local, @@ -2844,7 +2811,7 @@ interface IWineD3DBuffer : IWineD3DResource HRESULT Unmap( ); HRESULT GetDesc( - [out] WINED3DVERTEXBUFFER_DESC *desc + [out] WINED3DBUFFER_DESC *desc ); } @@ -2925,9 +2892,8 @@ interface IWineD3DDevice : IWineD3DBase HRESULT CreateIndexBuffer( [in] UINT length, [in] DWORD usage, - [in] WINED3DFORMAT format, [in] WINED3DPOOL pool, - [out] IWineD3DIndexBuffer **index_buffer, + [out] IWineD3DBuffer **index_buffer, [in] HANDLE *shared_handle, [in] IUnknown *parent ); @@ -3150,10 +3116,11 @@ interface IWineD3DDevice : IWineD3DBase [out] WINED3DGAMMARAMP *ramp ); HRESULT SetIndices( - [in] IWineD3DIndexBuffer *index_buffer + [in] IWineD3DBuffer *index_buffer, + [in] WINED3DFORMAT format ); HRESULT GetIndices( - [out] IWineD3DIndexBuffer **index_buffer + [out] IWineD3DBuffer **index_buffer ); HRESULT SetBaseVertexIndex( [in] INT base_index @@ -3380,7 +3347,8 @@ interface IWineD3DDevice : IWineD3DBase [in] UINT vertex_count, [in] IWineD3DBuffer *dest_buffer, [in] IWineD3DVertexDeclaration *declaration, - [in] DWORD flags + [in] DWORD flags, + [in] DWORD DestFVF ); HRESULT BeginStateBlock( );