Now that Alexandre has comitted my last patch, here comes the next :-) Changelog: - separate geometry tracing in a new debug channel (ddraw_geom) - added handling for some new texturing ops - prepare for addition of multi-texturing - another way to fix the device enumeration for the reference device -- Lionel Ulmer - http://www.bbrox.org/
Index: dlls/ddraw/mesa.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/mesa.c,v retrieving revision 1.36 diff -u -r1.36 mesa.c --- dlls/ddraw/mesa.c 12 Feb 2003 21:35:07 -0000 1.36 +++ dlls/ddraw/mesa.c 11 May 2003 07:17:27 -0000 @@ -461,7 +473,8 @@ break; default: - ERR("Unhandled dwRenderStateType %s (%08x) !\n", _get_renderstate(dwRenderStateType), dwRenderStateType); + ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n", + _get_renderstate(dwRenderStateType), dwRenderStateType, dwRenderState); } LEAVE_GL(); } Index: dlls/ddraw/mesa_private.h =================================================================== RCS file: /home/wine/wine/dlls/ddraw/mesa_private.h,v retrieving revision 1.41 diff -u -r1.41 mesa_private.h --- dlls/ddraw/mesa_private.h 12 Feb 2003 21:26:05 -0000 1.41 +++ dlls/ddraw/mesa_private.h 11 May 2003 07:17:27 -0000 @@ -133,7 +133,7 @@ extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surface); /* Used for Direct3D to request the device to enumerate itself */ -extern HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) ; +extern HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) ; extern HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context) ; extern HRESULT d3ddevice_find(IDirect3DImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lplpD3DDevice); Index: dlls/ddraw/d3ddevice/main.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/main.c,v retrieving revision 1.39 diff -u -r1.39 main.c --- dlls/ddraw/d3ddevice/main.c 11 May 2003 03:44:53 -0000 1.39 +++ dlls/ddraw/d3ddevice/main.c 11 May 2003 07:17:28 -0000 @@ -149,7 +149,7 @@ D3DTSS_MIPFILTER, D3DTFP_NONE, D3DTSS_MIPMAPLODBIAS, 0x00000000, /* 0.0f */ D3DTSS_MAXMIPLEVEL, 0, - D3DTSS_MAXANISOTROPY, 1, + /* D3DTSS_MAXANISOTROPY, 1, */ /* This is to prevent warnings :-) */ /* FIXME: D3DTSS_BUMPENVLSCALE */ /* FIXME: D3DTSS_NUMPENVLOFFSET */ /* FIXME: D3DTSS_TEXTURETRANSFORMFLAGS */ Index: dlls/ddraw/d3ddevice/mesa.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v retrieving revision 1.95 diff -u -r1.95 mesa.c --- dlls/ddraw/d3ddevice/mesa.c 11 May 2003 03:44:53 -0000 1.95 +++ dlls/ddraw/d3ddevice/mesa.c 11 May 2003 07:17:29 -0000 @@ -37,6 +37,7 @@ #include "main.h" WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom); /* x11drv GDI escapes */ #define X11DRV_ESCAPE 6789 @@ -278,7 +279,7 @@ -HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) +HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) { D3DDEVICEDESC dref, d1, d2; HRESULT ret_value; @@ -290,14 +291,15 @@ fill_opengl_caps(&dref); -#if 0 /* FIXME: Reference device enumeration should be enable/disable in the configuration file */ - TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice)); - d1 = dref; - d2 = dref; - ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", device_name, &d1, &d2, context); - if (ret_value != D3DENUMRET_OK) - return ret_value; -#endif + if (version > 1) { + /* It seems that enumerating the reference IID on Direct3D 1 games (AvP / Motoracer2) breaks them */ + TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice)); + d1 = dref; + d2 = dref; + ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", device_name, &d1, &d2, context); + if (ret_value != D3DENUMRET_OK) + return ret_value; + } TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL)); d1 = dref; @@ -1073,6 +1048,10 @@ { BOOLEAN vertex_lighted = FALSE; IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; + int num_active_stages = 0; + + /* Compute the number of active texture stages */ + while (This->current_texture[num_active_stages] != NULL) num_active_stages++; /* This is to prevent 'thread contention' between a thread locking the device and another doing 3D display on it... */ @@ -1097,7 +1076,7 @@ draw_primitive_start_GL(d3dptPrimitiveType); /* Some fast paths first before the generic case.... */ - if (d3dvtVertexType == D3DFVF_VERTEX) { + if ((d3dvtVertexType == D3DFVF_VERTEX) && (num_active_stages <= 1)) { int index; for (index = 0; index < dwIndexCount; index++) { @@ -1113,12 +1092,12 @@ handle_texture(tex_coord); handle_xyz(position); - TRACE(" %f %f %f / %f %f %f (%f %f)\n", - position[0], position[1], position[2], - normal[0], normal[1], normal[2], - tex_coord[0], tex_coord[1]); + TRACE_(ddraw_geom)(" %f %f %f / %f %f %f (%f %f)\n", + position[0], position[1], position[2], + normal[0], normal[1], normal[2], + tex_coord[0], tex_coord[1]); } - } else if (d3dvtVertexType == D3DFVF_TLVERTEX) { + } else if ((d3dvtVertexType == D3DFVF_TLVERTEX) && (num_active_stages <= 1)) { int index; for (index = 0; index < dwIndexCount; index++) { @@ -1136,17 +1115,17 @@ handle_texture(tex_coord); handle_xyzrhw(position); - TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", - position[0], position[1], position[2], position[3], - (*color_d >> 16) & 0xFF, - (*color_d >> 8) & 0xFF, - (*color_d >> 0) & 0xFF, - (*color_d >> 24) & 0xFF, - (*color_s >> 16) & 0xFF, - (*color_s >> 8) & 0xFF, - (*color_s >> 0) & 0xFF, - (*color_s >> 24) & 0xFF, - tex_coord[0], tex_coord[1]); + TRACE_(ddraw_geom)(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", + position[0], position[1], position[2], position[3], + (*color_d >> 16) & 0xFF, + (*color_d >> 8) & 0xFF, + (*color_d >> 0) & 0xFF, + (*color_d >> 24) & 0xFF, + (*color_s >> 16) & 0xFF, + (*color_s >> 8) & 0xFF, + (*color_s >> 0) & 0xFF, + (*color_s >> 24) & 0xFF, + tex_coord[0], tex_coord[1]); } } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) || ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) { @@ -1154,8 +1133,12 @@ Note that people should write a fast path for all vertex formats out there... */ int index; + int num_tex_index = ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); + static const D3DVALUE no_index[] = { 0.0, 0.0, 0.0, 0.0 }; + for (index = 0; index < dwIndexCount; index++) { int i = (dwIndices == NULL) ? index : dwIndices[index]; + int tex_stage; if (d3dvtVertexType & D3DFVF_NORMAL) { D3DVALUE *normal = @@ -1179,21 +1162,19 @@ handle_diffuse(&(This->state_block), color_d, vertex_lighted); } } - - if (((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) == 1) { - /* Special case for single texture... */ - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride); - handle_texture(tex_coord); - } else { - int tex_index; - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + - i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - handle_textures(tex_coord, tex_index); + + for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) { + int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0xFFFF000; + if (tex_index >= num_tex_index) { + handle_textures((D3DVALUE *) no_index, tex_stage); + } else { + D3DVALUE *tex_coord = + (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + + i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); + handle_textures(tex_coord, tex_stage); } } + if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { D3DVALUE *position = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); @@ -1204,48 +1185,48 @@ handle_xyzrhw(position); } - if (TRACE_ON(ddraw)) { + if (TRACE_ON(ddraw_geom)) { int tex_index; if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { D3DVALUE *position = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - TRACE(" %f %f %f", position[0], position[1], position[2]); + TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]); } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { D3DVALUE *position = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]); + TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]); } if (d3dvtVertexType & D3DFVF_NORMAL) { D3DVALUE *normal = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride); - TRACE(" / %f %f %f", normal[0], normal[1], normal[2]); + TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]); } if (d3dvtVertexType & D3DFVF_DIFFUSE) { DWORD *color_d = (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - TRACE(" / %02lx %02lx %02lx %02lx", - (*color_d >> 16) & 0xFF, - (*color_d >> 8) & 0xFF, - (*color_d >> 0) & 0xFF, - (*color_d >> 24) & 0xFF); + TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", + (*color_d >> 16) & 0xFF, + (*color_d >> 8) & 0xFF, + (*color_d >> 0) & 0xFF, + (*color_d >> 24) & 0xFF); } if (d3dvtVertexType & D3DFVF_SPECULAR) { DWORD *color_s = (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - TRACE(" / %02lx %02lx %02lx %02lx", - (*color_s >> 16) & 0xFF, - (*color_s >> 8) & 0xFF, - (*color_s >> 0) & 0xFF, - (*color_s >> 24) & 0xFF); + TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", + (*color_s >> 16) & 0xFF, + (*color_s >> 8) & 0xFF, + (*color_s >> 0) & 0xFF, + (*color_s >> 24) & 0xFF); } for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { D3DVALUE *tex_coord = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - TRACE(" / %f %f", tex_coord[0], tex_coord[1]); + TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); } - TRACE("\n"); + TRACE_(ddraw_geom)("\n"); } } } else { @@ -1810,6 +1791,88 @@ FIXME(" Unhandled stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha); } } break; + + case D3DTSS_MIPMAPLODBIAS: { + D3DVALUE value = *((D3DVALUE *) &dwState); + BOOLEAN handled = TRUE; + + if (value != 0.0) + handled = FALSE; + + if (handled) { + TRACE(" Stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value); + } else { + FIXME(" Unhandled stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value); + } + } break; + + case D3DTSS_MAXMIPLEVEL: + if (dwState == 0) { + TRACE(" Stage type : D3DTSS_MAXMIPLEVEL => 0 (disabled) \n"); + } else { + FIXME(" Unhandled stage type : D3DTSS_MAXMIPLEVEL => %ld\n", dwState); + } + break; + + case D3DTSS_BORDERCOLOR: { + GLfloat color[4]; + + color[0] = ((dwState >> 16) & 0xFF) / 255.0; + color[1] = ((dwState >> 8) & 0xFF) / 255.0; + color[2] = ((dwState >> 0) & 0xFF) / 255.0; + color[3] = ((dwState >> 24) & 0xFF) / 255.0; + + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color); + } break; + + case D3DTSS_TEXCOORDINDEX: { + BOOLEAN handled = TRUE; + const char *value; + + switch (dwState & 0xFFFF0000) { +#define GEN_CASE(a) case a: value = #a; break + GEN_CASE(D3DTSS_TCI_PASSTHRU); + GEN_CASE(D3DTSS_TCI_CAMERASPACENORMAL); + GEN_CASE(D3DTSS_TCI_CAMERASPACEPOSITION); + GEN_CASE(D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); +#undef GEN_CASE + default: value = "UNKNOWN"; + } + if ((dwState & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU) + handled = FALSE; + + if (handled) { + TRACE(" Stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value); + } else { + FIXME(" Unhandled stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value); + } + } break; + + case D3DTSS_TEXTURETRANSFORMFLAGS: { + const char *projected = "", *value; + BOOLEAN handled = TRUE; + switch (dwState & 0xFF) { +#define GEN_CASE(a) case a: value = #a; break + GEN_CASE(D3DTTFF_DISABLE); + GEN_CASE(D3DTTFF_COUNT1); + GEN_CASE(D3DTTFF_COUNT2); + GEN_CASE(D3DTTFF_COUNT3); + GEN_CASE(D3DTTFF_COUNT4); +#undef GEN_CASE + default: value = "UNKNOWN"; + } + if (dwState & D3DTTFF_PROJECTED) + projected = " | D3DTTFF_PROJECTED"; + + if (dwState != D3DTTFF_DISABLE) + handled = FALSE; + + if (handled == TRUE) { + TRACE(" Stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected); + } else { + FIXME(" Unhandled stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected); + } + } break; default: FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); Index: dlls/ddraw/direct3d/main.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/direct3d/main.c,v retrieving revision 1.14 diff -u -r1.14 main.c --- dlls/ddraw/direct3d/main.c 3 Jan 2003 19:10:48 -0000 1.14 +++ dlls/ddraw/direct3d/main.c 11 May 2003 07:17:30 -0000 @@ -360,17 +360,6 @@ } HRESULT WINAPI -Thunk_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg); - return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirect3DImpl, IDirect3D, IDirect3D3, iface), - lpEnumDevicesCallback, - lpUserArg); -} - -HRESULT WINAPI Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface, LPDIRECT3DLIGHT* lplpDirect3DLight, IUnknown* pUnkOuter) Index: dlls/ddraw/direct3d/mesa.c =================================================================== RCS file: /home/wine/wine/dlls/ddraw/direct3d/mesa.c,v retrieving revision 1.26 diff -u -r1.26 mesa.c --- dlls/ddraw/direct3d/mesa.c 10 Apr 2003 00:19:26 -0000 1.26 +++ dlls/ddraw/direct3d/mesa.c 11 May 2003 07:17:30 -0000 @@ -43,15 +43,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); HRESULT WINAPI -GL_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) +GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface, + LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, + LPVOID lpUserArg) +{ + ICOM_THIS_FROM(IDirect3DImpl, IDirect3D, iface); + TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); + + /* Call functions defined in d3ddevices.c */ + if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK) + return D3D_OK; + + return D3D_OK; +} + +HRESULT WINAPI +GL_IDirect3DImpl_3_2T_EnumDevices(LPDIRECT3D3 iface, + LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, + LPVOID lpUserArg) { ICOM_THIS_FROM(IDirect3DImpl, IDirect3D3, iface); TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); /* Call functions defined in d3ddevices.c */ - if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg) != D3DENUMRET_OK) + if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK) return D3D_OK; return D3D_OK; @@ -313,7 +328,7 @@ XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface, XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef, XCAST(Release) Thunk_IDirect3DImpl_3_Release, - XCAST(EnumDevices) GL_IDirect3DImpl_3_2T_1T_EnumDevices, + XCAST(EnumDevices) GL_IDirect3DImpl_3_2T_EnumDevices, XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight, XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial, XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport, @@ -367,7 +382,7 @@ XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef, XCAST(Release) Thunk_IDirect3DImpl_1_Release, XCAST(Initialize) Main_IDirect3DImpl_1_Initialize, - XCAST(EnumDevices) Thunk_IDirect3DImpl_1_EnumDevices, + XCAST(EnumDevices) GL_IDirect3DImpl_1_EnumDevices, XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight, XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial, XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport,