Module: wine Branch: master Commit: 5fa0f7f77563bbd77f48b476817dd3c77a877d49 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5fa0f7f77563bbd77f48b47681...
Author: Stefan Dösinger stefandoesinger@gmx.at Date: Tue Jan 2 22:47:39 2007 +0100
wined3d: Move the world matrix to the state table.
---
dlls/wined3d/device.c | 7 +--- dlls/wined3d/state.c | 74 +++++++++++++++++++++++++++------------ dlls/wined3d/surface.c | 2 + dlls/wined3d/wined3d_private.h | 1 - 4 files changed, 54 insertions(+), 30 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 00a888c..f205db9 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1936,7 +1936,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl }
/* Initialize the current view state */ - This->modelview_valid = 1; This->proj_valid = 0; This->view_ident = 1; This->last_was_rhw = 0; @@ -2364,13 +2363,9 @@ static HRESULT WINAPI IWineD3DDeviceIm */
/* Capture the times we can just ignore the change for now */ - if (d3dts == WINED3DTS_WORLDMATRIX(0)) { - This->modelview_valid = FALSE; - } else if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */ + if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */ This->view_ident = !memcmp(lpmatrix, identity, 16 * sizeof(float)); /* Handled by the state manager */ - } else { /* What was requested!?? */ - WARN("invalid matrix specified: %i\n", d3dts); }
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_TRANSFORM(d3dts)); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 3361c85..ee56be2 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1813,6 +1813,29 @@ static void pixelshader(DWORD state, IWi } }
+static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock) { + /* Do not bother applying when we're in rhw mode. vertexdeclaration() will call + * transform_world if it switches out of rhw mode. This function is also called + * by transform_view below if the view matrix was changed + */ + if(stateblock->wineD3DDevice->last_was_rhw) { + return; + } + glMatrixMode(GL_MODELVIEW); + checkGLcall("glMatrixMode"); + + /* In the general case, the view matrix is the identity matrix */ + if (stateblock->wineD3DDevice->view_ident) { + glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); + checkGLcall("glLoadMatrixf"); + } else { + glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); + checkGLcall("glLoadMatrixf"); + glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); + checkGLcall("glMultMatrixf"); + } +} + static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) { unsigned int k;
@@ -1823,12 +1846,9 @@ static void transform_view(DWORD state, */
PLIGHTINFOEL *lightChain = NULL; - stateblock->wineD3DDevice->modelview_valid = FALSE;
glMatrixMode(GL_MODELVIEW); checkGLcall("glMatrixMode(GL_MODELVIEW)"); - glPushMatrix(); - checkGLcall("glPushMatrix()"); glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); checkGLcall("glLoadMatrixf(...)");
@@ -1847,11 +1867,20 @@ static void transform_view(DWORD state, glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]); checkGLcall("glClipPlane"); } - glPopMatrix(); - checkGLcall("glPopMatrix()");
- /* Call the vdecl update. Will be tidied up later */ - StateTable[STATE_VDECL].apply(STATE_VDECL, stateblock); + if(stateblock->wineD3DDevice->last_was_rhw) { + glLoadIdentity(); + checkGLcall("glLoadIdentity()"); + /* No need to update the world matrix, the identity is fine */ + return; + } + + /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix + * No need to do it here if the state is scheduled for update. + */ + if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) { + transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock); + } }
static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateBlock) { @@ -1869,9 +1898,10 @@ static void vertexdeclaration(DWORD stat BOOL transformed, lit; /* Some stuff is in the device until we have per context tracking */ IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; + BOOL wasrhw = device->last_was_rhw;
device->streamFixedUp = FALSE; - + /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software - * here simply check whether a shader was set, or the user disabled shaders */ @@ -1945,22 +1975,20 @@ static void vertexdeclaration(DWORD stat } else {
/* Untransformed, so relies on the view and projection matrices */ + device->last_was_rhw = FALSE; + /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/ device->untransformed = TRUE;
- if (!useVertexShaderFunction) { - device->modelview_valid = TRUE; - glMatrixMode(GL_MODELVIEW); - checkGLcall("glMatrixMode"); - - /* In the general case, the view matrix is the identity matrix */ - if (device->view_ident) { - glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); - checkGLcall("glLoadMatrixf"); - } else { - glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]); - checkGLcall("glLoadMatrixf"); - glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]); - checkGLcall("glMultMatrixf"); + /* Don't bother checking for !useVertexShaderFunction here. If shaders are always on wasrhw will never + * be true. If they are switched on and off then knowing that the fixed function matrices are ok makes + * those switches cheaper + */ + if (wasrhw) { + /* switching out of orthogonal mode? have to reapply the modelview matrix. + * Only do that when it is not dirty though + */ + if(!isStateDirty(device, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) { + transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock); } }
@@ -2763,7 +2791,7 @@ const struct StateEntry StateTable[] = { /*254, undefined */ 0, state_undefined }, { /*255, undefined */ 0, state_undefined }, /* End huge gap */ - { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_VDECL, vertexdeclaration }, + { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world }, { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex }, { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex }, { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex }, diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 031d320..200b52e 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1150,6 +1150,7 @@ static HRESULT WINAPI IWineD3DSurfaceImp we want to draw at screen position 0,0 - Set up ortho (rhw) mode as per drawprim (and leave set - it will sort itself out due to last_was_rhw */ d3ddevice_set_ortho(This->resource.wineD3DDevice); + IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
if (iface == implSwapChain->frontBuffer) { glDrawBuffer(GL_FRONT); @@ -2473,6 +2474,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOv /* Draw a textured quad */ d3ddevice_set_ortho(This->resource.wineD3DDevice); + IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
glBegin(GL_QUADS);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7e41f5c..7b5eaa1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -563,7 +563,6 @@ typedef struct IWineD3DDeviceImpl const shader_backend_t *shader_backend;
/* Optimization */ - BOOL modelview_valid; BOOL proj_valid; BOOL view_ident; /* true iff view matrix is identity */ BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */