[WINED3D 3] Add position_transformed flag to Strided data format.
Ivan Gyurdiev
ivg231 at gmail.com
Fri Jul 7 01:23:10 CDT 2006
I don't like how the transformed position is currently being tracked.
In half the places we compare the data type to a FLOAT4 - it doesn't
make sense to convert an explicit mark of transformed data (such as
D3DFVF_XYZRHW, or D3DDECLUSAGE_POSITIONT), to some kind of made up
FLOAT4 indicator. What's to say the app won't write 4-coordinate
untransformed data, with garbage in the 4th coord. Are there tests that
show this isn't the case (for vertex declarations)?
Then in the other half we use an FVF (even when there is no FVF, but
only a vertex declaration is available). We make up a fake FVF. While I
tend to use "fakes" myself, you use the new format to represent the old
data, not the other way around, which is a bad idea.
Get rid of all of this, store the transformed position flag when the
strided data is created.
-------------- next part --------------
---
dlls/ddraw/device.c | 4 +-
dlls/wined3d/drawprim.c | 96 ++++++++++++++++------------------------
dlls/wined3d/vertexbuffer.c | 9 ++--
dlls/wined3d/wined3d_private.h | 1
include/wine/wined3d_types.h | 1
5 files changed, 46 insertions(+), 65 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 63f272b..bdb4d05 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3076,7 +3076,9 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrid
if (VertexType & D3DFVF_XYZRHW)
{
WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
- }
+ WineD3DStrided.u.s.position_transformed = TRUE;
+ } else
+ WineD3DStrided.u.s.position_transformed = FALSE;
}
if(VertexType & D3DFVF_NORMAL)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index e15f74b..780dee6 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -38,30 +38,6 @@ extern IWineD3DPixelShaderImpl*
#undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */
#endif
-/* Returns bits for what is expected from the fixed function pipeline, and whether
- a vertex shader will be in use. Note the fvf bits returned may be split over
- multiple streams only if the vertex shader was created, otherwise it all relates
- to stream 0 */
-static BOOL initializeFVF(IWineD3DDevice *iface, DWORD *FVFbits)
-{
-
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-#if 0 /* TODO: d3d8 call setvertexshader needs to set the FVF in the state block when implemented */
- /* The first thing to work out is if we are using the fixed function pipeline
- which is either SetVertexShader with < VS_HIGHESTFIXEDFXF - in which case this
- is the FVF, or with a shader which was created with no function - in which
- case there is an FVF per declared stream. If this occurs, we also maintain
- an 'OR' of all the FVF's together so we know what to expect across all the
- streams */
-#endif
- *FVFbits = This->stateBlock->fvf;
-#if 0
- *FVFbits = This->stateBlock->vertexShaderDecl->allFVF;
-#endif
- return FALSE;
-}
-
/* Issues the glBegin call for gl given the primitive type and count */
static DWORD primitiveToGl(D3DPRIMITIVETYPE PrimitiveType,
DWORD NumPrimitives,
@@ -246,21 +222,37 @@ 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 BOOL primitiveInitState(IWineD3DDevice *iface, BOOL vtx_transformed, BOOL vtx_lit, BOOL useVS) {
+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;
- BOOL isLightingOn = FALSE;
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 (vtx_lit || useVS) {
- isLightingOn = glIsEnabled(GL_LIGHTING);
+ if (fixed_vtx_lit || useVS) {
+ *lighting_changed = TRUE;
+ *lighting_original = glIsEnabled(GL_LIGHTING);
glDisable(GL_LIGHTING);
checkGLcall("glDisable(GL_LIGHTING);");
- TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn);
+ TRACE("Disabled lighting, old state = %d\n", *lighting_original);
}
- if (!useVS && vtx_transformed) {
+ if (!useVS && fixed_vtx_transformed) {
d3ddevice_set_ortho(This);
} else {
@@ -352,7 +344,6 @@ static BOOL primitiveInitState(IWineD3DD
}
}
}
- return isLightingOn;
}
void primitiveDeclarationConvertToStridedData(
@@ -360,7 +351,6 @@ void primitiveDeclarationConvertToStride
BOOL useVertexShaderFunction,
WineDirect3DVertexStridedData *strided,
LONG BaseVertexIndex,
- DWORD *fvf,
BOOL *fixup) {
/* We need to deal with frequency data!*/
@@ -442,6 +432,7 @@ void primitiveDeclarationConvertToStride
TRACE("Set strided %s. data %p, type %d. stride %ld\n", "position2", data, element->Type, stride);
break;
}
+ strided->u.s.position_transformed = FALSE;
break;
case D3DDECLUSAGE_NORMAL:
switch (element->UsageIndex) {
@@ -461,7 +452,6 @@ void primitiveDeclarationConvertToStride
TRACE("Set strided %s. data %p, type %d. stride %ld\n", "normal2", data, element->Type, stride);
break;
}
- *fvf |= D3DFVF_NORMAL;
break;
case D3DDECLUSAGE_BLENDINDICES:
/* demo @http://www.ati.com/developer/vertexblend.html
@@ -573,9 +563,7 @@ void primitiveDeclarationConvertToStride
TRACE("Set strided %s. data %p, type %d. stride %ld\n", "position2T", data, element->Type, stride);
break;
}
- /* TODO: change fvf usage to a plain boolean flag */
- *fvf |= D3DFVF_XYZRHW;
- /* FIXME: were faking this flag so that we don't transform the data again */
+ strided->u.s.position_transformed = TRUE;
break;
case D3DDECLUSAGE_FOG:
/* maybe GL_EXT_fog_coord ?
@@ -632,8 +620,10 @@ void primitiveConvertFVFtoOffset(DWORD t
data += 3 * sizeof(float);
if (thisFVF & D3DFVF_XYZRHW) {
strided->u.s.position.dwType = D3DDECLTYPE_FLOAT4;
+ strided->u.s.position_transformed = TRUE;
data += sizeof(float);
- }
+ } else
+ strided->u.s.position_transformed = FALSE;
}
/* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
@@ -1318,7 +1308,7 @@ static inline void fixed_prepare_draw(
draw->position.w = 1.0;
/* Data contains rhw */
- if (strided->u.s.position.dwType == D3DDECLTYPE_FLOAT4) {
+ if (strided->u.s.position_transformed) {
float rhw = ptrToCoords[3];
draw->is_transformed = TRUE;
@@ -1740,10 +1730,11 @@ #undef BUFFER_OR_DATA
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
-void inline drawPrimitiveTraceDataLocations(WineDirect3DVertexStridedData *dataLocations,DWORD fvf) {
+void inline drawPrimitiveTraceDataLocations(
+ WineDirect3DVertexStridedData *dataLocations) {
/* Dump out what parts we have supplied */
- TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
+ TRACE("Strided Data:\n");
TRACE_STRIDED((dataLocations), position);
TRACE_STRIDED((dataLocations), blendWeights);
TRACE_STRIDED((dataLocations), blendMatrixIndices);
@@ -1950,17 +1941,16 @@ void drawPrimitive(IWineD3DDevice *iface
int minIndex,
WineDirect3DVertexStridedData *DrawPrimStrideData) {
- BOOL rc = FALSE;
- DWORD fvf = 0;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
BOOL useVertexShaderFunction = FALSE;
BOOL usePixelShaderFunction = FALSE;
- BOOL isLightingOn = FALSE;
WineDirect3DVertexStridedData *dataLocations;
IWineD3DSwapChainImpl *swapchain;
int i;
BOOL fixup = FALSE;
+ BOOL lighting_changed, lighting_original;
+
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
* here simply check whether a shader was set, or the user disabled shaders */
if (wined3d_settings.vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader &&
@@ -1971,14 +1961,6 @@ void drawPrimitive(IWineD3DDevice *iface
((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function)
usePixelShaderFunction = TRUE;
- if (This->stateBlock->vertexDecl == NULL) {
- /* Work out what the FVF should look like */
- rc = initializeFVF(iface, &fvf);
- if (rc) return;
- } else {
- TRACE("(%p) : using vertex declaration %p\n", iface, This->stateBlock->vertexDecl);
- }
-
/* Invalidate the back buffer memory so LockRect will read it the next time */
for(i = 0; i < IWineD3DDevice_GetNumberOfSwapChains(iface); i++) {
IWineD3DDevice_GetSwapChain(iface, i, (IWineD3DSwapChain **) &swapchain);
@@ -1991,8 +1973,6 @@ void drawPrimitive(IWineD3DDevice *iface
/* Ok, we will be updating the screen from here onwards so grab the lock */
ENTER_GL();
- /* convert the FVF or vertexDeclaration into a strided stream (this should be done when the fvf or declaration is created) */
-
if(DrawPrimStrideData) {
TRACE("================ Strided Input ===================\n");
dataLocations = DrawPrimStrideData;
@@ -2006,7 +1986,7 @@ void drawPrimitive(IWineD3DDevice *iface
ERR("Out of memory!\n");
return;
}
- primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, dataLocations, StartVertexIndex, &fvf, &fixup);
+ primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, dataLocations, StartVertexIndex, &fixup);
} else {
TRACE("================ FVF ===================\n");
@@ -2019,10 +1999,10 @@ void drawPrimitive(IWineD3DDevice *iface
}
/* write out some debug information*/
- drawPrimitiveTraceDataLocations(dataLocations, fvf);
+ drawPrimitiveTraceDataLocations(dataLocations);
/* Setup transform matrices and sort out */
- isLightingOn = primitiveInitState(iface, fvf & D3DFVF_XYZRHW, !(fvf & D3DFVF_NORMAL), useVertexShaderFunction);
+ primitiveInitState(iface, dataLocations, useVertexShaderFunction, &lighting_changed, &lighting_original);
/* Now initialize the materials state */
init_materials(iface, (dataLocations->u.s.diffuse.lpData != NULL || dataLocations->u.s.diffuse.VBO != 0));
@@ -2049,8 +2029,8 @@ void drawPrimitive(IWineD3DDevice *iface
if(!DrawPrimStrideData) HeapFree(GetProcessHeap(), 0, dataLocations);
/* If vertex shaders or no normals, restore previous lighting state */
- if (useVertexShaderFunction || !(fvf & D3DFVF_NORMAL)) {
- if (isLightingOn) glEnable(GL_LIGHTING);
+ if (lighting_changed) {
+ if (lighting_original) glEnable(GL_LIGHTING);
else glDisable(GL_LIGHTING);
TRACE("Restored lighting to original state\n");
}
diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index b58591c..35a4d9e 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -117,7 +117,6 @@ static void WINAPI IWineD3DVertexBuf
BOOL useVertexShaderFunction = FALSE, fixup = FALSE;
BYTE *data;
UINT i;
- DWORD declFVF; /* Not interested */
UINT start = 0, end = 0, stride = 0;
if(This->Flags & VBFLAG_DIRTY) {
@@ -173,7 +172,6 @@ static void WINAPI IWineD3DVertexBuf
useVertexShaderFunction,
&strided,
0,
- &declFVF,
&fixup);
This->Flags &= ~VBFLAG_LOAD;
@@ -198,7 +196,7 @@ static void WINAPI IWineD3DVertexBuf
}
/* If any data that needs conversion has changed we have to reload the whole buffer */
- if( ( (This->strided.u.s.position.dwType != WINED3DDECLTYPE_FLOAT4 || strided.u.s.position.dwType != WINED3DDECLTYPE_FLOAT4) &&
+ if( ( (This->strided.u.s.position_transformed || strided.u.s.position_transformed) &&
This->strided.u.s.position.lpData != strided.u.s.position.lpData) ||
!(This->strided.u.s.diffuse.lpData == strided.u.s.diffuse.lpData || strided.u.s.diffuse.VBO != This->vbo) ||
!(This->strided.u.s.specular.lpData == strided.u.s.specular.lpData || strided.u.s.specular.VBO != This->vbo) ) {
@@ -240,8 +238,9 @@ static void WINAPI IWineD3DVertexBuf
memcpy(data, This->resource.allocatedMemory + start, end - start);
for(i = 0; i < ( end - start) / stride; i++) {
- if(strided.u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 ) {
- float *p = (float *) (((int) This->resource.allocatedMemory + (int) strided.u.s.position.lpData) + start + i * stride);
+ if(strided.u.s.position_transformed) {
+ float *p = (float *) (((int) This->resource.allocatedMemory +
+ (int) strided.u.s.position.lpData) + start + i * stride);
float x, y, z, w;
/* rhw conversion like in drawStridedSlow */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e70a9a0..ad872d9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -366,7 +366,6 @@ void primitiveDeclarationConvertToStride
BOOL useVertexShaderFunction,
WineDirect3DVertexStridedData *strided,
LONG BaseVertexIndex,
- DWORD *fvf,
BOOL *fixup);
void primitiveConvertFVFtoOffset(DWORD thisFVF,
diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h
index f097bf0..26d2902 100644
--- a/include/wine/wined3d_types.h
+++ b/include/wine/wined3d_types.h
@@ -905,6 +905,7 @@ typedef struct WineDirect3DVertexStrided
union {
struct {
WineDirect3DStridedData position;
+ BOOL position_transformed;
WineDirect3DStridedData blendWeights;
WineDirect3DStridedData blendMatrixIndices;
WineDirect3DStridedData normal;
--
1.4.0
More information about the wine-patches
mailing list