[dx58] begin of d3d8/d3dcore split
Raphaël Junqueira
fenix at club-internet.fr
Sat Jun 21 06:31:41 CDT 2003
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi,
first, sorry bout this huge patch (difficult to split our code) ;(
Changelog:
- begin of d3dcore split for future d3d9 promote
- currently only debug, utils, shaders and draw functions code
- definitions of 3 headers (as dx use to do): gl, types, interface
Regards,
Raphael
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQE+9EIgp7NA3AmQTU4RAps8AJ9henSJRUPC5V7IU9r6QwuxeHvcmgCgklwQ
SYPfBwGhe5yPkj3rZ6WOWHg=
=K9ED
-----END PGP SIGNATURE-----
-------------- next part --------------
diff -u --new-file /tmp/basetexture.c dlls/d3dcore/basetexture.c
--- /tmp/basetexture.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/basetexture.c 2003-06-21 13:13:01.000000000 +0200
@@ -0,0 +1,38 @@
+/*
+ * IDirect3DBaseTexture implementation
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+D3DRESOURCETYPE WINAPI IDirect3DBaseTextureImpl_GetType(IDirect3DBaseTextureImpl* This) {
+ /*TRACE("(%p) : returning %d\n", This, This->ResourceType);*/
+ return This->parent.ResourceType;
+}
diff -u --new-file /tmp/d3dcore_gl.h dlls/d3dcore/d3dcore_gl.h
--- /tmp/d3dcore_gl.h 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/d3dcore_gl.h 2003-06-20 20:38:35.000000000 +0200
@@ -0,0 +1,327 @@
+/*
+ * Direct3D gl definitions
+ *
+ * Copyright 2003 Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_D3DCORE_GL_H
+#define __WINE_D3DCORE_GL_H
+
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
+#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */
+#include <GL/gl.h>
+#include <GL/glx.h>
+#ifdef HAVE_GL_GLEXT_H
+# include <GL/glext.h>
+#endif
+#undef XMD_H
+
+/**********************************
+ * Usefull GL Macros
+ */
+
+#define checkGLcall(A) \
+{ \
+ GLint err = glGetError(); \
+ if (err != GL_NO_ERROR) { \
+ FIXME(">>>>>>>>>>>>>>>>> %x from %s @ %s / %d\n", err, A, __FILE__, __LINE__); \
+ } else { \
+ TRACE("%s call ok %s / %d\n", A, __FILE__, __LINE__); \
+ } \
+}
+#define vcheckGLcall(A) \
+{ \
+ GLint err = glGetError(); \
+ if (err != GL_NO_ERROR) { \
+ FIXME(">>>>>>>>>>>>>>>>> %x from %s @ %s / %d\n", err, A, __FILE__, __LINE__); \
+ } else { \
+ VTRACE(("%s call ok %s / %d\n", A, __FILE__, __LINE__)); \
+ } \
+}
+
+#define GL_LIMITS(ExtName) (This->direct3d->gl_info.max_##ExtName)
+#define GL_SUPPORT(ExtName) (TRUE == This->direct3d->gl_info.supported[ExtName])
+#define GL_SUPPORT_DEV(ExtName, dev) (TRUE == (dev)->direct3d->gl_info.supported[ExtName])
+#define GL_EXTCALL(FuncName) (This->direct3d->gl_info.FuncName)
+
+
+/**********************************
+ * OpenGL Extensions (EXT and ARB)
+ * defines and functions pointer
+ */
+
+/* GL_EXT_secondary_color */
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+typedef void (APIENTRY * PGLFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRY * PGLFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRY * PGLFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRY * PGLFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+/* GL_EXT_paletted_texture */
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+typedef void (APIENTRY * PGLFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+/* GL_EXT_point_parameters */
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#endif
+typedef void (APIENTRY * PGLFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRY * PGLFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_SUBTRACT_EXT 0x84E7
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE3_RGB_EXT 0x8583
+#define GL_SOURCE4_RGB_EXT 0x8584
+#define GL_SOURCE5_RGB_EXT 0x8585
+#define GL_SOURCE6_RGB_EXT 0x8586
+#define GL_SOURCE7_RGB_EXT 0x8587
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_SOURCE3_ALPHA_EXT 0x858B
+#define GL_SOURCE4_ALPHA_EXT 0x858C
+#define GL_SOURCE5_ALPHA_EXT 0x858D
+#define GL_SOURCE6_ALPHA_EXT 0x858E
+#define GL_SOURCE7_ALPHA_EXT 0x858F
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND3_RGB_EXT 0x8593
+#define GL_OPERAND4_RGB_EXT 0x8594
+#define GL_OPERAND5_RGB_EXT 0x8595
+#define GL_OPERAND6_RGB_EXT 0x8596
+#define GL_OPERAND7_RGB_EXT 0x8597
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#define GL_OPERAND3_ALPHA_EXT 0x859B
+#define GL_OPERAND4_ALPHA_EXT 0x859C
+#define GL_OPERAND5_ALPHA_EXT 0x859D
+#define GL_OPERAND6_ALPHA_EXT 0x859E
+#define GL_OPERAND7_ALPHA_EXT 0x859F
+#endif
+/* GL_EXT_texture_env_dot3 */
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif
+
+
+/*******
+ * OpenGL Official Version
+ * defines
+ */
+
+/* GL_VERSION_1_3 */
+#if !defined(GL_DOT3_RGBA)
+# define GL_DOT3_RGBA 0x8741
+#endif
+#if !defined(GL_SUBTRACT)
+# define GL_SUBTRACT 0x84E7
+#endif
+
+
+/*********************************
+ * OpenGL GLX Extensions
+ * defines and functions pointer
+ */
+
+
+
+/*********************************
+ * OpenGL GLX Official Version
+ * defines and functions pointer
+ */
+
+/* GLX_VERSION_1_3 */
+typedef GLXFBConfig * (APIENTRY * PGLXFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef GLXFBConfig * (APIENTRY * PGLXFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef int (APIENTRY * PGLXFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef XVisualInfo * (APIENTRY * PGLXFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef GLXWindow (APIENTRY * PGLXFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void (APIENTRY * PGLXFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXPixmap (APIENTRY * PGLXFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef void (APIENTRY * PGLXFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef GLXPbuffer (APIENTRY * PGLXFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef void (APIENTRY * PGLXFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void (APIENTRY * PGLXFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef GLXContext (APIENTRY * PGLXFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef Bool (APIENTRY * PGLXFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable (APIENTRY * PGLXFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef Display * (APIENTRY * PGLXFNGLXGETCURRENTDISPLAYPROC) (void);
+typedef int (APIENTRY * PGLXFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void (APIENTRY * PGLXFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+typedef void (APIENTRY * PGLXFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+
+
+/********************************************
+ * OpenGL Supported Extensions (ARB and EXT)
+ */
+
+typedef enum _GL_SupportedExt {
+ /* ARB */
+ ARB_FRAGMENT_PROGRAM,
+ ARB_MULTISAMPLE,
+ ARB_MULTITEXTURE,
+ ARB_POINT_PARAMETERS,
+ ARB_TEXTURE_COMPRESSION,
+ ARB_TEXTURE_CUBE_MAP,
+ ARB_TEXTURE_ENV_COMBINE,
+ ARB_TEXTURE_ENV_DOT3,
+ ARB_VERTEX_PROGRAM,
+ ARB_VERTEX_BLEND,
+ /* EXT */
+ EXT_FOG_COORD,
+ EXT_PALETTED_TEXTURE,
+ EXT_POINT_PARAMETERS,
+ EXT_SECONDARY_COLOR,
+ EXT_TEXTURE_COMPRESSION_S3TC,
+ EXT_TEXTURE_FILTER_ANISOTROPIC,
+ EXT_TEXTURE_LOD,
+ EXT_TEXTURE_LOD_BIAS,
+ EXT_VERTEX_WEIGHTING,
+ /* NVIDIA */
+ NV_FRAGMENT_PROGRAM,
+ NV_VERTEX_PROGRAM,
+ /* ATI */
+ EXT_VERTEX_SHADER,
+
+ OPENGL_SUPPORTED_EXT_END
+} GL_SupportedExt;
+
+typedef enum _GL_VSVersion {
+ VS_VERSION_NOT_SUPPORTED = 0x0,
+ VS_VERSION_10 = 0x10,
+ VS_VERSION_11 = 0x11,
+ VS_VERSION_20 = 0x20,
+ VS_VERSION_30 = 0x30,
+ /*Force 32-bits*/
+ VS_VERSION_FORCE_DWORD = 0x7FFFFFFF
+} GL_VSVersion;
+
+typedef enum _GL_PSVersion {
+ PS_VERSION_NOT_SUPPORTED = 0x0,
+ PS_VERSION_10 = 0x10,
+ PS_VERSION_11 = 0x11,
+ PS_VERSION_12 = 0x12,
+ PS_VERSION_13 = 0x13,
+ PS_VERSION_14 = 0x14,
+ PS_VERSION_20 = 0x20,
+ PS_VERSION_30 = 0x30,
+ /*Force 32-bits*/
+ PS_VERSION_FORCE_DWORD = 0x7FFFFFFF
+} GL_PSVersion;
+
+
+#define GL_EXT_FUNCS_GEN \
+ /** EXT Extensions **/ \
+ /* GL_EXT_fog_coord */ \
+ /* GL_EXT_paletted_texture */ \
+ USE_GL_FUNC(PGLFNGLCOLORTABLEEXTPROC, glColorTableEXT); \
+ /* GL_EXT_point_parameters */ \
+ USE_GL_FUNC(PGLFNGLPOINTPARAMETERFEXTPROC, glPointParameterfEXT); \
+ USE_GL_FUNC(PGLFNGLPOINTPARAMETERFVEXTPROC, glPointParameterfvEXT); \
+ /* GL_EXT_secondary_color */ \
+ USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3UBEXTPROC, glSecondaryColor3ubEXT); \
+ USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3FEXTPROC, glSecondaryColor3fEXT); \
+ USE_GL_FUNC(PGLFNGLSECONDARYCOLOR3FVEXTPROC, glSecondaryColor3fvEXT); \
+ USE_GL_FUNC(PGLFNGLSECONDARYCOLORPOINTEREXTPROC, glSecondaryColorPointerEXT); \
+
+#define GLX_EXT_FUNCS_GEN \
+ /** GLX_VERSION_1_3 **/ \
+ USE_GL_FUNC(PGLXFNGLXCREATEPBUFFERPROC, glXCreatePbuffer); \
+ USE_GL_FUNC(PGLXFNGLXDESTROYPBUFFERPROC, glXDestroyPbuffer); \
+ USE_GL_FUNC(PGLXFNGLXCREATEPIXMAPPROC, glXCreatePixmap); \
+ USE_GL_FUNC(PGLXFNGLXDESTROYPIXMAPPROC, glXDestroyPixmap); \
+ USE_GL_FUNC(PGLXFNGLXCREATENEWCONTEXTPROC, glXCreateNewContext); \
+ USE_GL_FUNC(PGLXFNGLXMAKECONTEXTCURRENTPROC, glXMakeContextCurrent); \
+ USE_GL_FUNC(PGLXFNGLXCHOOSEFBCONFIGPROC, glXChooseFBConfig); \
+
+#undef APIENTRY
+#undef CALLBACK
+#undef WINAPI
+
+/* Redefines the constants */
+#define CALLBACK __stdcall
+#define WINAPI __stdcall
+#define APIENTRY WINAPI
+
+
+#define USE_GL_FUNC(type, pfn) type pfn;
+typedef struct _GL_Info {
+ /**
+ * CAPS Constants
+ */
+ UINT max_lights;
+ UINT max_textures;
+ UINT max_clipplanes;
+
+ GL_PSVersion ps_arb_version;
+ GL_PSVersion ps_nv_version;
+
+ GL_VSVersion vs_arb_version;
+ GL_VSVersion vs_nv_version;
+ GL_VSVersion vs_ati_version;
+
+ BOOL supported[30];
+
+ /** OpenGL EXT and ARB functions ptr */
+ GL_EXT_FUNCS_GEN;
+ /** OpenGL GLX functions ptr */
+ GLX_EXT_FUNCS_GEN;
+ /**/
+} GL_Info;
+#undef USE_GL_FUNC
+
+
+#endif /* __WINE_D3DCORE_GL_H */
diff -u --new-file /tmp/d3dcore_interface.h dlls/d3dcore/d3dcore_interface.h
--- /tmp/d3dcore_interface.h 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/d3dcore_interface.h 2003-06-21 13:14:13.000000000 +0200
@@ -0,0 +1,449 @@
+/*
+ * Direct3D core interface include file
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_D3DCORE_INTERFACE_H
+#define __WINE_D3DCORE_INTERFACE_H
+
+#if !defined( __WINE_CONFIG_H )
+# error You must include config.h to use this header
+#endif
+
+#if !defined( __WINE_D3D8_H ) && !defined( __WINE_D3D9_H )
+# error You must include d3d8.h or d3d9.h header to use this header
+#endif
+
+/*****************************************************************
+ * THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES
+ * PLEASE USE d3dcore_gl.h INSTEAD
+ */
+#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */
+#include <GL/gl.h>
+#include <GL/glx.h>
+#ifdef HAVE_GL_GLEXT_H
+# include <GL/glext.h>
+#endif
+#undef XMD_H
+
+/*****************************************************************
+ * Some defines
+ */
+
+/* Device caps */
+#define MAX_PALETTES 256
+#define MAX_STREAMS 16
+#define MAX_ACTIVE_LIGHTS 8
+#define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES
+#define MAX_LEVELS 256
+
+/* Other useful values */
+#define HIGHEST_RENDER_STATE 174
+#define HIGHEST_TEXTURE_STATE 29
+#define HIGHEST_TRANSFORMSTATE 512
+#define D3DSBT_RECORDED 0xfffffffe
+
+#define D3D_VSHADER_MAX_CONSTANTS 96
+#define D3D_PSHADER_MAX_CONSTANTS 32
+
+/*****************************************************************
+ * Some Macros
+ */
+extern void (*wine_tsx11_lock_ptr)(void);
+extern void (*wine_tsx11_unlock_ptr)(void);
+
+/* As GLX relies on X, this is needed */
+extern int num_lock;
+#if 0
+#define ENTER_GL() ++num_lock; TRACE("inc lock to: %d\n", num_lock); wine_tsx11_lock_ptr()
+#define LEAVE_GL() if (num_lock > 2) TRACE("fucking locks: %d\n", num_lock); --num_lock; wine_tsx11_unlock_ptr()
+#else
+#define ENTER_GL() wine_tsx11_lock_ptr()
+#define LEAVE_GL() wine_tsx11_unlock_ptr()
+#endif
+
+/* Per-vertex trace: */
+#if 0 /* NOTE: Must be 0 in cvs */
+# define VTRACE(A) TRACE A
+#else
+# define VTRACE(A)
+#endif
+#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
+#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%ld, type:%ld)\n", sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType);
+
+
+/*****************************************************************
+ * Some includes
+ */
+
+#include "d3dcore_gl.h"
+#include "d3dcore_types.h"
+
+
+/*****************************************************************
+ * Some defines
+ */
+
+typedef struct IDirect3DBaseTextureImpl IDirect3DBaseTextureImpl;
+typedef struct IDirect3DVolumeTextureImpl IDirect3DVolumeTextureImpl;
+typedef struct IDirect3DImpl IDirect3DImpl;
+typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;
+typedef struct IDirect3DTextureImpl IDirect3DTextureImpl;
+typedef struct IDirect3DCubeTextureImpl IDirect3DCubeTextureImpl;
+typedef struct IDirect3DIndexBufferImpl IDirect3DIndexBufferImpl;
+typedef struct IDirect3DSurfaceImpl IDirect3DSurfaceImpl;
+typedef struct IDirect3DSwapChainImpl IDirect3DSwapChainImpl;
+typedef struct IDirect3DResourceImpl IDirect3DResourceImpl;
+typedef struct IDirect3DVolumeImpl IDirect3DVolumeImpl;
+typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl;
+typedef struct IDirect3DStateBlockImpl IDirect3DStateBlockImpl;
+typedef struct IDirect3DVertexShaderImpl IDirect3DVertexShaderImpl;
+typedef struct IDirect3DPixelShaderImpl IDirect3DPixelShaderImpl;
+typedef struct IDirect3DVertexShaderDeclarationImpl IDirect3DVertexShaderDeclarationImpl;
+
+
+/*************************************************************
+ * d3dcore interfaces defs
+ */
+
+struct IDirect3DImpl {
+ GL_Info gl_info;
+};
+
+struct IDirect3DDeviceImpl {
+ IDirect3DImpl *direct3d;
+
+ IDirect3DSurfaceImpl *frontBuffer;
+ IDirect3DSurfaceImpl *backBuffer;
+ IDirect3DSurfaceImpl *depthStencilBuffer;
+
+ IDirect3DSurfaceImpl *renderTarget;
+ IDirect3DSurfaceImpl *stencilBufferTarget;
+
+ D3DPRESENT_PARAMETERS PresentParms;
+ D3DDEVICE_CREATION_PARAMETERS CreateParms;
+
+ UINT adapterNo;
+ D3DDEVTYPE devType;
+
+ UINT srcBlend;
+ UINT dstBlend;
+ UINT alphafunc;
+ UINT stencilfunc;
+
+ /* State block related */
+ BOOL isRecordingState;
+ IDirect3DStateBlockImpl *StateBlock;
+ IDirect3DStateBlockImpl *UpdateStateBlock;
+
+ /* Other required values */
+ float lightPosn[MAX_ACTIVE_LIGHTS][4];
+ float lightDirn[MAX_ACTIVE_LIGHTS][4];
+
+ /* palettes texture management */
+ PALETTEENTRY palettes[MAX_PALETTES][256];
+ UINT currentPalette;
+
+ /* Optimization */
+ D3DMATRIX lastProj;
+ D3DMATRIX lastView;
+ D3DMATRIX lastWorld0;
+ D3DMATRIX lastTexTrans[8];
+
+ /* OpenGL related */
+ GLXContext glCtx;
+ XVisualInfo *visInfo;
+ Display *display;
+ HWND win_handle;
+ Window win;
+ GLXContext render_ctx;
+ Drawable drawable;
+
+ /* OpenGL Extension related */
+
+ /* Cursor management */
+ BOOL bCursorVisible;
+ UINT xHotSpot;
+ UINT yHotSpot;
+ UINT xScreenSpace;
+ UINT yScreenSpace;
+ GLint cursor;
+
+ UINT dummyTextureName[8];
+};
+
+struct IDirect3DVolumeImpl {
+ IDirect3DDeviceImpl *Device;
+ D3DRESOURCETYPE ResourceType;
+
+ IUnknown *Container;
+ D3DVOLUME_DESC myDesc;
+ BYTE *allocatedMemory;
+ UINT textureName;
+ UINT bytesPerPixel;
+
+ BOOL lockable;
+ BOOL locked;
+ D3DBOX lockedBox;
+ D3DBOX dirtyBox;
+ BOOL Dirty;
+};
+
+struct IDirect3DSwapChainImpl {
+ IDirect3DSurfaceImpl *frontBuffer;
+ IDirect3DSurfaceImpl *backBuffer;
+ IDirect3DSurfaceImpl *depthStencilBuffer;
+ D3DPRESENT_PARAMETERS PresentParms;
+ /* OpenGL/GLX related */
+ GLXContext swap_ctx;
+ Drawable swap_drawable;
+};
+
+struct IDirect3DSurfaceImpl {
+ IDirect3DDeviceImpl *Device;
+ D3DRESOURCETYPE ResourceType;
+
+ IUnknown *Container;
+ D3DSURFACE_DESC myDesc;
+ BYTE *allocatedMemory;
+ UINT textureName;
+ UINT bytesPerPixel;
+
+ BOOL lockable;
+ BOOL locked;
+ RECT lockedRect;
+ RECT dirtyRect;
+ BOOL Dirty;
+};
+
+struct IDirect3DResourceImpl {
+ IDirect3DDeviceImpl *Device;
+ D3DRESOURCETYPE ResourceType;
+};
+
+struct IDirect3DVertexBufferImpl {
+ IDirect3DResourceImpl parent;
+ BYTE *allocatedMemory;
+ D3DVERTEXBUFFER_DESC currentDesc;
+};
+
+struct IDirect3DIndexBufferImpl {
+ IDirect3DResourceImpl parent;
+ void *allocatedMemory;
+ D3DINDEXBUFFER_DESC currentDesc;
+};
+
+struct IDirect3DBaseTextureImpl {
+ IDirect3DResourceImpl parent;
+ BOOL Dirty;
+ D3DFORMAT format;
+ UINT levels;
+};
+
+extern D3DRESOURCETYPE WINAPI IDirect3DBaseTextureImpl_GetType(IDirect3DBaseTextureImpl* This);
+
+struct IDirect3DCubeTextureImpl {
+ IDirect3DBaseTextureImpl parent;
+ UINT edgeLength;
+ DWORD usage;
+ IDirect3DSurfaceImpl *surfaces[6][MAX_LEVELS];
+};
+
+struct IDirect3DTextureImpl {
+ IDirect3DBaseTextureImpl parent;
+ UINT width;
+ UINT height;
+ DWORD usage;
+ IDirect3DSurfaceImpl *surfaces[MAX_LEVELS];
+};
+
+struct IDirect3DVolumeTextureImpl {
+ IDirect3DBaseTextureImpl parent;
+ UINT width;
+ UINT height;
+ UINT depth;
+ DWORD usage;
+ IDirect3DVolumeImpl *volumes[MAX_LEVELS];
+};
+
+struct IDirect3DStateBlockImpl {
+ /* The device */
+ IDirect3DDeviceImpl* device;
+
+ D3DSTATEBLOCKTYPE blockType;
+
+ SAVEDSTATES Changed;
+ SAVEDSTATES Set;
+
+ /* Light Enable */
+ BOOL lightEnable[MAX_ACTIVE_LIGHTS];
+
+ /* ClipPlane */
+ double clipplane[MAX_CLIPPLANES][4];
+
+ /* Stream Source */
+ UINT stream_stride[MAX_STREAMS];
+ IDirect3DVertexBufferImpl *stream_source[MAX_STREAMS];
+ BOOL streamIsUP;
+
+ /* Indices */
+ IDirect3DIndexBufferImpl* pIndexData;
+ UINT baseVertexIndex;
+
+ /* Texture */
+ IDirect3DBaseTextureImpl* textures[8];
+ int textureDimensions[8];
+ /* Texture State Stage */
+ DWORD texture_state[8][HIGHEST_TEXTURE_STATE];
+
+ /* RenderState */
+ DWORD renderstate[HIGHEST_RENDER_STATE];
+
+ /* Transform */
+ D3DMATRIX transforms[HIGHEST_TRANSFORMSTATE];
+
+#if DIRECT3D_VERSION == 0x0800
+ /* ViewPort */
+ D3DVIEWPORT8 viewport;
+ /* Lights */
+ D3DLIGHT8 lights[MAX_ACTIVE_LIGHTS];
+ /* Material */
+ D3DMATERIAL8 material;
+#elif DIRECT3D_VERSION == 0x0900
+ /* ViewPort */
+ D3DVIEWPORT9 viewport;
+ /* Lights */
+ D3DLIGHT9 lights[MAX_ACTIVE_LIGHTS];
+ /* Material */
+ D3DMATERIAL9 material;
+#endif
+
+ DWORD FVF;
+
+ /* Vertex Shader */
+ IDirect3DVertexShaderImpl* VertexShader;
+
+ /* Vertex Shader Declaration */
+ IDirect3DVertexShaderDeclarationImpl* vertexShaderDecl;
+
+ /* Pixel Shader */
+ IDirect3DPixelShaderImpl* PixelShader;
+
+ /* Indexed Vertex Blending */
+ D3DVERTEXBLENDFLAGS vertex_blend;
+ FLOAT tween_factor;
+
+ /* Vertex Shader Constant */
+ D3DSHADERVECTOR vertexShaderConstant[D3D_VSHADER_MAX_CONSTANTS];
+ /* Pixel Shader Constant */
+ D3DSHADERVECTOR pixelShaderConstant[D3D_PSHADER_MAX_CONSTANTS];
+};
+
+struct IDirect3DVertexShaderDeclarationImpl {
+ /* The device */
+ IDirect3DDeviceImpl* device;
+
+ /** precomputed fvf if simple declaration */
+ DWORD fvf[MAX_STREAMS];
+ DWORD allFVF;
+
+ /** dx8 compatible Declaration fields */
+ DWORD* pDeclaration8;
+ DWORD declaration8Length;
+};
+
+struct IDirect3DVertexShaderImpl {
+ /* The device */
+ IDirect3DDeviceImpl* device;
+
+ DWORD* function;
+ UINT functionLength;
+ DWORD usage;
+ DWORD version;
+ /* run time datas */
+ VSHADERDATA* data;
+ VSHADERINPUTDATA input;
+ VSHADEROUTPUTDATA output;
+};
+
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetFunction(IDirect3DVertexShaderImpl* This, VOID* pData, UINT* pSizeOfData);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantB(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantI(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST INT* pConstantData, UINT Vector4iCount);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantB(IDirect3DVertexShaderImpl* This, UINT StartRegister, BOOL* pConstantData, UINT BoolCount);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantI(IDirect3DVertexShaderImpl* This, UINT StartRegister, INT* pConstantData, UINT Vector4iCount);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount);
+/* internal Interfaces */
+extern DWORD WINAPI IDirect3DVertexShaderImpl_GetVersion(IDirect3DVertexShaderImpl* This);
+extern HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* This, VSHADERINPUTDATA* input, VSHADEROUTPUTDATA* output);
+extern HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDeviceImpl* This, IDirect3DVertexShaderImpl* vshader, DWORD SkipnStrides);
+
+
+struct IDirect3DPixelShaderImpl {
+ /* The device */
+ IDirect3DDeviceImpl* device;
+
+ DWORD* function;
+ UINT functionLength;
+ DWORD version;
+ /* run time datas */
+ PSHADERDATA* data;
+ PSHADERINPUTDATA input;
+ PSHADEROUTPUTDATA output;
+};
+
+void IDirect3DDeviceImpl_DrawPrimitive(IDirect3DDeviceImpl* This, int PrimitiveType, long NumPrimitives, long StartVertexIndex,
+ long StartIdx, short idxBytes, const void* idxData, int minIndex);
+void IDirect3DDeviceImpl_SetTexOp(IDirect3DDeviceImpl* This, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
+
+
+void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
+
+SHORT D3DFmtGetBpp(IDirect3DDeviceImpl* This, D3DFORMAT fmt);
+GLint D3DFmt2GLIntFmt(IDirect3DDeviceImpl* This, D3DFORMAT fmt);
+GLenum D3DFmt2GLFmt(IDirect3DDeviceImpl* This, D3DFORMAT fmt);
+GLenum D3DFmt2GLType(IDirect3DDeviceImpl* This, D3DFORMAT fmt);
+
+GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt);
+GLenum D3DFmt2GLDepthType(D3DFORMAT fmt);
+
+int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim);
+int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType);
+int D3DFVFGetSize(D3DFORMAT fvf);
+
+int SOURCEx_RGB_EXT(DWORD arg);
+int OPERANDx_RGB_EXT(DWORD arg);
+int SOURCEx_ALPHA_EXT(DWORD arg);
+int OPERANDx_ALPHA_EXT(DWORD arg);
+GLenum StencilOp(DWORD op);
+
+
+/**
+ * Debug functions
+ */
+const char* debug_d3ddevicetype(D3DDEVTYPE devtype);
+const char* debug_d3dusage(DWORD usage);
+const char* debug_d3dformat(D3DFORMAT fmt);
+const char* debug_d3dressourcetype(D3DRESOURCETYPE res);
+const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType);
+const char* debug_d3dpool(D3DPOOL Pool);
+const char *debug_d3drenderstate(DWORD State);
+const char *debug_d3dtexturestate(DWORD State);
+
+#endif
diff -u --new-file /tmp/d3dcore_main.c dlls/d3dcore/d3dcore_main.c
--- /tmp/d3dcore_main.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/d3dcore_main.c 2003-06-20 20:42:50.000000000 +0200
@@ -0,0 +1,51 @@
+/* Direct3D 8
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wine/debug.h"
+
+#include "d3d8.h"
+#include "d3dcore_gl.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+int num_lock = 0;
+void (*wine_tsx11_lock_ptr)(void) = NULL;
+void (*wine_tsx11_unlock_ptr)(void) = NULL;
+
+/* At process attach */
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
+{
+ TRACE("fdwReason=%ld\n", fdwReason);
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ HMODULE mod = GetModuleHandleA( "x11drv.dll" );
+ if (mod)
+ {
+ wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
+ wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
+ }
+ }
+ return TRUE;
+}
diff -u --new-file /tmp/d3dcore.spec dlls/d3dcore/d3dcore.spec
--- /tmp/d3dcore.spec 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/d3dcore.spec 2003-06-20 20:47:34.000000000 +0200
@@ -0,0 +1,2 @@
+@ stdcall ValidatePixelShader(ptr ptr)
+@ stdcall ValidateVertexShader(ptr ptr)
diff -u --new-file /tmp/d3dcore_types.h dlls/d3dcore/d3dcore_types.h
--- /tmp/d3dcore_types.h 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/d3dcore_types.h 2003-06-20 20:38:40.000000000 +0200
@@ -0,0 +1,151 @@
+/*
+ * Direct3D core types include file
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_D3DCORE_TYPES_H
+#define __WINE_D3DCORE_TYPES_H
+
+typedef struct _D3DVECTOR_3 {
+ float x;
+ float y;
+ float z;
+} D3DVECTOR_3;
+
+typedef struct _D3DVECTOR_4 {
+ float x;
+ float y;
+ float z;
+ float w;
+} D3DVECTOR_4;
+
+typedef struct D3DSHADERVECTOR {
+ float x;
+ float y;
+ float z;
+ float w;
+} D3DSHADERVECTOR;
+
+typedef struct D3DSHADERSCALAR {
+ float x;
+} D3DSHADERSCALAR;
+
+typedef D3DSHADERVECTOR VSHADERCONSTANTS8[D3D_VSHADER_MAX_CONSTANTS];
+
+typedef struct VSHADERDATA {
+ /** Run Time Shader Function Constants */
+ /*D3DXBUFFER* constants;*/
+ VSHADERCONSTANTS8 C;
+ /** Shader Code as char ... */
+ CONST DWORD* code;
+ UINT codeLength;
+} VSHADERDATA;
+
+/** temporary here waiting for buffer code */
+typedef struct VSHADERINPUTDATA {
+ D3DSHADERVECTOR V[17];
+} VSHADERINPUTDATA;
+
+/** temporary here waiting for buffer code */
+typedef struct VSHADEROUTPUTDATA {
+ D3DSHADERVECTOR oPos;
+ D3DSHADERVECTOR oD[2];
+ D3DSHADERVECTOR oT[8];
+ D3DSHADERVECTOR oFog;
+ D3DSHADERVECTOR oPts;
+} VSHADEROUTPUTDATA;
+
+typedef D3DSHADERVECTOR PSHADERCONSTANTS8[D3D_PSHADER_MAX_CONSTANTS];
+
+typedef struct PSHADERDATA {
+ /** Run Time Shader Function Constants */
+ /*D3DXBUFFER* constants;*/
+ PSHADERCONSTANTS8 C;
+ /** Shader Code as char ... */
+ CONST DWORD* code;
+ UINT codeLength;
+} PSHADERDATA;
+
+/** temporary here waiting for buffer code */
+typedef struct PSHADERINPUTDATA {
+ D3DSHADERVECTOR V[2];
+ D3DSHADERVECTOR T[8];
+ D3DSHADERVECTOR S[16];
+ /*D3DSHADERVECTOR R[12];*/
+} PSHADERINPUTDATA;
+
+/** temporary here waiting for buffer code */
+typedef struct PSHADEROUTPUTDATA {
+ D3DSHADERVECTOR oC[4];
+ D3DSHADERVECTOR oDepth;
+} PSHADEROUTPUTDATA;
+
+/**
+ * State Block for Begin/End/Capture/Create/Apply State Block
+ * Note: Very long winded but I do not believe gl Lists will
+ * resolve everything we need, so doing it manually for now
+ */
+typedef struct SAVEDSTATES {
+ BOOL lightEnable[MAX_ACTIVE_LIGHTS];
+ BOOL Indices;
+ BOOL lights[MAX_ACTIVE_LIGHTS];
+ BOOL material;
+ BOOL stream_source[MAX_STREAMS];
+ BOOL textures[8];
+ BOOL transform[HIGHEST_TRANSFORMSTATE];
+ BOOL viewport;
+ BOOL vertexShader;
+ BOOL vertexShaderConstant;
+ BOOL vertexShaderDecl;
+ BOOL pixelShader;
+ BOOL pixelShaderConstant;
+ BOOL renderstate[HIGHEST_RENDER_STATE];
+ BOOL texture_state[8][HIGHEST_TEXTURE_STATE];
+ BOOL clipplane[MAX_CLIPPLANES];
+} SAVEDSTATES;
+
+
+/*****************************************
+ * Structures required to draw primitives
+ */
+
+typedef struct Direct3DStridedData {
+ BYTE *lpData; /* Pointer to start of data */
+ DWORD dwStride; /* Stride between occurances of this data */
+ DWORD dwType; /* Type (as in D3DVSDT_TYPE) */
+} Direct3DStridedData;
+
+typedef struct Direct3DVertexStridedData {
+ union {
+ struct {
+ Direct3DStridedData position;
+ Direct3DStridedData blendWeights;
+ Direct3DStridedData blendMatrixIndices;
+ Direct3DStridedData normal;
+ Direct3DStridedData pSize;
+ Direct3DStridedData diffuse;
+ Direct3DStridedData specular;
+ Direct3DStridedData texCoords[8];
+ } DUMMYSTRUCTNAME;
+ Direct3DStridedData input[16]; /* Indexed by constants in D3DVSDE_REGISTER */
+ } DUMMYUNIONNAME;
+} Direct3DVertexStridedData;
+
+
+#endif
diff -u --new-file /tmp/debug.c dlls/d3dcore/debug.c
--- /tmp/debug.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/debug.c 2003-06-20 20:13:52.000000000 +0200
@@ -0,0 +1,295 @@
+/*
+ * D3D core debug utils
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
+ switch (devtype) {
+#define DEVTYPE_TO_STR(dev) case dev: return #dev
+ DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
+ DEVTYPE_TO_STR(D3DDEVTYPE_REF);
+ DEVTYPE_TO_STR(D3DDEVTYPE_SW);
+#undef DEVTYPE_TO_STR
+ default:
+ FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dusage(DWORD usage) {
+ switch (usage) {
+#define D3DUSAGE_TO_STR(u) case u: return #u
+ D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
+ D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
+ D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
+ D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
+ D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
+ D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
+ D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
+ D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
+ D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
+#undef D3DUSAGE_TO_STR
+ case 0: return "none";
+ default:
+ FIXME("Unrecognized %lu Usage!\n", usage);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dformat(D3DFORMAT fmt) {
+ switch (fmt) {
+#define FMT_TO_STR(fmt) case fmt: return #fmt
+ FMT_TO_STR(D3DFMT_UNKNOWN);
+ FMT_TO_STR(D3DFMT_R8G8B8);
+ FMT_TO_STR(D3DFMT_A8R8G8B8);
+ FMT_TO_STR(D3DFMT_X8R8G8B8);
+ FMT_TO_STR(D3DFMT_R5G6B5);
+ FMT_TO_STR(D3DFMT_X1R5G5B5);
+ FMT_TO_STR(D3DFMT_A1R5G5B5);
+ FMT_TO_STR(D3DFMT_A4R4G4B4);
+ FMT_TO_STR(D3DFMT_R3G3B2);
+ FMT_TO_STR(D3DFMT_A8);
+ FMT_TO_STR(D3DFMT_A8R3G3B2);
+ FMT_TO_STR(D3DFMT_X4R4G4B4);
+ FMT_TO_STR(D3DFMT_A8P8);
+ FMT_TO_STR(D3DFMT_P8);
+ FMT_TO_STR(D3DFMT_L8);
+ FMT_TO_STR(D3DFMT_A8L8);
+ FMT_TO_STR(D3DFMT_A4L4);
+ FMT_TO_STR(D3DFMT_V8U8);
+ FMT_TO_STR(D3DFMT_L6V5U5);
+ FMT_TO_STR(D3DFMT_X8L8V8U8);
+ FMT_TO_STR(D3DFMT_Q8W8V8U8);
+ FMT_TO_STR(D3DFMT_V16U16);
+ FMT_TO_STR(D3DFMT_W11V11U10);
+ FMT_TO_STR(D3DFMT_UYVY);
+ FMT_TO_STR(D3DFMT_YUY2);
+ FMT_TO_STR(D3DFMT_DXT1);
+ FMT_TO_STR(D3DFMT_DXT2);
+ FMT_TO_STR(D3DFMT_DXT3);
+ FMT_TO_STR(D3DFMT_DXT4);
+ FMT_TO_STR(D3DFMT_DXT5);
+ FMT_TO_STR(D3DFMT_D16_LOCKABLE);
+ FMT_TO_STR(D3DFMT_D32);
+ FMT_TO_STR(D3DFMT_D15S1);
+ FMT_TO_STR(D3DFMT_D24S8);
+ FMT_TO_STR(D3DFMT_D16);
+ FMT_TO_STR(D3DFMT_D24X8);
+ FMT_TO_STR(D3DFMT_D24X4S4);
+ FMT_TO_STR(D3DFMT_VERTEXDATA);
+ FMT_TO_STR(D3DFMT_INDEX16);
+ FMT_TO_STR(D3DFMT_INDEX32);
+#undef FMT_TO_STR
+ default:
+ FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
+ switch (res) {
+#define RES_TO_STR(res) case res: return #res;
+ RES_TO_STR(D3DRTYPE_SURFACE);
+ RES_TO_STR(D3DRTYPE_VOLUME);
+ RES_TO_STR(D3DRTYPE_TEXTURE);
+ RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
+ RES_TO_STR(D3DRTYPE_CUBETEXTURE);
+ RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
+ RES_TO_STR(D3DRTYPE_INDEXBUFFER);
+#undef RES_TO_STR
+ default:
+ FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
+ switch (PrimitiveType) {
+#define PRIM_TO_STR(prim) case prim: return #prim;
+ PRIM_TO_STR(D3DPT_POINTLIST);
+ PRIM_TO_STR(D3DPT_LINELIST);
+ PRIM_TO_STR(D3DPT_LINESTRIP);
+ PRIM_TO_STR(D3DPT_TRIANGLELIST);
+ PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
+ PRIM_TO_STR(D3DPT_TRIANGLEFAN);
+#undef PRIM_TO_STR
+ default:
+ FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dpool(D3DPOOL Pool) {
+ switch (Pool) {
+#define POOL_TO_STR(p) case p: return #p;
+ POOL_TO_STR(D3DPOOL_DEFAULT);
+ POOL_TO_STR(D3DPOOL_MANAGED);
+ POOL_TO_STR(D3DPOOL_SYSTEMMEM);
+ POOL_TO_STR(D3DPOOL_SCRATCH);
+#undef POOL_TO_STR
+ default:
+ FIXME("Unrecognized %u D3DPOOL!\n", Pool);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3drenderstate(DWORD state) {
+ switch (state) {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(D3DRS_ZENABLE );
+ D3DSTATE_TO_STR(D3DRS_FILLMODE );
+ D3DSTATE_TO_STR(D3DRS_SHADEMODE );
+ D3DSTATE_TO_STR(D3DRS_LINEPATTERN );
+ D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE );
+ D3DSTATE_TO_STR(D3DRS_LASTPIXEL );
+ D3DSTATE_TO_STR(D3DRS_SRCBLEND );
+ D3DSTATE_TO_STR(D3DRS_DESTBLEND );
+ D3DSTATE_TO_STR(D3DRS_CULLMODE );
+ D3DSTATE_TO_STR(D3DRS_ZFUNC );
+ D3DSTATE_TO_STR(D3DRS_ALPHAREF );
+ D3DSTATE_TO_STR(D3DRS_ALPHAFUNC );
+ D3DSTATE_TO_STR(D3DRS_DITHERENABLE );
+ D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE );
+ D3DSTATE_TO_STR(D3DRS_FOGENABLE );
+ D3DSTATE_TO_STR(D3DRS_SPECULARENABLE );
+ D3DSTATE_TO_STR(D3DRS_ZVISIBLE );
+ D3DSTATE_TO_STR(D3DRS_FOGCOLOR );
+ D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE );
+ D3DSTATE_TO_STR(D3DRS_FOGSTART );
+ D3DSTATE_TO_STR(D3DRS_FOGEND );
+ D3DSTATE_TO_STR(D3DRS_FOGDENSITY );
+ D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS );
+ D3DSTATE_TO_STR(D3DRS_ZBIAS );
+ D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE );
+ D3DSTATE_TO_STR(D3DRS_STENCILENABLE );
+ D3DSTATE_TO_STR(D3DRS_STENCILFAIL );
+ D3DSTATE_TO_STR(D3DRS_STENCILZFAIL );
+ D3DSTATE_TO_STR(D3DRS_STENCILPASS );
+ D3DSTATE_TO_STR(D3DRS_STENCILFUNC );
+ D3DSTATE_TO_STR(D3DRS_STENCILREF );
+ D3DSTATE_TO_STR(D3DRS_STENCILMASK );
+ D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK );
+ D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR );
+ D3DSTATE_TO_STR(D3DRS_WRAP0 );
+ D3DSTATE_TO_STR(D3DRS_WRAP1 );
+ D3DSTATE_TO_STR(D3DRS_WRAP2 );
+ D3DSTATE_TO_STR(D3DRS_WRAP3 );
+ D3DSTATE_TO_STR(D3DRS_WRAP4 );
+ D3DSTATE_TO_STR(D3DRS_WRAP5 );
+ D3DSTATE_TO_STR(D3DRS_WRAP6 );
+ D3DSTATE_TO_STR(D3DRS_WRAP7 );
+ D3DSTATE_TO_STR(D3DRS_CLIPPING );
+ D3DSTATE_TO_STR(D3DRS_LIGHTING );
+ D3DSTATE_TO_STR(D3DRS_AMBIENT );
+ D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE );
+ D3DSTATE_TO_STR(D3DRS_COLORVERTEX );
+ D3DSTATE_TO_STR(D3DRS_LOCALVIEWER );
+ D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS );
+ D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE );
+ D3DSTATE_TO_STR(D3DRS_VERTEXBLEND );
+ D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE );
+ D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN );
+ D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_A );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_B );
+ D3DSTATE_TO_STR(D3DRS_POINTSCALE_C );
+ D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS );
+ D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK );
+ D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE );
+ D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS );
+ D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN );
+ D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX );
+ D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE );
+ D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE );
+ D3DSTATE_TO_STR(D3DRS_TWEENFACTOR );
+ D3DSTATE_TO_STR(D3DRS_BLENDOP );
+ D3DSTATE_TO_STR(D3DRS_POSITIONORDER );
+ D3DSTATE_TO_STR(D3DRS_NORMALORDER );
+#undef D3DSTATE_TO_STR
+ default:
+ FIXME("Unrecognized %lu render state!\n", state);
+ return "unrecognized";
+ }
+}
+
+const char* debug_d3dtexturestate(DWORD state) {
+ switch (state) {
+#define D3DSTATE_TO_STR(u) case u: return #u
+ D3DSTATE_TO_STR(D3DTSS_COLOROP );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG1 );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG2 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAOP );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG1 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG2 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10 );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11 );
+ D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSU );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSV );
+ D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR );
+ D3DSTATE_TO_STR(D3DTSS_MAGFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MINFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MIPFILTER );
+ D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS );
+ D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL );
+ D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE );
+ D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET );
+ D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS );
+ D3DSTATE_TO_STR(D3DTSS_ADDRESSW );
+ D3DSTATE_TO_STR(D3DTSS_COLORARG0 );
+ D3DSTATE_TO_STR(D3DTSS_ALPHAARG0 );
+ D3DSTATE_TO_STR(D3DTSS_RESULTARG );
+#undef D3DSTATE_TO_STR
+ case 12:
+ /* Note D3DTSS are not consecutive, so skip these */
+ return "unused";
+ break;
+ default:
+ FIXME("Unrecognized %lu texture state!\n", state);
+ return "unrecognized";
+ }
+}
+
Les sous-répertoires /tmp/dinput et dlls/d3dcore/dinput sont identiques.
diff -u --new-file /tmp/drawprim.c dlls/d3dcore/drawprim.c
--- /tmp/drawprim.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/drawprim.c 2003-06-21 13:16:44.000000000 +0200
@@ -0,0 +1,1323 @@
+/*
+ * D3D8 utils
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
+
+
+#undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */
+
+/* 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 */
+BOOL initializeFVF(IDirect3DDeviceImpl* This,
+ DWORD *FVFbits, /* What to expect in the FVF across all streams */
+ BOOL *useVertexShaderFunction) /* Should we use the vertex shader */
+{
+
+ /* 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 */
+
+ if (NULL == This->UpdateStateBlock->VertexShader) {
+
+ /* Use this as the FVF */
+ *FVFbits = This->UpdateStateBlock->FVF;
+ *useVertexShaderFunction = FALSE;
+ TRACE("FVF explicitally defined, using fixed function pipeline with FVF=%lx\n", *FVFbits);
+
+ } else {
+
+ /* Use created shader */
+ IDirect3DVertexShaderImpl* vertex_shader = NULL;
+ vertex_shader = This->UpdateStateBlock->VertexShader;
+
+ if (vertex_shader == NULL) {
+
+ /* Hmm - User pulled figure out of the air? Unlikely, probably a bug */
+ ERR("trying to use an unitialised vertex shader\n");
+ return TRUE;
+
+ } else {
+
+ *FVFbits = This->UpdateStateBlock->vertexShaderDecl->allFVF;
+
+ if (vertex_shader->function == NULL) {
+ /* No function, so many streams supplied plus FVF definition pre stream */
+ *useVertexShaderFunction = FALSE;
+ TRACE("vertex shader (%lx) declared without program, using fixed function pipeline with FVF=%lx\n", This->StateBlock->VertexShader, *FVFbits);
+ } else {
+ /* Vertex shader needs calling */
+ *useVertexShaderFunction = TRUE;
+ TRACE("vertex shader will be used (unusued FVF=%lx)\n", *FVFbits);
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* Issues the glBegin call for gl given the primitive type and count */
+DWORD primitiveToGl(D3DPRIMITIVETYPE PrimitiveType,
+ DWORD NumPrimitives,
+ GLenum *primType)
+{
+ DWORD NumVertexes = NumPrimitives;
+
+ switch (PrimitiveType) {
+ case D3DPT_POINTLIST:
+ TRACE("POINTS\n");
+ *primType = GL_POINTS;
+ NumVertexes = NumPrimitives;
+ break;
+
+ case D3DPT_LINELIST:
+ TRACE("LINES\n");
+ *primType = GL_LINES;
+ NumVertexes = NumPrimitives * 2;
+ break;
+
+ case D3DPT_LINESTRIP:
+ TRACE("LINE_STRIP\n");
+ *primType = GL_LINE_STRIP;
+ NumVertexes = NumPrimitives + 1;
+ break;
+
+ case D3DPT_TRIANGLELIST:
+ TRACE("TRIANGLES\n");
+ *primType = GL_TRIANGLES;
+ NumVertexes = NumPrimitives * 3;
+ break;
+
+ case D3DPT_TRIANGLESTRIP:
+ TRACE("TRIANGLE_STRIP\n");
+ *primType = GL_TRIANGLE_STRIP;
+ NumVertexes = NumPrimitives + 2;
+ break;
+
+ case D3DPT_TRIANGLEFAN:
+ TRACE("TRIANGLE_FAN\n");
+ *primType = GL_TRIANGLE_FAN;
+ NumVertexes = NumPrimitives + 2;
+ break;
+
+ default:
+ FIXME("Unhandled primitive\n");
+ *primType = GL_POINTS;
+ break;
+ }
+ return NumVertexes;
+}
+
+/* Setup views - Transformed & lit if RHW, else untransformed.
+ Only unlit if Normals are supplied
+ Returns: Whether to restore lighting afterwards */
+BOOL primitiveInitState(IDirect3DDeviceImpl* This, BOOL vtx_transformed, BOOL vtx_lit) {
+
+ BOOL isLightingOn = FALSE;
+
+ /* If no normals, DISABLE lighting otherwise, dont touch lighing as it is
+ set by the appropriate render state */
+ if (vtx_lit) {
+ isLightingOn = glIsEnabled(GL_LIGHTING);
+ glDisable(GL_LIGHTING);
+ checkGLcall("glDisable(GL_LIGHTING);");
+ TRACE("Enabled lighting as no normals supplied, old state = %d\n", isLightingOn);
+ }
+
+ if (vtx_transformed) {
+ double X, Y, height, width, minZ, maxZ;
+
+ /* 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");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity");
+ /**
+ * As seen in d3d7 code:
+ * See the OpenGL Red Book for an explanation of the following translation (in the OpenGL
+ * Correctness Tips section).
+ */
+ glTranslatef(0.375f, 0.375f, 0.0f);
+ checkGLcall("glTranslatef(0.375f, 0.375f, 0.0f)");
+
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode");
+ glLoadIdentity();
+ checkGLcall("glLoadIdentity");
+
+ /* Set up the viewport to be full viewport */
+ X = This->StateBlock->viewport.X;
+ Y = This->StateBlock->viewport.Y;
+ height = This->StateBlock->viewport.Height;
+ width = This->StateBlock->viewport.Width;
+ minZ = This->StateBlock->viewport.MinZ;
+ maxZ = This->StateBlock->viewport.MaxZ;
+ TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
+ glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
+ checkGLcall("glOrtho");
+
+ } else {
+
+ /* Untransformed, so relies on the view and projection matrices */
+ glMatrixMode(GL_MODELVIEW);
+ checkGLcall("glMatrixMode");
+ glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ glMultMatrixf((float *) &This->StateBlock->transforms[D3DTS_WORLDMATRIX(0)].u.m[0][0]);
+ checkGLcall("glMultMatrixf");
+
+
+ glMatrixMode(GL_PROJECTION);
+ checkGLcall("glMatrixMode");
+ glLoadMatrixf((float *) &This->StateBlock->transforms[D3DTS_PROJECTION].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
+ }
+ return isLightingOn;
+}
+
+void primitiveConvertToStridedData(IDirect3DDeviceImpl* This, Direct3DVertexStridedData *strided, LONG BaseVertexIndex) {
+
+ short LoopThroughTo = 0;
+ short nStream;
+ BOOL canDoViaGLPointers = TRUE;
+ int numBlends;
+ int numTextures;
+ int textureNo;
+ int coordIdxInfo = 0x00; /* Information on number of coords supplied */
+ int numCoords[8]; /* Holding place for D3DFVF_TEXTUREFORMATx */
+
+ /* OK, Now to setup the data locations
+ For the non-created vertex shaders, the VertexShader var holds the real
+ FVF and only stream 0 matters
+ For the created vertex shaders, there is an FVF per stream */
+ if (NULL != This->UpdateStateBlock->VertexShader) {
+ LoopThroughTo = MAX_STREAMS;
+ } else {
+ LoopThroughTo = 1;
+ }
+
+ /* Work through stream by stream */
+ for (nStream=0; nStream<LoopThroughTo; nStream++) {
+ DWORD stride = This->StateBlock->stream_stride[nStream];
+ BYTE *data = NULL;
+ DWORD thisFVF = 0;
+
+ /* Skip empty streams */
+ if (This->StateBlock->stream_source[nStream] == NULL) continue;
+
+ /* Retrieve appropriate FVF */
+ if (LoopThroughTo == 1) { /* VertexShader is FVF */
+ thisFVF = This->UpdateStateBlock->FVF;
+ /* Handle memory passed directly as well as vertex buffers */
+ if (This->StateBlock->streamIsUP == TRUE) {
+ data = (BYTE*) This->StateBlock->stream_source[nStream];
+ } else {
+ data = ((IDirect3DVertexBufferImpl*) This->StateBlock->stream_source[nStream])->allocatedMemory;
+ }
+ } else {
+ thisFVF = This->StateBlock->vertexShaderDecl->fvf[nStream];
+ data = ((IDirect3DVertexBufferImpl*) This->StateBlock->stream_source[nStream])->allocatedMemory;
+ }
+ VTRACE(("FVF for stream %d is %lx\n", nStream, thisFVF));
+ if (thisFVF == 0) continue;
+
+ /* Now convert the stream into pointers */
+
+ /* Shuffle to the beginning of the vertexes to render and index from there */
+ data = data + (BaseVertexIndex * stride);
+
+ /* Either 3 or 4 floats depending on the FVF */
+ /* FIXME: Can blending data be in a different stream to the position data?
+ and if so using the fixed pipeline how do we handle it */
+ if (thisFVF & D3DFVF_POSITION_MASK) {
+ strided->u.s.position.lpData = data;
+ strided->u.s.position.dwType = D3DVSDT_FLOAT3;
+ strided->u.s.position.dwStride = stride;
+ data += 3 * sizeof(float);
+ if (thisFVF & D3DFVF_XYZRHW) {
+ strided->u.s.position.dwType = D3DVSDT_FLOAT4;
+ data += sizeof(float);
+ }
+ }
+
+ /* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
+ /** do we have to Check This->UpdateStateBlock->renderstate[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */
+ numBlends = ((thisFVF & D3DFVF_POSITION_MASK) >> 1) - 2 +
+ ((FALSE == (thisFVF & D3DFVF_LASTBETA_UBYTE4)) ? 0 : -1); /* WARNING can be < 0 because -2 */
+ if (numBlends > 0) {
+ canDoViaGLPointers = FALSE;
+ strided->u.s.blendWeights.lpData = data;
+ strided->u.s.blendWeights.dwType = D3DVSDT_FLOAT1 + (numBlends - 1);
+ strided->u.s.blendWeights.dwStride = stride;
+ data += numBlends * sizeof(FLOAT);
+
+ if (thisFVF & D3DFVF_LASTBETA_UBYTE4) {
+ strided->u.s.blendMatrixIndices.lpData = data;
+ strided->u.s.blendMatrixIndices.dwType = D3DVSDT_UBYTE4;
+ strided->u.s.blendMatrixIndices.dwStride= stride;
+ data += sizeof(DWORD);
+ }
+ }
+
+ /* Normal is always 3 floats */
+ if (thisFVF & D3DFVF_NORMAL) {
+ strided->u.s.normal.lpData = data;
+ strided->u.s.normal.dwType = D3DVSDT_FLOAT3;
+ strided->u.s.normal.dwStride = stride;
+ data += 3 * sizeof(FLOAT);
+ }
+
+ /* Pointsize is a single float */
+ if (thisFVF & D3DFVF_PSIZE) {
+ strided->u.s.pSize.lpData = data;
+ strided->u.s.pSize.dwType = D3DVSDT_FLOAT1;
+ strided->u.s.pSize.dwStride = stride;
+ data += sizeof(FLOAT);
+ }
+
+ /* Diffuse is 4 unsigned bytes */
+ if (thisFVF & D3DFVF_DIFFUSE) {
+ strided->u.s.diffuse.lpData = data;
+ strided->u.s.diffuse.dwType = D3DVSDT_SHORT4;
+ strided->u.s.diffuse.dwStride = stride;
+ data += sizeof(DWORD);
+ }
+
+ /* Specular is 4 unsigned bytes */
+ if (thisFVF & D3DFVF_SPECULAR) {
+ strided->u.s.specular.lpData = data;
+ strided->u.s.specular.dwType = D3DVSDT_SHORT4;
+ strided->u.s.specular.dwStride = stride;
+ data += sizeof(DWORD);
+ }
+
+ /* Texture coords */
+ numTextures = (thisFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+ coordIdxInfo = (thisFVF & 0x00FF0000) >> 16; /* 16 is from definition of D3DFVF_TEXCOORDSIZE1, and is 8 (0-7 stages) * 2bits long */
+
+ /* numTextures indicates the number of texture coordinates supplied */
+ /* However, the first set may not be for stage 0 texture - it all */
+ /* depends on D3DTSS_TEXCOORDINDEX. */
+ /* The number of bytes for each coordinate set is based off */
+ /* D3DFVF_TEXCOORDSIZEn, which are the bottom 2 bits */
+
+ /* So, for each supplied texture extract the coords */
+ for (textureNo = 0; textureNo < numTextures; ++textureNo) {
+
+ strided->u.s.texCoords[textureNo].lpData = data;
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT1;
+ strided->u.s.texCoords[textureNo].dwStride = stride;
+ numCoords[textureNo] = coordIdxInfo & 0x03;
+
+ /* Always one set */
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT1) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT2;
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT2) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT3;
+ data += sizeof(float);
+ if (numCoords[textureNo] != D3DFVF_TEXTUREFORMAT3) {
+ strided->u.s.texCoords[textureNo].dwType = D3DVSDT_FLOAT4;
+ data += sizeof(float);
+ }
+ }
+ }
+ coordIdxInfo = coordIdxInfo >> 2; /* Drop bottom two bits */
+ }
+ }
+}
+
+/* Draw a single vertex using this information */
+void draw_vertex(IDirect3DDeviceImpl* This, /* interface */
+ BOOL isXYZ, float x, float y, float z, float rhw, /* xyzn position*/
+ BOOL isNormal, float nx, float ny, float nz, /* normal */
+ BOOL isDiffuse, float *dRGBA, /* 1st colors */
+ BOOL isSpecular, float *sRGB, /* 2ndry colors */
+ BOOL isPtSize, float ptSize, /* pointSize */
+ D3DVECTOR_4 *texcoords, int *numcoords) /* texture info */
+{
+ int textureNo;
+ float s, t, r, q;
+
+ /* Diffuse -------------------------------- */
+ if (isDiffuse == TRUE) {
+ glColor4fv(dRGBA);
+ VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n", dRGBA[0], dRGBA[1], dRGBA[2], dRGBA[3]));
+ }
+
+ /* Specular Colour ------------------------------------------*/
+ if (isSpecular == TRUE) {
+#if defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ GL_EXTCALL(glSecondaryColor3fvEXT(sRGB));
+ VTRACE(("glSecondaryColor4f: r,g,b=%f,%f,%f\n", sRGB[0], sRGB[1], sRGB[2]));
+ }
+#endif
+ }
+
+ /* Normal -------------------------------- */
+ if (isNormal == TRUE) {
+ VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
+ glNormal3f(nx, ny, nz);
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (isPtSize == TRUE) {
+
+ /* no such functionality in the fixed function GL pipeline */
+ FIXME("Cannot change ptSize here in openGl\n");
+ }
+
+ /* Texture coords --------------------------- */
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ continue;
+ } else if (numcoords[coordIdx] == 0) {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied or no coords supplied\n", textureNo);
+ continue;
+ } else {
+
+ /* Initialize vars */
+ s = 0.0f;
+ t = 0.0f;
+ r = 0.0f;
+ q = 0.0f;
+
+ switch (numcoords[coordIdx]) {
+ case 4: q = texcoords[coordIdx].w; /* drop through */
+ case 3: r = texcoords[coordIdx].z; /* drop through */
+ case 2: t = texcoords[coordIdx].y; /* drop through */
+ case 1: s = texcoords[coordIdx].x;
+ }
+
+ switch (numcoords[coordIdx]) { /* Supply the provided texture coords */
+ case D3DTTFF_COUNT1:
+ VTRACE(("tex:%d, s=%f\n", textureNo, s));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s);
+#else
+ glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s);
+#endif
+ } else {
+ glTexCoord1f(s);
+ }
+ break;
+ case D3DTTFF_COUNT2:
+ VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
+#else
+ glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
+#endif
+ } else {
+ glTexCoord2f(s, t);
+ }
+ break;
+ case D3DTTFF_COUNT3:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
+#else
+ glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
+#endif
+ } else {
+ glTexCoord3f(s, t, r);
+ }
+ break;
+ case D3DTTFF_COUNT4:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q);
+#else
+ glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q);
+#endif
+ } else {
+ glTexCoord4f(s, t, r, q);
+ }
+ break;
+ default:
+ FIXME("Should not get here as numCoords should be 0->4 (%x)!\n", numcoords[coordIdx]);
+ }
+ }
+ }
+ } /* End of textures */
+
+ /* Position -------------------------------- */
+ if (isXYZ == TRUE) {
+ if (1.0f == rhw || rhw < 0.01f) {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
+ glVertex3f(x, y, z);
+ } else {
+ GLfloat w = 1.0f / rhw;
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
+ glVertex4f(x * w, y * w, z * w, 1.0f);
+ }
+ }
+}
+
+/*
+ * Actually draw using the supplied information.
+ * Faster GL version using pointers to data, harder to debug though
+ * Note does not handle vertex shaders yet
+ */
+void drawStridedFast(IDirect3DDeviceImpl* This, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+
+ TRACE("Using fast vertex array code\n");
+
+ /* Vertex Pointers -----------------------------------------*/
+ if (sd->u.s.position.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glVertexPointer(%ld, GL_FLOAT, %ld, %p)\n",
+ sd->u.s.position.dwStride,
+ sd->u.s.position.dwType + 1,
+ sd->u.s.position.lpData));
+ glVertexPointer(sd->u.s.position.dwType + 1, GL_FLOAT,
+ sd->u.s.position.dwStride,
+ sd->u.s.position.lpData);
+ checkGLcall("glVertexPointer(...)");
+ glEnableClientState(GL_VERTEX_ARRAY);
+ checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
+ }
+
+ /* Blend Data ----------------------------------------------*/
+ if ((sd->u.s.blendWeights.lpData != NULL) ||
+ (sd->u.s.blendMatrixIndices.lpData != NULL)) {
+ /* FIXME: Wont get here as will drop to slow method */
+ FIXME("Blending not supported in fast draw routine\n");
+
+#if 0 /* Vertex blend support needs to be added */
+ if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
+ /*FIXME("TODO\n");*/
+ } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
+ /*FIXME("TODO\n");*/
+ /*
+ GLExtCall(glVertexWeightPointerEXT)(numBlends, GL_FLOAT, skip, curPos);
+ checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
+ glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
+ checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
+ */
+ } else {
+ FIXME("unsupported blending in openGl\n");
+ }
+ } else {
+ if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
+ FIXME("TODO\n");
+ } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
+ FIXME("TODO\n");
+ /*
+ glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
+ checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
+ */
+ }
+#endif
+ }
+
+ /* Normals -------------------------------------------------*/
+ if (sd->u.s.normal.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glNormalPointer(GL_FLOAT, %ld, %p)\n",
+ sd->u.s.normal.dwStride,
+ sd->u.s.normal.lpData));
+ glNormalPointer(GL_FLOAT,
+ sd->u.s.normal.dwStride,
+ sd->u.s.normal.lpData);
+ checkGLcall("glNormalPointer(...)");
+ glEnableClientState(GL_NORMAL_ARRAY);
+ checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_NORMAL_ARRAY);
+ checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
+ glNormal3f(0, 0, 1);
+ checkGLcall("glNormal3f(0, 0, 1)");
+ }
+
+ /* Point Size ----------------------------------------------*/
+ if (sd->u.s.pSize.lpData != NULL) {
+
+ /* no such functionality in the fixed function GL pipeline */
+ /* FIXME: Wont get here as will drop to slow method */
+ FIXME("Cannot change ptSize here in openGl\n");
+ }
+
+ /* Diffuse Colour ------------------------------------------*/
+ /* WARNING: Data here MUST be in RGBA format, so cannot */
+ /* go directly into fast mode from app pgm, because */
+ /* directx requires data in BGRA format. */
+ if (sd->u.s.diffuse.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n",
+ sd->u.s.diffuse.dwStride,
+ sd->u.s.diffuse.lpData));
+ glColorPointer(4, GL_UNSIGNED_BYTE,
+ sd->u.s.diffuse.dwStride,
+ sd->u.s.diffuse.lpData);
+ checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_COLOR_ARRAY);
+ checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
+
+ } else {
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ checkGLcall("glColor4f(1, 1, 1, 1)");
+ }
+
+ /* Specular Colour ------------------------------------------*/
+ if (sd->u.s.specular.lpData != NULL) {
+
+ /* Note dwType == float3 or float4 == 2 or 3 */
+ VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %ld, %p)\n",
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData));
+
+#if defined(GL_VERSION_1_4)
+ glSecondaryColorPointer(4, GL_UNSIGNED_BYTE,
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData);
+ vcheckGLcall("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
+ vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY)");
+#elif defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
+ sd->u.s.specular.dwStride,
+ sd->u.s.specular.lpData);
+ checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
+ glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ }
+#else
+ /* Missing specular color is not critical, no warnings */
+ VTRACE(("Specular colour is not supported in this GL implementation\n"));
+#endif
+
+ } else {
+
+#if defined(GL_VERSION_1_4)
+ glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
+ checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY)");
+ glSecondaryColor3f(0, 0, 0);
+ checkGLcall("glSecondaryColor3f(0, 0, 0)");
+#elif defined(GL_EXT_secondary_color)
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+ glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
+ checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
+ checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
+ }
+#else
+ /* Do not worry if specular colour missing and disable request */
+#endif
+ }
+
+ /* Texture coords -------------------------------------------*/
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
+ VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
+ } else {
+ int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */
+ int numFloats = coordsToUse;
+#if defined(GL_VERSION_1_3)
+ glClientActiveTexture(GL_TEXTURE0 + textureNo);
+#else
+ glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo);
+#endif
+ /* If texture transform flags in effect, values passed through to vertex
+ depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+
+ /* This indicates how many coords to use regardless of the
+ texture type. However, d3d/opengl fill in the rest appropriately */
+ coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+
+ /* BUT - Projected is more 'fun' - Cant be done for ptr mode.
+ Probably should scan enabled texture units and drop back to
+ slow mode if found? */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+ FIXME("Cannot handle projected transform state in fast mode\n");
+ }
+
+ /* coordsToUse maps to D3DTTFF_COUNT1,2,3,4 == 1,2,3,4 which is correct */
+ }
+ if (numFloats == 0) {
+ FIXME("Skipping as invalid request - numfloats=%d, coordIdx=%d\n", numFloats, coordIdx);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ checkGLcall("glDisableClientState(GL_TEXTURE_COORD_ARRAY);");
+ } else {
+ VTRACE(("tex: %d, ptr=%p, numcoords=%d\n", textureNo, sd->u.s.texCoords[coordIdx].lpData, numFloats));
+ glTexCoordPointer(numFloats, GL_FLOAT, sd->u.s.texCoords[coordIdx].dwStride, sd->u.s.texCoords[coordIdx].lpData);
+ checkGLcall("glTexCoordPointer(x, ...)");
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ checkGLcall("glEnableClientState(GL_TEXTURE_COORD_ARRAY);");
+ }
+ }
+ }
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that
+ will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Finally do the drawing */
+ if (idxData != NULL) {
+
+ TRACE("glElements(%x, %d, %ld, ...)\n", glPrimType, NumVertexes, minIndex);
+ if (idxSize==2) {
+#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
+ glDrawElements(glPrimType, NumVertexes, GL_UNSIGNED_SHORT,
+ (char *)idxData+(2 * startIdx));
+#else
+ glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes,
+ GL_UNSIGNED_SHORT, (char *)idxData+(2 * startIdx));
+#endif
+ } else {
+#if 1 /* FIXME: Want to use DrawRangeElements, but wrong calculation! */
+ glDrawElements(glPrimType, NumVertexes, GL_UNSIGNED_INT,
+ (char *)idxData+(4 * startIdx));
+#else
+ glDrawRangeElements(glPrimType, minIndex, minIndex+NumVertexes-1, NumVertexes,
+ GL_UNSIGNED_INT, (char *)idxData+(2 * startIdx));
+#endif
+ }
+ checkGLcall("glDrawRangeElements");
+
+ } else {
+
+ /* Note first is now zero as we shuffled along earlier */
+ TRACE("glDrawArrays(%x, 0, %d)\n", glPrimType, NumVertexes);
+ glDrawArrays(glPrimType, 0, NumVertexes);
+ checkGLcall("glDrawArrays");
+
+ }
+}
+
+/*
+ * Actually draw using the supplied information.
+ * Slower GL version which extracts info about each vertex in turn
+ */
+void drawStridedSlow(IDirect3DDeviceImpl* This, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+ const short *pIdxBufS = NULL;
+ const long *pIdxBufL = NULL;
+ LONG SkipnStrides = 0;
+ LONG vx_index;
+ float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
+ float nx = 0.0f, ny = 0.0, nz = 0.0f; /* normal x,y,z coordinates */
+ float rhw = 0.0f; /* rhw */
+ float ptSize = 0.0f; /* Point size */
+ DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
+ DWORD specularColor = 0; /* Specular Color */
+
+ TRACE("Using slow vertex array code\n");
+
+ /* Variable Initialization */
+ if (idxData != NULL) {
+ if (idxSize == 2) pIdxBufS = (short *) idxData;
+ else pIdxBufL = (long *) idxData;
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Start drawing in GL */
+ VTRACE(("glBegin(%x)\n", glPrimType));
+ glBegin(glPrimType);
+
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
+
+ /* Initialize diffuse color */
+ diffuseColor = 0xFFFFFFFF;
+
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData != NULL) {
+
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2) {
+ VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ SkipnStrides = pIdxBufS[startIdx+vx_index];
+ } else {
+ VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ SkipnStrides = pIdxBufL[startIdx+vx_index];
+ }
+ }
+
+ /* Position Information ------------------ */
+ if (sd->u.s.position.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride));
+ x = ptrToCoords[0];
+ y = ptrToCoords[1];
+ z = ptrToCoords[2];
+ rhw = 1.0;
+ VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
+
+ /* RHW follows, only if transformed, ie 4 floats were provided */
+ if (sd->u.s.position.dwType == D3DVSDT_FLOAT4) {
+ rhw = ptrToCoords[3];
+ VTRACE(("rhw=%f\n", rhw));
+ }
+ }
+
+ /* Blending data -------------------------- */
+ if (sd->u.s.blendWeights.lpData != NULL) {
+ /*float *ptrToCoords = (float *)(sd->u.s.blendWeights.lpData + (SkipnStrides * sd->u.s.blendWeights.dwStride));*/
+ FIXME("Blending not supported yet\n");
+
+ if (sd->u.s.blendMatrixIndices.lpData != NULL) {
+ /*DWORD *ptrToCoords = (DWORD *)(sd->u.s.blendMatrixIndices.lpData + (SkipnStrides * sd->u.s.blendMatrixIndices.dwStride));*/
+ }
+ }
+
+ /* Vertex Normal Data (untransformed only)- */
+ if (sd->u.s.normal.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride));
+ nx = ptrToCoords[0];
+ ny = ptrToCoords[1];
+ nz = ptrToCoords[2];
+ VTRACE(("nx,ny,nz=%f,%f,%f\n", nx, ny, nz));
+ }
+
+ /* Point Size ----------------------------- */
+ if (sd->u.s.pSize.lpData != NULL) {
+
+ float *ptrToCoords = (float *)(sd->u.s.pSize.lpData + (SkipnStrides * sd->u.s.pSize.dwStride));
+ ptSize = ptrToCoords[0];
+ VTRACE(("ptSize=%f\n", ptSize));
+ FIXME("No support for ptSize yet\n");
+ }
+
+ /* Diffuse -------------------------------- */
+ if (sd->u.s.diffuse.lpData != NULL) {
+
+ DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride));
+ diffuseColor = ptrToCoords[0];
+ VTRACE(("diffuseColor=%lx\n", diffuseColor));
+ }
+
+ /* Specular -------------------------------- */
+ if (sd->u.s.specular.lpData != NULL) {
+
+ DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride));
+ specularColor = ptrToCoords[0];
+ VTRACE(("specularColor=%lx\n", specularColor));
+ }
+
+ /* Texture coords --------------------------- */
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
+ continue ;
+ }
+
+ /* Query tex coords */
+ if (This->StateBlock->textures[textureNo] != NULL) {
+
+ int coordIdx = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXCOORDINDEX];
+ float *ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
+ float s = 0.0, t = 0.0, r = 0.0, q = 0.0;
+
+ if (coordIdx > 7) {
+ VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
+ continue;
+ } else if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
+ TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
+ continue;
+ } else {
+
+ int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DVSDT_FLOAT1 etc */
+
+ /* If texture transform flags in effect, values passed through to vertex
+ depend on the D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+
+ /* This indicates how many coords to use regardless of the
+ texture type. However, d3d/opengl fill in the rest appropriately */
+ coordsToUse = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+
+ switch (coordsToUse) {
+ case 4: q = ptrToCoords[3]; /* drop through */
+ case 3: r = ptrToCoords[2]; /* drop through */
+ case 2: t = ptrToCoords[1]; /* drop through */
+ case 1: s = ptrToCoords[0];
+ }
+
+ /* BUT - Projected is more 'fun' - Move the last coord to the 'q'
+ parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+ switch (coordsToUse) {
+ case 0: /* Drop Through */
+ case 1:
+ FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
+ break;
+ case 2:
+ q = t;
+ t = 0.0;
+ coordsToUse = 4;
+ break;
+ case 3:
+ q = r;
+ r = 0.0;
+ coordsToUse = 4;
+ break;
+ case 4: /* Nop here */
+ break;
+ default:
+ FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
+ This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
+ }
+ }
+ } else {
+ switch (coordsToUse) {
+ case 4: q = ptrToCoords[3]; /* drop through */
+ case 3: r = ptrToCoords[2]; /* drop through */
+ case 2: t = ptrToCoords[1]; /* drop through */
+ case 1: s = ptrToCoords[0];
+ }
+ }
+
+ switch (coordsToUse) { /* Supply the provided texture coords */
+ case D3DTTFF_COUNT1:
+ VTRACE(("tex:%d, s=%f\n", textureNo, s));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord1f(GL_TEXTURE0 + textureNo, s);
+#else
+ glMultiTexCoord1fARB(GL_TEXTURE0_ARB + textureNo, s);
+#endif
+ } else {
+ glTexCoord1f(s);
+ }
+ break;
+ case D3DTTFF_COUNT2:
+ VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord2f(GL_TEXTURE0 + textureNo, s, t);
+#else
+ glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
+#endif
+ } else {
+ glTexCoord2f(s, t);
+ }
+ break;
+ case D3DTTFF_COUNT3:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord3f(GL_TEXTURE0 + textureNo, s, t, r);
+#else
+ glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
+#endif
+ } else {
+ glTexCoord3f(s, t, r);
+ }
+ break;
+ case D3DTTFF_COUNT4:
+ VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
+ if (GL_SUPPORT(ARB_MULTITEXTURE)) {
+#if defined(GL_VERSION_1_3)
+ glMultiTexCoord4f(GL_TEXTURE0 + textureNo, s, t, r, q);
+#else
+ glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, s, t, r, q);
+#endif
+ } else {
+ glTexCoord4f(s, t, r, q);
+ }
+ break;
+ default:
+ FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse);
+ }
+ }
+ }
+ } /* End of textures */
+
+ /* Diffuse -------------------------------- */
+ if (sd->u.s.diffuse.lpData != NULL) {
+ glColor4ub((diffuseColor >> 16) & 0xFF,
+ (diffuseColor >> 8) & 0xFF,
+ (diffuseColor >> 0) & 0xFF,
+ (diffuseColor >> 24) & 0xFF);
+ VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n",
+ ((diffuseColor >> 16) & 0xFF) / 255.0f,
+ ((diffuseColor >> 8) & 0xFF) / 255.0f,
+ ((diffuseColor >> 0) & 0xFF) / 255.0f,
+ ((diffuseColor >> 24) & 0xFF) / 255.0f));
+ }
+
+ /* Normal -------------------------------- */
+ if (sd->u.s.normal.lpData != NULL) {
+ VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
+ glNormal3f(nx, ny, nz);
+ }
+
+ /* Position -------------------------------- */
+ if (sd->u.s.position.lpData != NULL) {
+ if (1.0f == rhw || rhw < 0.01f) {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
+ glVertex3f(x, y, z);
+ } else {
+ VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
+ glVertex4f(x / rhw, y / rhw, z / rhw, 1.0f / rhw);
+ }
+ }
+
+ /* For non indexed mode, step onto next parts */
+ if (idxData == NULL) {
+ SkipnStrides += 1;
+ }
+ }
+
+ glEnd();
+ checkGLcall("glEnd and previous calls");
+}
+
+/*
+ * Draw with emulated vertex shaders
+ * Note: strided data is uninitialized, as we need to pass the vertex
+ * shader directly as ordering irs yet
+ */
+void drawStridedSoftwareVS(IDirect3DDeviceImpl* This, Direct3DVertexStridedData *sd,
+ int PrimitiveType, ULONG NumPrimitives,
+ const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
+
+ int textureNo = 0;
+ GLenum glPrimType = GL_POINTS;
+ int NumVertexes = NumPrimitives;
+ const short *pIdxBufS = NULL;
+ const long *pIdxBufL = NULL;
+ LONG SkipnStrides = 0;
+ LONG vx_index;
+ float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
+ float rhw = 0.0f; /* rhw */
+ float ptSize = 0.0f; /* Point size */
+ D3DVECTOR_4 texcoords[8]; /* Texture Coords */
+ int numcoords[8]; /* Number of coords */
+
+ IDirect3DVertexShaderImpl* vertex_shader = NULL;
+
+ TRACE("Using slow software vertex shader code\n");
+
+ /* Variable Initialization */
+ if (idxData != NULL) {
+ if (idxSize == 2) pIdxBufS = (short *) idxData;
+ else pIdxBufL = (long *) idxData;
+ }
+
+ /* Ok, Work out which primitive is requested and how many vertexes that will be */
+ NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
+
+ /* Retrieve the VS information */
+ vertex_shader = This->StateBlock->VertexShader;
+
+ /* Start drawing in GL */
+ VTRACE(("glBegin(%x)\n", glPrimType));
+ glBegin(glPrimType);
+
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; vx_index++) {
+
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData != NULL) {
+
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2) {
+ VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ SkipnStrides = pIdxBufS[startIdx+vx_index];
+ } else {
+ VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ SkipnStrides = pIdxBufL[startIdx+vx_index];
+ }
+ }
+
+ /* Fill the vertex shader input */
+ IDirect3DDeviceImpl_FillVertexShaderInput(This, vertex_shader, SkipnStrides);
+
+ /* Now execute the vertex shader */
+ memset(&vertex_shader->output, 0, sizeof(VSHADEROUTPUTDATA));
+ IDirect3DVertexShaderImpl_ExecuteSW(vertex_shader, &vertex_shader->input, &vertex_shader->output);
+
+ /*
+ TRACE_VECTOR(vertex_shader->output.oPos);
+ TRACE_VECTOR(vertex_shader->output.oD[0]);
+ TRACE_VECTOR(vertex_shader->output.oD[1]);
+ TRACE_VECTOR(vertex_shader->output.oT[0]);
+ TRACE_VECTOR(vertex_shader->output.oT[1]);
+ TRACE_VECTOR(vertex_shader->input.V[0]);
+ TRACE_VECTOR(vertex_shader->data->C[0]);
+ TRACE_VECTOR(vertex_shader->data->C[1]);
+ TRACE_VECTOR(vertex_shader->data->C[2]);
+ TRACE_VECTOR(vertex_shader->data->C[3]);
+ TRACE_VECTOR(vertex_shader->data->C[4]);
+ TRACE_VECTOR(vertex_shader->data->C[5]);
+ TRACE_VECTOR(vertex_shader->data->C[6]);
+ TRACE_VECTOR(vertex_shader->data->C[7]);
+ */
+
+ /* Extract out the output */
+ /*FIXME: Fog coords? */
+ x = vertex_shader->output.oPos.x;
+ y = vertex_shader->output.oPos.y;
+ z = vertex_shader->output.oPos.z;
+ rhw = vertex_shader->output.oPos.w;
+ ptSize = vertex_shader->output.oPts.x; /* Fixme - Is this right? */
+
+ /** Update textures coords using vertex_shader->output.oT[0->7] */
+ memset(texcoords, 0x00, sizeof(texcoords));
+ memset(numcoords, 0x00, sizeof(numcoords));
+ for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
+ if (This->StateBlock->textures[textureNo] != NULL) {
+ texcoords[textureNo].x = vertex_shader->output.oT[textureNo].x;
+ texcoords[textureNo].y = vertex_shader->output.oT[textureNo].y;
+ texcoords[textureNo].z = vertex_shader->output.oT[textureNo].z;
+ texcoords[textureNo].w = vertex_shader->output.oT[textureNo].w;
+ if (This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
+ numcoords[textureNo] = This->UpdateStateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
+ } else {
+ switch (IDirect3DBaseTextureImpl_GetType(This->StateBlock->textures[textureNo])) {
+ case D3DRTYPE_TEXTURE: numcoords[textureNo] = 2; break;
+ case D3DRTYPE_VOLUMETEXTURE: numcoords[textureNo] = 3; break;
+ default: numcoords[textureNo] = 4;
+ }
+ }
+ } else {
+ numcoords[textureNo] = 0;
+ }
+ }
+
+ /* Draw using this information */
+ draw_vertex(This,
+ TRUE, x, y, z, rhw,
+ FALSE, 0.0f, 0.0f, 0.0f,
+ TRUE, (float*) &vertex_shader->output.oD[0],
+ TRUE, (float*) &vertex_shader->output.oD[1],
+ FALSE, ptSize, /* FIXME: Change back when supported */
+ texcoords, numcoords);
+
+ /* For non indexed mode, step onto next parts */
+ if (idxData == NULL) {
+ SkipnStrides += 1;
+ }
+
+ } /* for each vertex */
+
+ glEnd();
+ checkGLcall("glEnd and previous calls");
+}
+
+/* Routine common to the draw primitive and draw indexed primitive routines */
+void IDirect3DDeviceImpl_DrawPrimitive(IDirect3DDeviceImpl* This,
+ int PrimitiveType,
+ long NumPrimitives,
+ /* for Indexed: */
+ long StartVertexIndex,
+ long StartIdx,
+ short idxSize,
+ const void *idxData,
+ int minIndex) {
+
+ BOOL rc = FALSE;
+ DWORD fvf = 0;
+ IDirect3DVertexShaderImpl *vertex_shader = NULL;
+ BOOL useVertexShaderFunction = FALSE;
+ BOOL isLightingOn = FALSE;
+ Direct3DVertexStridedData dataLocations;
+
+
+ /* Work out what the FVF should look like */
+ rc = initializeFVF(This, &fvf, &useVertexShaderFunction);
+ if (rc) return;
+
+ /* If we will be using a vertex shader, do some initialization for it */
+ if (useVertexShaderFunction == TRUE) {
+ vertex_shader = This->UpdateStateBlock->VertexShader;
+ memset(&vertex_shader->input, 0, sizeof(VSHADERINPUTDATA));
+
+ /** init Constants */
+ if (TRUE == This->UpdateStateBlock->Changed.vertexShaderConstant) {
+ TRACE_(d3d_shader)("vertex shader init Constant\n");
+ IDirect3DVertexShaderImpl_SetConstantF(vertex_shader, 0, (CONST FLOAT*) &This->UpdateStateBlock->vertexShaderConstant[0], 96);
+ }
+ }
+
+ /* Ok, we will be updating the screen from here onwards so grab the lock */
+ ENTER_GL();
+
+ /* Setup transform matrices and sort out */
+ isLightingOn = primitiveInitState(This,
+ fvf & D3DFVF_XYZRHW,
+ !(fvf & D3DFVF_NORMAL));
+
+ /* Initialize all values to null */
+ if (useVertexShaderFunction == FALSE) {
+ memset(&dataLocations, 0x00, sizeof(dataLocations));
+
+ /* Convert to strided data */
+ primitiveConvertToStridedData(This, &dataLocations, StartVertexIndex);
+
+ /* Dump out what parts we have supplied */
+ TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
+ TRACE_STRIDED((&dataLocations), position);
+ TRACE_STRIDED((&dataLocations), blendWeights);
+ TRACE_STRIDED((&dataLocations), blendMatrixIndices);
+ TRACE_STRIDED((&dataLocations), normal);
+ TRACE_STRIDED((&dataLocations), pSize);
+ TRACE_STRIDED((&dataLocations), diffuse);
+ TRACE_STRIDED((&dataLocations), specular);
+ TRACE_STRIDED((&dataLocations), texCoords[0]);
+ TRACE_STRIDED((&dataLocations), texCoords[1]);
+ TRACE_STRIDED((&dataLocations), texCoords[2]);
+ TRACE_STRIDED((&dataLocations), texCoords[3]);
+ TRACE_STRIDED((&dataLocations), texCoords[4]);
+ TRACE_STRIDED((&dataLocations), texCoords[5]);
+ TRACE_STRIDED((&dataLocations), texCoords[6]);
+ TRACE_STRIDED((&dataLocations), texCoords[7]);
+ }
+
+ /* Now draw the graphics to the screen */
+ if (useVertexShaderFunction == TRUE) {
+
+ /* Ideally, we should have software FV and hardware VS, possibly
+ depending on the device type? */
+
+ /* We will have to use the very, very slow emulation layer */
+ drawStridedSoftwareVS(This, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+
+ } else if (TRUE ||
+ (dataLocations.u.s.pSize.lpData != NULL) ||
+ (dataLocations.u.s.diffuse.lpData != NULL) ||
+ (dataLocations.u.s.blendWeights.lpData != NULL)) {
+
+ /* Fixme, Ideally, only use the per-vertex code for software HAL
+ but until opengl supports all the functions returned to setup
+ vertex arrays, we need to drop down to the slow mechanism for
+ certain functions */
+
+ /* We will have to use the slow version of GL per vertex setup */
+ drawStridedSlow(This, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+
+ } else {
+
+ /* We can use the fast version of GL pointers */
+ drawStridedFast(This, &dataLocations, PrimitiveType, NumPrimitives,
+ idxData, idxSize, minIndex, StartIdx);
+ }
+
+ /* If no normals, restore previous lighting state */
+ if (!(fvf & D3DFVF_NORMAL)) {
+ if (isLightingOn) 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");
+
+ /* Diagnostics */
+#if defined(SHOW_FRAME_MAKEUP)
+ {
+ if (isDumpingFrames == TRUE) {
+ D3DLOCKED_RECT r;
+ char buffer[80];
+ IDirect3DSurface8Impl_LockRect((LPDIRECT3DSURFACE8) This->backBuffer, &r, NULL, D3DLOCK_READONLY);
+ sprintf(buffer, "/tmp/backbuffer_%ld.ppm", primCounter++);
+ TRACE("Saving screenshot %s\n", buffer);
+ IDirect3DSurface8Impl_SaveSnapshot((LPDIRECT3DSURFACE8) This->backBuffer, buffer);
+ IDirect3DSurface8Impl_UnlockRect((LPDIRECT3DSURFACE8) This->backBuffer);
+ }
+ }
+#endif
+}
Les sous-répertoires /tmp/.font-unix et dlls/d3dcore/.font-unix sont identiques.
Les sous-répertoires /tmp/gconfd-fenix et dlls/d3dcore/gconfd-fenix sont identiques.
Les sous-répertoires /tmp/gconfd-root et dlls/d3dcore/gconfd-root sont identiques.
Les sous-répertoires /tmp/.ICE-unix et dlls/d3dcore/.ICE-unix sont identiques.
Les sous-répertoires /tmp/kde-fenix et dlls/d3dcore/kde-fenix sont identiques.
Les sous-répertoires /tmp/ksocket-fenix et dlls/d3dcore/ksocket-fenix sont identiques.
diff -u --new-file /tmp/Makefile.in dlls/d3dcore/Makefile.in
--- /tmp/Makefile.in 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/Makefile.in 2003-06-21 13:11:36.000000000 +0200
@@ -0,0 +1,26 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = d3dcore.dll
+IMPORTS = user32 gdi32 kernel32
+EXTRAINCL = @X_CFLAGS@
+EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
+
+LDDLLFLAGS = @LDDLLFLAGS@
+SYMBOLFILE = $(MODULE).tmp.o
+
+C_SRCS = \
+ basetexture.c \
+ d3dcore_main.c \
+ debug.c \
+ drawprim.c \
+ utils.c \
+ vertexshader.c \
+ vertexshaderdeclaration.c
+
+RC_SRCS = version.rc
+
+ at MAKE_DLL_RULES@
+
+### Dependencies:
Les sous-répertoires /tmp/mcop-fenix et dlls/d3dcore/mcop-fenix sont identiques.
diff -u --new-file /tmp/utils.c dlls/d3dcore/utils.c
--- /tmp/utils.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/utils.c 2003-06-20 20:39:28.000000000 +0200
@@ -0,0 +1,1017 @@
+/*
+ * D3D8 utils
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <math.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include "d3d8.h"
+#include "d3dcore_gl.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+
+/*
+ * Simple utility routines used for dx -> gl mapping of byte formats
+ */
+int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim) {
+ switch (PrimitiveType) {
+ case D3DPT_POINTLIST: return iNumPrim;
+ case D3DPT_LINELIST: return iNumPrim * 2;
+ case D3DPT_LINESTRIP: return iNumPrim + 1;
+ case D3DPT_TRIANGLELIST: return iNumPrim * 3;
+ case D3DPT_TRIANGLESTRIP: return iNumPrim + 2;
+ case D3DPT_TRIANGLEFAN: return iNumPrim + 2;
+ default:
+ FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
+ return 0;
+ }
+}
+
+int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType) {
+ switch (PrimitiveType) {
+ case D3DPT_POINTLIST: return GL_POINTS;
+ case D3DPT_LINELIST: return GL_LINES;
+ case D3DPT_LINESTRIP: return GL_LINE_STRIP;
+ case D3DPT_TRIANGLELIST: return GL_TRIANGLES;
+ case D3DPT_TRIANGLESTRIP: return GL_TRIANGLE_STRIP;
+ case D3DPT_TRIANGLEFAN: return GL_TRIANGLE_FAN;
+ default:
+ FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
+ return GL_POLYGON;
+ }
+}
+
+int D3DFVFGetSize(D3DFORMAT fvf) {
+ int ret = 0;
+ if (fvf & D3DFVF_XYZ) ret += 3 * sizeof(float);
+ else if (fvf & D3DFVF_XYZRHW) ret += 4 * sizeof(float);
+ if (fvf & D3DFVF_NORMAL) ret += 3 * sizeof(float);
+ if (fvf & D3DFVF_PSIZE) ret += sizeof(float);
+ if (fvf & D3DFVF_DIFFUSE) ret += sizeof(DWORD);
+ if (fvf & D3DFVF_SPECULAR) ret += sizeof(DWORD);
+ /*if (fvf & D3DFVF_TEX1) ret += 1;*/
+ return ret;
+}
+
+GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt) {
+ switch (fmt) {
+ /* depth/stencil buffer */
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D16:
+ case D3DFMT_D15S1:
+ case D3DFMT_D24X4S4:
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D32:
+ return GL_DEPTH_COMPONENT;
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ }
+ return 0;
+}
+
+GLenum D3DFmt2GLDepthType(D3DFORMAT fmt) {
+ switch (fmt) {
+ /* depth/stencil buffer */
+ case D3DFMT_D15S1:
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D16:
+ return GL_UNSIGNED_SHORT;
+ case D3DFMT_D24X4S4:
+ case D3DFMT_D24S8:
+ case D3DFMT_D24X8:
+ case D3DFMT_D32:
+ return GL_UNSIGNED_INT;
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ }
+ return 0;
+}
+
+SHORT D3DFmtGetBpp(IDirect3DDeviceImpl* This, D3DFORMAT fmt) {
+ SHORT retVal;
+
+ switch (fmt) {
+ /* color buffer */
+ case D3DFMT_P8: retVal = 1; break;
+ case D3DFMT_R3G3B2: retVal = 1; break;
+ case D3DFMT_R5G6B5: retVal = 2; break;
+ case D3DFMT_X1R5G5B5: retVal = 2; break;
+ case D3DFMT_A4R4G4B4: retVal = 2; break;
+ case D3DFMT_X4R4G4B4: retVal = 2; break;
+ case D3DFMT_A1R5G5B5: retVal = 2; break;
+ case D3DFMT_R8G8B8: retVal = 3; break;
+ case D3DFMT_X8R8G8B8: retVal = 4; break;
+ case D3DFMT_A8R8G8B8: retVal = 4; break;
+ /* depth/stencil buffer */
+ case D3DFMT_D16_LOCKABLE: retVal = 2; break;
+ case D3DFMT_D16: retVal = 2; break;
+ case D3DFMT_D15S1: retVal = 2; break;
+ case D3DFMT_D24X4S4: retVal = 4; break;
+ case D3DFMT_D24S8: retVal = 4; break;
+ case D3DFMT_D24X8: retVal = 4; break;
+ case D3DFMT_D32: retVal = 4; break;
+ /* unknown */
+ case D3DFMT_UNKNOWN:
+ /* Guess at the highest value of the above */
+ TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
+ retVal = 4;
+ break;
+
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ retVal = 4;
+ }
+ TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
+ return retVal;
+}
+
+GLint D3DFmt2GLIntFmt(IDirect3DDeviceImpl* This, D3DFORMAT fmt) {
+ GLint retVal;
+
+ switch (fmt) {
+ case D3DFMT_P8: retVal = GL_COLOR_INDEX8_EXT; break;
+ case D3DFMT_A8P8: retVal = GL_COLOR_INDEX8_EXT; break;
+
+ case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
+ case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
+ case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
+ case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
+ case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
+ case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ retVal = GL_RGB8;
+ }
+#if defined(GL_EXT_texture_compression_s3tc)
+ if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
+ switch (fmt) {
+ case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
+ case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
+ case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
+ default:
+ /* stupid compiler */
+ break;
+ }
+ }
+#endif
+ TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
+ return retVal;
+}
+
+GLenum D3DFmt2GLFmt(IDirect3DDeviceImpl* This, D3DFORMAT fmt) {
+ GLenum retVal;
+
+ switch (fmt) {
+ case D3DFMT_P8: retVal = GL_COLOR_INDEX; break;
+ case D3DFMT_A8P8: retVal = GL_COLOR_INDEX; break;
+
+ case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
+ case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
+ case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
+ case D3DFMT_R8G8B8: retVal = GL_BGR; break;
+ case D3DFMT_R5G6B5: retVal = GL_RGB; break;
+ case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ retVal = GL_BGR;
+ }
+#if defined(GL_EXT_texture_compression_s3tc)
+ if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
+ switch (fmt) {
+ case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
+ case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
+ case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
+ default:
+ /* stupid compiler */
+ break;
+ }
+ }
+#endif
+ TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
+ return retVal;
+}
+
+GLenum D3DFmt2GLType(IDirect3DDeviceImpl* This, D3DFORMAT fmt) {
+ GLenum retVal;
+
+ switch (fmt) {
+ case D3DFMT_P8: retVal = GL_UNSIGNED_BYTE; break;
+ case D3DFMT_A8P8: retVal = GL_UNSIGNED_BYTE; break;
+
+ case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
+ case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
+ case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
+ case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break;
+ case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
+ case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
+ default:
+ FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
+ retVal = GL_UNSIGNED_BYTE;
+ }
+#if defined(GL_EXT_texture_compression_s3tc)
+ if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
+ switch (fmt) {
+ case D3DFMT_DXT1: retVal = 0; break;
+ case D3DFMT_DXT3: retVal = 0; break;
+ case D3DFMT_DXT5: retVal = 0; break;
+ default:
+ /* stupid compiler */
+ break;
+ }
+ }
+#endif
+ TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
+ return retVal;
+}
+
+int SOURCEx_RGB_EXT(DWORD arg) {
+ switch(arg) {
+ case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
+ case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
+ case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
+ case D3DTSS_ALPHAARG0:
+ case D3DTSS_ALPHAARG1:
+ case D3DTSS_ALPHAARG2:
+ default:
+ FIXME("Invalid arg %ld\n", arg);
+ return GL_SOURCE0_RGB_EXT;
+ }
+}
+
+int OPERANDx_RGB_EXT(DWORD arg) {
+ switch(arg) {
+ case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
+ case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
+ case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
+ case D3DTSS_ALPHAARG0:
+ case D3DTSS_ALPHAARG1:
+ case D3DTSS_ALPHAARG2:
+ default:
+ FIXME("Invalid arg %ld\n", arg);
+ return GL_OPERAND0_RGB_EXT;
+ }
+}
+
+int SOURCEx_ALPHA_EXT(DWORD arg) {
+ switch(arg) {
+ case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
+ case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
+ case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
+ case D3DTSS_COLORARG0:
+ case D3DTSS_COLORARG1:
+ case D3DTSS_COLORARG2:
+ default:
+ FIXME("Invalid arg %ld\n", arg);
+ return GL_SOURCE0_ALPHA_EXT;
+ }
+}
+
+int OPERANDx_ALPHA_EXT(DWORD arg) {
+ switch(arg) {
+ case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
+ case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
+ case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
+ case D3DTSS_COLORARG0:
+ case D3DTSS_COLORARG1:
+ case D3DTSS_COLORARG2:
+ default:
+ FIXME("Invalid arg %ld\n", arg);
+ return GL_OPERAND0_ALPHA_EXT;
+ }
+}
+
+GLenum StencilOp(DWORD op) {
+ switch(op) {
+ case D3DSTENCILOP_KEEP : return GL_KEEP;
+ case D3DSTENCILOP_ZERO : return GL_ZERO;
+ case D3DSTENCILOP_REPLACE : return GL_REPLACE;
+ case D3DSTENCILOP_INCRSAT : return GL_INCR;
+ case D3DSTENCILOP_DECRSAT : return GL_DECR;
+ case D3DSTENCILOP_INVERT : return GL_INVERT;
+#if defined(GL_VERSION_1_4)
+ case D3DSTENCILOP_INCR : return GL_INCR_WRAP;
+ case D3DSTENCILOP_DECR : return GL_DECR_WRAP;
+#elif defined(GL_EXT_stencil_wrap)
+ case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
+ case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
+#else
+ case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
+ return GL_INCR; /* Fixme - needs to support wrap */
+ case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
+ return GL_DECR; /* Fixme - needs to support wrap */
+#endif
+ default:
+ FIXME("Invalid stencil op %ld\n", op);
+ return GL_ALWAYS;
+ }
+}
+
+/**
+ * @nodoc: todo
+ */
+void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
+{
+ BOOL isAlphaReplicate = FALSE;
+ BOOL isComplement = FALSE;
+
+ *operand = GL_SRC_COLOR;
+ *source = GL_TEXTURE;
+
+ /* Catch alpha replicate */
+ if (iValue & D3DTA_ALPHAREPLICATE) {
+ iValue = iValue & ~D3DTA_ALPHAREPLICATE;
+ isAlphaReplicate = TRUE;
+ }
+
+ /* Catch Complement */
+ if (iValue & D3DTA_COMPLEMENT) {
+ iValue = iValue & ~D3DTA_COMPLEMENT;
+ isComplement = TRUE;
+ }
+
+ /* Calculate the operand */
+ if (isAlphaReplicate && !isComplement) {
+ *operand = GL_SRC_ALPHA;
+ } else if (isAlphaReplicate && isComplement) {
+ *operand = GL_ONE_MINUS_SRC_ALPHA;
+ } else if (isComplement) {
+ if (isAlphaArg) {
+ *operand = GL_ONE_MINUS_SRC_ALPHA;
+ } else {
+ *operand = GL_ONE_MINUS_SRC_COLOR;
+ }
+ } else {
+ if (isAlphaArg) {
+ *operand = GL_SRC_ALPHA;
+ } else {
+ *operand = GL_SRC_COLOR;
+ }
+ }
+
+ /* Calculate the source */
+ switch (iValue & D3DTA_SELECTMASK) {
+ case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
+ break;
+ case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
+ break;
+ case D3DTA_TEXTURE: *source = GL_TEXTURE;
+ break;
+ case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
+ break;
+ case D3DTA_SPECULAR:
+ /**
+ * According to the GL_ARB_texture_env_combine specs, SPECULAR is 'Secondary color' and
+ * isnt supported until base GL supports it
+ * There is no concept of temp registers as far as I can tell
+ */
+
+ default:
+ FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
+ *source = GL_TEXTURE;
+ }
+}
+
+/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
+#if defined (GL_VERSION_1_3)
+# define useext(A) A
+# define combine_ext 1
+#elif defined (GL_EXT_texture_env_combine)
+# define useext(A) A##_EXT
+# define combine_ext 1
+#elif defined (GL_ARB_texture_env_combine)
+# define useext(A) A##_ARB
+# define combine_ext 1
+#else
+# undef combine_ext
+#endif
+
+#if !defined(combine_ext)
+void IDirect3DDeviceImpl_SetTexOp(IDirect3DDeviceImpl* This, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ FIXME("Requires opengl combine extensions to work\n");
+ return;
+}
+#else
+/* Setup the texture operations texture stage states */
+void IDirect3DDeviceImpl_SetTexOp(IDirect3DDeviceImpl* This, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+ GLenum src1, src2, src3;
+ GLenum opr1, opr2, opr3;
+ GLenum comb_target;
+ GLenum src0_target, src1_target, src2_target;
+ GLenum opr0_target, opr1_target, opr2_target;
+ GLenum scal_target;
+ GLenum opr=0, invopr, src3_target, opr3_target;
+ BOOL Handled = FALSE;
+
+ TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
+ if (op == D3DTOP_DISABLE) return;
+
+ ENTER_GL();
+
+ /* Note: Operations usually involve two ars, src0 and src1 and are operations of
+ the form (a1 <operation> a2). However, some of the more complex operations
+ take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
+ in a third parameter called a0. Therefore these are operations of the form
+ a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
+
+ However, below we treat the new (a0) parameter as src2/opr2, so in the actual
+ functions below, expect their syntax to differ slightly to those listed in the
+ manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
+ This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP */
+
+ if (isAlpha) {
+ comb_target = useext(GL_COMBINE_ALPHA);
+ src0_target = useext(GL_SOURCE0_ALPHA);
+ src1_target = useext(GL_SOURCE1_ALPHA);
+ src2_target = useext(GL_SOURCE2_ALPHA);
+ opr0_target = useext(GL_OPERAND0_ALPHA);
+ opr1_target = useext(GL_OPERAND1_ALPHA);
+ opr2_target = useext(GL_OPERAND2_ALPHA);
+ scal_target = GL_ALPHA_SCALE;
+ }
+ else {
+ comb_target = useext(GL_COMBINE_RGB);
+ src0_target = useext(GL_SOURCE0_RGB);
+ src1_target = useext(GL_SOURCE1_RGB);
+ src2_target = useext(GL_SOURCE2_RGB);
+ opr0_target = useext(GL_OPERAND0_RGB);
+ opr1_target = useext(GL_OPERAND1_RGB);
+ opr2_target = useext(GL_OPERAND2_RGB);
+ scal_target = useext(GL_RGB_SCALE);
+ }
+
+ /* From MSDN (D3DTSS_ALPHAARG1) :
+ The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
+ then the default argument is D3DTA_DIFFUSE.
+ FIXME? If texture added/removed, may need to reset back as well? */
+ if (isAlpha && This->StateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
+ GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);
+ } else {
+ GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
+ }
+ GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
+ GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
+
+ TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
+
+ Handled = TRUE; /* Assume will be handled */
+ switch (op) {
+ case D3DTOP_SELECTARG1:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_SELECTARG2:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATE:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATE2X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case D3DTOP_MODULATE4X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+ break;
+ case D3DTOP_ADD:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_ADDSIGNED:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_ADDSIGNED2X:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+ break;
+ case D3DTOP_SUBTRACT:
+ if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ } else {
+ FIXME("This version of opengl does not support GL_SUBTRACT\n");
+ }
+ break;
+
+ case D3DTOP_BLENDDIFFUSEALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDTEXTUREALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDFACTORALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDCURRENTALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_DOTPRODUCT3:
+ if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA");
+ } else {
+ FIXME("This version of opengl does not support GL_DOT3\n");
+ }
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_LERP:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+ checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ default:
+ Handled = FALSE;
+ }
+
+ if (Handled) {
+ BOOL combineOK = TRUE;
+#if defined(GL_NV_texture_env_combine4)
+ DWORD op2;
+
+ if (isAlpha) {
+ op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP];
+ } else {
+ op2 = This->UpdateStateBlock->texture_state[Stage][D3DTSS_ALPHAOP];
+ }
+
+ /* Note: If COMBINE4 in effect cant go back to combine! */
+ switch (op2)
+ {
+ case D3DTOP_ADDSMOOTH:
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ case D3DTOP_MULTIPLYADD:
+ /* Ignore those implemented in both cases */
+ switch (op) {
+ case D3DTOP_SELECTARG1:
+ case D3DTOP_SELECTARG2:
+ combineOK = FALSE;
+ Handled = FALSE;
+ break;
+ default:
+ FIXME("Cant have COMBINE4 and COMBINE in efferct together, thisop=%d, otherop=%ld, isAlpha(%d)\n",
+ op, op2, isAlpha);
+
+ LEAVE_GL();
+ return;
+ }
+ }
+#endif
+
+ if (combineOK == TRUE) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
+
+ LEAVE_GL();
+ return;
+ }
+ }
+
+ /* Other texture operations require special extensions: */
+#if defined(GL_NV_texture_env_combine4)
+ if (isAlpha) {
+ opr = GL_SRC_ALPHA;
+ invopr = GL_ONE_MINUS_SRC_ALPHA;
+ src3_target = GL_SOURCE3_ALPHA_NV;
+ opr3_target = GL_OPERAND3_ALPHA_NV;
+ }
+ else {
+ opr = GL_SRC_COLOR;
+ invopr = GL_ONE_MINUS_SRC_COLOR;
+ src3_target = GL_SOURCE3_RGB_NV;
+ opr3_target = GL_OPERAND3_RGB_NV;
+ }
+ Handled = TRUE; /* Again, assume handled */
+ switch (op) {
+ case D3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
+ case D3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ if (op == D3DTOP_SELECTARG1) {
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ } else {
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+ }
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ break;
+
+ case D3DTOP_ADDSMOOTH:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_BLENDTEXTUREALPHAPM:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEALPHA_ADDCOLOR:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATECOLOR_ADDALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+ case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+ switch (opr1) {
+ case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
+ }
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+ case D3DTOP_MULTIPLYADD:
+ glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+ checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+ glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
+ checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+ glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
+ checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+ glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+ checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+ glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+ checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+ glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+ checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+ glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+ checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+ glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
+ checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
+ glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
+ checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
+ glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+ checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+ break;
+
+ default:
+ Handled = FALSE;
+ }
+ if (Handled) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+ checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
+
+ LEAVE_GL();
+ return;
+ }
+#endif /* GL_NV_texture_env_combine4 */
+
+ LEAVE_GL();
+
+ /* After all the extensions, if still unhandled, report fixme */
+ FIXME("Unhandled texture operation %d\n", op);
+}
+#endif
diff -u --new-file /tmp/version.rc dlls/d3dcore/version.rc
--- /tmp/version.rc 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/version.rc 2003-06-20 20:41:28.000000000 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2001 Ove Kaaven
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine Direct3D core"
+#define WINE_FILENAME_STR "d3dcore.dll"
+#define WINE_FILEVERSION 1,0,0,001
+#define WINE_FILEVERSION_STR "1.0.0.001"
+#define WINE_PRODUCTVERSION 1,0,0,001
+#define WINE_PRODUCTVERSION_STR "1.0"
+#define WINE_PRODUCTNAME_STR "WineD3DCore"
+
+#include "wine/wine_common_ver.rc"
diff -u --new-file /tmp/vertexshader.c dlls/d3dcore/vertexshader.c
--- /tmp/vertexshader.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/vertexshader.c 2003-06-20 20:53:50.000000000 +0200
@@ -0,0 +1,1270 @@
+/*
+ * shaders implementation
+ *
+ * Copyright 2002-2003 Jason Edmeades
+ * Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include <math.h>
+
+#include "d3d8.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+/* Shader debugging - Change the following line to enable debugging of software
+ vertex shaders */
+#if 0 /* Must not be 1 in cvs version */
+# define VSTRACE(A) TRACE A
+# define TRACE_VSVECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
+#else
+# define VSTRACE(A)
+# define TRACE_VSVECTOR(name)
+#endif
+
+
+/**
+ * DirectX9 SDK download
+ * http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp
+ *
+ * Exploring D3DX
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp
+ *
+ * Using Vertex Shaders
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp
+ *
+ * Dx9 New
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp
+ *
+ * Dx9 Shaders
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp
+ *
+ * Dx9 D3DX
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp
+ *
+ * FVF
+ * http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp
+ *
+ * NVIDIA: DX8 Vertex Shader to NV Vertex Program
+ * http://developer.nvidia.com/view.asp?IO=vstovp
+ *
+ * NVIDIA: Memory Management with VAR
+ * http://developer.nvidia.com/view.asp?IO=var_memory_management
+ */
+
+typedef void (*shader_fct_t)();
+
+typedef struct SHADER_OPCODE {
+ CONST BYTE opcode;
+ const char* name;
+ CONST UINT num_params;
+ shader_fct_t soft_fct;
+ DWORD min_version;
+ DWORD max_version;
+} SHADER_OPCODE;
+
+/*******************************
+ * vshader functions software VM
+ */
+
+void vshader_add(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = s0->x + s1->x;
+ d->y = s0->y + s1->y;
+ d->z = s0->z + s1->z;
+ d->w = s0->w + s1->w;
+ VSTRACE(("executing add: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_dp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z;
+ VSTRACE(("executing dp3: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_dp4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z + s0->w * s1->w;
+ VSTRACE(("executing dp4: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_dst(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = 1.0f;
+ d->y = s0->y * s1->y;
+ d->z = s0->z;
+ d->w = s1->w;
+ VSTRACE(("executing dst: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_expp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ float tmp_f = floorf(s0->w);
+ DWORD tmp_d = 0;
+ tmp_f = powf(2.0f, s0->w);
+ tmp_d = *((DWORD*) &tmp_f) & 0xFFFFFF00;
+
+ d->x = powf(2.0f, tmp_f);
+ d->y = s0->w - tmp_f;
+ d->z = *((float*) &tmp_d);
+ d->w = 1.0f;
+ VSTRACE(("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_lit(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ d->x = 1.0f;
+ d->y = (0.0f < s0->x) ? s0->x : 0.0f;
+ d->z = (0.0f < s0->x && 0.0f < s0->y) ? powf(s0->y, s0->w) : 0.0f;
+ d->w = 1.0f;
+ VSTRACE(("executing lit: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_logp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ float tmp_f = fabsf(s0->w);
+ d->x = d->y = d->z = d->w = (0.0f != tmp_f) ? logf(tmp_f) / logf(2.0f) : -HUGE;
+ VSTRACE(("executing logp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_mad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) {
+ d->x = s0->x * s1->x + s2->x;
+ d->y = s0->y * s1->y + s2->y;
+ d->z = s0->z * s1->z + s2->z;
+ d->w = s0->w * s1->w + s2->w;
+ VSTRACE(("executing mad: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) s2=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, s2->x, s2->y, s2->z, s2->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_max(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = (s0->x >= s1->x) ? s0->x : s1->x;
+ d->y = (s0->y >= s1->y) ? s0->y : s1->y;
+ d->z = (s0->z >= s1->z) ? s0->z : s1->z;
+ d->w = (s0->w >= s1->w) ? s0->w : s1->w;
+ VSTRACE(("executing max: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_min(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = (s0->x < s1->x) ? s0->x : s1->x;
+ d->y = (s0->y < s1->y) ? s0->y : s1->y;
+ d->z = (s0->z < s1->z) ? s0->z : s1->z;
+ d->w = (s0->w < s1->w) ? s0->w : s1->w;
+ VSTRACE(("executing min: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_mov(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ d->x = s0->x;
+ d->y = s0->y;
+ d->z = s0->z;
+ d->w = s0->w;
+ VSTRACE(("executing mov: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_mul(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = s0->x * s1->x;
+ d->y = s0->y * s1->y;
+ d->z = s0->z * s1->z;
+ d->w = s0->w * s1->w;
+ VSTRACE(("executing mul: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_nop(void) {
+ /* NOPPPP ahhh too easy ;) */
+}
+
+void vshader_rcp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ d->x = d->y = d->z = d->w = (0.0f == s0->w) ? HUGE : 1.0f / s0->w;
+ VSTRACE(("executing rcp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_rsq(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ float tmp_f = fabsf(s0->w);
+ d->x = d->y = d->z = d->w = (0.0f == tmp_f) ? HUGE : ((1.0f != tmp_f) ? 1.0f / sqrtf(tmp_f) : 1.0f);
+ VSTRACE(("executing rsq: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_sge(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = (s0->x >= s1->x) ? 1.0f : 0.0f;
+ d->y = (s0->y >= s1->y) ? 1.0f : 0.0f;
+ d->z = (s0->z >= s1->z) ? 1.0f : 0.0f;
+ d->w = (s0->w >= s1->w) ? 1.0f : 0.0f;
+ VSTRACE(("executing sge: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_slt(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = (s0->x < s1->x) ? 1.0f : 0.0f;
+ d->y = (s0->y < s1->y) ? 1.0f : 0.0f;
+ d->z = (s0->z < s1->z) ? 1.0f : 0.0f;
+ d->w = (s0->w < s1->w) ? 1.0f : 0.0f;
+ VSTRACE(("executing slt: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_sub(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+ d->x = s0->x - s1->x;
+ d->y = s0->y - s1->y;
+ d->z = s0->z - s1->z;
+ d->w = s0->w - s1->w;
+ VSTRACE(("executing sub: s0=(%f, %f, %f, %f) s1=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, s1->x, s1->y, s1->z, s1->w, d->x, d->y, d->z, d->w));
+}
+
+/**
+ * Version 1.1 specific
+ */
+
+void vshader_exp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ d->x = d->y = d->z = d->w = powf(2.0f, s0->w);
+ VSTRACE(("executing exp: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_log(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ float tmp_f = fabsf(s0->w);
+ d->x = d->y = d->z = d->w = (0.0f != tmp_f) ? logf(tmp_f) / logf(2.0f) : -HUGE;
+ VSTRACE(("executing log: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+void vshader_frc(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+ d->x = s0->x - floorf(s0->x);
+ d->y = s0->y - floorf(s0->y);
+ d->z = 0.0f;
+ d->w = 1.0f;
+ VSTRACE(("executing frc: s0=(%f, %f, %f, %f) => d=(%f, %f, %f, %f)\n",
+ s0->x, s0->y, s0->z, s0->w, d->x, d->y, d->z, d->w));
+}
+
+typedef FLOAT D3DMATRIX44[4][4];
+typedef FLOAT D3DMATRIX43[4][3];
+typedef FLOAT D3DMATRIX34[4][4];
+typedef FLOAT D3DMATRIX33[4][3];
+typedef FLOAT D3DMATRIX32[4][2];
+
+void vshader_m4x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, /*D3DSHADERVECTOR* mat1*/ D3DMATRIX44 mat) {
+ /*
+ * BuGGY CODE: here only if cast not work for copy/paste
+ D3DSHADERVECTOR* mat2 = mat1 + 1;
+ D3DSHADERVECTOR* mat3 = mat1 + 2;
+ D3DSHADERVECTOR* mat4 = mat1 + 3;
+ d->x = mat1->x * s0->x + mat2->x * s0->y + mat3->x * s0->z + mat4->x * s0->w;
+ d->y = mat1->y * s0->x + mat2->y * s0->y + mat3->y * s0->z + mat4->y * s0->w;
+ d->z = mat1->z * s0->x + mat2->z * s0->y + mat3->z * s0->z + mat4->z * s0->w;
+ d->w = mat1->w * s0->x + mat2->w * s0->y + mat3->w * s0->z + mat4->w * s0->w;
+ */
+ d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w;
+ d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w;
+ d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w;
+ d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z + mat[3][3] * s0->w;
+ VSTRACE(("executing m4x4(1): mat=(%f, %f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], mat[0][3], s0->x, d->x));
+ VSTRACE(("executing m4x4(2): mat=(%f, %f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], mat[1][3], s0->y, d->y));
+ VSTRACE(("executing m4x4(3): mat=(%f, %f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], mat[2][3], s0->z, d->z));
+ VSTRACE(("executing m4x4(4): mat=(%f, %f, %f, %f) (%f) (%f) \n", mat[3][0], mat[3][1], mat[3][2], mat[3][3], s0->w, d->w));
+}
+
+void vshader_m4x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX43 mat) {
+ d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z + mat[0][3] * s0->w;
+ d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z + mat[1][3] * s0->w;
+ d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z + mat[2][3] * s0->w;
+ d->w = 1.0f;
+ VSTRACE(("executing m4x3(1): mat=(%f, %f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], mat[0][3], s0->x, d->x));
+ VSTRACE(("executing m4x3(2): mat=(%f, %f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], mat[1][3], s0->y, d->y));
+ VSTRACE(("executing m4x3(3): mat=(%f, %f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], mat[2][3], s0->z, d->z));
+ VSTRACE(("executing m4x3(4): (%f) (%f) \n", s0->w, d->w));
+}
+
+void vshader_m3x4(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX34 mat) {
+ d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z;
+ d->y = mat[2][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z;
+ d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z;
+ d->w = mat[3][0] * s0->x + mat[3][1] * s0->y + mat[3][2] * s0->z;
+ VSTRACE(("executing m3x4(1): mat=(%f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], s0->x, d->x));
+ VSTRACE(("executing m3x4(2): mat=(%f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], s0->y, d->y));
+ VSTRACE(("executing m3x4(3): mat=(%f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], s0->z, d->z));
+ VSTRACE(("executing m3x4(4): mat=(%f, %f, %f) (%f) (%f) \n", mat[3][0], mat[3][1], mat[3][2], s0->w, d->w));
+}
+
+void vshader_m3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX33 mat) {
+ d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[2][2] * s0->z;
+ d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[2][2] * s0->z;
+ d->z = mat[2][0] * s0->x + mat[2][1] * s0->y + mat[2][2] * s0->z;
+ d->w = 1.0f;
+ VSTRACE(("executing m3x3(1): mat=(%f, %f, %f) s0=(%f) d=(%f) \n", mat[0][0], mat[0][1], mat[0][2], s0->x, d->x));
+ VSTRACE(("executing m3x3(2): mat=(%f, %f, %f) (%f) (%f) \n", mat[1][0], mat[1][1], mat[1][2], s0->y, d->y));
+ VSTRACE(("executing m3x3(3): mat=(%f, %f, %f) X (%f) = (%f) \n", mat[2][0], mat[2][1], mat[2][2], s0->z, d->z));
+ VSTRACE(("executing m3x3(4): (%f) \n", d->w));
+}
+
+void vshader_m3x2(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DMATRIX32 mat) {
+ FIXME("check\n");
+ d->x = mat[0][0] * s0->x + mat[0][1] * s0->y + mat[0][2] * s0->z;
+ d->y = mat[1][0] * s0->x + mat[1][1] * s0->y + mat[1][2] * s0->z;
+ d->z = 0.0f;
+ d->w = 1.0f;
+}
+
+/**
+ * Version 2.0 specific
+ */
+void vshader_lrp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) {
+ d->x = s0->x * (s1->x - s2->x) + s2->x;
+ d->y = s0->y * (s1->y - s2->y) + s2->y;
+ d->z = s0->z * (s1->z - s2->z) + s2->z;
+ d->w = s0->w * (s1->w - s2->w) + s2->x;
+}
+
+/**
+ * log, exp, frc, m*x* seems to be macros ins ... to see
+ */
+static CONST SHADER_OPCODE vshader_ins [] = {
+ {D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0},
+ {D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0},
+ {D3DSIO_ADD, "add", 3, vshader_add, 0, 0},
+ {D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0},
+ {D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0},
+ {D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0},
+ {D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0},
+ {D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0},
+ {D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0},
+ {D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0},
+ {D3DSIO_MIN, "min", 3, vshader_min, 0, 0},
+ {D3DSIO_MAX, "max", 3, vshader_max, 0, 0},
+ {D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0},
+ {D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0},
+ {D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0},
+ {D3DSIO_LOG, "log", 2, vshader_log, 0, 0},
+ {D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0},
+ {D3DSIO_DST, "dst", 3, vshader_dst, 0, 0},
+ {D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0},
+ {D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0},
+ {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0},
+ {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0},
+ {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0},
+ {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0},
+ {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0},
+ /** FIXME: use direct access so add the others opcodes as stubs */
+ {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0},
+ {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0},
+
+ {0, NULL, 0, NULL, 0, 0}
+};
+
+
+inline static const SHADER_OPCODE* vshader_program_get_opcode(const DWORD code) {
+ DWORD i = 0;
+ /** TODO: use dichotomic search */
+ while (NULL != vshader_ins[i].name) {
+ if ((code & D3DSI_OPCODE_MASK) == vshader_ins[i].opcode) {
+ return &vshader_ins[i];
+ }
+ ++i;
+ }
+ return NULL;
+}
+
+inline static void vshader_program_dump_param(const DWORD param, int input) {
+ static const char* rastout_reg_names[] = { "oPos", "oFog", "oPts" };
+ static const char swizzle_reg_chars[] = "xyzw";
+
+ DWORD reg = param & 0x00001FFF;
+ DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT);
+
+ if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) TRACE("-");
+
+ switch (regtype << D3DSP_REGTYPE_SHIFT) {
+ case D3DSPR_TEMP:
+ TRACE("R[%lu]", reg);
+ break;
+ case D3DSPR_INPUT:
+ TRACE("V[%lu]", reg);
+ break;
+ case D3DSPR_CONST:
+ TRACE("C[%s%lu]", (reg & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg);
+ break;
+ case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/
+ TRACE("a[%lu]", reg);
+ break;
+ case D3DSPR_RASTOUT:
+ TRACE("%s", rastout_reg_names[reg]);
+ break;
+ case D3DSPR_ATTROUT:
+ TRACE("oD[%lu]", reg);
+ break;
+ case D3DSPR_TEXCRDOUT:
+ TRACE("oT[%lu]", reg);
+ break;
+ default:
+ break;
+ }
+
+ if (!input) {
+ /** operand output */
+ if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) {
+ if (param & D3DSP_WRITEMASK_0) TRACE(".x");
+ if (param & D3DSP_WRITEMASK_1) TRACE(".y");
+ if (param & D3DSP_WRITEMASK_2) TRACE(".z");
+ if (param & D3DSP_WRITEMASK_3) TRACE(".w");
+ }
+ } else {
+ /** operand input */
+ DWORD swizzle = (param & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT;
+ DWORD swizzle_x = swizzle & 0x03;
+ DWORD swizzle_y = (swizzle >> 2) & 0x03;
+ DWORD swizzle_z = (swizzle >> 4) & 0x03;
+ DWORD swizzle_w = (swizzle >> 6) & 0x03;
+ /**
+ * swizzle bits fields:
+ * WWZZYYXX
+ */
+ if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */
+ if (swizzle_x == swizzle_y &&
+ swizzle_x == swizzle_z &&
+ swizzle_x == swizzle_w) {
+ TRACE(".%c", swizzle_reg_chars[swizzle_x]);
+ } else {
+ TRACE(".%c%c%c%c",
+ swizzle_reg_chars[swizzle_x],
+ swizzle_reg_chars[swizzle_y],
+ swizzle_reg_chars[swizzle_z],
+ swizzle_reg_chars[swizzle_w]);
+ }
+ }
+ }
+}
+
+inline static BOOL vshader_is_version_token(DWORD token) {
+ return 0xFFFE0000 == (token & 0xFFFE0000);
+}
+
+inline static BOOL vshader_is_comment_token(DWORD token) {
+ return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK);
+}
+
+/**
+ * Function parser ...
+ */
+inline static VOID IDirect3DVertexShaderImpl_ParseProgram(IDirect3DVertexShaderImpl* vshader, CONST DWORD* pFunction) {
+ const DWORD* pToken = pFunction;
+ const SHADER_OPCODE* curOpcode = NULL;
+ DWORD len = 0;
+ DWORD i;
+
+ if (NULL != pToken) {
+ while (D3DVS_END() != *pToken) {
+ if (vshader_is_version_token(*pToken)) { /** version */
+ TRACE("vs.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F));
+ ++pToken;
+ ++len;
+ continue;
+ }
+ if (vshader_is_comment_token(*pToken)) { /** comment */
+ DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
+ ++pToken;
+ /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/
+ pToken += comment_len;
+ len += comment_len + 1;
+ continue;
+ }
+ curOpcode = vshader_program_get_opcode(*pToken);
+ ++pToken;
+ ++len;
+ if (NULL == curOpcode) {
+ /* unkown current opcode ... */
+ while (*pToken & 0x80000000) {
+ TRACE("unrecognized opcode: %08lx\n", *pToken);
+ ++pToken;
+ ++len;
+ }
+ } else {
+ TRACE("%s ", curOpcode->name);
+ if (curOpcode->num_params > 0) {
+ vshader_program_dump_param(*pToken, 0);
+ ++pToken;
+ ++len;
+ for (i = 1; i < curOpcode->num_params; ++i) {
+ TRACE(", ");
+ vshader_program_dump_param(*pToken, 1);
+ ++pToken;
+ ++len;
+ }
+ }
+ TRACE("\n");
+ }
+ }
+ vshader->functionLength = (len + 1) * sizeof(DWORD);
+ } else {
+ vshader->functionLength = 1; /* no Function defined use fixed function vertex processing */
+ }
+ /* copy the function ... because it will certainly be released by application */
+
+ if (NULL != pFunction) {
+ vshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, vshader->functionLength);
+ memcpy(vshader->function, pFunction, vshader->functionLength);
+ } else {
+ vshader->function = NULL;
+ }
+}
+
+BOOL IDirect3DVertexShaderImpl_ExecuteHAL(IDirect3DVertexShaderImpl* vshader, VSHADERINPUTDATA* input, VSHADEROUTPUTDATA* output) {
+ /**
+ * TODO: use the NV_vertex_program (or 1_1) extension
+ * and specifics vendors (ARB_vertex_program??) variants for it
+ */
+ return TRUE;
+}
+
+HRESULT WINAPI IDirect3DVertexShaderImpl_ExecuteSW(IDirect3DVertexShaderImpl* vshader, VSHADERINPUTDATA* input, VSHADEROUTPUTDATA* output) {
+ /** Vertex Shader Temporary Registers */
+ D3DSHADERVECTOR R[12];
+ /*D3DSHADERSCALAR A0;*/
+ D3DSHADERVECTOR A[1];
+ /** temporary Vector for modifier management */
+ D3DSHADERVECTOR d;
+ D3DSHADERVECTOR s[3];
+ /** parser datas */
+ const DWORD* pToken = vshader->function;
+ const SHADER_OPCODE* curOpcode = NULL;
+ /** functions parameters */
+ D3DSHADERVECTOR* p[4];
+ D3DSHADERVECTOR* p_send[4];
+ DWORD i;
+
+ /** init temporary register */
+ memset(R, 0, 12 * sizeof(D3DSHADERVECTOR));
+
+ /* vshader_program_parse(vshader); */
+#if 0 /* Must not be 1 in cvs */
+ TRACE("Input:\n");
+ TRACE_VSVECTOR(vshader->data->C[0]);
+ TRACE_VSVECTOR(vshader->data->C[1]);
+ TRACE_VSVECTOR(vshader->data->C[2]);
+ TRACE_VSVECTOR(vshader->data->C[3]);
+ TRACE_VSVECTOR(vshader->data->C[4]);
+ TRACE_VSVECTOR(vshader->data->C[5]);
+ TRACE_VSVECTOR(vshader->data->C[6]);
+ TRACE_VSVECTOR(vshader->data->C[7]);
+ TRACE_VSVECTOR(vshader->data->C[8]);
+ TRACE_VSVECTOR(vshader->data->C[64]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_POSITION]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_BLENDWEIGHT]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_BLENDINDICES]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_NORMAL]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_PSIZE]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_DIFFUSE]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_SPECULAR]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD0]);
+ TRACE_VSVECTOR(input->V[D3DVSDE_TEXCOORD1]);
+#endif
+
+ TRACE_VSVECTOR(vshader->data->C[64]);
+
+ /* the first dword is the version tag */
+ /* TODO: parse it */
+
+ if (vshader_is_version_token(*pToken)) { /** version */
+ ++pToken;
+ }
+ while (D3DVS_END() != *pToken) {
+ if (vshader_is_comment_token(*pToken)) { /** comment */
+ DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
+ ++pToken;
+ pToken += comment_len;
+ continue ;
+ }
+ curOpcode = vshader_program_get_opcode(*pToken);
+ ++pToken;
+ if (NULL == curOpcode) {
+ i = 0;
+ /* unkown current opcode ... */
+ while (*pToken & 0x80000000) {
+ if (i == 0) {
+ TRACE("unrecognized opcode: pos=%d token=%08lX\n", (pToken - 1) - vshader->function, *(pToken - 1));
+ }
+ TRACE("unrecognized opcode param: pos=%d token=%08lX what=", pToken - vshader->function, *pToken);
+ vshader_program_dump_param(*pToken, i);
+ TRACE("\n");
+ ++i;
+ ++pToken;
+ }
+ /*return FALSE;*/
+ } else {
+ if (curOpcode->num_params > 0) {
+ /*TRACE(">> execting opcode: pos=%d opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken);*/
+ for (i = 0; i < curOpcode->num_params; ++i) {
+ DWORD reg = pToken[i] & 0x00001FFF;
+ DWORD regtype = ((pToken[i] & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT);
+
+ switch (regtype << D3DSP_REGTYPE_SHIFT) {
+ case D3DSPR_TEMP:
+ /*TRACE("p[%d]=R[%d]\n", i, reg);*/
+ p[i] = &R[reg];
+ break;
+ case D3DSPR_INPUT:
+ /*TRACE("p[%d]=V[%s]\n", i, VertexShaderDeclRegister[reg]);*/
+ p[i] = &input->V[reg];
+ break;
+ case D3DSPR_CONST:
+ if (reg & D3DVS_ADDRMODE_RELATIVE) {
+ p[i] = &vshader->data->C[(DWORD) A[0].x + reg];
+ } else {
+ p[i] = &vshader->data->C[reg];
+ }
+ break;
+ case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/
+ if (0 != reg) {
+ ERR("cannot handle address registers != a0, forcing use of a0\n");
+ reg = 0;
+ }
+ /*TRACE("p[%d]=A[%d]\n", i, reg);*/
+ p[i] = &A[reg];
+ break;
+ case D3DSPR_RASTOUT:
+ switch (reg) {
+ case D3DSRO_POSITION:
+ p[i] = &output->oPos;
+ break;
+ case D3DSRO_FOG:
+ p[i] = &output->oFog;
+ break;
+ case D3DSRO_POINT_SIZE:
+ p[i] = &output->oPts;
+ break;
+ }
+ break;
+ case D3DSPR_ATTROUT:
+ /*TRACE("p[%d]=oD[%d]\n", i, reg);*/
+ p[i] = &output->oD[reg];
+ break;
+ case D3DSPR_TEXCRDOUT:
+ /*TRACE("p[%d]=oT[%d]\n", i, reg);*/
+ p[i] = &output->oT[reg];
+ break;
+ default:
+ break;
+ }
+
+ if (i > 0) { /* input reg */
+ DWORD swizzle = (pToken[i] & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT;
+ UINT isNegative = ((pToken[i] & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG);
+
+ if (!isNegative && (D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) == swizzle) {
+ /*TRACE("p[%d] not swizzled\n", i);*/
+ p_send[i] = p[i];
+ } else {
+ DWORD swizzle_x = swizzle & 0x03;
+ DWORD swizzle_y = (swizzle >> 2) & 0x03;
+ DWORD swizzle_z = (swizzle >> 4) & 0x03;
+ DWORD swizzle_w = (swizzle >> 6) & 0x03;
+ /*TRACE("p[%d] swizzled\n", i);*/
+ float* tt = (float*) p[i];
+ s[i].x = (isNegative) ? -tt[swizzle_x] : tt[swizzle_x];
+ s[i].y = (isNegative) ? -tt[swizzle_y] : tt[swizzle_y];
+ s[i].z = (isNegative) ? -tt[swizzle_z] : tt[swizzle_z];
+ s[i].w = (isNegative) ? -tt[swizzle_w] : tt[swizzle_w];
+ p_send[i] = &s[i];
+ }
+ } else { /* output reg */
+ if ((pToken[i] & D3DSP_WRITEMASK_ALL) == D3DSP_WRITEMASK_ALL) {
+ p_send[i] = p[i];
+ } else {
+ p_send[i] = &d; /* to be post-processed for modifiers management */
+ }
+ }
+ }
+ }
+
+ switch (curOpcode->num_params) {
+ case 0:
+ curOpcode->soft_fct();
+ break;
+ case 1:
+ curOpcode->soft_fct(p_send[0]);
+ break;
+ case 2:
+ curOpcode->soft_fct(p_send[0], p_send[1]);
+ break;
+ case 3:
+ curOpcode->soft_fct(p_send[0], p_send[1], p_send[2]);
+ break;
+ case 4:
+ curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3]);
+ break;
+ case 5:
+ curOpcode->soft_fct(p_send[0], p_send[1], p_send[2], p_send[3], p_send[4]);
+ break;
+ default:
+ ERR("%s too many params: %u\n", curOpcode->name, curOpcode->num_params);
+ }
+
+ /* check if output reg modifier post-process */
+ if (curOpcode->num_params > 0 && (pToken[0] & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) {
+ if (pToken[0] & D3DSP_WRITEMASK_0) p[0]->x = d.x;
+ if (pToken[0] & D3DSP_WRITEMASK_1) p[0]->y = d.y;
+ if (pToken[0] & D3DSP_WRITEMASK_2) p[0]->z = d.z;
+ if (pToken[0] & D3DSP_WRITEMASK_3) p[0]->w = d.w;
+ }
+
+#if 0
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
+ TRACE_VSVECTOR(R[0]);
+ TRACE_VSVECTOR(R[1]);
+ TRACE_VSVECTOR(R[2]);
+ TRACE_VSVECTOR(R[3]);
+ TRACE_VSVECTOR(R[4]);
+ TRACE_VSVECTOR(R[5]);
+#endif
+
+ /* to next opcode token */
+ pToken += curOpcode->num_params;
+ }
+#if 0
+ TRACE("End of current instruction:\n");
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
+ TRACE_VSVECTOR(R[0]);
+ TRACE_VSVECTOR(R[1]);
+ TRACE_VSVECTOR(R[2]);
+ TRACE_VSVECTOR(R[3]);
+ TRACE_VSVECTOR(R[4]);
+ TRACE_VSVECTOR(R[5]);
+#endif
+ }
+#if 0 /* Must not be 1 in cvs */
+ TRACE("Output:\n");
+ TRACE_VSVECTOR(output->oPos);
+ TRACE_VSVECTOR(output->oD[0]);
+ TRACE_VSVECTOR(output->oD[1]);
+ TRACE_VSVECTOR(output->oT[0]);
+ TRACE_VSVECTOR(output->oT[1]);
+#endif
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DVertexShaderImpl_GetFunction(IDirect3DVertexShaderImpl* This, VOID* pData, UINT* pSizeOfData) {
+ if (NULL == pData) {
+ *pSizeOfData = This->functionLength;
+ return D3D_OK;
+ }
+ if (*pSizeOfData < This->functionLength) {
+ *pSizeOfData = This->functionLength;
+ return D3DERR_MOREDATA;
+ }
+ if (NULL == This->function) { /* no function defined */
+ TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
+ (*(DWORD **) pData) = NULL;
+ } else {
+ TRACE("(%p) : GetFunction copying to %p\n", This, pData);
+ memcpy(pData, This->function, This->functionLength);
+ }
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DVertexShaderImpl_SetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) {
+ if (StartRegister + Vector4fCount > D3D_VSHADER_MAX_CONSTANTS) {
+ return D3DERR_INVALIDCALL;
+ }
+ if (NULL == This->data) { /* temporary while datas not supported */
+ FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
+ return D3DERR_INVALIDCALL;
+ }
+ memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT));
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) {
+ if (StartRegister + Vector4fCount > D3D_VSHADER_MAX_CONSTANTS) {
+ return D3DERR_INVALIDCALL;
+ }
+ if (NULL == This->data) { /* temporary while datas not supported */
+ return D3DERR_INVALIDCALL;
+ }
+ memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT));
+ return D3D_OK;
+}
+
+
+/**********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************/
+
+void pshader_texcoord(D3DSHADERVECTOR* d) {
+}
+
+void pshader_texkill(D3DSHADERVECTOR* d) {
+}
+
+void pshader_tex(D3DSHADERVECTOR* d) {
+}
+
+void pshader_texbem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texbeml(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texreg2ar(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texreg2gb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x2pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x2tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x3pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x3diff(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x3spec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+}
+
+void pshader_texm3x3vspec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_cnd(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) {
+}
+
+void pshader_def(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) {
+}
+
+void pshader_texreg2rgb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texdp3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x2depth(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texdp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texm3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
+}
+
+void pshader_texdepth(D3DSHADERVECTOR* d) {
+}
+
+void pshader_cmp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) {
+}
+
+void pshader_bem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
+}
+
+static CONST SHADER_OPCODE pshader_ins [] = {
+ {D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0},
+ {D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0},
+ {D3DSIO_ADD, "add", 3, vshader_add, 0, 0},
+ {D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0},
+ {D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0},
+ {D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0},
+ {D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0},
+ {D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0},
+ {D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0},
+ {D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0},
+ {D3DSIO_MIN, "min", 3, vshader_min, 0, 0},
+ {D3DSIO_MAX, "max", 3, vshader_max, 0, 0},
+ {D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0},
+ {D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0},
+ {D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0},
+ {D3DSIO_LOG, "log", 2, vshader_log, 0, 0},
+ {D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0},
+ {D3DSIO_DST, "dst", 3, vshader_dst, 0, 0},
+ {D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0},
+ {D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0},
+ {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0},
+ {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0},
+ {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0},
+ {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0},
+ {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0},
+
+ {D3DSIO_TEXCOORD, "texcoord", 1, pshader_texcoord, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXKILL, "texkill", 1, pshader_texkill, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEX, "tex", 1, pshader_tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)},
+ {D3DSIO_TEXBEM, "texbem", 2, pshader_texbem, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXBEML, "texbeml", 2, pshader_texbeml, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXREG2AR, "texreg2ar", 2, pshader_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXREG2GB, "texreg2gb", 2, pshader_texreg2gb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, pshader_texm3x2pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, pshader_texm3x2tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, pshader_texm3x3pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, pshader_texm3x3tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, pshader_texm3x3diff, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)},
+ {D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, pshader_texm3x3spec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, pshader_texm3x3vspec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+
+ {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0},
+ {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0},
+
+ {D3DSIO_CND, "cnd", 4, pshader_cnd, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)},
+ {D3DSIO_DEF, "def", 5, pshader_def, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)},
+ {D3DSIO_TEXREG2RGB, "texbreg2rgb", 2, pshader_texreg2rgb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+
+ {D3DSIO_TEXDP3TEX, "texdp3tex", 2, pshader_texdp3tex, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, pshader_texm3x2depth, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXDP3, "texdp3", 2, pshader_texdp3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXM3x3, "texm3x3", 2, pshader_texm3x3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+ {D3DSIO_TEXDEPTH, "texdepth", 1, pshader_texdepth, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)},
+ {D3DSIO_CMP, "cmp", 4, pshader_cmp, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)},
+ {D3DSIO_BEM, "bem", 3, pshader_bem, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)},
+
+ {0, NULL, 0, NULL}
+};
+
+inline static const SHADER_OPCODE* pshader_program_get_opcode(const DWORD code) {
+ DWORD i = 0;
+ /** TODO: use dichotomic search */
+ while (NULL != pshader_ins[i].name) {
+ if ((code & D3DSI_OPCODE_MASK) == pshader_ins[i].opcode) {
+ return &pshader_ins[i];
+ }
+ ++i;
+ }
+ return NULL;
+}
+
+inline static void pshader_program_dump_opcode(const SHADER_OPCODE* curOpcode, const DWORD code, const DWORD output) {
+ if (0 != (code & ~D3DSI_OPCODE_MASK)) {
+ DWORD mask = (code & ~D3DSI_OPCODE_MASK);
+ switch (mask) {
+ case 0x40000000: TRACE("+"); break;
+ default:
+ TRACE(" unhandled modifier(0x%08lx) ", mask);
+ }
+ }
+ TRACE("%s", curOpcode->name);
+ /**
+ * normally this is a destination reg modifier
+ * but in pixel shaders asm code its specified as:
+ * dp3_x4 t1.rgba, r1, c1
+ * or
+ * dp3_x2_sat r0, t0_bx2, v0_bx2
+ * so for better debbuging i use the same norm
+ */
+ if (0 != (output & D3DSP_DSTSHIFT_MASK)) {
+ DWORD shift = (output & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT;
+ if (shift > 0) {
+ TRACE("_x%u", 1 << shift);
+ }
+ }
+ /**
+ * TODO: fix the divide shifts: d2, d4, d8
+ * so i have to find a sample
+ */
+ if (0 != (output & D3DSP_DSTMOD_MASK)) {
+ DWORD mask = output & D3DSP_DSTMOD_MASK;
+ switch (mask) {
+ case D3DSPDM_SATURATE: TRACE("_sat"); break;
+ default:
+ TRACE("_unhandled_modifier(0x%08lx)", mask);
+ }
+ }
+ TRACE(" ");
+}
+
+inline static void pshader_program_dump_param(const DWORD param, int input) {
+ static const char* rastout_reg_names[] = { "oC0", "oC1", "oC2", "oC3", "oDepth" };
+ static const char swizzle_reg_chars[] = "rgba";
+
+ DWORD reg = param & 0x00001FFF;
+ DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT);
+
+ if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) {
+ TRACE("-");
+ }
+
+ switch (regtype << D3DSP_REGTYPE_SHIFT) {
+ case D3DSPR_TEMP:
+ TRACE("R[%lu]", reg);
+ break;
+ case D3DSPR_INPUT:
+ TRACE("V[%lu]", reg);
+ break;
+ case D3DSPR_CONST:
+ TRACE("C[%s%lu]", (reg & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg);
+ break;
+ case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
+ TRACE("t[%lu]", reg);
+ break;
+ case D3DSPR_RASTOUT:
+ TRACE("%s", rastout_reg_names[reg]);
+ break;
+ case D3DSPR_ATTROUT:
+ TRACE("oD[%lu]", reg);
+ break;
+ case D3DSPR_TEXCRDOUT:
+ TRACE("oT[%lu]", reg);
+ break;
+ default:
+ break;
+ }
+
+ if (!input) {
+ /** operand output */
+ /**
+ * for better debugging traces it's done into opcode dump code
+ * @see pshader_program_dump_opcode
+ if (0 != (param & D3DSP_DSTMOD_MASK)) {
+ DWORD mask = param & D3DSP_DSTMOD_MASK;
+ switch (mask) {
+ case D3DSPDM_SATURATE: TRACE("_sat"); break;
+ default:
+ TRACE("_unhandled_modifier(0x%08lx)", mask);
+ }
+ }
+ if (0 != (param & D3DSP_DSTSHIFT_MASK)) {
+ DWORD shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT;
+ if (shift > 0) {
+ TRACE("_x%u", 1 << shift);
+ }
+ }
+ */
+ if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) {
+ if (param & D3DSP_WRITEMASK_0) TRACE(".r");
+ if (param & D3DSP_WRITEMASK_1) TRACE(".g");
+ if (param & D3DSP_WRITEMASK_2) TRACE(".b");
+ if (param & D3DSP_WRITEMASK_3) TRACE(".a");
+ }
+ } else {
+ /** operand input */
+ DWORD swizzle = (param & D3DSP_SWIZZLE_MASK) >> D3DSP_SWIZZLE_SHIFT;
+ DWORD swizzle_x = swizzle & 0x03;
+ DWORD swizzle_y = (swizzle >> 2) & 0x03;
+ DWORD swizzle_z = (swizzle >> 4) & 0x03;
+ DWORD swizzle_w = (swizzle >> 6) & 0x03;
+ /**
+ * swizzle bits fields:
+ * WWZZYYXX
+ */
+ if ((D3DSP_NOSWIZZLE >> D3DSP_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */
+ if (swizzle_x == swizzle_y &&
+ swizzle_x == swizzle_z &&
+ swizzle_x == swizzle_w) {
+ TRACE(".%c", swizzle_reg_chars[swizzle_x]);
+ } else {
+ TRACE(".%c%c%c%c",
+ swizzle_reg_chars[swizzle_x],
+ swizzle_reg_chars[swizzle_y],
+ swizzle_reg_chars[swizzle_z],
+ swizzle_reg_chars[swizzle_w]);
+ }
+ }
+ if (0 != (param & D3DSP_SRCMOD_MASK)) {
+ DWORD mask = param & D3DSP_SRCMOD_MASK;
+ /*TRACE("_modifier(0x%08lx) ", mask);*/
+ switch (mask) {
+ case D3DSPSM_NONE: break;
+ case D3DSPSM_NEG: break;
+ case D3DSPSM_BIAS: TRACE("_bias"); break;
+ case D3DSPSM_BIASNEG: TRACE("_bias"); break;
+ case D3DSPSM_SIGN: TRACE("_sign"); break;
+ case D3DSPSM_SIGNNEG: TRACE("_sign"); break;
+ case D3DSPSM_COMP: TRACE("_comp"); break;
+ case D3DSPSM_X2: TRACE("_x2"); break;
+ case D3DSPSM_X2NEG: TRACE("_bx2"); break;
+ case D3DSPSM_DZ: TRACE("_dz"); break;
+ case D3DSPSM_DW: TRACE("_dw"); break;
+ default:
+ TRACE("_unknown(0x%08lx)", mask);
+ }
+ }
+ }
+}
+
+inline static BOOL pshader_is_version_token(DWORD token) {
+ return 0xFFFF0000 == (token & 0xFFFF0000);
+}
+
+inline static BOOL pshader_is_comment_token(DWORD token) {
+ return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK);
+}
+
+
+
+/**
+ * Pixel Shaders
+ *
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader1_X/modifiers/sourceregistermodifiers.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader2_0/Registers/Registers.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/IDirect3DPixelShader9/_IDirect3DPixelShader9.asp
+ *
+ */
+inline static VOID IDirect3DPixelShaderImpl_ParseProgram(IDirect3DPixelShaderImpl* pshader, CONST DWORD* pFunction) {
+ const DWORD* pToken = pFunction;
+ const SHADER_OPCODE* curOpcode = NULL;
+ DWORD code;
+ DWORD len = 0;
+ DWORD i;
+
+ if (NULL != pToken) {
+ while (D3DPS_END() != *pToken) {
+ if (pshader_is_version_token(*pToken)) { /** version */
+ TRACE("ps.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F));
+ ++pToken;
+ ++len;
+ continue;
+ }
+ if (pshader_is_comment_token(*pToken)) { /** comment */
+ DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
+ ++pToken;
+ /*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/
+ pToken += comment_len;
+ len += comment_len + 1;
+ continue;
+ }
+ code = *pToken;
+ curOpcode = pshader_program_get_opcode(code);
+ ++pToken;
+ ++len;
+ if (NULL == curOpcode) {
+ /* unkown current opcode ... */
+ while (*pToken & 0x80000000) {
+ TRACE("unrecognized opcode: %08lx\n", *pToken);
+ ++pToken;
+ ++len;
+ }
+ } else {
+ TRACE(" ");
+ pshader_program_dump_opcode(curOpcode, code, *pToken);
+ if (curOpcode->num_params > 0) {
+ pshader_program_dump_param(*pToken, 0);
+ ++pToken;
+ ++len;
+ for (i = 1; i < curOpcode->num_params; ++i) {
+ TRACE(", ");
+ if (D3DSIO_DEF != code) {
+ pshader_program_dump_param(*pToken, 1);
+ } else {
+ TRACE("%f", *((float*) pToken));
+ }
+ ++pToken;
+ ++len;
+ }
+ }
+ TRACE("\n");
+ }
+ pshader->functionLength = (len + 1) * sizeof(DWORD);
+ }
+ } else {
+ pshader->functionLength = 1; /* no Function defined use fixed function vertex processing */
+ }
+ if (NULL != pFunction) {
+ pshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pshader->functionLength);
+ memcpy(pshader->function, pFunction, pshader->functionLength);
+ } else {
+ pshader->function = NULL;
+ }
+}
+
+HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData) {
+ if (NULL == pData) {
+ *pSizeOfData = This->functionLength;
+ return D3D_OK;
+ }
+ if (*pSizeOfData < This->functionLength) {
+ *pSizeOfData = This->functionLength;
+ return D3DERR_MOREDATA;
+ }
+ if (NULL == This->function) { /* no function defined */
+ TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
+ (*(DWORD **) pData) = NULL;
+ } else {
+ TRACE("(%p) : GetFunction copying to %p\n", This, pData);
+ memcpy(pData, This->function, This->functionLength);
+ }
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DPixelShaderImpl_SetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) {
+ if (StartRegister + Vector4fCount > D3D_VSHADER_MAX_CONSTANTS) {
+ return D3DERR_INVALIDCALL;
+ }
+ if (NULL == This->data) { /* temporary while datas not supported */
+ FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
+ return D3DERR_INVALIDCALL;
+ }
+ memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT));
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DPixelShaderImpl_GetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) {
+ if (StartRegister + Vector4fCount > D3D_VSHADER_MAX_CONSTANTS) {
+ return D3DERR_INVALIDCALL;
+ }
+ if (NULL == This->data) { /* temporary while datas not supported */
+ return D3DERR_INVALIDCALL;
+ }
+ memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT));
+ return D3D_OK;
+}
+
+/**********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************/
+
+/***********************************************************************
+ * ValidateVertexShader (D3D8.@)
+ */
+BOOL WINAPI ValidateVertexShader(LPVOID what, LPVOID toto) {
+ FIXME("(void): stub: %p %p\n", what, toto);
+ return TRUE;
+}
+
+/***********************************************************************
+ * ValidatePixelShader (D3D8.@)
+ */
+BOOL WINAPI ValidatePixelShader(LPVOID what, LPVOID toto) {
+ FIXME("(void): stub: %p %p\n", what, toto);
+ return TRUE;
+}
diff -u --new-file /tmp/vertexshaderdeclaration.c dlls/d3dcore/vertexshaderdeclaration.c
--- /tmp/vertexshaderdeclaration.c 1970-01-01 01:00:00.000000000 +0100
+++ dlls/d3dcore/vertexshaderdeclaration.c 2003-06-20 20:57:46.000000000 +0200
@@ -0,0 +1,577 @@
+/*
+ * vertex shaders declaration implementation
+ *
+ * Copyright 2002 Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+
+#include <math.h>
+
+#include "d3d8.h"
+#include "d3dcore_interface.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
+
+/**
+ * DirectX9 SDK download
+ * http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp
+ *
+ * Exploring D3DX
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp
+ *
+ * Using Vertex Shaders
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp
+ *
+ * Dx9 New
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp
+ *
+ * Dx9 Shaders
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp
+ *
+ * Dx9 D3DX
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp
+ *
+ * FVF
+ * http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp
+ *
+ * NVIDIA: DX8 Vertex Shader to NV Vertex Program
+ * http://developer.nvidia.com/view.asp?IO=vstovp
+ *
+ * NVIDIA: Memory Management with VAR
+ * http://developer.nvidia.com/view.asp?IO=var_memory_management
+ */
+
+/** Vertex Shader Declaration data types tokens */
+#define MAX_VSHADER_DECL_TYPES 8
+static CONST char* VertexShaderDeclDataTypes[] = {
+ "D3DVSDT_FLOAT1",
+ "D3DVSDT_FLOAT2",
+ "D3DVSDT_FLOAT3",
+ "D3DVSDT_FLOAT4",
+ "D3DVSDT_D3DCOLOR",
+ "D3DVSDT_UBYTE4",
+ "D3DVSDT_SHORT2",
+ "D3DVSDT_SHORT4",
+ NULL
+};
+
+static CONST char* VertexShaderDeclRegister[] = {
+ "D3DVSDE_POSITION",
+ "D3DVSDE_BLENDWEIGHT",
+ "D3DVSDE_BLENDINDICES",
+ "D3DVSDE_NORMAL",
+ "D3DVSDE_PSIZE",
+ "D3DVSDE_DIFFUSE",
+ "D3DVSDE_SPECULAR",
+ "D3DVSDE_TEXCOORD0",
+ "D3DVSDE_TEXCOORD1",
+ "D3DVSDE_TEXCOORD2",
+ "D3DVSDE_TEXCOORD3",
+ "D3DVSDE_TEXCOORD4",
+ "D3DVSDE_TEXCOORD5",
+ "D3DVSDE_TEXCOORD6",
+ "D3DVSDE_TEXCOORD7",
+ "D3DVSDE_POSITION2",
+ "D3DVSDE_NORMAL2",
+ NULL
+};
+
+/** todo check decl validity */
+/*inline static*/ DWORD Direct3DVextexShaderDeclarationImpl_ParseToken(const DWORD* pToken) {
+ const DWORD token = *pToken;
+ DWORD tokenlen = 1;
+
+ switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
+ case D3DVSD_TOKEN_NOP:
+ TRACE(" 0x%08lx NOP()\n", token);
+ break;
+ case D3DVSD_TOKEN_STREAM:
+ if (token & D3DVSD_STREAMTESSMASK) {
+ TRACE(" 0x%08lx STREAM_TESS()\n", token);
+ } else {
+ TRACE(" 0x%08lx STREAM(%lu)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
+ }
+ break;
+ case D3DVSD_TOKEN_STREAMDATA:
+ if (token & 0x10000000) {
+ TRACE(" 0x%08lx SKIP(%lu)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
+ } else {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ TRACE(" 0x%08lx REG(%s, %s)\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
+ }
+ break;
+ case D3DVSD_TOKEN_TESSELLATOR:
+ if (token & 0x10000000) {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ TRACE(" 0x%08lx TESSUV(%s) as %s\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
+ } else {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
+ TRACE(" 0x%08lx TESSNORMAL(%s, %s) as %s\n", token, VertexShaderDeclRegister[regin], VertexShaderDeclRegister[regout], VertexShaderDeclDataTypes[type]);
+ }
+ break;
+ case D3DVSD_TOKEN_CONSTMEM:
+ {
+ DWORD i;
+ DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
+ TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
+ ++pToken;
+ for (i = 0; i < count; ++i) {
+#if 0
+ TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
+ constaddress,
+ *pToken,
+ *(pToken + 1),
+ *(pToken + 2),
+ *(pToken + 3));
+#endif
+ TRACE(" c[%lu] = (%8f, %8f, %8f, %8f)\n",
+ constaddress,
+ *(float*) pToken,
+ *(float*) (pToken + 1),
+ *(float*) (pToken + 2),
+ *(float*) (pToken + 3));
+ pToken += 4;
+ ++constaddress;
+ }
+ tokenlen = (4 * count) + 1;
+ }
+ break;
+ case D3DVSD_TOKEN_EXT:
+ {
+ DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT);
+ TRACE(" 0x%08lx EXT(%lu, %lu)\n", token, count, extinfo);
+ /* todo ... print extension */
+ tokenlen = count + 1;
+ }
+ break;
+ case D3DVSD_TOKEN_END:
+ TRACE(" 0x%08lx END()\n", token);
+ break;
+ default:
+ TRACE(" 0x%08lx UNKNOWN\n", token);
+ /* argg error */
+ }
+ return tokenlen;
+}
+
+HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDeviceImpl* This, CONST DWORD* pDeclaration8, IDirect3DVertexShaderDeclarationImpl** ppVertexShaderDecl) {
+ /** parser data */
+ const DWORD* pToken = pDeclaration8;
+ DWORD fvf = 0;
+ DWORD len = 0;
+ DWORD stream = 0;
+ DWORD token;
+ DWORD tokenlen;
+ DWORD tokentype;
+ DWORD tex = D3DFVF_TEX0;
+ /** TRUE if declaration can be matched by a fvf */
+ IDirect3DVertexShaderDeclarationImpl* object;
+ BOOL invalid_fvf = FALSE;
+
+ TRACE("(%p) : pDeclaration8(%p)\n", This, pDeclaration8);
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexShaderDeclarationImpl));
+ /*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/
+ /*object->ref = 1;*/
+ object->device = This;
+ object->allFVF = 0;
+
+ while (D3DVSD_END() != *pToken) {
+ token = *pToken;
+ tokenlen = Direct3DVextexShaderDeclarationImpl_ParseToken(pToken);
+ tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
+
+ /** FVF generation block */
+ if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
+ /**
+ * how really works streams,
+ * in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
+ */
+ DWORD oldStream = stream;
+ stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
+
+ /* copy fvf if valid */
+ if (FALSE == invalid_fvf) {
+ fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
+ tex = 0;
+ object->fvf[oldStream] = fvf;
+ object->allFVF |= fvf;
+ } else {
+ object->fvf[oldStream] = 0;
+ tex = 0;
+ }
+
+ /* reset valid/invalid fvf */
+ fvf = 0;
+ invalid_fvf = FALSE;
+
+ } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+
+ switch (reg) {
+ case D3DVSDE_POSITION:
+ switch (type) {
+ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break;
+ case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ if (type >= MAX_VSHADER_DECL_TYPES) {
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported and unrecognized type %08lx\n", type);
+ } else {
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ }
+ break;
+
+ case D3DVSDE_BLENDWEIGHT:
+ switch (type) {
+ case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break;
+ case D3DVSDT_FLOAT2: fvf |= D3DFVF_XYZB2; break;
+ case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break;
+ case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_BLENDINDICES: /* seem to be B5 as said in MSDN Dx9SDK ?? */
+ switch (type) {
+ case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_NORMAL: /* TODO: only FLOAT3 supported ... another choice possible ? */
+ switch (type) {
+ case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_PSIZE: /* TODO: only FLOAT1 supported ... another choice possible ? */
+ switch (type) {
+ case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_DIFFUSE: /* TODO: only D3DCOLOR supported */
+ switch (type) {
+ case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_SPECULAR: /* TODO: only D3DCOLOR supported */
+ switch (type) {
+ case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ break;
+
+ case D3DVSDE_TEXCOORD0:
+ case D3DVSDE_TEXCOORD1:
+ case D3DVSDE_TEXCOORD2:
+ case D3DVSDE_TEXCOORD3:
+ case D3DVSDE_TEXCOORD4:
+ case D3DVSDE_TEXCOORD5:
+ case D3DVSDE_TEXCOORD6:
+ case D3DVSDE_TEXCOORD7:
+ /* Fixme? - assume all tex coords in same stream */
+ {
+ int texNo = 1 + (reg - D3DVSDE_TEXCOORD0);
+ tex = max(tex, texNo);
+ switch (type) {
+ case D3DVSDT_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
+ case D3DVSDT_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
+ case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
+ case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
+ default:
+ /** errooooorr mismatched use of a register, invalid fvf computing */
+ invalid_fvf = TRUE;
+ TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
+ }
+ }
+ break;
+
+ case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */
+ case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */
+ TRACE("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
+ break;
+ }
+ TRACE("VertexShader declaration define %lx as current FVF\n", fvf);
+ }
+ len += tokenlen;
+ pToken += tokenlen;
+ }
+ /* here D3DVSD_END() */
+ len += Direct3DVextexShaderDeclarationImpl_ParseToken(pToken);
+
+ /* copy fvf if valid */
+ if (FALSE == invalid_fvf) {
+ fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
+ object->fvf[stream] = fvf;
+ object->allFVF |= fvf;
+ } else {
+ object->fvf[stream] = 0;
+ }
+ TRACE("Completed, allFVF = %lx\n", object->allFVF);
+
+ /* compute size */
+ object->declaration8Length = len * sizeof(DWORD);
+ /* copy the declaration */
+ object->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declaration8Length);
+ memcpy(object->pDeclaration8, pDeclaration8, object->declaration8Length);
+ /* returns */
+ *ppVertexShaderDecl = object;
+ return D3D_OK;
+}
+
+
+HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDeviceImpl* This,
+ IDirect3DVertexShaderImpl* vshader,
+ DWORD SkipnStrides) {
+ /** parser data */
+ const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8;
+ DWORD stream = 0;
+ DWORD token;
+ /*DWORD tokenlen;*/
+ DWORD tokentype;
+ /** for input readers */
+ const char* curPos = NULL;
+ FLOAT x, y, z, w;
+ SHORT u, v, r, t;
+ DWORD dw;
+
+ TRACE("(%p) - This:%p, skipstrides=%lu\n", vshader, This, SkipnStrides);
+
+ while (D3DVSD_END() != *pToken) {
+ token = *pToken;
+ tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
+
+ /** FVF generation block */
+ if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
+ IDirect3DVertexBufferImpl* pVB;
+ int skip = 0;
+
+ ++pToken;
+ /**
+ * how really works streams,
+ * in DolphinVS dx8 dsk sample use it !!!
+ */
+ stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
+ skip = This->StateBlock->stream_stride[stream];
+ pVB = This->StateBlock->stream_source[stream];
+
+ if (NULL == pVB) {
+ ERR("using unitialised stream[%lu]\n", stream);
+ return D3DERR_INVALIDCALL;
+ } else {
+ if (This->StateBlock->streamIsUP == TRUE) {
+ curPos = ((char *) pVB) + (SkipnStrides * skip); /* Not really a VB */
+ } else {
+ curPos = ((IDirect3DVertexBufferImpl*) pVB)->allocatedMemory + (SkipnStrides * skip);
+ }
+
+ TRACE(" using stream[%lu] with %p (%p + (Stride %d * skip %ld))\n", stream, curPos,
+ ((IDirect3DVertexBufferImpl*) pVB)->allocatedMemory, skip, SkipnStrides);
+ }
+ } else if (D3DVSD_TOKEN_CONSTMEM == tokentype) {
+ /** Const decl */
+ DWORD i;
+ DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
+ DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
+ ++pToken;
+ for (i = 0; i < count; ++i) {
+ vshader->data->C[constaddress + i].x = *(float*)pToken;
+ vshader->data->C[constaddress + i].y = *(float*)(pToken + 1);
+ vshader->data->C[constaddress + i].z = *(float*)(pToken + 2);
+ vshader->data->C[constaddress + i].w = *(float*)(pToken + 3);
+ pToken += 4;
+ }
+
+ } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) {
+ /** skip datas */
+ DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
+ curPos = curPos + skipCount * sizeof(DWORD);
+ ++pToken;
+
+ } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
+ DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
+ DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
+ ++pToken;
+
+ switch (type) {
+ case D3DVSDT_FLOAT1:
+ x = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ /**/
+ vshader->input.V[reg].x = x;
+ vshader->input.V[reg].y = 0.0f;
+ vshader->input.V[reg].z = 0.0f;
+ vshader->input.V[reg].w = 1.0f;
+ break;
+
+ case D3DVSDT_FLOAT2:
+ x = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ y = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ /**/
+ vshader->input.V[reg].x = x;
+ vshader->input.V[reg].y = y;
+ vshader->input.V[reg].z = 0.0f;
+ vshader->input.V[reg].w = 1.0f;
+ break;
+
+ case D3DVSDT_FLOAT3:
+ x = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ y = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ z = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ /**/
+ vshader->input.V[reg].x = x;
+ vshader->input.V[reg].y = y;
+ vshader->input.V[reg].z = z;
+ vshader->input.V[reg].w = 1.0f;
+ break;
+
+ case D3DVSDT_FLOAT4:
+ x = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ y = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ z = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ w = *(float*) curPos;
+ curPos = curPos + sizeof(float);
+ /**/
+ vshader->input.V[reg].x = x;
+ vshader->input.V[reg].y = y;
+ vshader->input.V[reg].z = z;
+ vshader->input.V[reg].w = w;
+ break;
+
+ case D3DVSDT_D3DCOLOR:
+ dw = *(DWORD*) curPos;
+ curPos = curPos + sizeof(DWORD);
+ /**/
+ vshader->input.V[reg].x = (float) (((dw >> 16) & 0xFF) / 255.0f);
+ vshader->input.V[reg].y = (float) (((dw >> 8) & 0xFF) / 255.0f);
+ vshader->input.V[reg].z = (float) (((dw >> 0) & 0xFF) / 255.0f);
+ vshader->input.V[reg].w = (float) (((dw >> 24) & 0xFF) / 255.0f);
+ break;
+
+ case D3DVSDT_SHORT2:
+ u = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ v = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ /**/
+ vshader->input.V[reg].x = (float) u;
+ vshader->input.V[reg].y = (float) v;
+ vshader->input.V[reg].z = 0.0f;
+ vshader->input.V[reg].w = 1.0f;
+ break;
+
+ case D3DVSDT_SHORT4:
+ u = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ v = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ r = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ t = *(SHORT*) curPos;
+ curPos = curPos + sizeof(SHORT);
+ /**/
+ vshader->input.V[reg].x = (float) u;
+ vshader->input.V[reg].y = (float) v;
+ vshader->input.V[reg].z = (float) r;
+ vshader->input.V[reg].w = (float) t;
+ break;
+
+ case D3DVSDT_UBYTE4:
+ dw = *(DWORD*) curPos;
+ curPos = curPos + sizeof(DWORD);
+ /**/
+ vshader->input.V[reg].x = (float) ((dw & 0x000F) >> 0);
+ vshader->input.V[reg].y = (float) ((dw & 0x00F0) >> 8);
+ vshader->input.V[reg].z = (float) ((dw & 0x0F00) >> 16);
+ vshader->input.V[reg].w = (float) ((dw & 0xF000) >> 24);
+
+ break;
+
+ default: /** errooooorr what to do ? */
+ ERR("Error in VertexShader declaration of %s register: unsupported type %s\n", VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
+ }
+ }
+
+ }
+ /* here D3DVSD_END() */
+ return D3D_OK;
+}
+
+HRESULT WINAPI IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(IDirect3DVertexShaderDeclarationImpl* This, DWORD* pData, UINT* pSizeOfData) {
+ if (NULL == pData) {
+ *pSizeOfData = This->declaration8Length;
+ return D3D_OK;
+ }
+ if (*pSizeOfData < This->declaration8Length) {
+ *pSizeOfData = This->declaration8Length;
+ return D3DERR_MOREDATA;
+ }
+ TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
+ memcpy(pData, This->pDeclaration8, This->declaration8Length);
+ return D3D_OK;
+}
Les sous-répertoires /tmp/.wine-fenix et dlls/d3dcore/.wine-fenix sont identiques.
Les sous-répertoires /tmp/.wine-root et dlls/d3dcore/.wine-root sont identiques.
Les sous-répertoires /tmp/winetmp-fenix et dlls/d3dcore/winetmp-fenix sont identiques.
Les sous-répertoires /tmp/.X11-unix et dlls/d3dcore/.X11-unix sont identiques.
More information about the wine-patches
mailing list