Encode/decode CERT_PUBLIC_KEY_INFO, with tests.
[wine] / dlls / wined3d / stateblock.c
1 /*
2  * state block implementation
3  *
4  * Copyright 2002 Raphael Junqueira
5  * Copyright 2004 Jason Edmeades
6  * Copyright 2005 Oliver Stieber
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24 #include "wined3d_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
27 #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->wineD3DDevice)->wineD3D))->gl_info
28
29 /**********************************************************
30  * IWineD3DStateBlockImpl IUnknown parts follows
31  **********************************************************/
32 HRESULT WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj)
33 {
34     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
35     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
36     if (IsEqualGUID(riid, &IID_IUnknown)
37         || IsEqualGUID(riid, &IID_IWineD3DStateBlock)){
38         IUnknown_AddRef(iface);
39         *ppobj = This;
40         return D3D_OK;
41     }
42     return E_NOINTERFACE;
43 }
44
45 ULONG WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) {
46     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
47     ULONG refCount = InterlockedIncrement(&This->ref);
48
49     TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
50     return refCount;
51 }
52
53 ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
54     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
55     ULONG refCount = InterlockedDecrement(&This->ref);
56
57     TRACE("(%p) : Releasing from %ld\n", This, refCount + 1);
58
59     if (!refCount) {
60         HeapFree(GetProcessHeap(), 0, This);
61     }
62     return refCount;
63 }
64
65 /**********************************************************
66  * IWineD3DStateBlockImpl parts follows
67  **********************************************************/
68 HRESULT WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnknown **pParent) {
69     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
70     IUnknown_AddRef(This->parent);
71     *pParent = This->parent;
72     return D3D_OK;
73 }
74
75 HRESULT WINAPI IWineD3DStateBlockImpl_GetDevice(IWineD3DStateBlock *iface, IWineD3DDevice** ppDevice){
76
77     IWineD3DStateBlockImpl *This   = (IWineD3DStateBlockImpl *)iface;
78
79     *ppDevice = (IWineD3DDevice*)This->wineD3DDevice;
80     IWineD3DDevice_AddRef(*ppDevice);
81     return D3D_OK;
82
83 }
84
85 HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){
86
87     IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
88     IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
89
90     TRACE("(%p) : Updating state block %p ------------------v \n", targetStateBlock, This);
91
92     /* If not recorded, then update can just recapture */
93     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED  */ 0) {
94         IWineD3DStateBlockImpl* tmpBlock;
95         PLIGHTINFOEL *tmp = This->lights;
96
97         IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)This->wineD3DDevice, This->blockType, (IWineD3DStateBlock**) &tmpBlock, NULL/*parent*/);
98
99         /* Note just swap the light chains over so when deleting, the old one goes */
100         memcpy(This, tmpBlock, sizeof(IWineD3DStateBlockImpl));
101         tmpBlock->lights = tmp;
102
103         /* Delete the temporary one (which points to the old light chain though */
104         IWineD3DStateBlock_Release((IWineD3DStateBlock *)tmpBlock);
105         /*IDirect3DDevice_DeleteStateBlock(pDevice, tmpBlock);*/
106
107     } else {
108         unsigned int i, j;
109
110         PLIGHTINFOEL *src;
111
112         /* Recorded => Only update 'changed' values */
113         if (This->set.vertexShader && This->vertexShader != targetStateBlock->vertexShader) {
114             This->vertexShader = targetStateBlock->vertexShader;
115             TRACE("Updating vertex shader to %p\n", targetStateBlock->vertexShader);
116         }
117
118         /* TODO: Vertex Shader Constants */
119
120         /* Lights... For a recorded state block, we just had a chain of actions to perform,
121              so we need to walk that chain and update any actions which differ */
122         src = This->lights;
123         while (src != NULL) {
124             PLIGHTINFOEL *realLight = NULL;
125
126             /* Locate the light in the live lights */
127             realLight = targetStateBlock->lights;
128             while (realLight != NULL && realLight->OriginalIndex != src->OriginalIndex) realLight = realLight->next;
129
130             if (realLight == NULL) {
131                 FIXME("A captured light no longer exists...?\n");
132             } else {
133
134                 /* If 'changed' then its a SetLight command. Rather than comparing to see
135                      if the OriginalParms have changed and then copy them (twice through
136                      memory) just do the copy                                              */
137                 if (src->changed) {
138                     TRACE("Updating lights for light %ld\n", src->OriginalIndex);
139                     memcpy(&src->OriginalParms, &realLight->OriginalParms, sizeof(PLIGHTINFOEL));
140                 }
141
142                 /* If 'enabledchanged' then its a LightEnable command */
143                 if (src->enabledChanged) {
144                     TRACE("Updating lightEnabled for light %ld\n", src->OriginalIndex);
145                     src->lightEnabled = realLight->lightEnabled;
146                 }
147
148             }
149
150             src = src->next;
151         }
152
153
154 #if 0 /*TODO: Pixel shaders*/
155         if (This->set.pixelShader && This->pixelShader != pDeviceImpl->stateBlock->pixelShader) {
156             TRACE("Updating pixel shader to %p\n", pDeviceImpl->stateBlock->pixelShader);
157             This->pixelShader = targetStateBlock->pixelShader;
158         }
159 #endif
160         /* TODO: Pixel Shader Constants */
161
162         /* Others + Render & Texture */
163         for (i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
164             if (This->set.transform[i] && memcmp(&targetStateBlock->transforms[i],
165                                     &This->transforms[i],
166                                     sizeof(D3DMATRIX)) != 0) {
167                 TRACE("Updating transform %d\n", i);
168                 memcpy(&This->transforms[i], &targetStateBlock->transforms[i], sizeof(D3DMATRIX));
169             }
170         }
171
172         if (This->set.indices && ((This->pIndexData != targetStateBlock->pIndexData)
173                         || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
174             TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
175             targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
176             This->pIndexData = targetStateBlock->pIndexData;
177             This->baseVertexIndex = targetStateBlock->baseVertexIndex;
178         }
179
180         if(This->set.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){
181             This->vertexDecl = targetStateBlock->vertexDecl;
182         }
183
184         if(This->set.fvf && This->fvf != targetStateBlock->fvf){
185             This->fvf = targetStateBlock->fvf;
186         }
187
188         if (This->set.material && memcmp(&targetStateBlock->material,
189                                                     &This->material,
190                                                     sizeof(D3DMATERIAL9)) != 0) {
191             TRACE("Updating material\n");
192             memcpy(&This->material, &targetStateBlock->material, sizeof(D3DMATERIAL9));
193         }
194
195         if (This->set.viewport && memcmp(&targetStateBlock->viewport,
196                                                     &This->viewport,
197                                                     sizeof(D3DVIEWPORT9)) != 0) {
198             TRACE("Updating viewport\n");
199             memcpy(&This->viewport, &targetStateBlock->viewport, sizeof(D3DVIEWPORT9));
200         }
201
202         for (i = 0; i < MAX_STREAMS; i++) {
203             if (This->set.streamSource[i] &&
204                             ((This->streamStride[i] != targetStateBlock->streamStride[i]) ||
205                             (This->streamSource[i] != targetStateBlock->streamSource[i]))) {
206                 TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i],
207                                                                             targetStateBlock->streamStride[i]);
208                 This->streamStride[i] = targetStateBlock->streamStride[i];
209                 This->streamSource[i] = targetStateBlock->streamSource[i];
210             }
211
212             if (This->set.streamFreq[i] &&
213             (This->streamFreq[i] != targetStateBlock->streamFreq[i]
214             || This->streamFlags[i] != targetStateBlock->streamFlags[i])){
215                     TRACE("Updating stream frequency %d to %d flags to %d\n", i ,  targetStateBlock->streamFreq[i] ,
216                                                                                    targetStateBlock->streamFlags[i]);
217                     This->streamFreq[i]  =  targetStateBlock->streamFreq[i];
218                     This->streamFlags[i] =  targetStateBlock->streamFlags[i];
219             }
220         }
221
222         for (i = 0; i < GL_LIMITS(clipplanes); i++) {
223             if (This->set.clipplane[i] && memcmp(&targetStateBlock->clipplane[i],
224                                                         &This->clipplane[i],
225                                                         sizeof(This->clipplane)) != 0) {
226
227                 TRACE("Updating clipplane %d\n", i);
228                 memcpy(&This->clipplane[i], &targetStateBlock->clipplane[i],
229                                         sizeof(This->clipplane));
230             }
231         }
232
233         /* Render */
234         for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
235
236             if (This->set.renderState[i] && (This->renderState[i] != targetStateBlock->renderState[i])) {
237                 TRACE("Updating renderState %d to %ld\n", i, targetStateBlock->renderState[i]);
238                 This->renderState[i] = targetStateBlock->renderState[i];
239             }
240         }
241
242         /* FIXME: textures are upto MAX_SAMPLERS for d3d9? */
243         /* Texture */
244         for (j = 0; j < GL_LIMITS(textures); j++) {
245             for (i = 1; i <= HIGHEST_TEXTURE_STATE ; i++) {
246
247                 if (This->set.textureState[j][i] && (This->textureState[j][i] !=
248                                                                     targetStateBlock->textureState[j][i])) {
249                     TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, targetStateBlock->textureState[j][i],
250                     This->textureState[j][i]);
251                     This->textureState[j][i] =  targetStateBlock->textureState[j][i];
252                     This->renderState[i] = targetStateBlock->renderState[i];
253                 }
254
255             }
256
257             if ((This->set.textures[j] && (This->textures[j] != targetStateBlock->textures[j]))) {
258                 TRACE("Updating texture %d to %p (was %p)\n", j, targetStateBlock->textures[j],  This->textures[j]);
259                 This->textures[j] = targetStateBlock->textures[j];
260             }
261
262         }
263
264         /* Samplers */
265         for (j = 0 ; j < GL_LIMITS(samplers); j++){
266             for (i = 1; i <= HIGHEST_SAMPLER_STATE ; i++){ /* States are 1 based */
267                 if (This->set.samplerState[j][i] && (This->samplerState[j][i] !=
268                                                         targetStateBlock->samplerState[j][i])) {
269                     TRACE("Updating sampler state %d,%d to %ld (was %ld)\n",
270                     j, i, targetStateBlock->samplerState[j][i],
271                     This->samplerState[j][i]);
272                     This->samplerState[j][i] = targetStateBlock->samplerState[j][i];
273                 }
274             }
275         }
276     }
277
278     TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This);
279
280     return D3D_OK;
281 }
282
283 HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface){
284     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
285     IWineD3DDevice*        pDevice     = (IWineD3DDevice*)This->wineD3DDevice;
286
287 /*Copy thing over to updateBlock is isRecording otherwise StateBlock,
288 should really perform a delta so that only the changes get updated*/
289
290
291     UINT i;
292     UINT j;
293
294     TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
295
296     /* FIXME: Only apply applicable states not all states */
297
298     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */This->blockType == D3DSBT_ALL || This->blockType == D3DSBT_VERTEXSTATE) {
299
300
301         PLIGHTINFOEL *toDo = This->lights;
302         while (toDo != NULL) {
303             if (toDo->changed)
304                   IWineD3DDevice_SetLight(pDevice, toDo->OriginalIndex, &toDo->OriginalParms);
305             if (toDo->enabledChanged)
306                   IWineD3DDevice_SetLightEnable(pDevice, toDo->OriginalIndex, toDo->lightEnabled);
307             toDo = toDo->next;
308         }
309
310 #if 0 /*TODO: VertexShaders*/
311         if (This->set.vertexShader && This->changed.vertexShader)
312             IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
313         /* TODO: Vertex Shader Constants */
314 #endif
315     }
316
317 #if 0 /*TODO: Pixel Shaders*/
318     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == D3DSBT_ALL || This->blockType == D3DSBT_PIXELSTATE) {
319
320         if (This->set.pixelShader && This->changed.pixelShader)
321             IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
322
323         /* TODO: Pixel Shader Constants */
324     }
325 #endif
326
327     if (This->set.fvf && This->changed.fvf) {
328         IWineD3DDevice_SetFVF(pDevice, This->fvf);
329     }
330
331     if (This->set.vertexDecl && This->changed.vertexDecl) {
332         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
333     }
334
335     /* Others + Render & Texture */
336     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == D3DSBT_ALL) {
337         for (i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
338             if (This->set.transform[i] && This->changed.transform[i])
339                 IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
340         }
341
342         if (This->set.indices && This->changed.indices)
343             IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->baseVertexIndex);
344
345         if (This->set.material && This->changed.material )
346             IWineD3DDevice_SetMaterial(pDevice, &This->material);
347
348         if (This->set.viewport && This->changed.viewport)
349             IWineD3DDevice_SetViewport(pDevice, &This->viewport);
350
351         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
352         for (i=0; i<MAX_STREAMS; i++) {
353             if (This->set.streamSource[i] && This->changed.streamSource[i])
354                 IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
355
356             if (This->set.streamFreq[i] && This->changed.streamFreq[i])
357                 IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
358         }
359
360         for (i = 0; i < GL_LIMITS(clipplanes); i++) {
361             if (This->set.clipplane[i] && This->changed.clipplane[i]) {
362                 float clip[4];
363
364                 clip[0] = This->clipplane[i][0];
365                 clip[1] = This->clipplane[i][1];
366                 clip[2] = This->clipplane[i][2];
367                 clip[3] = This->clipplane[i][3];
368                 IWineD3DDevice_SetClipPlane(pDevice, i, clip);
369             }
370         }
371
372         /* Render */
373         for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
374             if (This->set.renderState[i] && This->changed.renderState[i])
375                 IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
376         }
377
378         /* FIXME: Texture are set against samplers... not just TextureStages */
379         /* Texture */
380         for (j = 0; j < GL_LIMITS(textures); j++) { /* Set The texture first, just incase it resets the states? */
381             if (This->set.textures[j] && This->changed.textures[j]) {
382                 IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
383             }
384             for (i = 1; i <= HIGHEST_TEXTURE_STATE; i++) {
385                 if (This->set.textureState[j][i] && This->changed.textureState[j][i]) {
386                     IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
387                 }
388             }
389         }
390
391         /* Samplers */
392         for (j = 0 ; j < GL_LIMITS(samplers); j++){
393             for (i = 1; i <= HIGHEST_SAMPLER_STATE; i++){
394                  if (This->set.samplerState[j][i] && This->changed.samplerState[j][i] && This->samplerState[j][i] != 0) {
395                         IWineD3DDevice_SetSamplerState(pDevice, j, i, This->samplerState[j][i]);
396                  }
397             }
398
399         }
400
401     } else if (This->blockType == D3DSBT_PIXELSTATE) {
402
403         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
404             if (This->set.renderState[SavedPixelStates_R[i]] && This->changed.renderState[SavedPixelStates_R[i]])
405                 IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]);
406
407         }
408
409         for (j = 0; j < GL_LIMITS(textures); i++) {
410             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
411                 if (This->set.textureState[j][SavedPixelStates_T[i]] &&
412                     This->changed.textureState[j][SavedPixelStates_T[i]])
413                     IWineD3DDevice_SetTextureStageState(pDevice, j, SavedPixelStates_T[i], This->textureState[j][SavedPixelStates_T[i]]);
414             }
415         }
416
417     } else if (This->blockType == D3DSBT_VERTEXSTATE) {
418
419         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
420             if ( This->set.renderState[SavedVertexStates_R[i]] && This->changed.renderState[SavedVertexStates_R[i]])
421                 IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]);
422         }
423
424         for (j = 0; j < GL_LIMITS(textures); i++) {
425             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
426                 if ( This->set.textureState[j][SavedVertexStates_T[i]] &&
427                     This->changed.textureState[j][SavedVertexStates_T[i]])
428                     IWineD3DDevice_SetTextureStageState(pDevice, j, SavedVertexStates_T[i], This->textureState[j][SavedVertexStates_T[i]]);
429             }
430         }
431
432
433     } else {
434         FIXME("Unrecognized state block type %d\n", This->blockType);
435     }
436     memcpy(&((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed, sizeof(((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed));
437     TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
438
439     return D3D_OK;
440 }
441
442 HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
443     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
444     IWineD3DDevice         *device = (IWineD3DDevice *)This->wineD3DDevice;
445     IWineD3DDeviceImpl     *ThisDevice = (IWineD3DDeviceImpl *)device;
446     union {
447         D3DLINEPATTERN lp;
448         DWORD d;
449     } lp;
450     union {
451         float f;
452         DWORD d;
453     } tmpfloat;
454     unsigned int i;
455
456     /* Note this may have a large overhead but it should only be executed
457        once, in order to initialize the complete state of the device and 
458        all opengl equivalents                                            */
459     TRACE("-----------------------> Setting up device defaults...\n");
460     This->blockType = D3DSBT_ALL;
461
462     /* FIXME: Set some of the defaults for lights, transforms etc */
463     memcpy(&This->transforms[D3DTS_PROJECTION], &identity, sizeof(identity));
464     memcpy(&This->transforms[D3DTS_VIEW], &identity, sizeof(identity));
465     for (i = 0; i < 256; ++i) {
466       memcpy(&This->transforms[D3DTS_WORLDMATRIX(i)], &identity, sizeof(identity));
467     }
468
469     TRACE("Render states\n");
470     /* Render states: */
471     if (ThisDevice->depthStencilBuffer != NULL) {
472        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       D3DZB_TRUE);
473     } else {
474        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       D3DZB_FALSE);
475     }
476     IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE,         D3DFILL_SOLID);
477     IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE,        D3DSHADE_GOURAUD);
478     lp.lp.wRepeatFactor = 0;
479     lp.lp.wLinePattern  = 0;
480     IWineD3DDevice_SetRenderState(device, WINED3DRS_LINEPATTERN,      lp.d);
481     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZWRITEENABLE,     TRUE);
482     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHATESTENABLE,  FALSE);
483     IWineD3DDevice_SetRenderState(device, WINED3DRS_LASTPIXEL,        TRUE);
484     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLEND,         D3DBLEND_ONE);
485     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLEND,        D3DBLEND_ZERO);
486     IWineD3DDevice_SetRenderState(device, WINED3DRS_CULLMODE,         D3DCULL_CCW);
487     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZFUNC,            D3DCMP_LESSEQUAL);
488     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAFUNC,        D3DCMP_ALWAYS);
489     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAREF,         0xff); /*??*/
490     IWineD3DDevice_SetRenderState(device, WINED3DRS_DITHERENABLE,     FALSE);
491     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHABLENDENABLE, FALSE);
492     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGENABLE,        FALSE);
493     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARENABLE,   FALSE);
494     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZVISIBLE,         0);
495     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGCOLOR,         0);
496     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGTABLEMODE,     D3DFOG_NONE);
497     tmpfloat.f = 0.0f;
498     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGSTART,         tmpfloat.d);
499     tmpfloat.f = 1.0f;
500     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGEND,           tmpfloat.d);
501     tmpfloat.f = 1.0f;
502     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGDENSITY,       tmpfloat.d);
503     IWineD3DDevice_SetRenderState(device, WINED3DRS_EDGEANTIALIAS,    FALSE);
504     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZBIAS,            0);
505     IWineD3DDevice_SetRenderState(device, WINED3DRS_RANGEFOGENABLE,   FALSE);
506     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILENABLE,    FALSE);
507     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP);
508     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP);
509     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILPASS,      D3DSTENCILOP_KEEP);
510
511     /* Setting stencil func also uses values for stencil ref/mask, so manually set defaults
512      * so only a single call performed (and ensure defaults initialized before making that call)
513      *
514      * IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILREF, 0);
515      * IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILMASK, 0xFFFFFFFF);
516      */
517     This->renderState[WINED3DRS_STENCILREF] = 0;
518     This->renderState[WINED3DRS_STENCILMASK] = 0xFFFFFFFF;
519     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFUNC,      D3DCMP_ALWAYS);
520     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
521     IWineD3DDevice_SetRenderState(device, WINED3DRS_TEXTUREFACTOR,    0xFFFFFFFF);
522     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP0, 0);
523     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP1, 0);
524     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP2, 0);
525     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP3, 0);
526     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP4, 0);
527     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP5, 0);
528     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP6, 0);
529     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP7, 0);
530     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPING,                 TRUE);
531     IWineD3DDevice_SetRenderState(device, WINED3DRS_LIGHTING,                 TRUE);
532     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENT,                  0);
533     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGVERTEXMODE,            D3DFOG_NONE);
534     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORVERTEX,              TRUE);
535     IWineD3DDevice_SetRenderState(device, WINED3DRS_LOCALVIEWER,              TRUE);
536     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALIZENORMALS,         FALSE);
537     IWineD3DDevice_SetRenderState(device, WINED3DRS_DIFFUSEMATERIALSOURCE,    D3DMCS_COLOR1);
538     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARMATERIALSOURCE,   D3DMCS_COLOR2);
539     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENTMATERIALSOURCE,    D3DMCS_COLOR2);
540     IWineD3DDevice_SetRenderState(device, WINED3DRS_EMISSIVEMATERIALSOURCE,   D3DMCS_MATERIAL);
541     IWineD3DDevice_SetRenderState(device, WINED3DRS_VERTEXBLEND,              D3DVBF_DISABLE);
542     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPLANEENABLE,          0);
543     IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
544     tmpfloat.f = 1.0f;
545     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
546     tmpfloat.f = 0.0f;
547     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
548     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
549     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
550     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_A,             TRUE);
551     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_B,             TRUE);
552     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_C,             TRUE);
553     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEANTIALIAS,     TRUE);
554     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEMASK,          0xFFFFFFFF);
555     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHEDGESTYLE,           D3DPATCHEDGE_DISCRETE);
556     tmpfloat.f = 1.0f;
557     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
558     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        D3DDMT_DISABLE);
559     tmpfloat.f = 64.0f;
560     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
561     IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
562     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
563     tmpfloat.f = 0.0f;
564     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWEENFACTOR,              tmpfloat.d);
565     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOP,                  D3DBLENDOP_ADD);
566     IWineD3DDevice_SetRenderState(device, WINED3DRS_POSITIONDEGREE,           WINED3DDEGREE_CUBIC);
567     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALDEGREE,             WINED3DDEGREE_LINEAR);
568     /* states new in d3d9 */
569     IWineD3DDevice_SetRenderState(device, WINED3DRS_SCISSORTESTENABLE,        FALSE);
570     IWineD3DDevice_SetRenderState(device, WINED3DRS_SLOPESCALEDEPTHBIAS,      0);
571     tmpfloat.f = 1.0f;
572     IWineD3DDevice_SetRenderState(device, WINED3DRS_MINTESSELLATIONLEVEL,     tmpfloat.d);
573     IWineD3DDevice_SetRenderState(device, WINED3DRS_MAXTESSELLATIONLEVEL,     tmpfloat.d);
574     IWineD3DDevice_SetRenderState(device, WINED3DRS_ANTIALIASEDLINEENABLE,    FALSE);
575     tmpfloat.f = 0.0f;
576     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_X,           tmpfloat.d);
577     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Y,           tmpfloat.d);
578     tmpfloat.f = 1.0f;
579     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Z,           tmpfloat.d);
580     tmpfloat.f = 0.0f;
581     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_W,           tmpfloat.d);
582     IWineD3DDevice_SetRenderState(device, WINED3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
583     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWOSIDEDSTENCILMODE,      FALSE);
584     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFAIL,          D3DSTENCILOP_KEEP);
585     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILZFAIL,         D3DSTENCILOP_KEEP);
586     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILPASS,          D3DSTENCILOP_KEEP);
587     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFUNC,          D3DCMP_ALWAYS);
588     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE1,        0x0000000F);
589     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE2,        0x0000000F);
590     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE3,        0x0000000F);
591     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDFACTOR,              0xFFFFFFFF);
592     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRGBWRITEENABLE,          0);
593     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEPTHBIAS,                0);
594     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP8,  0);
595     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP9,  0);
596     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP10, 0);
597     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP11, 0);
598     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP12, 0);
599     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP13, 0);
600     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP14, 0);
601     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP15, 0);
602     IWineD3DDevice_SetRenderState(device, WINED3DRS_SEPARATEALPHABLENDENABLE, FALSE);
603     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLENDALPHA,            D3DBLEND_ONE);
604     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLENDALPHA,           D3DBLEND_ZERO);
605     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOPALPHA,             D3DBLENDOP_ADD);
606
607     /* clipping status */
608     This->clip_status.ClipUnion = 0;
609     This->clip_status.ClipIntersection = 0xFFFFFFFF;
610
611     /* Texture Stage States - Put directly into state block, we will call function below */
612     for (i = 0; i < GL_LIMITS(textures); i++) {
613         TRACE("Setting up default texture states for texture Stage %d\n", i);
614         memcpy(&This->transforms[D3DTS_TEXTURE0 + i], &identity, sizeof(identity));
615         This->textureState[i][D3DTSS_COLOROP               ] = (i==0)? D3DTOP_MODULATE :  D3DTOP_DISABLE;
616         This->textureState[i][D3DTSS_COLORARG1             ] = D3DTA_TEXTURE;
617         This->textureState[i][D3DTSS_COLORARG2             ] = D3DTA_CURRENT;
618         This->textureState[i][D3DTSS_ALPHAOP               ] = (i==0)? D3DTOP_SELECTARG1 :  D3DTOP_DISABLE;
619         This->textureState[i][D3DTSS_ALPHAARG1             ] = D3DTA_TEXTURE;
620         This->textureState[i][D3DTSS_ALPHAARG2             ] = D3DTA_CURRENT;
621         This->textureState[i][D3DTSS_BUMPENVMAT00          ] = (DWORD) 0.0;
622         This->textureState[i][D3DTSS_BUMPENVMAT01          ] = (DWORD) 0.0;
623         This->textureState[i][D3DTSS_BUMPENVMAT10          ] = (DWORD) 0.0;
624         This->textureState[i][D3DTSS_BUMPENVMAT11          ] = (DWORD) 0.0;
625         This->textureState[i][D3DTSS_TEXCOORDINDEX         ] = i;
626         This->textureState[i][D3DTSS_BUMPENVLSCALE         ] = (DWORD) 0.0;
627         This->textureState[i][D3DTSS_BUMPENVLOFFSET        ] = (DWORD) 0.0;
628         This->textureState[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
629         This->textureState[i][D3DTSS_ADDRESSW              ] = D3DTADDRESS_WRAP;
630         This->textureState[i][D3DTSS_COLORARG0             ] = D3DTA_CURRENT;
631         This->textureState[i][D3DTSS_ALPHAARG0             ] = D3DTA_CURRENT;
632         This->textureState[i][D3DTSS_RESULTARG             ] = D3DTA_CURRENT;
633     }
634
635         /* Sampler states*/
636     for (i = 0 ; i <  MAX_SAMPLERS; i++) {
637         TRACE("Setting up default samplers states for sampler %d\n", i);        
638         This->samplerState[i][WINED3DSAMP_ADDRESSU         ] = D3DTADDRESS_WRAP;
639         This->samplerState[i][WINED3DSAMP_ADDRESSV         ] = D3DTADDRESS_WRAP;
640         This->samplerState[i][WINED3DSAMP_ADDRESSW         ] = D3DTADDRESS_WRAP;
641         This->samplerState[i][WINED3DSAMP_BORDERCOLOR      ] = 0x00;
642         This->samplerState[i][WINED3DSAMP_MAGFILTER        ] = D3DTEXF_POINT;
643         This->samplerState[i][WINED3DSAMP_MINFILTER        ] = D3DTEXF_POINT;
644         This->samplerState[i][WINED3DSAMP_MIPFILTER        ] = D3DTEXF_NONE;
645         This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS    ] = 0;
646         This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL      ] = 0;
647         This->samplerState[i][WINED3DSAMP_MAXANISOTROPY    ] = 1;
648         This->samplerState[i][WINED3DSAMP_SRGBTEXTURE      ] = 0; /* TODO: Gamma correction value*/
649         This->samplerState[i][WINED3DSAMP_ELEMENTINDEX     ] = 0; /* TODO: Indicates which element of a  multielement texture to use */
650         This->samplerState[i][WINED3DSAMP_DMAPOFFSET       ] = 256; /* TODO: Vertex offset in the presampled displacement map */
651     }
652
653     /* Under DirectX you can have texture stage operations even if no texture is
654        bound, whereas opengl will only do texture operations when a valid texture is
655        bound. We emulate this by creating dummy textures and binding them to each
656        texture stage, but disable all stages by default. Hence if a stage is enabled
657        then the default texture will kick in until replaced by a SetTexture call     */
658
659     ENTER_GL();
660
661     for (i = 0; i < GL_LIMITS(textures); i++) {
662         GLubyte white = 255;
663
664         /* Note this avoids calling settexture, so pretend it has been called */
665         This->set.textures[i]     = TRUE;
666         This->changed.textures[i] = TRUE;
667         This->textures[i]         = NULL;
668
669         /* Make appropriate texture active */
670         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
671             GLACTIVETEXTURE(i);
672         } else if (i > 0) {
673             FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
674         }
675
676         /* Generate an opengl texture name */
677         glGenTextures(1, &ThisDevice->dummyTextureName[i]);
678         checkGLcall("glGenTextures");
679         TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
680
681         /* Generate a dummy 1d texture */
682         This->textureDimensions[i] = GL_TEXTURE_1D;
683         glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
684         checkGLcall("glBindTexture");
685
686         glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
687         checkGLcall("glTexImage1D");
688
689         /* Reapply all the texture state information to this texture */
690         IWineD3DDevice_SetupTextureStates(device, i, REAPPLY_ALL);
691     }
692
693     LEAVE_GL();
694
695     /* Defaulting palettes - Note these are device wide but reinitialized here for convenience*/
696     for (i = 0; i < MAX_PALETTES; ++i) {
697       int j;
698       for (j = 0; j < 256; ++j) {
699         This->wineD3DDevice->palettes[i][j].peRed   = 0xFF;
700         This->wineD3DDevice->palettes[i][j].peGreen = 0xFF;
701         This->wineD3DDevice->palettes[i][j].peBlue  = 0xFF;
702         This->wineD3DDevice->palettes[i][j].peFlags = 0xFF;
703       }
704     }
705     This->wineD3DDevice->currentPalette = 0;
706
707     TRACE("-----------------------> Device defaults now set up...\n");
708     return D3D_OK;
709 }
710
711 /**********************************************************
712  * IWineD3DStateBlock VTbl follows
713  **********************************************************/
714
715 const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
716 {
717     IWineD3DStateBlockImpl_QueryInterface,
718     IWineD3DStateBlockImpl_AddRef,
719     IWineD3DStateBlockImpl_Release,
720     IWineD3DStateBlockImpl_GetParent,
721     IWineD3DStateBlockImpl_GetDevice,
722     IWineD3DStateBlockImpl_Capture,
723     IWineD3DStateBlockImpl_Apply,
724     IWineD3DStateBlockImpl_InitStartupStateBlock
725 };