wined3d: Add a few more WINED3DFMT formats to be recognized.
[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_IWineD3DBase)
38         || IsEqualGUID(riid, &IID_IWineD3DStateBlock)){
39         IUnknown_AddRef(iface);
40         *ppobj = This;
41         return D3D_OK;
42     }
43     return E_NOINTERFACE;
44 }
45
46 ULONG WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) {
47     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
48     ULONG refCount = InterlockedIncrement(&This->ref);
49
50     TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
51     return refCount;
52 }
53
54 ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
55     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
56     ULONG refCount = InterlockedDecrement(&This->ref);
57
58     TRACE("(%p) : Releasing from %ld\n", This, refCount + 1);
59
60     if (!refCount) {
61         /* type 0 represents the primary stateblock, so free all the resources */
62         if (This->blockType == WINED3DSBT_INIT) {
63             int counter;
64             FIXME("Releasing primary stateblock\n");
65             /* Free any streams still bound */
66             for (counter = 0 ; counter < MAX_STREAMS ; counter++) {
67                 if (This->streamSource[counter] != NULL) {
68                     IWineD3DVertexBuffer_Release(This->streamSource[counter]);
69                     This->streamSource[counter] = NULL;
70                 }
71             }
72
73             /* free any index data */
74             if (This->pIndexData) {
75                 IWineD3DIndexBuffer_Release(This->pIndexData);
76                 This->pIndexData = NULL;
77             }
78
79             if (NULL != This->pixelShader) {
80                 IWineD3DPixelShader_Release(This->pixelShader);
81             }
82
83             if (NULL != This->vertexShader) {
84                 IWineD3DVertexShader_Release(This->vertexShader);
85             }
86
87             if (NULL != This->vertexDecl) {
88                 IWineD3DVertexDeclaration_Release(This->vertexDecl);
89             }
90
91             /* NOTE: according to MSDN: The applicaion is responsible for making sure the texture references are cleared down */
92             for (counter = 0; counter < GL_LIMITS(textures); counter++) {
93                 if (This->textures[counter]) {
94                     /* release our 'internal' hold on the texture */
95                     if(0 != IWineD3DBaseTexture_Release(This->textures[counter])) {
96                         TRACE("Texture still referenced by stateblock, applications has leaked Stage = %u Texture = %p\n", counter, This->textures[counter]);
97                     }
98                 }
99             }
100
101         }
102         HeapFree(GetProcessHeap(), 0, This);
103     }
104     return refCount;
105 }
106
107 /**********************************************************
108  * IWineD3DStateBlockImpl parts follows
109  **********************************************************/
110 HRESULT WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnknown **pParent) {
111     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
112     IUnknown_AddRef(This->parent);
113     *pParent = This->parent;
114     return D3D_OK;
115 }
116
117 HRESULT WINAPI IWineD3DStateBlockImpl_GetDevice(IWineD3DStateBlock *iface, IWineD3DDevice** ppDevice){
118
119     IWineD3DStateBlockImpl *This   = (IWineD3DStateBlockImpl *)iface;
120
121     *ppDevice = (IWineD3DDevice*)This->wineD3DDevice;
122     IWineD3DDevice_AddRef(*ppDevice);
123     return D3D_OK;
124
125 }
126
127 HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){
128
129     IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
130     IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
131
132     TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This);
133
134     /* If not recorded, then update can just recapture */
135     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED  */ 0) {
136         IWineD3DStateBlockImpl* tmpBlock;
137         PLIGHTINFOEL *tmp = This->lights;
138
139         IWineD3DDevice_CreateStateBlock((IWineD3DDevice *)This->wineD3DDevice, This->blockType, (IWineD3DStateBlock**) &tmpBlock, NULL/*parent*/);
140
141         /* Note just swap the light chains over so when deleting, the old one goes */
142         memcpy(This, tmpBlock, sizeof(IWineD3DStateBlockImpl));
143         tmpBlock->lights = tmp;
144
145         /* Delete the temporary one (which points to the old light chain though */
146         IWineD3DStateBlock_Release((IWineD3DStateBlock *)tmpBlock);
147         /*IDirect3DDevice_DeleteStateBlock(pDevice, tmpBlock);*/
148
149     } else {
150         unsigned int i, j;
151
152         PLIGHTINFOEL *src;
153
154         /* Recorded => Only update 'changed' values */
155         if (This->vertexShader != targetStateBlock->vertexShader) {
156             TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader);
157
158             if (targetStateBlock->vertexShader) {
159                 IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
160             }
161             if (This->vertexShader) {
162                 IWineD3DVertexShader_Release(This->vertexShader);
163             }
164
165             This->vertexShader = targetStateBlock->vertexShader;
166         }
167
168         /* Vertex Shader Constants */
169         for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) {
170             if (This->set.vertexShaderConstants[i]) {
171                 TRACE("Setting %p from %p %d to %f\n", This, targetStateBlock, i,  targetStateBlock->vertexShaderConstantF[i * 4 + 1]);
172                 This->vertexShaderConstantB[i] = targetStateBlock->vertexShaderConstantB[i];
173                 This->vertexShaderConstantF[i * 4]      = targetStateBlock->vertexShaderConstantF[i * 4];
174                 This->vertexShaderConstantF[i * 4 + 1]  = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
175                 This->vertexShaderConstantF[i * 4 + 2]  = targetStateBlock->vertexShaderConstantF[i * 4 + 2];
176                 This->vertexShaderConstantF[i * 4 + 3]  = targetStateBlock->vertexShaderConstantF[i * 4 + 3];
177                 This->vertexShaderConstantI[i * 4]      = targetStateBlock->vertexShaderConstantI[i * 4];
178                 This->vertexShaderConstantI[i * 4 + 1]  = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
179                 This->vertexShaderConstantI[i * 4 + 2]  = targetStateBlock->vertexShaderConstantI[i * 4 + 2];
180                 This->vertexShaderConstantI[i * 4 + 3]  = targetStateBlock->vertexShaderConstantI[i * 4 + 3];
181                 This->vertexShaderConstantT[i]          = targetStateBlock->vertexShaderConstantT[i];
182             }
183         }
184
185         /* Lights... For a recorded state block, we just had a chain of actions to perform,
186              so we need to walk that chain and update any actions which differ */
187         src = This->lights;
188         while (src != NULL) {
189             PLIGHTINFOEL *realLight = NULL;
190
191             /* Locate the light in the live lights */
192             realLight = targetStateBlock->lights;
193             while (realLight != NULL && realLight->OriginalIndex != src->OriginalIndex) realLight = realLight->next;
194
195             if (realLight == NULL) {
196                 FIXME("A captured light no longer exists...?\n");
197             } else {
198
199                 /* If 'changed' then its a SetLight command. Rather than comparing to see
200                      if the OriginalParms have changed and then copy them (twice through
201                      memory) just do the copy                                              */
202                 if (src->changed) {
203                     TRACE("Updating lights for light %ld\n", src->OriginalIndex);
204                     memcpy(&src->OriginalParms, &realLight->OriginalParms, sizeof(PLIGHTINFOEL));
205                 }
206
207                 /* If 'enabledchanged' then its a LightEnable command */
208                 if (src->enabledChanged) {
209                     TRACE("Updating lightEnabled for light %ld\n", src->OriginalIndex);
210                     src->lightEnabled = realLight->lightEnabled;
211                 }
212
213             }
214
215             src = src->next;
216         }
217
218         /* Recorded => Only update 'changed' values */
219         if (This->pixelShader != targetStateBlock->pixelShader) {
220             TRACE("Updating pixel shader from %p to %p\n", This->pixelShader, targetStateBlock->pixelShader);
221
222             if (targetStateBlock->pixelShader) {
223                 IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
224             }
225             if (This->pixelShader) {
226                 IWineD3DPixelShader_Release(This->pixelShader);
227             }
228
229             This->pixelShader = targetStateBlock->pixelShader;
230         }
231
232         /* Pixel Shader Constants */
233         for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) {
234             if (This->set.pixelShaderConstants[i]) {
235                 TRACE("Setting %p from %p %d to %f\n", This, targetStateBlock, i,  targetStateBlock->pixelShaderConstantF[i * 4 + 1]);
236                 This->pixelShaderConstantB[i] = targetStateBlock->pixelShaderConstantB[i];
237                 This->pixelShaderConstantF[i * 4]      = targetStateBlock->pixelShaderConstantF[i * 4];
238                 This->pixelShaderConstantF[i * 4 + 1]  = targetStateBlock->pixelShaderConstantF[i * 4 + 1];
239                 This->pixelShaderConstantF[i * 4 + 2]  = targetStateBlock->pixelShaderConstantF[i * 4 + 2];
240                 This->pixelShaderConstantF[i * 4 + 3]  = targetStateBlock->pixelShaderConstantF[i * 4 + 3];
241                 This->pixelShaderConstantI[i * 4]      = targetStateBlock->pixelShaderConstantI[i * 4];
242                 This->pixelShaderConstantI[i * 4 + 1]  = targetStateBlock->pixelShaderConstantI[i * 4 + 1];
243                 This->pixelShaderConstantI[i * 4 + 2]  = targetStateBlock->pixelShaderConstantI[i * 4 + 2];
244                 This->pixelShaderConstantI[i * 4 + 3]  = targetStateBlock->pixelShaderConstantI[i * 4 + 3];
245                 This->pixelShaderConstantT[i]          = targetStateBlock->pixelShaderConstantT[i];
246             }
247         }
248
249         /* Others + Render & Texture */
250         for (i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
251             if (This->set.transform[i] && memcmp(&targetStateBlock->transforms[i],
252                                     &This->transforms[i],
253                                     sizeof(D3DMATRIX)) != 0) {
254                 TRACE("Updating transform %d\n", i);
255                 memcpy(&This->transforms[i], &targetStateBlock->transforms[i], sizeof(D3DMATRIX));
256             }
257         }
258
259         if (This->set.indices && ((This->pIndexData != targetStateBlock->pIndexData)
260                         || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
261             TRACE("Updating pindexData to %p, baseVertexIndex to %d\n",
262             targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
263             This->pIndexData = targetStateBlock->pIndexData;
264             This->baseVertexIndex = targetStateBlock->baseVertexIndex;
265         }
266
267         if(This->set.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){
268             TRACE("Updating vertex declaration from %p to %p\n", This->vertexDecl, targetStateBlock->vertexDecl);
269
270             if (targetStateBlock->vertexDecl) {
271                 IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl);
272             }
273             if (This->vertexDecl) {
274                 IWineD3DVertexDeclaration_Release(This->vertexDecl);
275             }
276
277             This->vertexDecl = targetStateBlock->vertexDecl;
278         }
279
280         if(This->set.fvf && This->fvf != targetStateBlock->fvf){
281             This->fvf = targetStateBlock->fvf;
282         }
283
284         if (This->set.material && memcmp(&targetStateBlock->material,
285                                                     &This->material,
286                                                     sizeof(D3DMATERIAL9)) != 0) {
287             TRACE("Updating material\n");
288             memcpy(&This->material, &targetStateBlock->material, sizeof(D3DMATERIAL9));
289         }
290
291         if (This->set.viewport && memcmp(&targetStateBlock->viewport,
292                                                     &This->viewport,
293                                                     sizeof(D3DVIEWPORT9)) != 0) {
294             TRACE("Updating viewport\n");
295             memcpy(&This->viewport, &targetStateBlock->viewport, sizeof(D3DVIEWPORT9));
296         }
297
298         for (i = 0; i < MAX_STREAMS; i++) {
299             if (This->set.streamSource[i] &&
300                             ((This->streamStride[i] != targetStateBlock->streamStride[i]) ||
301                             (This->streamSource[i] != targetStateBlock->streamSource[i]))) {
302                 TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i],
303                                                                             targetStateBlock->streamStride[i]);
304                 This->streamStride[i] = targetStateBlock->streamStride[i];
305                 This->streamSource[i] = targetStateBlock->streamSource[i];
306             }
307
308             if (This->set.streamFreq[i] &&
309             (This->streamFreq[i] != targetStateBlock->streamFreq[i]
310             || This->streamFlags[i] != targetStateBlock->streamFlags[i])){
311                     TRACE("Updating stream frequency %d to %d flags to %d\n", i ,  targetStateBlock->streamFreq[i] ,
312                                                                                    targetStateBlock->streamFlags[i]);
313                     This->streamFreq[i]  =  targetStateBlock->streamFreq[i];
314                     This->streamFlags[i] =  targetStateBlock->streamFlags[i];
315             }
316         }
317
318         for (i = 0; i < GL_LIMITS(clipplanes); i++) {
319             if (This->set.clipplane[i] && memcmp(&targetStateBlock->clipplane[i],
320                                                         &This->clipplane[i],
321                                                         sizeof(This->clipplane)) != 0) {
322
323                 TRACE("Updating clipplane %d\n", i);
324                 memcpy(&This->clipplane[i], &targetStateBlock->clipplane[i],
325                                         sizeof(This->clipplane));
326             }
327         }
328
329         /* Render */
330         for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
331
332             if (This->set.renderState[i] && (This->renderState[i] != targetStateBlock->renderState[i])) {
333                 TRACE("Updating renderState %d to %ld\n", i, targetStateBlock->renderState[i]);
334                 This->renderState[i] = targetStateBlock->renderState[i];
335             }
336         }
337
338         /* FIXME: textures are up to MAX_SAMPLERS for d3d9? */
339         /* Texture */
340         for (j = 0; j < GL_LIMITS(textures); j++) {
341             /* TODO: move over to using memcpy */
342             for (i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE ; i++) {
343                 if (This->set.textureState[j][i]) {
344                     TRACE("Updating texturestagestate %d,%d to %ld (was %ld)\n", j,i, targetStateBlock->textureState[j][i],
345                     This->textureState[j][i]);
346                     This->textureState[j][i]         =  targetStateBlock->textureState[j][i];
347                 }
348             }
349
350             if (This->set.textures[j]) {
351                 TRACE("Updating texture %d to %p (was %p)\n", j, targetStateBlock->textures[j],  This->textures[j]);
352                 This->textures[j] = targetStateBlock->textures[j];
353             }
354
355         }
356
357         /* Samplers */
358         /* TODO: move over to using memcpy */
359         for (j = 0 ; j < GL_LIMITS(samplers); j++){
360             for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE ; i++){ /* States are 1 based */
361                 if (This->set.samplerState[j][i]) {
362                     TRACE("Updating sampler state %d,%d to %ld (was %ld)\n",
363                     j, i, targetStateBlock->samplerState[j][i],
364                     This->samplerState[j][i]);
365                     This->samplerState[j][i]         = targetStateBlock->samplerState[j][i];
366                 }
367             }
368         }
369     }
370
371     TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This);
372
373     return D3D_OK;
374 }
375
376 HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface){
377     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
378     IWineD3DDevice*        pDevice     = (IWineD3DDevice*)This->wineD3DDevice;
379
380 /*Copy thing over to updateBlock is isRecording otherwise StateBlock,
381 should really perform a delta so that only the changes get updated*/
382
383
384     UINT i;
385     UINT j;
386
387     TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
388
389     /* FIXME: Only apply applicable states not all states */
390
391     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */This->blockType == WINED3DSBT_INIT || This->blockType == WINED3DSBT_ALL || This->blockType == WINED3DSBT_VERTEXSTATE) {
392
393
394         PLIGHTINFOEL *toDo = This->lights;
395         while (toDo != NULL) {
396             if (toDo->changed)
397                   IWineD3DDevice_SetLight(pDevice, toDo->OriginalIndex, &toDo->OriginalParms);
398             if (toDo->enabledChanged)
399                   IWineD3DDevice_SetLightEnable(pDevice, toDo->OriginalIndex, toDo->lightEnabled);
400             toDo = toDo->next;
401         }
402
403         /* Vertex Shader */
404         if (This->set.vertexShader && This->changed.vertexShader) {
405             IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
406         }
407
408         /* Vertex Shader Constants */
409         for (i = 0; i < MAX_VSHADER_CONSTANTS; ++i) {
410             if (This->set.vertexShaderConstants[i] && This->changed.vertexShaderConstants[i]) {
411                 switch (This->vertexShaderConstantT[i]) {
412                 case WINESHADERCNST_FLOAT:
413                     IWineD3DDevice_SetVertexShaderConstantF(pDevice, i, This->vertexShaderConstantF + i * 4, 1);
414                 break;
415                 case WINESHADERCNST_BOOL:
416                     IWineD3DDevice_SetVertexShaderConstantB(pDevice, i, This->vertexShaderConstantB + i, 1);
417                 break;
418                 case WINESHADERCNST_INTEGER:
419                     IWineD3DDevice_SetVertexShaderConstantI(pDevice, i, This->vertexShaderConstantI + i * 4, 1);
420                 break;
421                 case WINESHADERCNST_NONE:
422                     IWineD3DDevice_SetVertexShaderConstantN(pDevice, i, 1);
423                 break;
424                 }
425             }
426         }
427
428     }
429
430     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == D3DSBT_ALL || This->blockType == D3DSBT_PIXELSTATE) {
431
432         /* Pixel Shader */
433         if (This->set.pixelShader && This->changed.pixelShader) {
434             IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
435         }
436
437         /* Pixel Shader Constants */
438         for (i = 0; i < MAX_PSHADER_CONSTANTS; ++i) {
439             if (This->set.pixelShaderConstants[i] && This->changed.pixelShaderConstants[i]) {
440                 switch (This->pixelShaderConstantT[i]) {
441                 case WINESHADERCNST_FLOAT:
442                     IWineD3DDevice_SetPixelShaderConstantF(pDevice, i, This->pixelShaderConstantF + i * 4, 1);
443                 break;
444                 case WINESHADERCNST_BOOL:
445                     IWineD3DDevice_SetPixelShaderConstantB(pDevice, i, This->pixelShaderConstantB + i, 1);
446                 break;
447                 case WINESHADERCNST_INTEGER:
448                     IWineD3DDevice_SetPixelShaderConstantI(pDevice, i, This->pixelShaderConstantI + i * 4, 1);
449                 break;
450                 case WINESHADERCNST_NONE:
451                     IWineD3DDevice_SetPixelShaderConstantN(pDevice, i, 1);
452                 break;
453                 }
454             }
455         }
456     }
457
458     if (This->set.fvf && This->changed.fvf) {
459         IWineD3DDevice_SetFVF(pDevice, This->fvf);
460     }
461
462     if (This->set.vertexDecl && This->changed.vertexDecl) {
463         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
464     }
465
466     /* Others + Render & Texture */
467     if (/*TODO: 'magic' statetype, replace with BOOL This->blockType == D3DSBT_RECORDED || */ This->blockType == WINED3DSBT_ALL || This->blockType == WINED3DSBT_INIT) {
468         for (i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
469             if (This->set.transform[i] && This->changed.transform[i])
470                 IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
471         }
472
473         if (This->set.indices && This->changed.indices)
474             IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->baseVertexIndex);
475
476         if (This->set.material && This->changed.material )
477             IWineD3DDevice_SetMaterial(pDevice, &This->material);
478
479         if (This->set.viewport && This->changed.viewport)
480             IWineD3DDevice_SetViewport(pDevice, &This->viewport);
481
482         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
483         for (i=0; i<MAX_STREAMS; i++) {
484             if (This->set.streamSource[i] && This->changed.streamSource[i])
485                 IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
486
487             if (This->set.streamFreq[i] && This->changed.streamFreq[i])
488                 IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
489         }
490
491         for (i = 0; i < GL_LIMITS(clipplanes); i++) {
492             if (This->set.clipplane[i] && This->changed.clipplane[i]) {
493                 float clip[4];
494
495                 clip[0] = This->clipplane[i][0];
496                 clip[1] = This->clipplane[i][1];
497                 clip[2] = This->clipplane[i][2];
498                 clip[3] = This->clipplane[i][3];
499                 IWineD3DDevice_SetClipPlane(pDevice, i, clip);
500             }
501         }
502
503         /* Render */
504         for (i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
505             if (This->set.renderState[i] && This->changed.renderState[i])
506                 IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
507         }
508
509         /* FIXME: Texture are set against samplers... not just TextureStages */
510         /* Texture */
511         for (j = 0; j < GL_LIMITS(textures); j++) { /* Set The texture first, just in case it resets the states? */
512             if (This->set.textures[j] && This->changed.textures[j]) {
513                 IWineD3DDevice_SetTexture(pDevice, j, This->textures[j]);
514             }
515             /* TODO: move over to memcpy */
516             for (i = 1; i <= WINED3D_HIGHEST_TEXTURE_STATE; i++) {
517                 if (This->set.textureState[j][i] && This->changed.textureState[j][i]) { /* tb_dx9_10 failes without this test */
518                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][i]         = This->textureState[j][i];
519                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->set.textureState[j][i]     = TRUE;
520                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[j][i] = TRUE;
521                 }
522             }
523         }
524
525         /* Samplers */
526         /* TODO: move over to memcpy */
527         for (j = 0 ; j < GL_LIMITS(samplers); j++){
528             for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; i++){
529                 if (This->set.samplerState[j][i] && This->changed.samplerState[j][i]) {
530                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][i]         = This->samplerState[j][i];
531                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->set.samplerState[j][i]     = TRUE;
532                     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[j][i] = TRUE;
533                 }
534             }
535
536         }
537
538     } else if (This->blockType == WINED3DSBT_PIXELSTATE) {
539
540         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
541             if (This->set.renderState[SavedPixelStates_R[i]] && This->changed.renderState[SavedPixelStates_R[i]])
542                 IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]);
543
544         }
545
546         for (j = 0; j < GL_LIMITS(textures); j++) {
547             for (i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
548                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedPixelStates_T[i]] = This->textureState[j][SavedPixelStates_T[i]];
549             }
550         }
551
552         for (j = 0; j < GL_LIMITS(samplers); j++) {
553             for (i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
554                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][SavedPixelStates_S[i]] = This->samplerState[j][SavedPixelStates_S[i]];
555             }
556         }
557
558     } else if (This->blockType == WINED3DSBT_VERTEXSTATE) {
559
560         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
561             if ( This->set.renderState[SavedVertexStates_R[i]] && This->changed.renderState[SavedVertexStates_R[i]])
562                 IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]);
563         }
564
565         for (j = 0; j < GL_LIMITS(textures); j++) {
566             for (i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
567                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][SavedVertexStates_T[i]] = This->textureState[j][SavedVertexStates_T[i]];
568             }
569         }
570
571         for (j = 0; j < GL_LIMITS(textures); j++) {
572             for (i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
573                 ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[j][SavedVertexStates_S[i]] = This->samplerState[j][SavedVertexStates_S[i]];
574             }
575         }
576
577
578     } else {
579         FIXME("Unrecognized state block type %d\n", This->blockType);
580     }
581     memcpy(&((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed, &This->changed, sizeof(((IWineD3DDeviceImpl*)pDevice)->stateBlock->changed));
582     TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
583
584     return D3D_OK;
585 }
586
587 HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
588     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
589     IWineD3DDevice         *device = (IWineD3DDevice *)This->wineD3DDevice;
590     IWineD3DDeviceImpl     *ThisDevice = (IWineD3DDeviceImpl *)device;
591     union {
592         D3DLINEPATTERN lp;
593         DWORD d;
594     } lp;
595     union {
596         float f;
597         DWORD d;
598     } tmpfloat;
599     unsigned int i;
600
601     /* Note this may have a large overhead but it should only be executed
602        once, in order to initialize the complete state of the device and
603        all opengl equivalents                                            */
604     TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, This->wineD3DDevice);
605     /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */
606     This->blockType = WINED3DSBT_INIT;
607
608     /* Set some of the defaults for lights, transforms etc */
609     memcpy(&This->transforms[D3DTS_PROJECTION], &identity, sizeof(identity));
610     memcpy(&This->transforms[D3DTS_VIEW], &identity, sizeof(identity));
611     for (i = 0; i < 256; ++i) {
612       memcpy(&This->transforms[D3DTS_WORLDMATRIX(i)], &identity, sizeof(identity));
613     }
614
615     TRACE("Render states\n");
616     /* Render states: */
617     if (ThisDevice->depthStencilBuffer != NULL) {
618        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       D3DZB_TRUE);
619     } else {
620        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       D3DZB_FALSE);
621     }
622     IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE,         D3DFILL_SOLID);
623     IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE,        D3DSHADE_GOURAUD);
624     lp.lp.wRepeatFactor = 0;
625     lp.lp.wLinePattern  = 0;
626     IWineD3DDevice_SetRenderState(device, WINED3DRS_LINEPATTERN,      lp.d);
627     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZWRITEENABLE,     TRUE);
628     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHATESTENABLE,  FALSE);
629     IWineD3DDevice_SetRenderState(device, WINED3DRS_LASTPIXEL,        TRUE);
630     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLEND,         D3DBLEND_ONE);
631     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLEND,        D3DBLEND_ZERO);
632     IWineD3DDevice_SetRenderState(device, WINED3DRS_CULLMODE,         D3DCULL_CCW);
633     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZFUNC,            D3DCMP_LESSEQUAL);
634     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAFUNC,        D3DCMP_ALWAYS);
635     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAREF,         0xff); /*??*/
636     IWineD3DDevice_SetRenderState(device, WINED3DRS_DITHERENABLE,     FALSE);
637     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHABLENDENABLE, FALSE);
638     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGENABLE,        FALSE);
639     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARENABLE,   FALSE);
640     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZVISIBLE,         0);
641     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGCOLOR,         0);
642     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGTABLEMODE,     D3DFOG_NONE);
643     tmpfloat.f = 0.0f;
644     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGSTART,         tmpfloat.d);
645     tmpfloat.f = 1.0f;
646     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGEND,           tmpfloat.d);
647     tmpfloat.f = 1.0f;
648     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGDENSITY,       tmpfloat.d);
649     IWineD3DDevice_SetRenderState(device, WINED3DRS_EDGEANTIALIAS,    FALSE);
650     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZBIAS,            0);
651     IWineD3DDevice_SetRenderState(device, WINED3DRS_RANGEFOGENABLE,   FALSE);
652     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILENABLE,    FALSE);
653     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP);
654     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP);
655     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILPASS,      D3DSTENCILOP_KEEP);
656
657     /* Setting stencil func also uses values for stencil ref/mask, so manually set defaults
658      * so only a single call performed (and ensure defaults initialized before making that call)
659      *
660      * IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILREF, 0);
661      * IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILMASK, 0xFFFFFFFF);
662      */
663     This->renderState[WINED3DRS_STENCILREF] = 0;
664     This->renderState[WINED3DRS_STENCILMASK] = 0xFFFFFFFF;
665     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFUNC,      D3DCMP_ALWAYS);
666     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
667     IWineD3DDevice_SetRenderState(device, WINED3DRS_TEXTUREFACTOR,    0xFFFFFFFF);
668     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP0, 0);
669     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP1, 0);
670     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP2, 0);
671     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP3, 0);
672     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP4, 0);
673     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP5, 0);
674     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP6, 0);
675     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP7, 0);
676     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPING,                 TRUE);
677     IWineD3DDevice_SetRenderState(device, WINED3DRS_LIGHTING,                 TRUE);
678     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENT,                  0);
679     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGVERTEXMODE,            D3DFOG_NONE);
680     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORVERTEX,              TRUE);
681     IWineD3DDevice_SetRenderState(device, WINED3DRS_LOCALVIEWER,              TRUE);
682     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALIZENORMALS,         FALSE);
683     IWineD3DDevice_SetRenderState(device, WINED3DRS_DIFFUSEMATERIALSOURCE,    D3DMCS_COLOR1);
684     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARMATERIALSOURCE,   D3DMCS_COLOR2);
685     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENTMATERIALSOURCE,    D3DMCS_COLOR2);
686     IWineD3DDevice_SetRenderState(device, WINED3DRS_EMISSIVEMATERIALSOURCE,   D3DMCS_MATERIAL);
687     IWineD3DDevice_SetRenderState(device, WINED3DRS_VERTEXBLEND,              D3DVBF_DISABLE);
688     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPLANEENABLE,          0);
689     IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
690     tmpfloat.f = 1.0f;
691     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
692     tmpfloat.f = 0.0f;
693     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
694     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
695     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
696     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_A,             TRUE);
697     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_B,             TRUE);
698     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_C,             TRUE);
699     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEANTIALIAS,     TRUE);
700     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEMASK,          0xFFFFFFFF);
701     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHEDGESTYLE,           D3DPATCHEDGE_DISCRETE);
702     tmpfloat.f = 1.0f;
703     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
704     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        D3DDMT_DISABLE);
705     tmpfloat.f = 64.0f;
706     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
707     IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
708     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
709     tmpfloat.f = 0.0f;
710     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWEENFACTOR,              tmpfloat.d);
711     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOP,                  D3DBLENDOP_ADD);
712     IWineD3DDevice_SetRenderState(device, WINED3DRS_POSITIONDEGREE,           WINED3DDEGREE_CUBIC);
713     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALDEGREE,             WINED3DDEGREE_LINEAR);
714     /* states new in d3d9 */
715     IWineD3DDevice_SetRenderState(device, WINED3DRS_SCISSORTESTENABLE,        FALSE);
716     IWineD3DDevice_SetRenderState(device, WINED3DRS_SLOPESCALEDEPTHBIAS,      0);
717     tmpfloat.f = 1.0f;
718     IWineD3DDevice_SetRenderState(device, WINED3DRS_MINTESSELLATIONLEVEL,     tmpfloat.d);
719     IWineD3DDevice_SetRenderState(device, WINED3DRS_MAXTESSELLATIONLEVEL,     tmpfloat.d);
720     IWineD3DDevice_SetRenderState(device, WINED3DRS_ANTIALIASEDLINEENABLE,    FALSE);
721     tmpfloat.f = 0.0f;
722     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_X,           tmpfloat.d);
723     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Y,           tmpfloat.d);
724     tmpfloat.f = 1.0f;
725     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Z,           tmpfloat.d);
726     tmpfloat.f = 0.0f;
727     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_W,           tmpfloat.d);
728     IWineD3DDevice_SetRenderState(device, WINED3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
729     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWOSIDEDSTENCILMODE,      FALSE);
730     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFAIL,          D3DSTENCILOP_KEEP);
731     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILZFAIL,         D3DSTENCILOP_KEEP);
732     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILPASS,          D3DSTENCILOP_KEEP);
733     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFUNC,          D3DCMP_ALWAYS);
734     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE1,        0x0000000F);
735     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE2,        0x0000000F);
736     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE3,        0x0000000F);
737     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDFACTOR,              0xFFFFFFFF);
738     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRGBWRITEENABLE,          0);
739     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEPTHBIAS,                0);
740     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP8,  0);
741     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP9,  0);
742     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP10, 0);
743     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP11, 0);
744     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP12, 0);
745     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP13, 0);
746     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP14, 0);
747     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP15, 0);
748     IWineD3DDevice_SetRenderState(device, WINED3DRS_SEPARATEALPHABLENDENABLE, FALSE);
749     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLENDALPHA,            D3DBLEND_ONE);
750     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLENDALPHA,           D3DBLEND_ZERO);
751     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOPALPHA,             D3DBLENDOP_ADD);
752
753     /* clipping status */
754     This->clip_status.ClipUnion = 0;
755     This->clip_status.ClipIntersection = 0xFFFFFFFF;
756
757     /* Texture Stage States - Put directly into state block, we will call function below */
758     for (i = 0; i < GL_LIMITS(textures); i++) {
759         TRACE("Setting up default texture states for texture Stage %d\n", i);
760         memcpy(&This->transforms[D3DTS_TEXTURE0 + i], &identity, sizeof(identity));
761         This->textureState[i][D3DTSS_COLOROP               ] = (i==0)? D3DTOP_MODULATE :  D3DTOP_DISABLE;
762         This->textureState[i][D3DTSS_COLORARG1             ] = D3DTA_TEXTURE;
763         This->textureState[i][D3DTSS_COLORARG2             ] = D3DTA_CURRENT;
764         This->textureState[i][D3DTSS_ALPHAOP               ] = (i==0)? D3DTOP_SELECTARG1 :  D3DTOP_DISABLE;
765         This->textureState[i][D3DTSS_ALPHAARG1             ] = D3DTA_TEXTURE;
766         This->textureState[i][D3DTSS_ALPHAARG2             ] = D3DTA_CURRENT;
767         This->textureState[i][D3DTSS_BUMPENVMAT00          ] = (DWORD) 0.0;
768         This->textureState[i][D3DTSS_BUMPENVMAT01          ] = (DWORD) 0.0;
769         This->textureState[i][D3DTSS_BUMPENVMAT10          ] = (DWORD) 0.0;
770         This->textureState[i][D3DTSS_BUMPENVMAT11          ] = (DWORD) 0.0;
771         This->textureState[i][D3DTSS_TEXCOORDINDEX         ] = i;
772         This->textureState[i][D3DTSS_BUMPENVLSCALE         ] = (DWORD) 0.0;
773         This->textureState[i][D3DTSS_BUMPENVLOFFSET        ] = (DWORD) 0.0;
774         This->textureState[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
775         This->textureState[i][D3DTSS_ADDRESSW              ] = D3DTADDRESS_WRAP;
776         This->textureState[i][D3DTSS_COLORARG0             ] = D3DTA_CURRENT;
777         This->textureState[i][D3DTSS_ALPHAARG0             ] = D3DTA_CURRENT;
778         This->textureState[i][D3DTSS_RESULTARG             ] = D3DTA_CURRENT;
779     }
780
781         /* Sampler states*/
782     for (i = 0 ; i <  GL_LIMITS(samplers); i++) {
783         TRACE("Setting up default samplers states for sampler %d\n", i);
784         This->samplerState[i][WINED3DSAMP_ADDRESSU         ] = D3DTADDRESS_WRAP;
785         This->samplerState[i][WINED3DSAMP_ADDRESSV         ] = D3DTADDRESS_WRAP;
786         This->samplerState[i][WINED3DSAMP_ADDRESSW         ] = D3DTADDRESS_WRAP;
787         This->samplerState[i][WINED3DSAMP_BORDERCOLOR      ] = 0x00;
788         This->samplerState[i][WINED3DSAMP_MAGFILTER        ] = D3DTEXF_POINT;
789         This->samplerState[i][WINED3DSAMP_MINFILTER        ] = D3DTEXF_POINT;
790         This->samplerState[i][WINED3DSAMP_MIPFILTER        ] = D3DTEXF_NONE;
791         This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS    ] = 0;
792         This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL      ] = 0;
793         This->samplerState[i][WINED3DSAMP_MAXANISOTROPY    ] = 1;
794         This->samplerState[i][WINED3DSAMP_SRGBTEXTURE      ] = 0; /* TODO: Gamma correction value*/
795         This->samplerState[i][WINED3DSAMP_ELEMENTINDEX     ] = 0; /* TODO: Indicates which element of a  multielement texture to use */
796         This->samplerState[i][WINED3DSAMP_DMAPOFFSET       ] = 256; /* TODO: Vertex offset in the presampled displacement map */
797     }
798
799     /* Under DirectX you can have texture stage operations even if no texture is
800        bound, whereas opengl will only do texture operations when a valid texture is
801        bound. We emulate this by creating dummy textures and binding them to each
802        texture stage, but disable all stages by default. Hence if a stage is enabled
803        then the default texture will kick in until replaced by a SetTexture call     */
804
805     ENTER_GL();
806
807     for (i = 0; i < GL_LIMITS(textures); i++) {
808         GLubyte white = 255;
809
810         /* Note this avoids calling settexture, so pretend it has been called */
811         This->set.textures[i]     = TRUE;
812         This->changed.textures[i] = TRUE;
813         This->textures[i]         = NULL;
814
815         /* Make appropriate texture active */
816         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
817             GLACTIVETEXTURE(i);
818         } else if (i > 0) {
819             FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
820         }
821
822         /* Generate an opengl texture name */
823         glGenTextures(1, &ThisDevice->dummyTextureName[i]);
824         checkGLcall("glGenTextures");
825         TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
826
827         /* Generate a dummy 1d texture */
828         This->textureDimensions[i] = GL_TEXTURE_1D;
829         glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
830         checkGLcall("glBindTexture");
831
832         glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
833         checkGLcall("glTexImage1D");
834 #if 1   /* TODO: move the setting texture states off to basetexture */
835         /* Reapply all the texture state information to this texture */
836         IWineD3DDevice_SetupTextureStates(device, i, REAPPLY_ALL);
837 #endif
838     }
839
840     LEAVE_GL();
841
842     /* Defaulting palettes - Note these are device wide but reinitialized here for convenience*/
843     for (i = 0; i < MAX_PALETTES; ++i) {
844       int j;
845       for (j = 0; j < 256; ++j) {
846         This->wineD3DDevice->palettes[i][j].peRed   = 0xFF;
847         This->wineD3DDevice->palettes[i][j].peGreen = 0xFF;
848         This->wineD3DDevice->palettes[i][j].peBlue  = 0xFF;
849         This->wineD3DDevice->palettes[i][j].peFlags = 0xFF;
850       }
851     }
852     This->wineD3DDevice->currentPalette = 0;
853
854     TRACE("-----------------------> Device defaults now set up...\n");
855     return D3D_OK;
856 }
857
858 /**********************************************************
859  * IWineD3DStateBlock VTbl follows
860  **********************************************************/
861
862 const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
863 {
864     /* IUnknown */
865     IWineD3DStateBlockImpl_QueryInterface,
866     IWineD3DStateBlockImpl_AddRef,
867     IWineD3DStateBlockImpl_Release,
868     /* IWineD3DStateBlock */
869     IWineD3DStateBlockImpl_GetParent,
870     IWineD3DStateBlockImpl_GetDevice,
871     IWineD3DStateBlockImpl_Capture,
872     IWineD3DStateBlockImpl_Apply,
873     IWineD3DStateBlockImpl_InitStartupStateBlock
874 };