[dx45] begin of hardware shaders support merging

Raphaël Junqueira fenix at club-internet.fr
Sat May 31 09:05:44 CDT 2003


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

 This is the first patch of a huge merge: Hardware shaders in d3d8 ;)

Changelog:
 - pixel shader program dump code
 - pixel shader code split into a new "COM object" (as done before for vertex 
shader)
 - some fixes on Validate* functions call types
 - add pixel shader (ie fragment_program) detection on caps code

Regards,
Raphael
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE+2La4p7NA3AmQTU4RAthaAJ9HsNdDfj0f4lUMpPi1Gmb3AqRojACfYF14
WpUROzGR2BTnyOVwqrGUY84=
=i0wZ
-----END PGP SIGNATURE-----
-------------- next part --------------
diff -u dlls/d3d8_44/d3d8_main.c dlls/d3d8/d3d8_main.c
--- dlls/d3d8_44/d3d8_main.c	2003-05-31 15:53:09.000000000 +0200
+++ dlls/d3d8/d3d8_main.c	2003-05-30 01:39:23.000000000 +0200
@@ -38,9 +38,9 @@
     return 0;
 }
 
-HRESULT WINAPI DebugSetMute(void)
+HRESULT CDECL DebugSetMute(DWORD dummy)
 {
-    FIXME("(void): stub\n");
+    FIXME("(void): stub %lu\n", dummy);
     return 0;
 }
 
diff -u dlls/d3d8_44/d3d8_private.h dlls/d3d8/d3d8_private.h
--- dlls/d3d8_44/d3d8_private.h	2003-05-31 15:53:09.000000000 +0200
+++ dlls/d3d8/d3d8_private.h	2003-05-30 16:13:33.000000000 +0200
@@ -99,17 +99,16 @@
 } D3DSHADERSCALAR;
 
 #define D3D8_VSHADER_MAX_CONSTANTS 96
-#define D3D8_PSHADER_MAX_CONSTANTS 96
 typedef D3DSHADERVECTOR VSHADERCONSTANTS8[D3D8_VSHADER_MAX_CONSTANTS];
 
-typedef struct SHADERDATA8 {
+typedef struct VSHADERDATA8 {
   /** Run Time Shader Function Constants */
   /*D3DXBUFFER* constants;*/
   VSHADERCONSTANTS8 C;
   /** Shader Code as char ... */
   CONST DWORD* code;
   UINT codeLength;
-} SHADERDATA8;
+} VSHADERDATA8;
 
 /** temporary here waiting for buffer code */
 typedef struct VSHADERINPUTDATA8 {
@@ -125,6 +124,34 @@
   D3DSHADERVECTOR oPts;
 } VSHADEROUTPUTDATA8;
 
+
+#define D3D8_PSHADER_MAX_CONSTANTS 32
+typedef D3DSHADERVECTOR PSHADERCONSTANTS8[D3D8_PSHADER_MAX_CONSTANTS];
+
+typedef struct PSHADERDATA8 {
+  /** Run Time Shader Function Constants */
+  /*D3DXBUFFER* constants;*/
+  PSHADERCONSTANTS8 C;
+  /** Shader Code as char ... */
+  CONST DWORD* code;
+  UINT codeLength;
+} PSHADERDATA8;
+
+/** temporary here waiting for buffer code */
+typedef struct PSHADERINPUTDATA8 {
+  D3DSHADERVECTOR V[2];
+  D3DSHADERVECTOR T[8];
+  D3DSHADERVECTOR S[16];
+  /*D3DSHADERVECTOR R[12];*/
+} PSHADERINPUTDATA8;
+
+/** temporary here waiting for buffer code */
+typedef struct PSHADEROUTPUTDATA8 {
+  D3DSHADERVECTOR oC[4];
+  D3DSHADERVECTOR oDepth;
+} PSHADEROUTPUTDATA8;
+
+
 /*
  * External prototypes
  */
@@ -155,6 +182,7 @@
 
 typedef enum _GL_SupportedExt {
   /* ARB */
+  ARB_FRAGMENT_PROGRAM,
   ARB_MULTISAMPLE,
   ARB_MULTITEXTURE,
   ARB_POINT_PARAMETERS,
@@ -173,6 +201,7 @@
   EXT_TEXTURE_LOD_BIAS,
   EXT_VERTEX_WEIGHTING,
   /* NVIDIA */
+  NV_FRAGMENT_PROGRAM,
   NV_VERTEX_PROGRAM,
   /* ATI */
   EXT_VERTEX_SHADER,
@@ -190,6 +219,19 @@
   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;
+
 typedef struct _GL_Info {
   /** 
    * CAPS Constants 
@@ -198,11 +240,14 @@
   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[25];
+  BOOL supported[30];
 } GL_Info;
 
 #define GL_LIMITS(ExtName)     (This->direct3d8->gl_info.max_##ExtName)
@@ -1017,6 +1062,7 @@
         BOOL                      vertexShaderConstant;
         BOOL                      vertexShaderDecl;
         BOOL                      pixelShader;
+        BOOL                      pixelShaderConstant;
         BOOL                      renderstate[HIGHEST_RENDER_STATE];
         BOOL                      texture_state[8][HIGHEST_TEXTURE_STATE];
         BOOL                      clipplane[MAX_CLIPPLANES];
@@ -1091,7 +1137,6 @@
   
   /* Pixel Shader */
   DWORD                     PixelShader;
-  /* TODO: Pixel Shader Constant */
   
   /* Indexed Vertex Blending */
   D3DVERTEXBLENDFLAGS       vertex_blend;
@@ -1099,6 +1144,8 @@
 
   /* Vertex Shader Constant */
   D3DSHADERVECTOR           vertexShaderConstant[D3D8_VSHADER_MAX_CONSTANTS];
+  /* Pixel Shader Constant */
+  D3DSHADERVECTOR           pixelShaderConstant[D3D8_PSHADER_MAX_CONSTANTS];
 };
 
 /* exported Interfaces */
@@ -1171,7 +1218,7 @@
   DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */
   DWORD version;
   /* run time datas */
-  SHADERDATA8* data;
+  VSHADERDATA8* data;
   VSHADERINPUTDATA8 input;
   VSHADEROUTPUTDATA8 output;
 };
@@ -1210,18 +1257,21 @@
   /* The device, to be replaced by a IDirect3DDeviceImpl */
   IDirect3DDevice8Impl* device;
 
-  /* TODO: Pixel Shader */
-  CONST DWORD* function;
+  DWORD* function;
   UINT functionLength;
   DWORD version;
   /* run time datas */
-  SHADERDATA8* data;
+  PSHADERDATA8* data;
+  PSHADERINPUTDATA8 input;
+  PSHADEROUTPUTDATA8 output;
 };
 
 /* exported Interfaces */
 extern HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData);
 /* internal Interfaces */
 extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl* This);
+/* temporary internal Interfaces */
+extern HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader);
 
 
 /**
@@ -1229,7 +1279,10 @@
  *
  * to see how not defined it here
  */ 
+void   GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
 void   setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage);
+void   set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
+
 
 SHORT  D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
 GLint  D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
diff -u dlls/d3d8_44/d3d8.spec dlls/d3d8/d3d8.spec
--- dlls/d3d8_44/d3d8.spec	2003-05-31 15:53:09.000000000 +0200
+++ dlls/d3d8/d3d8.spec	2003-05-30 13:59:17.000000000 +0200
@@ -1,5 +1,5 @@
 @ stdcall D3D8GetSWInfo()
-@ stdcall DebugSetMute(long)
+@ cdecl   DebugSetMute(long)
 @ stdcall Direct3DCreate8(long)
-@ stdcall ValidatePixelShader(ptr ptr)
+@ cdecl ValidatePixelShader(ptr ptr)
 @ stdcall ValidateVertexShader(ptr ptr)
diff -u dlls/d3d8_44/device.c dlls/d3d8/device.c
--- dlls/d3d8_44/device.c	2003-05-31 15:53:25.000000000 +0200
+++ dlls/d3d8/device.c	2003-05-30 16:28:00.000000000 +0200
@@ -3606,7 +3606,7 @@
     IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
     return D3D_OK;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
+HRESULT  WINAPI  IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
 
     IDirect3DBaseTexture8 *oldTxt;
     BOOL reapplyStates = TRUE;
@@ -3646,22 +3646,20 @@
     }
 
     /* Decrement the count of the previous texture */
-    if (oldTxt != NULL) {
+    if (NULL != oldTxt) {
         IDirect3DBaseTexture8Impl_Release(oldTxt);
     }
 
-    if (pTexture) {
-        IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
+    if (NULL != pTexture) {
+        IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]);
 
         /* Now setup the texture appropraitly */
         textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
 
         if (textureType == D3DRTYPE_TEXTURE) {
-          IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl*) pTexture;
-
-          if ((void*) oldTxt == (void*) pTexture2 && pTexture2->Dirty == FALSE) {
-              TRACE("Skipping setting texture as old == new\n");
-              reapplyStates = FALSE;
+          if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
+            TRACE("Skipping setting texture as old == new\n");
+            reapplyStates = FALSE;
           } else {
             /* Standard 2D texture */
             TRACE("Standard 2d texture\n");
@@ -3671,19 +3669,29 @@
             IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
           }
         } else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
-            /* Standard 3D (volume) texture */
+	  if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
+	    TRACE("Skipping setting texture as old == new\n");
+	    reapplyStates = FALSE;
+          } else {
+	    /* Standard 3D (volume) texture */
             TRACE("Standard 3d texture\n");
             This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
 
             /* Load up the texture now */
 	    IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
+	  }
         } else if (textureType == D3DRTYPE_CUBETEXTURE) {
+	  if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
+	    TRACE("Skipping setting texture as old == new\n");
+	    reapplyStates = FALSE;
+          } else {
 	    /* Standard Cube texture */
 	    TRACE("Standard Cube texture\n");
 	    This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB;
 
 	    /* Load up the texture now */
 	    IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
+	  }
 	} else {
             FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
         }
@@ -3698,7 +3706,7 @@
     /* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
        a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
     if (reapplyStates) {
-       setupTextureStates (iface, Stage);
+       setupTextureStates(iface, Stage);
     }
        
     return D3D_OK;
@@ -4475,9 +4483,10 @@
 HRESULT  WINAPI  IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
     ICOM_THIS(IDirect3DDevice8Impl,iface);
     IDirect3DPixelShaderImpl* object;
+    HRESULT res;
     UINT i;
 
-    FIXME("(%p) : PixelShader not fully supported yet\n", This);    
+    TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction);
     if (NULL == pFunction || NULL == pHandle) {
       return D3DERR_INVALIDCALL;
     }
@@ -4485,21 +4494,16 @@
     if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
       return D3DERR_OUTOFVIDEOMEMORY;
     }
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
-    if (NULL == object) {
-      return D3DERR_OUTOFVIDEOMEMORY;
-    }
-    
-    object->data = NULL; /* TODO */
 
-    PixelShaders[i] = object;
-    *pHandle = VS_HIGHESTFIXEDFXF + i;
-
-    object->function = pFunction;
-    for (i = 0; D3DPS_END() != pFunction[i]; ++i) ;
-    object->functionLength = i + 1;
-
-    return D3D_OK;
+    /** Create the Pixel Shader */
+    res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object);
+    if (SUCCEEDED(res)) {
+      PixelShaders[i] = object;
+      *pHandle = VS_HIGHESTFIXEDFXF + i;
+      return D3D_OK;
+    } 
+    *pHandle = 0xFFFFFFFF;
+    return res;
 }
 HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
     ICOM_THIS(IDirect3DDevice8Impl,iface);
@@ -4510,22 +4514,22 @@
 
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
-        TRACE("Recording... not performing anything\n");
+        TRACE_(d3d_shader)("Recording... not performing anything\n");
         return D3D_OK;
     }
 
     /* FIXME: Quieten when not being used */
     if (Handle != 0) {
-      FIXME("(%p) : stub %ld\n", This, Handle);
+      FIXME_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
     } else {
-      TRACE("(%p) : stub %ld\n", This, Handle);
+      TRACE_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
     }
 
     return D3D_OK;
 }
 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
     ICOM_THIS(IDirect3DDevice8Impl,iface);
-    TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
+    TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
     *pHandle = This->StateBlock->PixelShader;
     return D3D_OK;
 }
@@ -4538,42 +4542,63 @@
       return D3DERR_INVALIDCALL;
     }
     object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
-    TRACE("(%p) : freeing PixelShader %p\n", This, object);
+    TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object);
     /* TODO: check validity of object before free */
+    if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
+    HeapFree(GetProcessHeap(), 0, (void *)object->data);
     HeapFree(GetProcessHeap(), 0, (void *)object);
-    PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
+    PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
+
     return D3D_OK;
 }
 
-HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);
-    return D3D_OK;
+HRESULT  WINAPI  IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
+  ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+  if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
+    ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register);
+    return D3DERR_INVALIDCALL;
+  }
+  if (NULL == pConstantData) {
+    return D3DERR_INVALIDCALL;
+  }
+  if (ConstantCount > 1) {
+    FLOAT* f = (FLOAT*)pConstantData;
+    UINT i;
+    TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
+    for (i = 0; i < ConstantCount; ++i) {
+      TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
+      f += 4;
+    }
+  } else { 
+    FLOAT* f = (FLOAT*) pConstantData;
+    TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
+  }
+  This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE;
+  memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
+  return D3D_OK;
 }
-HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
-    FIXME("(%p) : stub\n", This);  
-    return D3D_OK;
+HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
+  ICOM_THIS(IDirect3DDevice8Impl,iface);
+
+  TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
+  if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
+    return D3DERR_INVALIDCALL;
+  }
+  if (NULL == pConstantData) {
+    return D3DERR_INVALIDCALL;
+  }
+  memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
+  return D3D_OK;
 }
 HRESULT  WINAPI  IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
-    ICOM_THIS(IDirect3DDevice8Impl,iface);
     IDirect3DPixelShaderImpl* object;
 
     object = PIXEL_SHADER(Handle);
     if (NULL == object) {
       return D3DERR_INVALIDCALL;
-    }
-    if (NULL == pData) {
-      *pSizeOfData = object->functionLength;
-      return D3D_OK;
-    }
-    if (*pSizeOfData < object->functionLength) {
-      *pSizeOfData = object->functionLength;
-      return D3DERR_MOREDATA;
-    }
-    TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
-    memcpy(pData, object->function, object->functionLength);
-    return D3D_OK;
+    } 
+    return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
 }
 HRESULT  WINAPI  IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
     ICOM_THIS(IDirect3DDevice8Impl,iface);
diff -u dlls/d3d8_44/directx.c dlls/d3d8/directx.c
--- dlls/d3d8_44/directx.c	2003-05-31 15:53:09.000000000 +0200
+++ dlls/d3d8/directx.c	2003-05-30 17:57:52.000000000 +0200
@@ -681,12 +681,6 @@
         int dblBuf[] = {GLX_RGBA, 
 			GLX_STENCIL_SIZE, 8, /*  2 */
 			GLX_DEPTH_SIZE,  16, /*  4 */
-#if 0
-			GLX_RED_SIZE,     8, /*  6 */ 
-			GLX_GREEN_SIZE,   8, /*  8 */
-			GLX_BLUE_SIZE,    8, /* 10 */
-			GLX_ALPHA_SIZE,   8, /* 12 */
-#endif
 			GLX_DOUBLEBUFFER, None};
         /* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
 
@@ -889,8 +883,10 @@
      */
     memset(&This->gl_info.supported, 0, sizeof(This->gl_info.supported));
     This->gl_info.max_textures   = 1;
+    This->gl_info.ps_arb_version = PS_VERSION_NOT_SUPPORTED;
     This->gl_info.vs_arb_version = VS_VERSION_NOT_SUPPORTED;
     This->gl_info.vs_nv_version  = VS_VERSION_NOT_SUPPORTED;
+    This->gl_info.vs_ati_version = VS_VERSION_NOT_SUPPORTED;
 
     /* Retrieve opengl defaults */
     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
@@ -922,7 +918,11 @@
 	/**
 	 * ARB 
 	 */
-        if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
+	if (strcmp(ThisExtn, "GL_ARB_fragment_program") == 0) {
+	  This->gl_info.ps_arb_version = PS_VERSION_11;
+	  FIXME(" FOUND: ARB Pixel Shader support - version=%02x\n", This->gl_info.ps_arb_version);
+	  This->gl_info.supported[ARB_FRAGMENT_PROGRAM] = TRUE;
+        } else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
 	  FIXME(" FOUND: ARB Multisample support\n");
 	  This->gl_info.supported[ARB_MULTISAMPLE] = TRUE;
 	} else if (strcmp(ThisExtn, "GL_ARB_multitexture") == 0) {
@@ -976,6 +976,10 @@
 	/**
 	 * NVIDIA 
 	 */
+	} else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
+	  This->gl_info.ps_nv_version = PS_VERSION_11;
+	  FIXME(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This->gl_info.ps_nv_version);
+	  This->gl_info.supported[NV_FRAGMENT_PROGRAM] = TRUE;
 	} else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
 	  This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10);
 	  This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2"))   ? VS_VERSION_20 : VS_VERSION_10);
diff -u dlls/d3d8_44/shader.c dlls/d3d8/shader.c
--- dlls/d3d8_44/shader.c	2003-05-31 15:53:09.000000000 +0200
+++ dlls/d3d8/shader.c	2003-05-30 15:52:27.000000000 +0200
@@ -34,7 +34,7 @@
 
 /* Shader debugging - Change the following line to enable debugging of software
       vertex shaders                                                             */
-#if 1
+#if 0
 # define VSTRACE(A) TRACE A
 # define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
 #else 
@@ -82,6 +82,8 @@
   const char*   name;
   CONST UINT    num_params;
   shader_fct_t  soft_fct;
+  DWORD         min_version;
+  DWORD         max_version;
 } SHADER_OPCODE;
 
 /*******************************
@@ -345,36 +347,36 @@
  * log, exp, frc, m*x* seems to be macros ins ... to see
  */
 static CONST SHADER_OPCODE vshader_ins [] = {
-  {D3DSIO_NOP,  "nop",  0, vshader_nop},
-  {D3DSIO_MOV,  "mov",  2, vshader_mov},
-  {D3DSIO_ADD,  "add",  3, vshader_add},
-  {D3DSIO_SUB,  "sub",  3, vshader_sub},
-  {D3DSIO_MAD,  "mad",  4, vshader_mad},
-  {D3DSIO_MUL,  "mul",  3, vshader_mul},
-  {D3DSIO_RCP,  "rcp",  2, vshader_rcp},
-  {D3DSIO_RSQ,  "rsq",  2, vshader_rsq},
-  {D3DSIO_DP3,  "dp3",  3, vshader_dp3},
-  {D3DSIO_DP4,  "dp4",  3, vshader_dp4},
-  {D3DSIO_MIN,  "min",  3, vshader_min},
-  {D3DSIO_MAX,  "max",  3, vshader_max},
-  {D3DSIO_SLT,  "slt",  3, vshader_slt},
-  {D3DSIO_SGE,  "sge",  3, vshader_sge},
-  {D3DSIO_EXP,  "exp",  2, vshader_exp},
-  {D3DSIO_LOG,  "log",  2, vshader_log},
-  {D3DSIO_LIT,  "lit",  2, vshader_lit},
-  {D3DSIO_DST,  "dst",  3, vshader_dst},
-  {D3DSIO_LRP,  "lrp",  5, vshader_lrp},
-  {D3DSIO_FRC,  "frc",  2, vshader_frc},
-  {D3DSIO_M4x4, "m4x4", 3, vshader_m4x4},
-  {D3DSIO_M4x3, "m4x3", 3, vshader_m4x3},
-  {D3DSIO_M3x4, "m3x4", 3, vshader_m3x4},
-  {D3DSIO_M3x3, "m3x3", 3, vshader_m3x3},
-  {D3DSIO_M3x2, "m3x2", 3, vshader_m3x2},
+  {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},
-  {D3DSIO_LOGP, "logp", 2, vshader_logp},
+  {D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0},
+  {D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0},
 
-  {0, NULL, 0, NULL}
+  {0, NULL, 0, NULL, 0, 0}
 };
 
 
@@ -546,7 +548,7 @@
   object->ref = 1;
   
   object->usage = Usage;
-  object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
+  object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VSHADERDATA8));
     
   IDirect3DVertexShaderImpl_ParseProgram(object, pFunction);
 
@@ -839,6 +841,458 @@
 }
 
 
+/**********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************
+ **********************************************************************************************************************************************/
+
+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 IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader) {
+  IDirect3DPixelShaderImpl* object;
+
+  object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
+  if (NULL == object) {
+    *ppPixelShader = NULL;
+    return D3DERR_OUTOFVIDEOMEMORY;
+  }
+  /*object->lpVtbl = &Direct3DPixelShader9_Vtbl;*/
+  object->device = This;
+  object->ref = 1;
+  
+  object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PSHADERDATA8));
+    
+  IDirect3DPixelShaderImpl_ParseProgram(object, pFunction);
+
+  *ppPixelShader = object;
+  return D3D_OK;
+}
+
+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 > D3D8_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 > D3D8_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.@)
  */
@@ -850,7 +1304,7 @@
 /***********************************************************************
  *		ValidatePixelShader (D3D8.@)
  */
-BOOL WINAPI ValidatePixelShader(LPVOID what) {
-  FIXME("(void): stub: %p\n", what);
+BOOL WINAPI ValidatePixelShader(LPVOID what, LPVOID toto) {
+  FIXME("(void): stub: %p %p\n", what, toto);
   return TRUE;
 }
Seulement dans dlls/d3d8: version.res.FlJMFi


More information about the wine-patches mailing list