wined3d: Vertex buffers can use the declaration from the device.
This commit is contained in:
parent
6fb1869b98
commit
d47ec21280
|
@ -219,6 +219,10 @@ void primitiveDeclarationConvertToStridedData(
|
||||||
WINED3DVERTEXELEMENT *element;
|
WINED3DVERTEXELEMENT *element;
|
||||||
DWORD stride;
|
DWORD stride;
|
||||||
int reg;
|
int reg;
|
||||||
|
char isPreLoaded[MAX_STREAMS];
|
||||||
|
DWORD preLoadStreams[MAX_STREAMS], numPreloadStreams = 0;
|
||||||
|
|
||||||
|
memset(isPreLoaded, 0, sizeof(isPreLoaded));
|
||||||
|
|
||||||
/* Locate the vertex declaration */
|
/* Locate the vertex declaration */
|
||||||
if (This->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration) {
|
if (This->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration) {
|
||||||
|
@ -249,7 +253,11 @@ void primitiveDeclarationConvertToStridedData(
|
||||||
if(fixup && *fixup) FIXME("Missing fixed and unfixed vertices, expect graphics glitches\n");
|
if(fixup && *fixup) FIXME("Missing fixed and unfixed vertices, expect graphics glitches\n");
|
||||||
} else {
|
} else {
|
||||||
TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
|
TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
|
||||||
IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[element->Stream]);
|
if(!isPreLoaded[element->Stream]) {
|
||||||
|
preLoadStreams[numPreloadStreams] = element->Stream;
|
||||||
|
numPreloadStreams++;
|
||||||
|
isPreLoaded[element->Stream] = 1;
|
||||||
|
}
|
||||||
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
|
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
|
||||||
if(fixup) {
|
if(fixup) {
|
||||||
if( streamVBO != 0) *fixup = TRUE;
|
if( streamVBO != 0) *fixup = TRUE;
|
||||||
|
@ -287,6 +295,17 @@ void primitiveDeclarationConvertToStridedData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/* Now call PreLoad on all the vertex buffers. In the very rare case
|
||||||
|
* that the buffers stopps converting PreLoad will dirtify the VDECL again.
|
||||||
|
* The vertex buffer can now use the strided structure in the device instead of finding its
|
||||||
|
* own again.
|
||||||
|
*
|
||||||
|
* NULL streams won't be recorded in the array, UP streams won't be either. A stream is only
|
||||||
|
* once in there.
|
||||||
|
*/
|
||||||
|
for(i=0; i < numPreloadStreams; i++) {
|
||||||
|
IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[preLoadStreams[i]]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void primitiveConvertFVFtoOffset(DWORD thisFVF, DWORD stride, BYTE *data, WineDirect3DVertexStridedData *strided, GLint streamVBO) {
|
void primitiveConvertFVFtoOffset(DWORD thisFVF, DWORD stride, BYTE *data, WineDirect3DVertexStridedData *strided, GLint streamVBO) {
|
||||||
|
@ -413,6 +432,7 @@ void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStri
|
||||||
short LoopThroughTo = 0;
|
short LoopThroughTo = 0;
|
||||||
short nStream;
|
short nStream;
|
||||||
GLint streamVBO = 0;
|
GLint streamVBO = 0;
|
||||||
|
DWORD preLoadStreams[MAX_STREAMS], numPreloadStreams = 0;
|
||||||
|
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
|
|
||||||
|
@ -443,7 +463,11 @@ void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStri
|
||||||
streamVBO = 0;
|
streamVBO = 0;
|
||||||
data = (BYTE *)This->stateBlock->streamSource[nStream];
|
data = (BYTE *)This->stateBlock->streamSource[nStream];
|
||||||
} else {
|
} else {
|
||||||
IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[nStream]);
|
/* The for loop should iterate through here only once per stream, so we don't need magic to prevent double loading
|
||||||
|
* buffers
|
||||||
|
*/
|
||||||
|
preLoadStreams[numPreloadStreams] = nStream;
|
||||||
|
numPreloadStreams++;
|
||||||
/* GetMemory binds the VBO */
|
/* GetMemory binds the VBO */
|
||||||
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[nStream], 0, &streamVBO);
|
data = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[nStream], 0, &streamVBO);
|
||||||
if(fixup) {
|
if(fixup) {
|
||||||
|
@ -462,6 +486,17 @@ void primitiveConvertToStridedData(IWineD3DDevice *iface, WineDirect3DVertexStri
|
||||||
/* Now convert the stream into pointers */
|
/* Now convert the stream into pointers */
|
||||||
primitiveConvertFVFtoOffset(thisFVF, stride, data, strided, streamVBO);
|
primitiveConvertFVFtoOffset(thisFVF, stride, data, strided, streamVBO);
|
||||||
}
|
}
|
||||||
|
/* Now call PreLoad on all the vertex buffers. In the very rare case
|
||||||
|
* that the buffers stopps converting PreLoad will dirtify the VDECL again.
|
||||||
|
* The vertex buffer can now use the strided structure in the device instead of finding its
|
||||||
|
* own again.
|
||||||
|
*
|
||||||
|
* NULL streams won't be recorded in the array, UP streams won't be either. A stream is only
|
||||||
|
* once in there.
|
||||||
|
*/
|
||||||
|
for(nStream=0; nStream < numPreloadStreams; nStream++) {
|
||||||
|
IWineD3DVertexBuffer_PreLoad(This->stateBlock->streamSource[preLoadStreams[nStream]]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* TODO: Software Shaders */
|
#if 0 /* TODO: Software Shaders */
|
||||||
|
|
|
@ -164,7 +164,6 @@ inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
|
||||||
{
|
{
|
||||||
WineDirect3DVertexStridedData strided;
|
WineDirect3DVertexStridedData strided;
|
||||||
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
memset(&strided, 0, sizeof(strided));
|
memset(&strided, 0, sizeof(strided));
|
||||||
/* There are certain vertex data types that need to be fixed up. The Vertex Buffers FVF doesn't
|
/* There are certain vertex data types that need to be fixed up. The Vertex Buffers FVF doesn't
|
||||||
|
@ -191,38 +190,18 @@ inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
|
||||||
* FALSE: otherwise
|
* FALSE: otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(device->stateBlock->vertexShader != NULL && wined3d_settings.vs_mode != VS_NONE
|
if(device->stateBlock->vertexShader && ((IWineD3DVertexShaderImpl *) device->stateBlock->vertexShader)->baseShader.function) {
|
||||||
&&((IWineD3DVertexShaderImpl *)device->stateBlock->vertexShader)->baseShader.function != NULL
|
/* Assume no conversion */
|
||||||
&& GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
|
memset(&strided, 0, sizeof(strided));
|
||||||
/* Case 1: Vertex Shader: No conversion */
|
|
||||||
TRACE("Vertex Shader, no conversion needed\n");
|
|
||||||
} else if(device->stateBlock->vertexDecl || device->stateBlock->vertexShader) {
|
|
||||||
/* Case 2: Vertex Declaration */
|
|
||||||
TRACE("Using vertex declaration\n");
|
|
||||||
|
|
||||||
This->Flags |= VBFLAG_LOAD;
|
|
||||||
primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
|
|
||||||
FALSE,
|
|
||||||
&strided,
|
|
||||||
&ret /* buffer contains fixed data, ignored here */);
|
|
||||||
This->Flags &= ~VBFLAG_LOAD;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Case 3: FVF */
|
/* we need a copy because we modify some params */
|
||||||
if(!(This->Flags & VBFLAG_STREAM) ) {
|
memcpy(&strided, &device->strided_streams, sizeof(strided));
|
||||||
TRACE("No vertex decl used and buffer is not bound to a stream\n");
|
|
||||||
/* No reload needed */
|
/* Filter out data that does not come from this VBO */
|
||||||
return FALSE;
|
if(strided.u.s.position.VBO != This->vbo) memset(&strided.u.s.position, 0, sizeof(strided.u.s.position));
|
||||||
} else {
|
if(strided.u.s.diffuse.VBO != This->vbo) memset(&strided.u.s.diffuse, 0, sizeof(strided.u.s.diffuse));
|
||||||
This->Flags |= VBFLAG_LOAD;
|
if(strided.u.s.specular.VBO != This->vbo) memset(&strided.u.s.specular, 0, sizeof(strided.u.s.specular));
|
||||||
primitiveConvertFVFtoOffset(device->stateBlock->fvf,
|
if(strided.u.s.position2.VBO != This->vbo) memset(&strided.u.s.position2, 0, sizeof(strided.u.s.position2));
|
||||||
device->stateBlock->streamStride[This->stream],
|
|
||||||
NULL,
|
|
||||||
&strided,
|
|
||||||
This->vbo);
|
|
||||||
This->Flags &= ~VBFLAG_LOAD;
|
|
||||||
/* Data can only come from this buffer */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter out data that does not come from this VBO */
|
/* Filter out data that does not come from this VBO */
|
||||||
|
@ -297,6 +276,14 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
||||||
checkGLcall("glDeleteBuffersARB");
|
checkGLcall("glDeleteBuffersARB");
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
This->vbo = 0;
|
This->vbo = 0;
|
||||||
|
|
||||||
|
/* The stream source state handler might have read the memory of the vertex buffer already
|
||||||
|
* and got the memory in the vbo which is not valid any longer. Dirtify the stream source
|
||||||
|
* to force a reload. This happens only once per changed vertexbuffer and should occur rather
|
||||||
|
* rarely
|
||||||
|
*/
|
||||||
|
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_STREAMSRC);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Otherwise do not bother to release the VBO. If we're doing direct locking now,
|
/* Otherwise do not bother to release the VBO. If we're doing direct locking now,
|
||||||
|
|
Loading…
Reference in New Issue