Stub implementations for WPUCompleteOverlappedRequest,
[wine] / dlls / wined3d / stateblock.c
1 /*
2  * state block implementation
3  *
4  * Copyright 2002 Raphael Junqueira
5  *           2004 Jason Edmeades   
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include "wined3d_private.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
26 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
27
28 HRESULT WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnknown **pParent) {
29     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
30     IUnknown_AddRef(This->parent);
31     *pParent = This->parent;
32     return D3D_OK;
33 }
34
35 HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
36     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
37     IWineD3DDeviceImpl     *ThisDevice = (IWineD3DDeviceImpl *)(This->wineD3DDevice);
38     union {
39         D3DLINEPATTERN lp;
40         DWORD d;
41     } lp;
42     union {
43         float f;
44         DWORD d;
45     } tmpfloat;
46     unsigned int i;
47
48     /* Note this may have a large overhead but it should only be executed
49        once, in order to initialize the complete state of the device and 
50        all opengl equivalents                                            */
51     TRACE("-----------------------> Setting up device defaults...\n");
52     This->blockType = D3DSBT_ALL;
53
54     /* FIXME: Set some of the defaults for lights, transforms etc */
55     memcpy(&This->transforms[D3DTS_PROJECTION], &identity, sizeof(identity));
56     memcpy(&This->transforms[D3DTS_VIEW], &identity, sizeof(identity));
57     for (i = 0; i < 256; ++i) {
58       memcpy(&This->transforms[D3DTS_WORLDMATRIX(i)], &identity, sizeof(identity));
59     }
60  
61     /* Render states: */
62     if (ThisDevice->presentParms.EnableAutoDepthStencil) {
63        IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZENABLE, D3DZB_TRUE);
64     } else {
65        IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZENABLE, D3DZB_FALSE);
66     }
67     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FILLMODE, D3DFILL_SOLID);
68     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
69
70     lp.lp.wRepeatFactor = 0; lp.lp.wLinePattern = 0;
71     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_LINEPATTERN, lp.d);
72     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZWRITEENABLE, TRUE);
73     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ALPHATESTENABLE, FALSE);
74     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_LASTPIXEL, TRUE);
75     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE);
76     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ZERO);
77     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_CULLMODE, D3DCULL_CCW);
78     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
79     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
80     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ALPHAREF, 0xff); /*??*/
81     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_DITHERENABLE, FALSE);
82     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ALPHABLENDENABLE, FALSE);
83     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGENABLE, FALSE);
84     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_SPECULARENABLE, FALSE);
85     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZVISIBLE, 0);
86     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGCOLOR, 0);
87     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
88     tmpfloat.f = 0.0f;
89     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGSTART, tmpfloat.d);
90     tmpfloat.f = 1.0f;
91     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGEND, tmpfloat.d);
92     tmpfloat.f = 1.0f;
93     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGDENSITY, tmpfloat.d);
94     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_EDGEANTIALIAS, FALSE);
95     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_ZBIAS, 0);
96     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_RANGEFOGENABLE, FALSE);
97     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILENABLE, FALSE);
98     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
99     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
100     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
101
102     /* Setting stencil func also uses values for stencil ref/mask, so manually set defaults
103      * so only a single call performed (and ensure defaults initialized before making that call)    
104      *
105      * IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILREF, 0);
106      * IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILMASK, 0xFFFFFFFF);
107      */
108     This->renderState[D3DRS_STENCILREF] = 0;
109     This->renderState[D3DRS_STENCILMASK] = 0xFFFFFFFF;
110     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
111     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
112     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
113     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP0, 0);
114     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP1, 0);
115     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP2, 0);
116     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP3, 0);
117     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP4, 0);
118     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP5, 0);
119     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP6, 0);
120     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_WRAP7, 0);
121     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_CLIPPING, TRUE);
122     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_LIGHTING, TRUE);
123     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_AMBIENT, 0);
124     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
125     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_COLORVERTEX, TRUE);
126     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_LOCALVIEWER, TRUE);
127     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_NORMALIZENORMALS, FALSE);
128     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
129     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
130     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
131     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
132     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
133     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_CLIPPLANEENABLE, 0);
134     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
135     tmpfloat.f = 1.0f;
136     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSIZE, tmpfloat.d);
137     tmpfloat.f = 0.0f;
138     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSIZE_MIN, tmpfloat.d);
139     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSPRITEENABLE, FALSE);
140     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSCALEENABLE, FALSE);
141     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSCALE_A, TRUE);
142     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSCALE_B, TRUE);
143     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSCALE_C, TRUE);
144     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
145     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
146     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
147     tmpfloat.f = 1.0f;
148     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_PATCHSEGMENTS, tmpfloat.d);
149     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
150     tmpfloat.f = 64.0f;
151     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POINTSIZE_MAX, tmpfloat.d);
152     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
153     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_COLORWRITEENABLE, 0x0000000F);
154     tmpfloat.f = 0.0f;
155     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_TWEENFACTOR, tmpfloat.d);
156     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_BLENDOP, D3DBLENDOP_ADD);
157     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
158     IWineD3DDevice_SetRenderState((IWineD3DDevice *)This->wineD3DDevice, D3DRS_NORMALORDER, D3DORDER_LINEAR);
159
160     /** clipping status */
161     This->clip_status.ClipUnion = 0;
162     This->clip_status.ClipIntersection = 0xFFFFFFFF;
163         
164     /* Texture Stage States - Put directly into state block, we will call function below */
165     for (i = 0; i < GL_LIMITS(textures); i++) {
166         TRACE("Setting up default texture states for texture Stage %d\n", i);
167         memcpy(&This->transforms[D3DTS_TEXTURE0 + i], &identity, sizeof(identity));
168         This->textureState[i][D3DTSS_COLOROP               ] = (i==0)? D3DTOP_MODULATE :  D3DTOP_DISABLE;
169         This->textureState[i][D3DTSS_COLORARG1             ] = D3DTA_TEXTURE;
170         This->textureState[i][D3DTSS_COLORARG2             ] = D3DTA_CURRENT;
171         This->textureState[i][D3DTSS_ALPHAOP               ] = (i==0)? D3DTOP_SELECTARG1 :  D3DTOP_DISABLE;
172         This->textureState[i][D3DTSS_ALPHAARG1             ] = D3DTA_TEXTURE;
173         This->textureState[i][D3DTSS_ALPHAARG2             ] = D3DTA_CURRENT;
174         This->textureState[i][D3DTSS_BUMPENVMAT00          ] = (DWORD) 0.0;
175         This->textureState[i][D3DTSS_BUMPENVMAT01          ] = (DWORD) 0.0;
176         This->textureState[i][D3DTSS_BUMPENVMAT10          ] = (DWORD) 0.0;
177         This->textureState[i][D3DTSS_BUMPENVMAT11          ] = (DWORD) 0.0;
178         This->textureState[i][D3DTSS_TEXCOORDINDEX         ] = i;
179         This->textureState[i][D3DTSS_ADDRESSU              ] = D3DTADDRESS_WRAP;
180         This->textureState[i][D3DTSS_ADDRESSV              ] = D3DTADDRESS_WRAP;
181         This->textureState[i][D3DTSS_BORDERCOLOR           ] = 0x00;
182         This->textureState[i][D3DTSS_MAGFILTER             ] = D3DTEXF_POINT;
183         This->textureState[i][D3DTSS_MINFILTER             ] = D3DTEXF_POINT;
184         This->textureState[i][D3DTSS_MIPFILTER             ] = D3DTEXF_NONE;
185         This->textureState[i][D3DTSS_MIPMAPLODBIAS         ] = 0;
186         This->textureState[i][D3DTSS_MAXMIPLEVEL           ] = 0;
187         This->textureState[i][D3DTSS_MAXANISOTROPY         ] = 1;
188         This->textureState[i][D3DTSS_BUMPENVLSCALE         ] = (DWORD) 0.0;
189         This->textureState[i][D3DTSS_BUMPENVLOFFSET        ] = (DWORD) 0.0;
190         This->textureState[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
191         This->textureState[i][D3DTSS_ADDRESSW              ] = D3DTADDRESS_WRAP;
192         This->textureState[i][D3DTSS_COLORARG0             ] = D3DTA_CURRENT;
193         This->textureState[i][D3DTSS_ALPHAARG0             ] = D3DTA_CURRENT;
194         This->textureState[i][D3DTSS_RESULTARG             ] = D3DTA_CURRENT;
195     }
196
197     /* Under DirectX you can have texture stage operations even if no texture is
198        bound, whereas opengl will only do texture operations when a valid texture is
199        bound. We emulate this by creating dummy textures and binding them to each
200        texture stage, but disable all stages by default. Hence if a stage is enabled
201        then the default texture will kick in until replaced by a SetTexture call     */
202
203     ENTER_GL();
204
205     for (i = 0; i < GL_LIMITS(textures); i++) {
206         GLubyte white = 255;
207
208         /* Note this avoids calling settexture, so pretend it has been called */
209         This->set.textures[i] = TRUE;
210         This->changed.textures[i] = TRUE;
211         This->textures[i] = NULL;
212
213         /* Make appropriate texture active */
214         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
215             GLACTIVETEXTURE(i);
216         } else if (i > 0) {
217             FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
218         }
219
220         /* Generate an opengl texture name */
221         glGenTextures(1, &ThisDevice->dummyTextureName[i]);
222         checkGLcall("glGenTextures");
223         TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
224
225         /* Generate a dummy 1d texture */
226         This->textureDimensions[i] = GL_TEXTURE_1D;
227         glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
228         checkGLcall("glBindTexture");
229
230         glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white); 
231         checkGLcall("glTexImage1D");
232
233         /* Reapply all the texture state information to this texture */
234         IWineD3DDevice_SetupTextureStates((IWineD3DDevice *)This->wineD3DDevice, i, REAPPLY_ALL);
235     }
236
237     LEAVE_GL();
238
239     /* Defaulting palettes - Note these are device wide but reinitialized here for convenience*/
240     for (i = 0; i < MAX_PALETTES; ++i) {
241       int j;
242       for (j = 0; j < 256; ++j) {
243         This->wineD3DDevice->palettes[i][j].peRed   = 0xFF;
244         This->wineD3DDevice->palettes[i][j].peGreen = 0xFF;
245         This->wineD3DDevice->palettes[i][j].peBlue  = 0xFF;
246         This->wineD3DDevice->palettes[i][j].peFlags = 0xFF;
247       }
248     }
249     This->wineD3DDevice->currentPalette = 0;
250
251     TRACE("-----------------------> Device defaults now set up...\n");
252     return D3D_OK;
253 }
254
255 /**********************************************************
256  * IUnknown parts follows
257  **********************************************************/
258 HRESULT WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj)
259 {
260     return E_NOINTERFACE;
261 }
262
263 ULONG WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) {
264     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
265     TRACE("(%p) : AddRef increasing from %ld\n", This, This->ref);
266     return InterlockedIncrement(&This->ref);
267 }
268
269 ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
270     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
271     ULONG ref;
272     TRACE("(%p) : Releasing from %ld\n", This, This->ref);
273     ref = InterlockedDecrement(&This->ref);
274     if (ref == 0) {
275         IWineD3DDevice_Release((IWineD3DDevice *)This->wineD3DDevice);
276         HeapFree(GetProcessHeap(), 0, This);
277     }
278     return ref;
279 }
280
281 /**********************************************************
282  * IWineD3DStateBlock VTbl follows
283  **********************************************************/
284
285 IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
286 {
287     IWineD3DStateBlockImpl_QueryInterface,
288     IWineD3DStateBlockImpl_AddRef,
289     IWineD3DStateBlockImpl_Release,
290     IWineD3DStateBlockImpl_GetParent,
291     IWineD3DStateBlockImpl_InitStartupStateBlock
292 };