diff -u /cvs-src/wine-pending/d3d8_43/d3d8_main.c ./d3d8_main.c --- /cvs-src/wine-pending/d3d8_43/d3d8_main.c 2003-05-30 00:09:35.000000000 +0200 +++ ./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 /cvs-src/wine-pending/d3d8_43/d3d8_private.h ./d3d8_private.h --- /cvs-src/wine-pending/d3d8_43/d3d8_private.h 2003-05-30 00:09:35.000000000 +0200 +++ ./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 /cvs-src/wine-pending/d3d8_43/d3d8.spec ./d3d8.spec --- /cvs-src/wine-pending/d3d8_43/d3d8.spec 2003-05-30 00:09:35.000000000 +0200 +++ ./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 /cvs-src/wine-pending/d3d8_43/device.c ./device.c --- /cvs-src/wine-pending/d3d8_43/device.c 2003-05-30 00:09:35.000000000 +0200 +++ ./device.c 2003-05-30 16:28:00.000000000 +0200 @@ -996,71 +996,6 @@ TRACE("glEnd\n"); } -/** - * @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; - } -} - /* Apply the current values to the specified texture stage */ void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) { ICOM_THIS(IDirect3DDevice8Impl,iface); @@ -3671,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; @@ -3711,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"); @@ -3736,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)); } @@ -3763,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; @@ -3884,63 +3827,22 @@ } break; - case D3DTSS_COLORARG0 : - case D3DTSS_ALPHAARG0 : - /* FIXME: Mesa seems to struggle setting these at the moment */ - /*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/ - /*break;*/ - - case D3DTSS_COLORARG1 : - case D3DTSS_COLORARG2 : - case D3DTSS_ALPHAARG1 : - case D3DTSS_ALPHAARG2 : - { - BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0); - int operand = GL_SRC_COLOR; - int source = GL_TEXTURE; - - GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand); - if (isAlphaArg) { - - /* 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 (Type == D3DTSS_ALPHAARG1 && This->StateBlock->textures[Stage] == NULL && Value == D3DTA_TEXTURE) { - GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlphaArg, &source, &operand); - } - TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand); - glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);"); - glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);"); - } else { - TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand); - glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);"); - glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);"); - } - } - break; - case D3DTSS_ALPHAOP : case D3DTSS_COLOROP : { - int Scale = 1; - int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT; - - if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) { + if (Value == D3DTOP_DISABLE) { /* TODO: Disable by making this and all later levels disabled */ - glDisable(GL_TEXTURE_1D); - checkGLcall("Disable GL_TEXTURE_1D"); - glDisable(GL_TEXTURE_2D); - checkGLcall("Disable GL_TEXTURE_2D"); - glDisable(GL_TEXTURE_3D); - checkGLcall("Disable GL_TEXTURE_3D"); + if (Type == D3DTSS_COLOROP) { + glDisable(GL_TEXTURE_1D); + checkGLcall("Disable GL_TEXTURE_1D"); + glDisable(GL_TEXTURE_2D); + checkGLcall("Disable GL_TEXTURE_2D"); + glDisable(GL_TEXTURE_3D); + checkGLcall("Disable GL_TEXTURE_3D"); + } + break; /* Dont bother setting the texture operations */ } else { - /* Enable only the appropriate texture dimension */ if (Type == D3DTSS_COLOROP) { if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) { @@ -3972,139 +3874,27 @@ checkGLcall("Disable GL_TEXTURE_CUBE_MAP"); } } - - /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */ - if (Value != D3DTOP_DISABLE) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); - } - - /* Now set up the operand correctly */ - switch (Value) { - case D3DTOP_DISABLE : - /* Contrary to the docs, alpha can be disabled when colorop is enabled - and it works, so ignore this op */ - TRACE("Disable ALPHAOP but COLOROP enabled!\n"); - break; - - case D3DTOP_SELECTARG1 : - { - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)"); - } - break; - - case D3DTOP_SELECTARG2 : - { - BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP); - DWORD dwValue = 0; - GLenum source; - GLenum operand; - /*FIXME("see if D3DTOP_SELECTARG2 behavior is correct now!\n");*/ - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)"); - /* GL_REPLACE, swap args 0 and 1? */ - dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2]; - GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand); - if (isAlphaOp) { - TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')"); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')"); - } else { - TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')"); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')"); - } - dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1]; - GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand); - if (isAlphaOp) { - TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')"); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')"); - } else { - TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')"); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')"); - } - } - break; - - case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */ - case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */ - case D3DTOP_MODULATE : - - /* Correct scale */ - if (Type == D3DTSS_ALPHAOP) { - glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)"); - } else { - glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)"); - } - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);"); - break; - - case D3DTOP_ADD : - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)"); - break; - - case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */ - case D3DTOP_ADDSIGNED : - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT); - vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)"); - break; - - case D3DTOP_DOTPRODUCT3 : -#if defined(GL_VERSION_1_3) - if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);"); - break; - } -#endif - FIXME("DotProduct3 extension requested but not supported via this version of opengl\n"); - break; - - - case D3DTOP_SUBTRACT : -#if defined(GL_VERSION_1_3) - glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)"); - break; -#else - /** - * @TODO: to check: - * if ARB_texture_env_combine is supported - * we can use GL_SUBTRACT_ARB here - */ -#endif - - case D3DTOP_ADDSMOOTH : - case D3DTOP_BLENDDIFFUSEALPHA : - case D3DTOP_BLENDTEXTUREALPHA : - case D3DTOP_BLENDFACTORALPHA : - case D3DTOP_BLENDTEXTUREALPHAPM : - case D3DTOP_BLENDCURRENTALPHA : - case D3DTOP_PREMODULATE : - case D3DTOP_MODULATEALPHA_ADDCOLOR : - case D3DTOP_MODULATECOLOR_ADDALPHA : - case D3DTOP_MODULATEINVALPHA_ADDCOLOR : - case D3DTOP_MODULATEINVCOLOR_ADDALPHA : - case D3DTOP_BUMPENVMAP : - case D3DTOP_BUMPENVMAPLUMINANCE : - case D3DTOP_MULTIPLYADD : - case D3DTOP_LERP : - default: - FIXME("Unhandled texture operation %ld\n", Value); + } + /* Drop through... (Except disable case) */ + case D3DTSS_COLORARG0 : + case D3DTSS_COLORARG1 : + case D3DTSS_COLORARG2 : + case D3DTSS_ALPHAARG0 : + case D3DTSS_ALPHAARG1 : + case D3DTSS_ALPHAARG2 : + { + BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 || + Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0); + if (isAlphaArg) { + set_tex_op(iface, TRUE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_ALPHAOP], + This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1], + This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2], + This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]); + } else { + set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP], + This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1], + This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2], + This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]); } } break; @@ -4693,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; } @@ -4703,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); @@ -4728,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; } @@ -4756,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 /cvs-src/wine-pending/d3d8_43/directx.c ./directx.c --- /cvs-src/wine-pending/d3d8_43/directx.c 2003-05-30 00:09:35.000000000 +0200 +++ ./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 /cvs-src/wine-pending/d3d8_43/shader.c ./shader.c --- /cvs-src/wine-pending/d3d8_43/shader.c 2003-05-30 00:09:35.000000000 +0200 +++ ./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 .: shader.o Seulement dans .: stateblock.o Seulement dans .: surface.o Seulement dans .: swapchain.o Seulement dans .: texture.o diff -u /cvs-src/wine-pending/d3d8_43/utils.c ./utils.c --- /cvs-src/wine-pending/d3d8_43/utils.c 2003-05-30 00:09:35.000000000 +0200 +++ ./utils.c 2003-05-30 00:10:21.000000000 +0200 @@ -469,3 +469,617 @@ } } +/* 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 set_tex_op(LPDIRECT3DDEVICE8 iface, 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 set_tex_op(LPDIRECT3DDEVICE8 iface, 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; + ICOM_THIS(IDirect3DDevice8Impl,iface); + + 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; + + 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 = useext(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 && Stage==0 && 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 defined(GL_VERSION_1_3) || defined (GL_ARB_texture_env_combine) + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(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"); +#endif + 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, 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, 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, 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 defined(GL_EXT_texture_env_dot3) + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); +#elif defined(GL_ARB_texture_env_dot3) + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); +#elif defined (GL_VERSION_1_3) + 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"); +#endif + 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, 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, src3); + checkGLcall("GL_TEXTURE_ENV, src1_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, src1); + 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) { +#if defined(GL_NV_texture_env_combine4) + /* Note: If COMBINE4 in effect cant go back to combine! */ + if (isAlpha) { + switch (This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP]) + { + 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: + FIXME("Cant have COMBINE4 and COMBINE in efferct together, alphaop=%d\n", op); + return; + } + } +#endif + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); + checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); + return; + } + + /* Other texture operations require special extensions: */ +#if defined(GL_NV_texture_env_combine4) + if (isAlpha) { + invopr = GL_ONE_MINUS_SRC_ALPHA; + src3_target = GL_SOURCE3_ALPHA_NV; + opr3_target = GL_OPERAND3_ALPHA_NV; + } + else { + 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_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, 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, src3); + checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr3); + 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"); + return; + } +#endif /* GL_NV_texture_env_combine4 */ + + /* After all the extensions, if still unhandled, report fixme */ + FIXME("Unhandled texture operation %d\n", op); +} +#endif + +/** + * @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; + } +}