d3d: Fix ProcessVertices.
IDirect3DDevice9::ProcessVertices takes a vertex declaration, not a vertex buffer. The source for ProcessVertices is taken from the stateblock, not the vertex declaration.
This commit is contained in:
parent
0386eed91f
commit
460f71dcf8
|
@ -774,8 +774,9 @@ static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDE
|
||||||
|
|
||||||
static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9 iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
|
static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9 iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
|
||||||
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
|
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
|
||||||
|
IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
|
||||||
TRACE("(%p) Relay\n" , This);
|
TRACE("(%p) Relay\n" , This);
|
||||||
return IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer9Impl *)pDestBuffer)->wineD3DVertexBuffer, ((IDirect3DVertexBuffer9Impl *)pVertexDecl)->wineD3DVertexBuffer, Flags);
|
return IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer9Impl *)pDestBuffer)->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
|
IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
|
||||||
|
|
|
@ -341,6 +341,7 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
|
||||||
IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice);
|
IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice);
|
||||||
BOOL oldClip, doClip;
|
BOOL oldClip, doClip;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
WINED3DVERTEXBUFFER_DESC Desc;
|
||||||
|
|
||||||
TRACE("(%p)->(%08x,%d,%d,%p,%d,%p,%08x)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags);
|
TRACE("(%p)->(%08x,%d,%d,%p,%d,%p,%08x)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags);
|
||||||
|
|
||||||
|
@ -371,13 +372,21 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
|
||||||
doClip);
|
doClip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IWineD3DVertexBuffer_GetDesc(Src->wineD3DVertexBuffer,
|
||||||
|
&Desc);
|
||||||
|
IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice,
|
||||||
|
0, /* Stream No */
|
||||||
|
Src->wineD3DVertexBuffer,
|
||||||
|
0, /* Offset */
|
||||||
|
get_flexible_vertex_size(Desc.FVF));
|
||||||
|
IWineD3DDevice_SetVertexDeclaration(D3D->wineD3DDevice,
|
||||||
|
Src->wineD3DVertexDeclaration);
|
||||||
hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice,
|
hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice,
|
||||||
SrcIndex,
|
SrcIndex,
|
||||||
DestIndex,
|
DestIndex,
|
||||||
Count,
|
Count,
|
||||||
This->wineD3DVertexBuffer,
|
This->wineD3DVertexBuffer,
|
||||||
Src->wineD3DVertexBuffer,
|
NULL /* Output vdecl */,
|
||||||
Flags);
|
Flags);
|
||||||
|
|
||||||
/* Restore the states if needed */
|
/* Restore the states if needed */
|
||||||
|
|
|
@ -3489,7 +3489,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
|
||||||
|
|
||||||
#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
|
#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
|
||||||
static HRESULT
|
static HRESULT
|
||||||
process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, WineDirect3DVertexStridedData *lpStrideData, DWORD SrcFVF, IWineD3DVertexBufferImpl *dest, DWORD dwFlags) {
|
process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, WineDirect3DVertexStridedData *lpStrideData, IWineD3DVertexBufferImpl *dest, DWORD dwFlags) {
|
||||||
char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL;
|
char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
DWORD DestFVF = dest->fvf;
|
DWORD DestFVF = dest->fvf;
|
||||||
|
@ -3498,11 +3498,11 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
|
||||||
BOOL doClip;
|
BOOL doClip;
|
||||||
int numTextures;
|
int numTextures;
|
||||||
|
|
||||||
if (SrcFVF & WINED3DFVF_NORMAL) {
|
if (lpStrideData->u.s.normal.lpData) {
|
||||||
WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
|
WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (SrcFVF & WINED3DFVF_POSITION_MASK) != WINED3DFVF_XYZ) {
|
if (lpStrideData->u.s.position.lpData == NULL) {
|
||||||
ERR("Source has no position mask\n");
|
ERR("Source has no position mask\n");
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
@ -3837,15 +3837,14 @@ process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCo
|
||||||
}
|
}
|
||||||
#undef copy_and_next
|
#undef copy_and_next
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IWineD3DVertexBuffer* pDestBuffer, IWineD3DVertexBuffer* pVertexDecl, DWORD Flags) {
|
static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IWineD3DVertexBuffer* pDestBuffer, IWineD3DVertexDeclaration* pVertexDecl, DWORD Flags) {
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
IWineD3DVertexBufferImpl *SrcImpl = (IWineD3DVertexBufferImpl *) pVertexDecl;
|
|
||||||
WineDirect3DVertexStridedData strided;
|
WineDirect3DVertexStridedData strided;
|
||||||
|
BOOL vbo = FALSE;
|
||||||
TRACE("(%p)->(%d,%d,%d,%p,%p,%d\n", This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
|
TRACE("(%p)->(%d,%d,%d,%p,%p,%d\n", This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
|
||||||
|
|
||||||
if (!SrcImpl) {
|
if(pVertexDecl) {
|
||||||
WARN("NULL source vertex buffer\n");
|
ERR("Output vertex declaration not implemented yet\n");
|
||||||
return WINED3DERR_INVALIDCALL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need any context to write to the vbo. In a non-multithreaded environment a context is there anyway,
|
/* Need any context to write to the vbo. In a non-multithreaded environment a context is there anyway,
|
||||||
|
@ -3857,50 +3856,42 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't need the source vbo because this buffer is only used as
|
memset(&strided, 0, sizeof(strided));
|
||||||
* a source for ProcessVertices. Avoid wasting resources by converting the
|
if(This->stateBlock->vertexDecl) {
|
||||||
* buffer and loading the VBO
|
primitiveDeclarationConvertToStridedData(iface, FALSE, &strided, &vbo);
|
||||||
*/
|
} else {
|
||||||
if(SrcImpl->vbo) {
|
primitiveConvertToStridedData(iface, &strided, &vbo);
|
||||||
TRACE("Releasing the source vbo, it won't be needed\n");
|
|
||||||
|
|
||||||
if(!SrcImpl->resource.allocatedMemory) {
|
|
||||||
/* Rescue the data from the buffer */
|
|
||||||
void *src;
|
|
||||||
SrcImpl->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), 0, SrcImpl->resource.size);
|
|
||||||
if(!SrcImpl->resource.allocatedMemory) {
|
|
||||||
ERR("Out of memory\n");
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ENTER_GL();
|
|
||||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, SrcImpl->vbo));
|
|
||||||
checkGLcall("glBindBufferARB");
|
|
||||||
|
|
||||||
src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB));
|
|
||||||
if(src) {
|
|
||||||
memcpy(SrcImpl->resource.allocatedMemory, src, SrcImpl->resource.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB));
|
|
||||||
checkGLcall("glUnmapBufferARB");
|
|
||||||
} else {
|
|
||||||
ENTER_GL();
|
|
||||||
}
|
|
||||||
|
|
||||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
|
|
||||||
checkGLcall("glBindBufferARB");
|
|
||||||
GL_EXTCALL(glDeleteBuffersARB(1, &SrcImpl->vbo));
|
|
||||||
checkGLcall("glDeleteBuffersARB");
|
|
||||||
LEAVE_GL();
|
|
||||||
|
|
||||||
SrcImpl->vbo = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&strided, 0, sizeof(strided));
|
if(vbo || SrcStartIndex) {
|
||||||
primitiveConvertFVFtoOffset(SrcImpl->fvf, get_flexible_vertex_size(SrcImpl->fvf), SrcImpl->resource.allocatedMemory + get_flexible_vertex_size(SrcImpl->fvf) * SrcStartIndex, &strided, 0, 0);
|
unsigned int i;
|
||||||
|
/* ProcessVertices can't convert FROM a vbo, and vertex buffers used to source into ProcesVerticse are
|
||||||
|
* unlikely to ever be used for drawing. Release vbos in those buffers and fix up the strided structure
|
||||||
|
*
|
||||||
|
* Also get the start index in, but only loop over all elements if there's something to add at all.
|
||||||
|
*/
|
||||||
|
for(i=0; i < 16; i++) {
|
||||||
|
if(strided.u.input[i].VBO) {
|
||||||
|
IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[strided.u.input[i].streamNo];
|
||||||
|
|
||||||
return process_vertices_strided(This, DestIndex, VertexCount, &strided, SrcImpl->fvf, (IWineD3DVertexBufferImpl *) pDestBuffer, Flags);
|
/* The vertex buffer is supposed to have a system memory copy */
|
||||||
|
strided.u.input[i].VBO = 0;
|
||||||
|
strided.u.input[i].lpData = (BYTE *) ((unsigned long) strided.u.input[i].lpData + (unsigned long) vb->resource.allocatedMemory);
|
||||||
|
ENTER_GL();
|
||||||
|
GL_EXTCALL(glDeleteBuffersARB(1, &vb->vbo));
|
||||||
|
vb->vbo = 0;
|
||||||
|
LEAVE_GL();
|
||||||
|
|
||||||
|
/* To be safe. An app could technically draw, then call ProcessVertices, then draw again without ever changing the stream sources */
|
||||||
|
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
|
||||||
|
}
|
||||||
|
if(strided.u.input[i].lpData) {
|
||||||
|
strided.u.input[i].lpData += strided.u.input[i].dwStride * SrcStartIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return process_vertices_strided(This, DestIndex, VertexCount, &strided, (IWineD3DVertexBufferImpl *) pDestBuffer, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****
|
/*****
|
||||||
|
|
|
@ -452,7 +452,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase)
|
||||||
STDMETHOD(GetViewport)(THIS_ WINED3DVIEWPORT * pViewport) PURE;
|
STDMETHOD(GetViewport)(THIS_ WINED3DVIEWPORT * pViewport) PURE;
|
||||||
STDMETHOD(MultiplyTransform)(THIS_ WINED3DTRANSFORMSTATETYPE State, CONST WINED3DMATRIX * pMatrix) PURE;
|
STDMETHOD(MultiplyTransform)(THIS_ WINED3DTRANSFORMSTATETYPE State, CONST WINED3DMATRIX * pMatrix) PURE;
|
||||||
STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE;
|
STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE;
|
||||||
STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, struct IWineD3DVertexBuffer* pDestBuffer, struct IWineD3DVertexBuffer* pVertexDecl, DWORD Flags) PURE;
|
STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, struct IWineD3DVertexBuffer* pDestBuffer, struct IWineD3DVertexDeclaration* pVertexDecl, DWORD Flags) PURE;
|
||||||
STDMETHOD(BeginStateBlock)(THIS) PURE;
|
STDMETHOD(BeginStateBlock)(THIS) PURE;
|
||||||
STDMETHOD(EndStateBlock)(THIS_ struct IWineD3DStateBlock** ppStateBlock) PURE;
|
STDMETHOD(EndStateBlock)(THIS_ struct IWineD3DStateBlock** ppStateBlock) PURE;
|
||||||
STDMETHOD(BeginScene)(THIS) PURE;
|
STDMETHOD(BeginScene)(THIS) PURE;
|
||||||
|
|
Loading…
Reference in New Issue