[5/10] WineD3D: WineD3D: Move the functionality of
primitiveInitState to the state table
Stefan Dösinger
stefandoesinger at gmx.at
Tue Jan 2 15:47:10 CST 2007
Mainly a code move. I hope I got that biest tab-free finally :-)
-------------- next part --------------
From 3d991405be1b0c91318dba31019c43e890b2d0e8 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=C3=B6singer?= <stefan at imac.local>
Date: Tue, 2 Jan 2007 22:38:37 +0100
Subject: [PATCH] WineD3D: Move the functionality of primitiveInitState to the state table
---
dlls/wined3d/device.c | 15 ----
dlls/wined3d/drawprim.c | 122 --------------------------------
dlls/wined3d/state.c | 152 ++++++++++++++++++++++++++++++++++------
dlls/wined3d/wined3d_private.h | 1
4 files changed, 129 insertions(+), 161 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c7da5c8..268c0b0 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2366,21 +2366,6 @@ static HRESULT WINAPI IWineD3DDeviceIm
/* Capture the times we can just ignore the change for now */
if (d3dts == WINED3DTS_WORLDMATRIX(0)) {
This->modelview_valid = FALSE;
- return WINED3D_OK;
-
- } else if (d3dts == WINED3DTS_PROJECTION) {
- This->proj_valid = FALSE;
- return WINED3D_OK;
-
- } else if (d3dts >= WINED3DTS_WORLDMATRIX(1) && d3dts <= WINED3DTS_WORLDMATRIX(255)) {
- /* Indexed Vertex Blending Matrices 256 -> 511 */
- /* Use arb_vertex_blend or NV_VERTEX_WEIGHTING? */
- FIXME("WINED3DTS_WORLDMATRIX(1..255) not handled\n");
- return WINED3D_OK;
- }
-
- if (d3dts >= WINED3DTS_TEXTURE0 && d3dts <= WINED3DTS_TEXTURE7) { /* handle texture matrices */
- /* This is now set with the texture unit states, it may be a good idea to flag the change though! */
} else if (d3dts == WINED3DTS_VIEW) { /* handle the VIEW matrice */
This->view_ident = !memcmp(lpmatrix, identity, 16 * sizeof(float));
/* Handled by the state manager */
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 9fce659..c79c2b0 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -227,116 +227,6 @@ void d3ddevice_set_ortho(IWineD3DDeviceI
}
}
}
-/* Setup views - Transformed & lit if RHW, else untransformed.
- Only unlit if Normals are supplied
- Returns: Whether to restore lighting afterwards */
-static void primitiveInitState(
- IWineD3DDevice *iface,
- WineDirect3DVertexStridedData* strided,
- BOOL useVS,
- BOOL* lighting_changed,
- BOOL* lighting_original) {
-
- BOOL fixed_vtx_transformed =
- (strided->u.s.position.lpData != NULL || strided->u.s.position.VBO != 0 ||
- strided->u.s.position2.lpData != NULL || strided->u.s.position2.VBO != 0) &&
- strided->u.s.position_transformed;
-
- BOOL fixed_vtx_lit =
- strided->u.s.normal.lpData == NULL && strided->u.s.normal.VBO == 0 &&
- strided->u.s.normal2.lpData == NULL && strided->u.s.normal2.VBO == 0;
-
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- *lighting_changed = FALSE;
-
- /* If no normals, DISABLE lighting otherwise, don't touch lighing as it is
- set by the appropriate render state. Note Vertex Shader output is already lit */
- if (fixed_vtx_lit || useVS) {
- *lighting_changed = TRUE;
- *lighting_original = glIsEnabled(GL_LIGHTING);
- glDisable(GL_LIGHTING);
- checkGLcall("glDisable(GL_LIGHTING);");
- TRACE("Disabled lighting, old state = %d\n", *lighting_original);
- }
-
- if (!useVS && fixed_vtx_transformed) {
- d3ddevice_set_ortho(This);
-
- } else {
-
- /* Untransformed, so relies on the view and projection matrices */
- This->untransformed = TRUE;
-
- if (!useVS && (This->last_was_rhw || !This->modelview_valid)) {
- /* Only reapply when have to */
- This->modelview_valid = TRUE;
- glMatrixMode(GL_MODELVIEW);
- checkGLcall("glMatrixMode");
-
- /* In the general case, the view matrix is the identity matrix */
- if (This->view_ident) {
- glLoadMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- } else {
- glLoadMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_VIEW].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- glMultMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
- checkGLcall("glMultMatrixf");
- }
- }
-
- if (!useVS && (This->last_was_rhw || !This->proj_valid)) {
- /* Only reapply when have to */
- This->proj_valid = TRUE;
- glMatrixMode(GL_PROJECTION);
- checkGLcall("glMatrixMode");
-
- /* The rule is that the window coordinate 0 does not correspond to the
- beginning of the first pixel, but the center of the first pixel.
- As a consequence if you want to correctly draw one line exactly from
- the left to the right end of the viewport (with all matrices set to
- be identity), the x coords of both ends of the line would be not
- -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
- instead. */
- glLoadIdentity();
-
- glTranslatef(0.9 / This->stateBlock->viewport.Width, -0.9 / This->stateBlock->viewport.Height, 0);
- checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
-
- /* D3D texture coordinates are flipped compared to OpenGL ones, so
- * render everything upside down when rendering offscreen. */
- if (This->render_offscreen) {
- glMultMatrixf(invymat);
- checkGLcall("glMultMatrixf(invymat)");
- }
- glMultMatrixf((float *) &This->stateBlock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
- checkGLcall("glLoadMatrixf");
- }
-
- /* Vertex Shader output is already transformed, so set up identity matrices */
- if (useVS) {
- This->posFixup[1] = This->render_offscreen ? -1.0 : 1.0;
- This->posFixup[2] = 0.9 / This->stateBlock->viewport.Width;
- This->posFixup[3] = -0.9 / This->stateBlock->viewport.Height;
- }
- This->last_was_rhw = FALSE;
-
- /* Setup fogging */
- if (useVS && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->usesFog) {
- /* In D3D vertex shader return the 'final' fog value, while in OpenGL it is the 'input' fog value.
- * The code below 'disables' the OpenGL postprocessing by setting the formula to '1'. */
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogf(GL_FOG_START, 1.0f);
- glFogf(GL_FOG_END, 0.0f);
-
- } else if(This->stateBlock->renderState[WINED3DRS_FOGENABLE]
- && This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] != WINED3DFOG_NONE) {
- /* Reapply the fog */
- StateTable[STATE_RENDER(WINED3DRS_FOGENABLE)].apply(STATE_RENDER(WINED3DRS_FOGSTART), This->stateBlock);
- }
- }
-}
static BOOL fixed_get_input(
BYTE usage, BYTE usage_idx,
@@ -1947,8 +1837,6 @@ void drawPrimitive(IWineD3DDevice *iface
DWORD dirtyState, idx;
BYTE shift;
- BOOL lighting_changed, lighting_original = FALSE;
-
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
* here simply check whether a shader was set, or the user disabled shaders */
if (This->vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader &&
@@ -1991,9 +1879,6 @@ void drawPrimitive(IWineD3DDevice *iface
}
This->depth_copy_state = WINED3D_DCS_INITIAL;
- /* Setup transform matrices and sort out */
- primitiveInitState(iface, &This->strided_streams, useVertexShaderFunction, &lighting_changed, &lighting_original);
-
/* Now initialize the materials state */
init_materials(iface, (This->strided_streams.u.s.diffuse.lpData != NULL || This->strided_streams.u.s.diffuse.VBO != 0));
@@ -2010,13 +1895,6 @@ void drawPrimitive(IWineD3DDevice *iface
idxData, idxSize, minIndex, StartIdx, fixup);
}
- /* If vertex shaders or no normals, restore previous lighting state */
- if (lighting_changed) {
- if (lighting_original) glEnable(GL_LIGHTING);
- else glDisable(GL_LIGHTING);
- TRACE("Restored lighting to original state\n");
- }
-
/* Finshed updating the screen, restore lock */
LEAVE_GL();
TRACE("Done all gl drawing\n");
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 67869e8..9e6f15c 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -71,6 +71,8 @@ static void state_fillmode(DWORD state,
}
}
+#if 0
+/* if 0ed because it will be revived later */
static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock) {
/* TODO: Lighting is only enabled if Vertex normals are passed by the application,
@@ -85,6 +87,7 @@ static void state_lighting(DWORD state,
checkGLcall("glDisable GL_LIGHTING");
}
}
+#endif
static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
@@ -646,7 +649,6 @@ static void state_fog(DWORD state, IWine
tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
fogend = tmpvalue.f;
-#if 0
/* Activate when vertex shaders are in the state table */
if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
@@ -656,17 +658,14 @@ #if 0
fogend = 0.0;
stateblock->wineD3DDevice->last_was_foggy_shader = TRUE;
}
-#endif
-
/* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
* the system will apply only pixel(=table) fog effects."
*/
- /* else */ if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
+ else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
glHint(GL_FOG_HINT, GL_FASTEST);
checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
-#if 0
stateblock->wineD3DDevice->last_was_foggy_shader = FALSE;
-#endif
+
switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
/* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
* If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
@@ -727,9 +726,8 @@ #endif
} else {
glHint(GL_FOG_HINT, GL_NICEST);
checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
-#if 0
stateblock->wineD3DDevice->last_was_foggy_shader = FALSE;
-#endif
+
switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
case D3DFOG_EXP:
glFogi(GL_FOG_MODE, GL_EXP);
@@ -1841,29 +1839,48 @@ static void transform_view(DWORD state,
}
glPopMatrix();
checkGLcall("glPopMatrix()");
+
+ /* Call the vdecl update. Will be tidied up later */
+ StateTable[STATE_VDECL].apply(STATE_VDECL, stateblock);
}
static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateBlock) {
WARN("World matrix 1 - 255 not supported yet\n");
}
+static const GLfloat invymat[16] = {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+
static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
- BOOL useVertexShaderFunction = FALSE;
- stateblock->wineD3DDevice->streamFixedUp = FALSE;
+ BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
+ BOOL transformed, lit;
+ /* Some stuff is in the device until we have per context tracking */
+ IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
+
+ 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
*/
- if (stateblock->wineD3DDevice->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
- ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL)
+ if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
+ ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
useVertexShaderFunction = TRUE;
- if(stateblock->wineD3DDevice->up_strided) {
+ if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != device->last_was_foggy_shader) {
+ updateFog = TRUE;
+ }
+ } else if(device->last_was_foggy_shader) {
+ updateFog = TRUE;
+ }
+
+ if(device->up_strided) {
/* Note: this is a ddraw fixed-function code path */
TRACE("================ Strided Input ===================\n");
- memcpy(&stateblock->wineD3DDevice->strided_streams, stateblock->wineD3DDevice->up_strided, sizeof(stateblock->wineD3DDevice->strided_streams));
- stateblock->wineD3DDevice->streamFixedUp = FALSE;
+ memcpy(&device->strided_streams, device->up_strided, sizeof(device->strided_streams));
}
else if (stateblock->vertexDecl || stateblock->vertexShader) {
/* Note: This is a fixed function or shader codepath.
@@ -1872,13 +1889,13 @@ static void vertexdeclaration(DWORD stat
* don't set any declaration at all
*/
TRACE("================ Vertex Declaration ===================\n");
- memset(&stateblock->wineD3DDevice->strided_streams, 0, sizeof(stateblock->wineD3DDevice->strided_streams));
+ memset(&device->strided_streams, 0, sizeof(device->strided_streams));
if (stateblock->vertexDecl != NULL ||
((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->vertexDeclaration != NULL) {
- primitiveDeclarationConvertToStridedData((IWineD3DDevice *) stateblock->wineD3DDevice, useVertexShaderFunction,
- &stateblock->wineD3DDevice->strided_streams, &stateblock->wineD3DDevice->streamFixedUp);
+ primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
+ &device->strided_streams, &device->streamFixedUp);
}
} else {
/* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
@@ -1886,10 +1903,97 @@ static void vertexdeclaration(DWORD stat
* It will not work properly for shaders.
*/
TRACE("================ FVF ===================\n");
- memset(&stateblock->wineD3DDevice->strided_streams, 0, sizeof(stateblock->wineD3DDevice->strided_streams));
- primitiveConvertToStridedData((IWineD3DDevice *) stateblock->wineD3DDevice, &stateblock->wineD3DDevice->strided_streams,
- &stateblock->wineD3DDevice->streamFixedUp);
+ memset(&device->strided_streams, 0, sizeof(device->strided_streams));
+ primitiveConvertToStridedData((IWineD3DDevice *) device, &device->strided_streams,
+ &device->streamFixedUp);
}
+ /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 beeing equal to TRUE(=1)? */
+ transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
+ device->strided_streams.u.s.position.VBO != 0) &&
+ device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
+ lit = device->strided_streams.u.s.normal.lpData == NULL &&
+ device->strided_streams.u.s.normal.VBO == 0;
+
+ if(transformed != device->last_was_rhw && !useVertexShaderFunction) {
+ updateFog = TRUE;
+ }
+
+ /* TODO: The vertex declaration changes lighting, but lighting doesn't affect the vertex declaration and the
+ * stream sources. This can be handled nicer
+ */
+ if(stateblock->renderState[WINED3DRS_LIGHTING] && !lit) {
+ glEnable(GL_LIGHTING);
+ checkGLcall("glEnable(GL_LIGHTING)");
+ } else {
+ glDisable(GL_LIGHTING);
+ checkGLcall("glDisable(GL_LIGHTING");
+ }
+
+ if (!useVertexShaderFunction && transformed) {
+ d3ddevice_set_ortho(device);
+
+ } else {
+
+ /* Untransformed, so relies on the view and projection matrices */
+ 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");
+ }
+ }
+
+ if (!useVertexShaderFunction) {
+ device->proj_valid = TRUE;
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode");
+
+ /* The rule is that the window coordinate 0 does not correspond to the
+ beginning of the first pixel, but the center of the first pixel.
+ As a consequence if you want to correctly draw one line exactly from
+ the left to the right end of the viewport (with all matrices set to
+ be identity), the x coords of both ends of the line would be not
+ -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
+ instead. */
+ glLoadIdentity();
+
+ glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
+ checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
+
+ /* D3D texture coordinates are flipped compared to OpenGL ones, so
+ * render everything upside down when rendering offscreen. */
+ if (device->render_offscreen) {
+ glMultMatrixf(invymat);
+ checkGLcall("glMultMatrixf(invymat)");
+ }
+ glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ }
+
+ /* Vertex Shader output is already transformed, so set up identity matrices */
+ if (useVertexShaderFunction) {
+ device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
+ device->posFixup[2] = 0.9 / stateblock->viewport.Width;
+ device->posFixup[3] = -0.9 / stateblock->viewport.Height;
+ }
+ device->last_was_rhw = FALSE;
+ }
+
+ /* Setup fogging */
+ if(updateFog) {
+ state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
+ }
}
const struct StateEntry StateTable[] =
@@ -2033,7 +2137,7 @@ const struct StateEntry StateTable[] =
{ /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
{ /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
{ /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
- { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING) /* Vertex decl! */,state_lighting },
+ { /*137, WINED3DRS_LIGHTING */ STATE_VDECL, vertexdeclaration },
{ /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
{ /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
{ /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
@@ -2394,7 +2498,7 @@ const struct StateEntry StateTable[] =
/* Transform states follow */
{ /* 1, undefined */ 0, state_undefined },
{ /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
- { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), state_undefined },
+ { /* 3, WINED3DTS_PROJECTION */ STATE_VDECL, vertexdeclaration },
{ /* 4, undefined */ 0, state_undefined },
{ /* 5, undefined */ 0, state_undefined },
{ /* 6, undefined */ 0, state_undefined },
@@ -2649,7 +2753,7 @@ const struct StateEntry StateTable[] =
{ /*254, undefined */ 0, state_undefined },
{ /*255, undefined */ 0, state_undefined },
/* End huge gap */
- { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), state_undefined },
+ { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_VDECL, vertexdeclaration },
{ /*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/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8088b70..7e41f5c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -581,6 +581,7 @@ #define NEEDS_DI
BOOL last_was_notclipped;
BOOL untransformed;
BOOL last_was_pshader;
+ BOOL last_was_foggy_shader;
/* State block related */
BOOL isRecordingState;
--
1.4.2.4
More information about the wine-patches
mailing list