Module: wine
Branch: master
Commit: 5fa0f7f77563bbd77f48b476817dd3c77a877d49
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5fa0f7f77563bbd77f48b4768…
Author: Stefan Dösinger <stefandoesinger(a)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 */