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