[16/16] WineD3D: Some matrix handling cleanup
Stefan Dösinger
stefandoesinger at gmx.at
Mon Jan 1 18:45:08 CST 2007
This patch does some additional cleanup which didn't really fit into
the world and projection matrix patches. It removes
d3ddevice_set_ortho to have all matrix functionality in the world and
projection states. UnlockRect and BltOverride set this->last_was_rhw
and perform an immediate matrix application. Then the vertex decl is
dirtified to force restoring last_was_rhw and the matrices on the
next draw.
-------------- next part --------------
From 3938250a55f29dedc6518af49c5cdb0be9c69318 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=C3=B6singer?= <stefan at imac.local>
Date: Mon, 1 Jan 2007 22:29:03 +0100
Subject: [PATCH] WineD3D: Some matrix handling cleanup
---
dlls/wined3d/device.c | 3 -
dlls/wined3d/drawprim.c | 16 -------
dlls/wined3d/state.c | 92 +++++++++++++++++++++++-----------------
dlls/wined3d/surface.c | 8 ++-
dlls/wined3d/wined3d_private.h | 3 -
5 files changed, 58 insertions(+), 64 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 4bcb047..9f7531f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1931,7 +1931,6 @@ #endif
}
/* Initialize the current view state */
- This->proj_valid = 0;
This->view_ident = 1;
This->last_was_rhw = 0;
glGetIntegerv(GL_MAX_LIGHTS, &This->maxConcurrentLights);
@@ -5856,7 +5855,7 @@ static void device_render_to_texture(IWi
This->depth_copy_state = WINED3D_DCS_COPY;
}
This->last_was_rhw = FALSE;
- This->proj_valid = FALSE;
+ /* Viewport state will reapply the projection matrix for now */
IWineD3DDeviceImpl_MarkStateDirty(This, WINED3DRS_CULLMODE);
/* Restore recording */
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 7fe492a..d9c56a0 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -155,22 +155,6 @@ static const GLfloat invymat[16] = {
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f};
-void d3ddevice_set_ortho(IWineD3DDeviceImpl *This) {
- /* If the last draw was transformed as well, no need to reapply all the matrixes */
- if ( (!This->last_was_rhw) || (This->viewport_changed) ) {
- This->last_was_rhw = TRUE;
- This->viewport_changed = FALSE;
-
- /* Transformed already into viewport coordinates, so we do not need transform
- matrices. Reset all matrices to identity and leave the default matrix in world
- mode. */
- glMatrixMode(GL_MODELVIEW);
- checkGLcall("glMatrixMode(GL_MODELVIEW)");
- glLoadIdentity();
- checkGLcall("glLoadIdentity");
- }
-}
-
static BOOL fixed_get_input(
BYTE usage, BYTE usage_idx,
unsigned int* regnum) {
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index de0a17f..7820a6a 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1811,25 +1811,30 @@ #endif
}
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
+ /* This function is called by transform_view below if the view matrix was changed too
+ *
+ * Deliberately no check if the vertex declaration is dirty because the vdecl state
+ * does not always update the world matrix, only on a switch between transformed
+ * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
+ * draw, but that should be rather rare and cheaper in total.
*/
- 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");
+ if(stateblock->wineD3DDevice->last_was_rhw) {
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity()");
} 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");
+ /* 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");
+ }
}
}
@@ -2028,50 +2033,57 @@ static void vertexdeclaration(DWORD stat
}
if (!useVertexShaderFunction && transformed) {
- d3ddevice_set_ortho(stateblock->wineD3DDevice);
-
+ stateblock->wineD3DDevice->last_was_rhw = TRUE;
} else {
/* Untransformed, so relies on the view and projection matrices */
stateblock->wineD3DDevice->last_was_rhw = FALSE;
/* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
stateblock->wineD3DDevice->untransformed = TRUE;
-
- /* 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(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
- transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
- }
- }
-
- if (!useVertexShaderFunction) {
- stateblock->wineD3DDevice->proj_valid = TRUE;
- }
+ /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
+ * Not needed as long as only hw shaders are supported
+ */
- /* Vertex Shader output is already transformed, so set up identity matrices */
+ /* This sets the shader output position correction constants.
+ * TODO: Move to the viewport state
+ */
if (useVertexShaderFunction) {
stateblock->wineD3DDevice->posFixup[1] = stateblock->wineD3DDevice->render_offscreen ? -1.0 : 1.0;
stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
}
- stateblock->wineD3DDevice->last_was_rhw = FALSE;
}
- /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
- * or transformed / untransformed was switched
+ /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
+ * off this function will be called again anyway to make sure they're properly set
*/
- if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
- transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock);
+ if(!useVertexShaderFunction) {
+
+ /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
+ * or transformed / untransformed was switched
+ */
+ if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
+ transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock);
+ }
+ /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
+ * mode.
+ *
+ * If a vertex shader is used, the world matrix changed and then vertex shader unbound
+ * this check will fail and the matrix not applied again. This is OK because a simple
+ * world matrix change reapplies the matrix - These checks here are only to satisfy the
+ * needs of the vertex declaration.
+ *
+ * World and view matrix go into the same gl matrix, so only apply them when neither is
+ * dirty
+ */
+ if(transformed != wasrhw &&
+ !isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
+ !isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_VIEW))) {
+ transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
+ }
}
- /* Setup fogging */
if(updateFog) {
state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index a349c35..765efa6 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1156,9 +1156,10 @@ static HRESULT WINAPI IWineD3DSurfaceImp
/* glDrawPixels transforms the raster position as though it was a vertex -
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);
- /* Apply the projection matrix, it sets up orthogonal projection due to last_was_rhw */
+ myDevice->last_was_rhw = TRUE;
+ /* Apply the projection and world matrices, it sets up orthogonal projection due to last_was_rhw */
StateTable[STATE_TRANSFORM(WINED3DTS_PROJECTION)].apply(STATE_TRANSFORM(WINED3DTS_PROJECTION), myDevice->stateBlock);
+ StateTable[STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))].apply(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), myDevice->stateBlock);
/* Will reapply the projection matrix too */
IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
@@ -2483,9 +2484,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOv
/* Draw a textured quad
*/
- d3ddevice_set_ortho(This->resource.wineD3DDevice);
+ myDevice->last_was_rhw = TRUE;
/* Apply the projection matrix, it sets up orthogonal projection due to last_was_rhw */
StateTable[STATE_TRANSFORM(WINED3DTS_PROJECTION)].apply(STATE_TRANSFORM(WINED3DTS_PROJECTION), myDevice->stateBlock);
+ StateTable[STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))].apply(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), myDevice->stateBlock);
/* That will reapply the projection matrix too */
IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_VDECL);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3a28d6c..47ffcac 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 proj_valid;
BOOL view_ident; /* true iff view matrix is identity */
BOOL last_was_rhw; /* true iff last draw_primitive was in xyzrhw mode */
BOOL viewport_changed; /* Was the viewport changed since the last draw? */
@@ -705,8 +704,6 @@ typedef struct PrivateData
DWORD size;
} PrivateData;
-void d3ddevice_set_ortho(IWineD3DDeviceImpl *This);
-
/*****************************************************************************
* IWineD3DResource implementation structure
*/
--
1.4.2.4
-------------- next part --------------
More information about the wine-patches
mailing list