wined3d: Explicitly pass gl_info to stateblock_savedstates_copy().
[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  * Copyright 2007 Stefan Dösinger for CodeWeavers
8  * Copyright 2009 Henri Verbeet for CodeWeavers
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24
25 #include "config.h"
26 #include "wined3d_private.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
29 #define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
30
31 /***************************************
32  * Stateblock helper functions follow
33  **************************************/
34
35 /* Allocates the correct amount of space for pixel and vertex shader constants,
36  * along with their set/changed flags on the given stateblock object
37  */
38 static HRESULT stateblock_allocate_shader_constants(IWineD3DStateBlockImpl *object)
39 {
40     IWineD3DStateBlockImpl *This = object;
41
42     /* Allocate space for floating point constants */
43     object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
44     if (!object->pixelShaderConstantF) goto fail;
45
46     object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(pshader_constantsF));
47     if (!object->changed.pixelShaderConstantsF) goto fail;
48
49     object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
50     if (!object->vertexShaderConstantF) goto fail;
51
52     object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOL) * GL_LIMITS(vshader_constantsF));
53     if (!object->changed.vertexShaderConstantsF) goto fail;
54
55     object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(vshader_constantsF));
56     if (!object->contained_vs_consts_f) goto fail;
57
58     object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * GL_LIMITS(pshader_constantsF));
59     if (!object->contained_ps_consts_f) goto fail;
60
61     return WINED3D_OK;
62
63 fail:
64     ERR("Failed to allocate memory\n");
65     HeapFree(GetProcessHeap(), 0, object->pixelShaderConstantF);
66     HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF);
67     HeapFree(GetProcessHeap(), 0, object->vertexShaderConstantF);
68     HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF);
69     HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f);
70     HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f);
71     return E_OUTOFMEMORY;
72 }
73
74 /* Copy all members of one stateblock to another */
75 static void stateblock_savedstates_copy(SAVEDSTATES *dest, const SAVEDSTATES *source,
76         const struct wined3d_gl_info *gl_info)
77 {
78     /* Single values */
79     dest->primitive_type = source->primitive_type;
80     dest->indices = source->indices;
81     dest->material = source->material;
82     dest->viewport = source->viewport;
83     dest->vertexDecl = source->vertexDecl;
84     dest->pixelShader = source->pixelShader;
85     dest->vertexShader = source->vertexShader;
86     dest->scissorRect = dest->scissorRect;
87
88     /* Fixed size arrays */
89     dest->streamSource = source->streamSource;
90     dest->streamFreq = source->streamFreq;
91     dest->textures = source->textures;
92     memcpy(dest->transform, source->transform, sizeof(source->transform));
93     memcpy(dest->renderState, source->renderState, sizeof(source->renderState));
94     memcpy(dest->textureState, source->textureState, sizeof(source->textureState));
95     memcpy(dest->samplerState, source->samplerState, sizeof(source->samplerState));
96     dest->clipplane = source->clipplane;
97     dest->pixelShaderConstantsB = source->pixelShaderConstantsB;
98     dest->pixelShaderConstantsI = source->pixelShaderConstantsI;
99     dest->vertexShaderConstantsB = source->vertexShaderConstantsB;
100     dest->vertexShaderConstantsI = source->vertexShaderConstantsI;
101
102     /* Dynamically sized arrays */
103     memcpy(dest->pixelShaderConstantsF, source->pixelShaderConstantsF,
104             sizeof(BOOL) * gl_info->max_pshader_constantsF);
105     memcpy(dest->vertexShaderConstantsF, source->vertexShaderConstantsF,
106             sizeof(BOOL) * gl_info->max_vshader_constantsF);
107 }
108
109 static inline void stateblock_set_bits(DWORD *map, UINT map_size)
110 {
111     DWORD mask = (1 << (map_size & 0x1f)) - 1;
112     memset(map, 0xff, (map_size >> 5) * sizeof(*map));
113     if (mask) map[map_size >> 5] = mask;
114 }
115
116 /** Set all members of a stateblock savedstate to the given value */
117 static void stateblock_savedstates_set(IWineD3DStateBlock *iface, SAVEDSTATES *states, BOOL value)
118 {
119     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
120     unsigned bsize = sizeof(BOOL);
121
122     /* Single values */
123     states->primitive_type = value;
124     states->indices = value;
125     states->material = value;
126     states->viewport = value;
127     states->vertexDecl = value;
128     states->pixelShader = value;
129     states->vertexShader = value;
130     states->scissorRect = value;
131
132     /* Fixed size arrays */
133     if (value)
134     {
135         int i;
136         states->streamSource = 0xffff;
137         states->streamFreq = 0xffff;
138         states->textures = 0xfffff;
139         stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
140         stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
141         for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
142         for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3fff;
143         states->clipplane = 0xffffffff;
144         states->pixelShaderConstantsB = 0xffff;
145         states->pixelShaderConstantsI = 0xffff;
146         states->vertexShaderConstantsB = 0xffff;
147         states->vertexShaderConstantsI = 0xffff;
148     }
149     else
150     {
151         states->streamSource = 0;
152         states->streamFreq = 0;
153         states->textures = 0;
154         memset(states->transform, 0, sizeof(states->transform));
155         memset(states->renderState, 0, sizeof(states->renderState));
156         memset(states->textureState, 0, sizeof(states->textureState));
157         memset(states->samplerState, 0, sizeof(states->samplerState));
158         states->clipplane = 0;
159         states->pixelShaderConstantsB = 0;
160         states->pixelShaderConstantsI = 0;
161         states->vertexShaderConstantsB = 0;
162         states->vertexShaderConstantsI = 0;
163     }
164
165     /* Dynamically sized arrays */
166     memset(states->pixelShaderConstantsF, value, bsize * GL_LIMITS(pshader_constantsF));
167     memset(states->vertexShaderConstantsF, value, bsize * GL_LIMITS(vshader_constantsF));
168 }
169
170 static void stateblock_copy(IWineD3DStateBlockImpl *dst, IWineD3DStateBlockImpl *src)
171 {
172     const struct wined3d_gl_info *gl_info = &src->wineD3DDevice->adapter->gl_info;
173     unsigned int l;
174
175     dst->lpVtbl = src->lpVtbl;
176     dst->ref = src->ref;
177     dst->parent = src->parent;
178     dst->wineD3DDevice = src->wineD3DDevice;
179     dst->blockType = src->blockType;
180
181     /* Saved states */
182     stateblock_savedstates_copy(&dst->changed, &src->changed, gl_info);
183
184     /* Single items */
185     dst->gl_primitive_type = src->gl_primitive_type;
186     dst->vertexDecl = src->vertexDecl;
187     dst->vertexShader = src->vertexShader;
188     dst->streamIsUP = src->streamIsUP;
189     dst->pIndexData = src->pIndexData;
190     dst->IndexFmt = src->IndexFmt;
191     dst->baseVertexIndex = src->baseVertexIndex;
192     dst->clip_status = src->clip_status;
193     dst->viewport = src->viewport;
194     dst->material = src->material;
195     dst->pixelShader = src->pixelShader;
196     dst->scissorRect = src->scissorRect;
197
198     /* Lights */
199     memset(dst->activeLights, 0, sizeof(dst->activeLights));
200     for (l = 0; l < LIGHTMAP_SIZE; ++l)
201     {
202         struct list *e1, *e2;
203         LIST_FOR_EACH_SAFE(e1, e2, &dst->lightMap[l])
204         {
205             PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry);
206             list_remove(&light->entry);
207             HeapFree(GetProcessHeap(), 0, light);
208         }
209
210         LIST_FOR_EACH(e1, &src->lightMap[l])
211         {
212             PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry), *light2;
213             light2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*light));
214             *light2 = *light;
215             list_add_tail(&dst->lightMap[l], &light2->entry);
216             if (light2->glIndex != -1) dst->activeLights[light2->glIndex] = light2;
217         }
218     }
219
220     /* Fixed size arrays */
221     memcpy(dst->vertexShaderConstantB, src->vertexShaderConstantB, sizeof(dst->vertexShaderConstantB));
222     memcpy(dst->vertexShaderConstantI, src->vertexShaderConstantI, sizeof(dst->vertexShaderConstantI));
223     memcpy(dst->pixelShaderConstantB, src->pixelShaderConstantB, sizeof(dst->pixelShaderConstantB));
224     memcpy(dst->pixelShaderConstantI, src->pixelShaderConstantI, sizeof(dst->pixelShaderConstantI));
225
226     memcpy(dst->streamStride, src->streamStride, sizeof(dst->streamStride));
227     memcpy(dst->streamOffset, src->streamOffset, sizeof(dst->streamOffset));
228     memcpy(dst->streamSource, src->streamSource, sizeof(dst->streamSource));
229     memcpy(dst->streamFreq, src->streamFreq, sizeof(dst->streamFreq));
230     memcpy(dst->streamFlags, src->streamFlags, sizeof(dst->streamFlags));
231     memcpy(dst->transforms, src->transforms, sizeof(dst->transforms));
232     memcpy(dst->clipplane, src->clipplane, sizeof(dst->clipplane));
233     memcpy(dst->renderState, src->renderState, sizeof(dst->renderState));
234     memcpy(dst->textures, src->textures, sizeof(dst->textures));
235     memcpy(dst->textureState, src->textureState, sizeof(dst->textureState));
236     memcpy(dst->samplerState, src->samplerState, sizeof(dst->samplerState));
237
238     /* Dynamically sized arrays */
239     memcpy(dst->vertexShaderConstantF, src->vertexShaderConstantF, sizeof(float) * gl_info->max_vshader_constantsF * 4);
240     memcpy(dst->pixelShaderConstantF,  src->pixelShaderConstantF,  sizeof(float) * gl_info->max_pshader_constantsF * 4);
241 }
242
243 /**********************************************************
244  * IWineD3DStateBlockImpl IUnknown parts follows
245  **********************************************************/
246 static HRESULT  WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj)
247 {
248     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
249     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
250     if (IsEqualGUID(riid, &IID_IUnknown)
251         || IsEqualGUID(riid, &IID_IWineD3DBase)
252         || IsEqualGUID(riid, &IID_IWineD3DStateBlock)){
253         IUnknown_AddRef(iface);
254         *ppobj = This;
255         return S_OK;
256     }
257     *ppobj = NULL;
258     return E_NOINTERFACE;
259 }
260
261 static ULONG  WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) {
262     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
263     ULONG refCount = InterlockedIncrement(&This->ref);
264
265     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
266     return refCount;
267 }
268
269 static ULONG  WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
270     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
271     ULONG refCount = InterlockedDecrement(&This->ref);
272
273     TRACE("(%p) : Releasing from %d\n", This, refCount + 1);
274
275     if (!refCount) {
276         int counter;
277
278         if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);
279
280         for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++)
281         {
282             if (This->textures[counter]) IWineD3DBaseTexture_Release(This->textures[counter]);
283         }
284
285         for (counter = 0; counter < MAX_STREAMS; counter++) {
286             if(This->streamSource[counter]) {
287                 if (IWineD3DBuffer_Release(This->streamSource[counter]))
288                 {
289                     TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]);
290                 }
291             }
292         }
293         if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
294         if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
295         if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
296
297         for(counter = 0; counter < LIGHTMAP_SIZE; counter++) {
298             struct list *e1, *e2;
299             LIST_FOR_EACH_SAFE(e1, e2, &This->lightMap[counter]) {
300                 PLIGHTINFOEL *light = LIST_ENTRY(e1, PLIGHTINFOEL, entry);
301                 list_remove(&light->entry);
302                 HeapFree(GetProcessHeap(), 0, light);
303             }
304         }
305
306         HeapFree(GetProcessHeap(), 0, This->vertexShaderConstantF);
307         HeapFree(GetProcessHeap(), 0, This->changed.vertexShaderConstantsF);
308         HeapFree(GetProcessHeap(), 0, This->pixelShaderConstantF);
309         HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF);
310         HeapFree(GetProcessHeap(), 0, This->contained_vs_consts_f);
311         HeapFree(GetProcessHeap(), 0, This->contained_ps_consts_f);
312         HeapFree(GetProcessHeap(), 0, This);
313     }
314     return refCount;
315 }
316
317 /**********************************************************
318  * IWineD3DStateBlockImpl parts follows
319  **********************************************************/
320 static HRESULT  WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnknown **pParent) {
321     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
322     IUnknown_AddRef(This->parent);
323     *pParent = This->parent;
324     return WINED3D_OK;
325 }
326
327 static HRESULT  WINAPI IWineD3DStateBlockImpl_GetDevice(IWineD3DStateBlock *iface, IWineD3DDevice** ppDevice){
328
329     IWineD3DStateBlockImpl *This   = (IWineD3DStateBlockImpl *)iface;
330
331     *ppDevice = (IWineD3DDevice*)This->wineD3DDevice;
332     IWineD3DDevice_AddRef(*ppDevice);
333     return WINED3D_OK;
334
335 }
336
337 static inline void record_lights(IWineD3DStateBlockImpl *This, IWineD3DStateBlockImpl *targetStateBlock) {
338     UINT i;
339
340     /* Lights... For a recorded state block, we just had a chain of actions to perform,
341      * so we need to walk that chain and update any actions which differ
342      */
343     for(i = 0; i < LIGHTMAP_SIZE; i++) {
344         struct list *e, *f;
345         LIST_FOR_EACH(e, &This->lightMap[i]) {
346             BOOL updated = FALSE;
347             PLIGHTINFOEL *src = LIST_ENTRY(e, PLIGHTINFOEL, entry), *realLight;
348             if (!src->changed && !src->enabledChanged) continue;
349
350             /* Look up the light in the destination */
351             LIST_FOR_EACH(f, &targetStateBlock->lightMap[i]) {
352                 realLight = LIST_ENTRY(f, PLIGHTINFOEL, entry);
353                 if(realLight->OriginalIndex == src->OriginalIndex) {
354                     if(src->changed) {
355                         src->OriginalParms = realLight->OriginalParms;
356                     }
357                     if(src->enabledChanged) {
358                             /* Need to double check because enabledChanged does not catch enabled -> disabled -> enabled
359                         * or disabled -> enabled -> disabled changes
360                             */
361                         if(realLight->glIndex == -1 && src->glIndex != -1) {
362                             /* Light disabled */
363                             This->activeLights[src->glIndex] = NULL;
364                         } else if(realLight->glIndex != -1 && src->glIndex == -1){
365                             /* Light enabled */
366                             This->activeLights[realLight->glIndex] = src;
367                         }
368                         src->glIndex = realLight->glIndex;
369                     }
370                     updated = TRUE;
371                     break;
372                 }
373             }
374
375             if(updated) {
376                 /* Found a light, all done, proceed with next hash entry */
377                 continue;
378             } else if(src->changed) {
379                 /* Otherwise assign defaul params */
380                 src->OriginalParms = WINED3D_default_light;
381             } else {
382                 /* Not enabled by default */
383                 src->glIndex = -1;
384             }
385         }
386     }
387 }
388
389 static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface){
390
391     IWineD3DStateBlockImpl *This             = (IWineD3DStateBlockImpl *)iface;
392     IWineD3DStateBlockImpl *targetStateBlock = This->wineD3DDevice->stateBlock;
393     unsigned int i, j;
394     DWORD map;
395
396     TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This);
397
398     /* If not recorded, then update can just recapture */
399     if (This->blockType == WINED3DSBT_RECORDED) {
400
401         /* Recorded => Only update 'changed' values */
402         if (This->changed.vertexShader && This->vertexShader != targetStateBlock->vertexShader) {
403             TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader);
404
405             if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
406             if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
407             This->vertexShader = targetStateBlock->vertexShader;
408         }
409
410         /* Vertex Shader Float Constants */
411         for (j = 0; j < This->num_contained_vs_consts_f; ++j) {
412             i = This->contained_vs_consts_f[j];
413             TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
414                     targetStateBlock->vertexShaderConstantF[i * 4],
415                     targetStateBlock->vertexShaderConstantF[i * 4 + 1],
416                     targetStateBlock->vertexShaderConstantF[i * 4 + 2],
417                     targetStateBlock->vertexShaderConstantF[i * 4 + 3]);
418
419             This->vertexShaderConstantF[i * 4]      = targetStateBlock->vertexShaderConstantF[i * 4];
420             This->vertexShaderConstantF[i * 4 + 1]  = targetStateBlock->vertexShaderConstantF[i * 4 + 1];
421             This->vertexShaderConstantF[i * 4 + 2]  = targetStateBlock->vertexShaderConstantF[i * 4 + 2];
422             This->vertexShaderConstantF[i * 4 + 3]  = targetStateBlock->vertexShaderConstantF[i * 4 + 3];
423         }
424
425         /* Vertex Shader Integer Constants */
426         for (j = 0; j < This->num_contained_vs_consts_i; ++j) {
427             i = This->contained_vs_consts_i[j];
428             TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
429                     targetStateBlock->vertexShaderConstantI[i * 4],
430                     targetStateBlock->vertexShaderConstantI[i * 4 + 1],
431                     targetStateBlock->vertexShaderConstantI[i * 4 + 2],
432                     targetStateBlock->vertexShaderConstantI[i * 4 + 3]);
433
434             This->vertexShaderConstantI[i * 4]      = targetStateBlock->vertexShaderConstantI[i * 4];
435             This->vertexShaderConstantI[i * 4 + 1]  = targetStateBlock->vertexShaderConstantI[i * 4 + 1];
436             This->vertexShaderConstantI[i * 4 + 2]  = targetStateBlock->vertexShaderConstantI[i * 4 + 2];
437             This->vertexShaderConstantI[i * 4 + 3]  = targetStateBlock->vertexShaderConstantI[i * 4 + 3];
438         }
439
440         /* Vertex Shader Boolean Constants */
441         for (j = 0; j < This->num_contained_vs_consts_b; ++j) {
442             i = This->contained_vs_consts_b[j];
443             TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
444                     targetStateBlock->vertexShaderConstantB[i] ? "TRUE" : "FALSE");
445
446             This->vertexShaderConstantB[i] =  targetStateBlock->vertexShaderConstantB[i];
447         }
448
449         /* Pixel Shader Float Constants */
450         for (j = 0; j < This->num_contained_ps_consts_f; ++j) {
451             i = This->contained_ps_consts_f[j];
452             TRACE("Setting %p from %p %u to {%f, %f, %f, %f}\n", This, targetStateBlock, i,
453                     targetStateBlock->pixelShaderConstantF[i * 4],
454                     targetStateBlock->pixelShaderConstantF[i * 4 + 1],
455                     targetStateBlock->pixelShaderConstantF[i * 4 + 2],
456                     targetStateBlock->pixelShaderConstantF[i * 4 + 3]);
457
458             This->pixelShaderConstantF[i * 4]      = targetStateBlock->pixelShaderConstantF[i * 4];
459             This->pixelShaderConstantF[i * 4 + 1]  = targetStateBlock->pixelShaderConstantF[i * 4 + 1];
460             This->pixelShaderConstantF[i * 4 + 2]  = targetStateBlock->pixelShaderConstantF[i * 4 + 2];
461             This->pixelShaderConstantF[i * 4 + 3]  = targetStateBlock->pixelShaderConstantF[i * 4 + 3];
462         }
463
464         /* Pixel Shader Integer Constants */
465         for (j = 0; j < This->num_contained_ps_consts_i; ++j) {
466             i = This->contained_ps_consts_i[j];
467             TRACE("Setting %p from %p %u to {%d, %d, %d, %d}\n", This, targetStateBlock, i,
468                     targetStateBlock->pixelShaderConstantI[i * 4],
469                     targetStateBlock->pixelShaderConstantI[i * 4 + 1],
470                     targetStateBlock->pixelShaderConstantI[i * 4 + 2],
471                     targetStateBlock->pixelShaderConstantI[i * 4 + 3]);
472
473             This->pixelShaderConstantI[i * 4]      = targetStateBlock->pixelShaderConstantI[i * 4];
474             This->pixelShaderConstantI[i * 4 + 1]  = targetStateBlock->pixelShaderConstantI[i * 4 + 1];
475             This->pixelShaderConstantI[i * 4 + 2]  = targetStateBlock->pixelShaderConstantI[i * 4 + 2];
476             This->pixelShaderConstantI[i * 4 + 3]  = targetStateBlock->pixelShaderConstantI[i * 4 + 3];
477         }
478
479         /* Pixel Shader Boolean Constants */
480         for (j = 0; j < This->num_contained_ps_consts_b; ++j) {
481             i = This->contained_ps_consts_b[j];
482             TRACE("Setting %p from %p %u to %s\n", This, targetStateBlock, i,
483                     targetStateBlock->pixelShaderConstantB[i] ? "TRUE" : "FALSE");
484
485             This->pixelShaderConstantB[i] =  targetStateBlock->pixelShaderConstantB[i];
486         }
487
488         /* Others + Render & Texture */
489         for (i = 0; i < This->num_contained_transform_states; i++) {
490             TRACE("Updating transform %u\n", i);
491             This->transforms[This->contained_transform_states[i]] =
492                 targetStateBlock->transforms[This->contained_transform_states[i]];
493         }
494
495         if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type;
496
497         if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
498                         || (This->baseVertexIndex != targetStateBlock->baseVertexIndex)
499                         || (This->IndexFmt != targetStateBlock->IndexFmt))) {
500             TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n",
501                     targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
502             if(targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
503             if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
504             This->pIndexData = targetStateBlock->pIndexData;
505             This->baseVertexIndex = targetStateBlock->baseVertexIndex;
506             This->IndexFmt = targetStateBlock->IndexFmt;
507         }
508
509         if(This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){
510             TRACE("Updating vertex declaration from %p to %p\n", This->vertexDecl, targetStateBlock->vertexDecl);
511
512             if (targetStateBlock->vertexDecl) IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl);
513             if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);
514             This->vertexDecl = targetStateBlock->vertexDecl;
515         }
516
517         if (This->changed.material && memcmp(&targetStateBlock->material,
518                                                     &This->material,
519                                                     sizeof(WINED3DMATERIAL)) != 0) {
520             TRACE("Updating material\n");
521             This->material = targetStateBlock->material;
522         }
523
524         if (This->changed.viewport && memcmp(&targetStateBlock->viewport,
525                                                     &This->viewport,
526                                                     sizeof(WINED3DVIEWPORT)) != 0) {
527             TRACE("Updating viewport\n");
528             This->viewport = targetStateBlock->viewport;
529         }
530
531         if(This->changed.scissorRect && memcmp(&targetStateBlock->scissorRect,
532                                            &This->scissorRect,
533                                            sizeof(targetStateBlock->scissorRect)))
534         {
535             TRACE("Updating scissor rect\n");
536             targetStateBlock->scissorRect = This->scissorRect;
537         }
538
539         map = This->changed.streamSource;
540         for (i = 0; map; map >>= 1, ++i)
541         {
542             if (!(map & 1)) continue;
543
544             if (This->streamStride[i] != targetStateBlock->streamStride[i]
545                     || This->streamSource[i] != targetStateBlock->streamSource[i])
546             {
547                 TRACE("Updating stream source %u to %p, stride to %u\n",
548                         i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]);
549                 This->streamStride[i] = targetStateBlock->streamStride[i];
550                 if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
551                 if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
552                 This->streamSource[i] = targetStateBlock->streamSource[i];
553             }
554         }
555
556         map = This->changed.streamFreq;
557         for (i = 0; map; map >>= 1, ++i)
558         {
559             if (!(map & 1)) continue;
560
561             if (This->streamFreq[i] != targetStateBlock->streamFreq[i]
562                     || This->streamFlags[i] != targetStateBlock->streamFlags[i])
563             {
564                 TRACE("Updating stream frequency %u to %u flags to %#x\n",
565                         i, targetStateBlock->streamFreq[i], targetStateBlock->streamFlags[i]);
566                 This->streamFreq[i] = targetStateBlock->streamFreq[i];
567                 This->streamFlags[i] = targetStateBlock->streamFlags[i];
568             }
569         }
570
571         map = This->changed.clipplane;
572         for (i = 0; map; map >>= 1, ++i)
573         {
574             if (!(map & 1)) continue;
575
576             if (memcmp(targetStateBlock->clipplane[i], This->clipplane[i], sizeof(*This->clipplane)))
577             {
578                 TRACE("Updating clipplane %u\n", i);
579                 memcpy(This->clipplane[i], targetStateBlock->clipplane[i], sizeof(*This->clipplane));
580             }
581         }
582
583         /* Render */
584         for (i = 0; i < This->num_contained_render_states; i++) {
585             TRACE("Updating renderState %u to %u\n", This->contained_render_states[i],
586                     targetStateBlock->renderState[This->contained_render_states[i]]);
587             This->renderState[This->contained_render_states[i]] = targetStateBlock->renderState[This->contained_render_states[i]];
588         }
589
590         /* Texture states */
591         for (j = 0; j < This->num_contained_tss_states; j++) {
592             DWORD stage = This->contained_tss_states[j].stage;
593             DWORD state = This->contained_tss_states[j].state;
594
595             TRACE("Updating texturestage state %u, %u to %u (was %u)\n", stage, state,
596                     targetStateBlock->textureState[stage][state], This->textureState[stage][state]);
597             This->textureState[stage][state] = targetStateBlock->textureState[stage][state];
598         }
599
600         /* Samplers */
601         map = This->changed.textures;
602         for (i = 0; map; map >>= 1, ++i)
603         {
604             if (!(map & 1)) continue;
605
606             TRACE("Updating texture %u to %p (was %p)\n", i, targetStateBlock->textures[i], This->textures[i]);
607             if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
608             if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
609             This->textures[i] = targetStateBlock->textures[i];
610         }
611
612         for (j = 0; j < This->num_contained_sampler_states; j++) {
613             DWORD stage = This->contained_sampler_states[j].stage;
614             DWORD state = This->contained_sampler_states[j].state;
615             TRACE("Updating sampler state %u, %u to %u (was %u)\n", stage, state,
616                     targetStateBlock->samplerState[stage][state], This->samplerState[stage][state]);
617             This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state];
618         }
619         if(This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) {
620             if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
621             if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
622             This->pixelShader = targetStateBlock->pixelShader;
623         }
624
625         record_lights(This, targetStateBlock);
626     } else if(This->blockType == WINED3DSBT_ALL) {
627         memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
628         memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
629         memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
630         This->gl_primitive_type = targetStateBlock->gl_primitive_type;
631         memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride));
632         memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset));
633         memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq));
634         memcpy(This->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags));
635         This->baseVertexIndex = targetStateBlock->baseVertexIndex;
636         memcpy(This->transforms, targetStateBlock->transforms, sizeof(This->transforms));
637         record_lights(This, targetStateBlock);
638         memcpy(This->clipplane, targetStateBlock->clipplane, sizeof(This->clipplane));
639         This->clip_status = targetStateBlock->clip_status;
640         This->viewport = targetStateBlock->viewport;
641         This->material = targetStateBlock->material;
642         memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
643         memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
644         memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
645         memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState));
646         memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
647         memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
648         This->scissorRect = targetStateBlock->scissorRect;
649
650         if (This->vertexDecl != targetStateBlock->vertexDecl)
651         {
652             if (targetStateBlock->vertexDecl) IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl);
653             if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl);
654             This->vertexDecl = targetStateBlock->vertexDecl;
655         }
656
657         for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
658         {
659             if (targetStateBlock->textures[i] != This->textures[i])
660             {
661                 if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
662                 if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
663                 This->textures[i] = targetStateBlock->textures[i];
664             }
665         }
666
667         if(targetStateBlock->pIndexData != This->pIndexData ||
668            targetStateBlock->IndexFmt != This->IndexFmt) {
669             if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
670             if (This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
671             This->pIndexData = targetStateBlock->pIndexData;
672             This->IndexFmt = targetStateBlock->IndexFmt;
673         }
674         for(i = 0; i < MAX_STREAMS; i++) {
675             if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
676                 if(targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
677                 if(This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
678                 This->streamSource[i] = targetStateBlock->streamSource[i];
679             }
680         }
681         if(This->vertexShader != targetStateBlock->vertexShader) {
682             if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
683             if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
684             This->vertexShader = targetStateBlock->vertexShader;
685         }
686         if(This->pixelShader != targetStateBlock->pixelShader) {
687             if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
688             if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
689             This->pixelShader = targetStateBlock->pixelShader;
690         }
691     } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
692         memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI));
693         memcpy(This->vertexShaderConstantI, targetStateBlock->vertexShaderConstantI, sizeof(This->vertexShaderConstantF));
694         memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4);
695         record_lights(This, targetStateBlock);
696         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
697             This->renderState[SavedVertexStates_R[i]] = targetStateBlock->renderState[SavedVertexStates_R[i]];
698         }
699         for (j = 0; j < MAX_COMBINED_SAMPLERS; j++) {
700             for (i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
701                 This->samplerState[j][SavedVertexStates_S[i]] = targetStateBlock->samplerState[j][SavedVertexStates_S[i]];
702             }
703         }
704         for (j = 0; j < MAX_TEXTURES; j++) {
705             for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
706                 This->textureState[j][SavedVertexStates_R[i]] = targetStateBlock->textureState[j][SavedVertexStates_R[i]];
707             }
708         }
709         for(i = 0; i < MAX_STREAMS; i++) {
710             if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
711                 if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
712                 if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
713                 This->streamSource[i] = targetStateBlock->streamSource[i];
714             }
715         }
716         if(This->vertexShader != targetStateBlock->vertexShader) {
717             if(targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader);
718             if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
719             This->vertexShader = targetStateBlock->vertexShader;
720         }
721     } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
722         memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));
723         memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
724         memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
725         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
726             This->renderState[SavedPixelStates_R[i]] = targetStateBlock->renderState[SavedPixelStates_R[i]];
727         }
728         for (j = 0; j < MAX_COMBINED_SAMPLERS; j++) {
729             for (i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
730                 This->samplerState[j][SavedPixelStates_S[i]] = targetStateBlock->samplerState[j][SavedPixelStates_S[i]];
731             }
732         }
733         for (j = 0; j < MAX_TEXTURES; j++) {
734             for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
735                 This->textureState[j][SavedPixelStates_R[i]] = targetStateBlock->textureState[j][SavedPixelStates_R[i]];
736             }
737         }
738         if(This->pixelShader != targetStateBlock->pixelShader) {
739             if(targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader);
740             if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
741             This->pixelShader = targetStateBlock->pixelShader;
742         }
743     }
744
745     TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This);
746
747     return WINED3D_OK;
748 }
749
750 static inline void apply_lights(IWineD3DDevice *pDevice, IWineD3DStateBlockImpl *This) {
751     UINT i;
752     for(i = 0; i < LIGHTMAP_SIZE; i++) {
753         struct list *e;
754
755         LIST_FOR_EACH(e, &This->lightMap[i]) {
756             const PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
757
758             if(light->changed) {
759                 IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms);
760             }
761             if(light->enabledChanged) {
762                 IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1);
763             }
764         }
765     }
766 }
767
768 static HRESULT  WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface){
769     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
770     IWineD3DDevice*        pDevice     = (IWineD3DDevice*)This->wineD3DDevice;
771
772 /*Copy thing over to updateBlock is isRecording otherwise StateBlock,
773 should really perform a delta so that only the changes get updated*/
774
775     UINT i;
776     UINT j;
777     DWORD map;
778
779     TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice);
780
781     TRACE("Blocktype: %d\n", This->blockType);
782
783     if(This->blockType == WINED3DSBT_RECORDED) {
784         if (This->changed.vertexShader) {
785             IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
786         }
787         /* Vertex Shader Constants */
788         for (i = 0; i < This->num_contained_vs_consts_f; i++) {
789             IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i],
790                     This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1);
791         }
792         for (i = 0; i < This->num_contained_vs_consts_i; i++) {
793             IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i],
794                     This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1);
795         }
796         for (i = 0; i < This->num_contained_vs_consts_b; i++) {
797             IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i],
798                     This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1);
799         }
800
801         apply_lights(pDevice, This);
802
803         if (This->changed.pixelShader) {
804             IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
805         }
806         /* Pixel Shader Constants */
807         for (i = 0; i < This->num_contained_ps_consts_f; i++) {
808             IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i],
809                     This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1);
810         }
811         for (i = 0; i < This->num_contained_ps_consts_i; i++) {
812             IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i],
813                     This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1);
814         }
815         for (i = 0; i < This->num_contained_ps_consts_b; i++) {
816             IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i],
817                     This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1);
818         }
819
820         /* Render */
821         for (i = 0; i <= This->num_contained_render_states; i++) {
822             IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i],
823                                           This->renderState[This->contained_render_states[i]]);
824         }
825         /* Texture states */
826         for (i = 0; i < This->num_contained_tss_states; i++) {
827             DWORD stage = This->contained_tss_states[i].stage;
828             DWORD state = This->contained_tss_states[i].state;
829             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[stage][state]         = This->textureState[stage][state];
830             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.textureState[stage] |= 1 << state;
831             /* TODO: Record a display list to apply all gl states. For now apply by brute force */
832             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_TEXTURESTAGE(stage, state));
833         }
834         /* Sampler states */
835         for (i = 0; i < This->num_contained_sampler_states; i++) {
836             DWORD stage = This->contained_sampler_states[i].stage;
837             DWORD state = This->contained_sampler_states[i].state;
838             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->samplerState[stage][state]         = This->samplerState[stage][state];
839             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->changed.samplerState[stage] |= 1 << state;
840             IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *)pDevice, STATE_SAMPLER(stage));
841         }
842
843         for (i = 0; i < This->num_contained_transform_states; i++) {
844             IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i],
845                                         &This->transforms[This->contained_transform_states[i]]);
846         }
847
848         if (This->changed.primitive_type)
849         {
850                 This->wineD3DDevice->updateStateBlock->changed.primitive_type = TRUE;
851                 This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type;
852         }
853
854         if (This->changed.indices)
855         {
856             IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt);
857             IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
858         }
859
860         if (This->changed.vertexDecl) {
861             IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
862         }
863
864         if (This->changed.material ) {
865             IWineD3DDevice_SetMaterial(pDevice, &This->material);
866         }
867
868         if (This->changed.viewport) {
869             IWineD3DDevice_SetViewport(pDevice, &This->viewport);
870         }
871
872         if (This->changed.scissorRect) {
873             IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
874         }
875
876         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
877         map = This->changed.streamSource;
878         for (i = 0; map; map >>= 1, ++i)
879         {
880             if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
881         }
882
883         map = This->changed.streamFreq;
884         for (i = 0; map; map >>= 1, ++i)
885         {
886             if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
887         }
888
889         map = This->changed.textures;
890         for (i = 0; map; map >>= 1, ++i)
891         {
892             if (!(map & 1)) continue;
893
894             if (i < MAX_FRAGMENT_SAMPLERS) IWineD3DDevice_SetTexture(pDevice, i, This->textures[i]);
895             else IWineD3DDevice_SetTexture(pDevice, WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS,
896                     This->textures[i]);
897         }
898
899         map = This->changed.clipplane;
900         for (i = 0; map; map >>= 1, ++i)
901         {
902             float clip[4];
903
904             if (!(map & 1)) continue;
905
906             clip[0] = This->clipplane[i][0];
907             clip[1] = This->clipplane[i][1];
908             clip[2] = This->clipplane[i][2];
909             clip[3] = This->clipplane[i][3];
910             IWineD3DDevice_SetClipPlane(pDevice, i, clip);
911         }
912     } else if(This->blockType == WINED3DSBT_VERTEXSTATE) {
913         IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
914         for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
915             IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
916                     This->vertexShaderConstantF + i * 4, 1);
917         }
918         for (i = 0; i < MAX_CONST_I; i++) {
919             IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
920                     This->vertexShaderConstantI + i * 4, 1);
921         }
922         for (i = 0; i < MAX_CONST_B; i++) {
923             IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
924                     This->vertexShaderConstantB + i, 1);
925         }
926
927         apply_lights(pDevice, This);
928
929         for(i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++) {
930             IWineD3DDevice_SetRenderState(pDevice, SavedVertexStates_R[i], This->renderState[SavedVertexStates_R[i]]);
931         }
932         for(j = 0; j < MAX_TEXTURES; j++) {
933             for(i = 0; i < NUM_SAVEDVERTEXSTATES_T; i++) {
934                 IWineD3DDevice_SetTextureStageState(pDevice, j, SavedVertexStates_T[i],
935                         This->textureState[j][SavedVertexStates_T[i]]);
936             }
937         }
938
939         for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
940             for(i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
941                 IWineD3DDevice_SetSamplerState(pDevice, j, SavedVertexStates_S[i],
942                                                This->samplerState[j][SavedVertexStates_S[i]]);
943             }
944         }
945         for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
946             for(i = 0; i < NUM_SAVEDVERTEXSTATES_S; i++) {
947                 IWineD3DDevice_SetSamplerState(pDevice,
948                                                WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
949                                                SavedVertexStates_S[i],
950                                                This->samplerState[j][SavedVertexStates_S[i]]);
951             }
952         }
953     } else if(This->blockType == WINED3DSBT_PIXELSTATE) {
954         IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
955         for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
956             IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
957                     This->pixelShaderConstantF + i * 4, 1);
958         }
959         for (i = 0; i < MAX_CONST_I; i++) {
960             IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
961                     This->pixelShaderConstantI + i * 4, 1);
962         }
963         for (i = 0; i < MAX_CONST_B; i++) {
964             IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
965                     This->pixelShaderConstantB + i, 1);
966         }
967
968         for(i = 0; i < NUM_SAVEDPIXELSTATES_R; i++) {
969             IWineD3DDevice_SetRenderState(pDevice, SavedPixelStates_R[i], This->renderState[SavedPixelStates_R[i]]);
970         }
971         for(j = 0; j < MAX_TEXTURES; j++) {
972             for(i = 0; i < NUM_SAVEDPIXELSTATES_T; i++) {
973                 IWineD3DDevice_SetTextureStageState(pDevice, j, SavedPixelStates_T[i],
974                         This->textureState[j][SavedPixelStates_T[i]]);
975             }
976         }
977
978         for(j = 0; j < MAX_FRAGMENT_SAMPLERS; j++) {
979             for(i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
980                 IWineD3DDevice_SetSamplerState(pDevice, j, SavedPixelStates_S[i],
981                                                This->samplerState[j][SavedPixelStates_S[i]]);
982             }
983         }
984         for(j = MAX_FRAGMENT_SAMPLERS; j < MAX_COMBINED_SAMPLERS; j++) {
985             for(i = 0; i < NUM_SAVEDPIXELSTATES_S; i++) {
986                 IWineD3DDevice_SetSamplerState(pDevice,
987                                                WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS,
988                                                SavedPixelStates_S[i],
989                                                This->samplerState[j][SavedPixelStates_S[i]]);
990             }
991         }
992     } else if(This->blockType == WINED3DSBT_ALL) {
993         IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader);
994         for (i = 0; i < GL_LIMITS(vshader_constantsF); i++) {
995             IWineD3DDevice_SetVertexShaderConstantF(pDevice, i,
996                     This->vertexShaderConstantF + i * 4, 1);
997         }
998         for (i = 0; i < MAX_CONST_I; i++) {
999             IWineD3DDevice_SetVertexShaderConstantI(pDevice, i,
1000                     This->vertexShaderConstantI + i * 4, 1);
1001         }
1002         for (i = 0; i < MAX_CONST_B; i++) {
1003             IWineD3DDevice_SetVertexShaderConstantB(pDevice, i,
1004                     This->vertexShaderConstantB + i, 1);
1005         }
1006
1007         IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader);
1008         for (i = 0; i < GL_LIMITS(pshader_constantsF); i++) {
1009             IWineD3DDevice_SetPixelShaderConstantF(pDevice, i,
1010                     This->pixelShaderConstantF + i * 4, 1);
1011         }
1012         for (i = 0; i < MAX_CONST_I; i++) {
1013             IWineD3DDevice_SetPixelShaderConstantI(pDevice, i,
1014                     This->pixelShaderConstantI + i * 4, 1);
1015         }
1016         for (i = 0; i < MAX_CONST_B; i++) {
1017             IWineD3DDevice_SetPixelShaderConstantB(pDevice, i,
1018                     This->pixelShaderConstantB + i, 1);
1019         }
1020
1021         apply_lights(pDevice, This);
1022
1023         for(i = 1; i <= WINEHIGHEST_RENDER_STATE; i++) {
1024             IWineD3DDevice_SetRenderState(pDevice, i, This->renderState[i]);
1025         }
1026         for(j = 0; j < MAX_TEXTURES; j++) {
1027             for (i = 0; i <= WINED3D_HIGHEST_TEXTURE_STATE; ++i)
1028             {
1029                 IWineD3DDevice_SetTextureStageState(pDevice, j, i, This->textureState[j][i]);
1030             }
1031         }
1032
1033         /* Skip unused values between TEXTURE8 and WORLD0 ? */
1034         for(i = 1; i <= HIGHEST_TRANSFORMSTATE; i++) {
1035             IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
1036         }
1037         This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type;
1038         IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt);
1039         IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
1040         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
1041         IWineD3DDevice_SetMaterial(pDevice, &This->material);
1042         IWineD3DDevice_SetViewport(pDevice, &This->viewport);
1043         IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect);
1044
1045         /* TODO: Proper implementation using SetStreamSource offset (set to 0 for the moment)\n") */
1046         for (i=0; i<MAX_STREAMS; i++) {
1047             IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]);
1048             IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]);
1049         }
1050         for (j = 0 ; j < MAX_COMBINED_SAMPLERS; j++){
1051             UINT sampler = j < MAX_FRAGMENT_SAMPLERS ? j : WINED3DVERTEXTEXTURESAMPLER0 + j - MAX_FRAGMENT_SAMPLERS;
1052
1053             IWineD3DDevice_SetTexture(pDevice, sampler, This->textures[j]);
1054             for (i = 1; i <= WINED3D_HIGHEST_SAMPLER_STATE; ++i)
1055             {
1056                 IWineD3DDevice_SetSamplerState(pDevice, sampler, i, This->samplerState[j][i]);
1057             }
1058         }
1059         for (i = 0; i < GL_LIMITS(clipplanes); i++) {
1060             float clip[4];
1061
1062             clip[0] = This->clipplane[i][0];
1063             clip[1] = This->clipplane[i][1];
1064             clip[2] = This->clipplane[i][2];
1065             clip[3] = This->clipplane[i][3];
1066             IWineD3DDevice_SetClipPlane(pDevice, i, clip);
1067         }
1068     }
1069
1070     ((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1;
1071     for(j = 0; j < MAX_TEXTURES - 1; j++) {
1072         if(((IWineD3DDeviceImpl *)pDevice)->stateBlock->textureState[j][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
1073             ((IWineD3DDeviceImpl *)pDevice)->stateBlock->lowest_disabled_stage = j;
1074             break;
1075         }
1076     }
1077     TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice);
1078
1079     return WINED3D_OK;
1080 }
1081
1082 static HRESULT  WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
1083     IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
1084     IWineD3DDevice         *device = (IWineD3DDevice *)This->wineD3DDevice;
1085     IWineD3DDeviceImpl     *ThisDevice = (IWineD3DDeviceImpl *)device;
1086     union {
1087         WINED3DLINEPATTERN lp;
1088         DWORD d;
1089     } lp;
1090     union {
1091         float f;
1092         DWORD d;
1093     } tmpfloat;
1094     unsigned int i;
1095     IWineD3DSwapChain *swapchain;
1096     IWineD3DSurface *backbuffer;
1097     HRESULT hr;
1098
1099     /* Note this may have a large overhead but it should only be executed
1100        once, in order to initialize the complete state of the device and
1101        all opengl equivalents                                            */
1102     TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, This->wineD3DDevice);
1103     /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */
1104     This->blockType = WINED3DSBT_INIT;
1105
1106     /* Set some of the defaults for lights, transforms etc */
1107     memcpy(&This->transforms[WINED3DTS_PROJECTION], identity, sizeof(identity));
1108     memcpy(&This->transforms[WINED3DTS_VIEW], identity, sizeof(identity));
1109     for (i = 0; i < 256; ++i) {
1110       memcpy(&This->transforms[WINED3DTS_WORLDMATRIX(i)], identity, sizeof(identity));
1111     }
1112
1113     TRACE("Render states\n");
1114     /* Render states: */
1115     if (ThisDevice->auto_depth_stencil_buffer != NULL) {
1116        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       WINED3DZB_TRUE);
1117     } else {
1118        IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE,       WINED3DZB_FALSE);
1119     }
1120     IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE,         WINED3DFILL_SOLID);
1121     IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE,        WINED3DSHADE_GOURAUD);
1122     lp.lp.wRepeatFactor = 0;
1123     lp.lp.wLinePattern  = 0;
1124     IWineD3DDevice_SetRenderState(device, WINED3DRS_LINEPATTERN,      lp.d);
1125     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZWRITEENABLE,     TRUE);
1126     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHATESTENABLE,  FALSE);
1127     IWineD3DDevice_SetRenderState(device, WINED3DRS_LASTPIXEL,        TRUE);
1128     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLEND,         WINED3DBLEND_ONE);
1129     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLEND,        WINED3DBLEND_ZERO);
1130     IWineD3DDevice_SetRenderState(device, WINED3DRS_CULLMODE,         WINED3DCULL_CCW);
1131     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZFUNC,            WINED3DCMP_LESSEQUAL);
1132     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAFUNC,        WINED3DCMP_ALWAYS);
1133     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAREF,         0);
1134     IWineD3DDevice_SetRenderState(device, WINED3DRS_DITHERENABLE,     FALSE);
1135     IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHABLENDENABLE, FALSE);
1136     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGENABLE,        FALSE);
1137     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARENABLE,   FALSE);
1138     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZVISIBLE,         0);
1139     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGCOLOR,         0);
1140     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGTABLEMODE,     WINED3DFOG_NONE);
1141     tmpfloat.f = 0.0f;
1142     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGSTART,         tmpfloat.d);
1143     tmpfloat.f = 1.0f;
1144     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGEND,           tmpfloat.d);
1145     tmpfloat.f = 1.0f;
1146     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGDENSITY,       tmpfloat.d);
1147     IWineD3DDevice_SetRenderState(device, WINED3DRS_EDGEANTIALIAS,    FALSE);
1148     IWineD3DDevice_SetRenderState(device, WINED3DRS_ZBIAS,            0);
1149     IWineD3DDevice_SetRenderState(device, WINED3DRS_RANGEFOGENABLE,   FALSE);
1150     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILENABLE,    FALSE);
1151     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFAIL,      WINED3DSTENCILOP_KEEP);
1152     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILZFAIL,     WINED3DSTENCILOP_KEEP);
1153     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILPASS,      WINED3DSTENCILOP_KEEP);
1154     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILREF,       0);
1155     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILMASK,      0xFFFFFFFF);
1156     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFUNC,      WINED3DCMP_ALWAYS);
1157     IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
1158     IWineD3DDevice_SetRenderState(device, WINED3DRS_TEXTUREFACTOR,    0xFFFFFFFF);
1159     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP0, 0);
1160     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP1, 0);
1161     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP2, 0);
1162     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP3, 0);
1163     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP4, 0);
1164     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP5, 0);
1165     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP6, 0);
1166     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP7, 0);
1167     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPING,                 TRUE);
1168     IWineD3DDevice_SetRenderState(device, WINED3DRS_LIGHTING,                 TRUE);
1169     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENT,                  0);
1170     IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGVERTEXMODE,            WINED3DFOG_NONE);
1171     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORVERTEX,              TRUE);
1172     IWineD3DDevice_SetRenderState(device, WINED3DRS_LOCALVIEWER,              TRUE);
1173     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALIZENORMALS,         FALSE);
1174     IWineD3DDevice_SetRenderState(device, WINED3DRS_DIFFUSEMATERIALSOURCE,    WINED3DMCS_COLOR1);
1175     IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARMATERIALSOURCE,   WINED3DMCS_COLOR2);
1176     IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENTMATERIALSOURCE,    WINED3DMCS_MATERIAL);
1177     IWineD3DDevice_SetRenderState(device, WINED3DRS_EMISSIVEMATERIALSOURCE,   WINED3DMCS_MATERIAL);
1178     IWineD3DDevice_SetRenderState(device, WINED3DRS_VERTEXBLEND,              WINED3DVBF_DISABLE);
1179     IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPLANEENABLE,          0);
1180     IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
1181     tmpfloat.f = 1.0f;
1182     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE,                tmpfloat.d);
1183     tmpfloat.f = ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion < 9 ? 0.0f : 1.0f;
1184     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN,            tmpfloat.d);
1185     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE,        FALSE);
1186     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE,         FALSE);
1187     tmpfloat.f = 1.0f;
1188     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_A,             tmpfloat.d);
1189     tmpfloat.f = 0.0f;
1190     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_B,             tmpfloat.d);
1191     tmpfloat.f = 0.0f;
1192     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_C,             tmpfloat.d);
1193     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEANTIALIAS,     TRUE);
1194     IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEMASK,          0xFFFFFFFF);
1195     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHEDGESTYLE,           WINED3DPATCHEDGE_DISCRETE);
1196     tmpfloat.f = 1.0f;
1197     IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS,            tmpfloat.d);
1198     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN,        0xbaadcafe);
1199     tmpfloat.f = GL_LIMITS(pointsize);
1200     IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX,            tmpfloat.d);
1201     IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
1202     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE,         0x0000000F);
1203     tmpfloat.f = 0.0f;
1204     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWEENFACTOR,              tmpfloat.d);
1205     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOP,                  WINED3DBLENDOP_ADD);
1206     IWineD3DDevice_SetRenderState(device, WINED3DRS_POSITIONDEGREE,           WINED3DDEGREE_CUBIC);
1207     IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALDEGREE,             WINED3DDEGREE_LINEAR);
1208     /* states new in d3d9 */
1209     IWineD3DDevice_SetRenderState(device, WINED3DRS_SCISSORTESTENABLE,        FALSE);
1210     IWineD3DDevice_SetRenderState(device, WINED3DRS_SLOPESCALEDEPTHBIAS,      0);
1211     tmpfloat.f = 1.0f;
1212     IWineD3DDevice_SetRenderState(device, WINED3DRS_MINTESSELLATIONLEVEL,     tmpfloat.d);
1213     IWineD3DDevice_SetRenderState(device, WINED3DRS_MAXTESSELLATIONLEVEL,     tmpfloat.d);
1214     IWineD3DDevice_SetRenderState(device, WINED3DRS_ANTIALIASEDLINEENABLE,    FALSE);
1215     tmpfloat.f = 0.0f;
1216     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_X,           tmpfloat.d);
1217     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Y,           tmpfloat.d);
1218     tmpfloat.f = 1.0f;
1219     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Z,           tmpfloat.d);
1220     tmpfloat.f = 0.0f;
1221     IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_W,           tmpfloat.d);
1222     IWineD3DDevice_SetRenderState(device, WINED3DRS_ENABLEADAPTIVETESSELLATION, FALSE);
1223     IWineD3DDevice_SetRenderState(device, WINED3DRS_TWOSIDEDSTENCILMODE,      FALSE);
1224     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFAIL,          WINED3DSTENCILOP_KEEP);
1225     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILZFAIL,         WINED3DSTENCILOP_KEEP);
1226     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILPASS,          WINED3DSTENCILOP_KEEP);
1227     IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFUNC,          WINED3DCMP_ALWAYS);
1228     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE1,        0x0000000F);
1229     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE2,        0x0000000F);
1230     IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE3,        0x0000000F);
1231     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDFACTOR,              0xFFFFFFFF);
1232     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRGBWRITEENABLE,          0);
1233     IWineD3DDevice_SetRenderState(device, WINED3DRS_DEPTHBIAS,                0);
1234     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP8,  0);
1235     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP9,  0);
1236     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP10, 0);
1237     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP11, 0);
1238     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP12, 0);
1239     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP13, 0);
1240     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP14, 0);
1241     IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP15, 0);
1242     IWineD3DDevice_SetRenderState(device, WINED3DRS_SEPARATEALPHABLENDENABLE, FALSE);
1243     IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLENDALPHA,            WINED3DBLEND_ONE);
1244     IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLENDALPHA,           WINED3DBLEND_ZERO);
1245     IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOPALPHA,             WINED3DBLENDOP_ADD);
1246
1247     /* clipping status */
1248     This->clip_status.ClipUnion = 0;
1249     This->clip_status.ClipIntersection = 0xFFFFFFFF;
1250
1251     /* Texture Stage States - Put directly into state block, we will call function below */
1252     for (i = 0; i < MAX_TEXTURES; i++) {
1253         TRACE("Setting up default texture states for texture Stage %d\n", i);
1254         memcpy(&This->transforms[WINED3DTS_TEXTURE0 + i], identity, sizeof(identity));
1255         This->textureState[i][WINED3DTSS_COLOROP               ] = (i==0)? WINED3DTOP_MODULATE :  WINED3DTOP_DISABLE;
1256         This->textureState[i][WINED3DTSS_COLORARG1             ] = WINED3DTA_TEXTURE;
1257         This->textureState[i][WINED3DTSS_COLORARG2             ] = WINED3DTA_CURRENT;
1258         This->textureState[i][WINED3DTSS_ALPHAOP               ] = (i==0)? WINED3DTOP_SELECTARG1 :  WINED3DTOP_DISABLE;
1259         This->textureState[i][WINED3DTSS_ALPHAARG1             ] = WINED3DTA_TEXTURE;
1260         This->textureState[i][WINED3DTSS_ALPHAARG2             ] = WINED3DTA_CURRENT;
1261         This->textureState[i][WINED3DTSS_BUMPENVMAT00          ] = 0;
1262         This->textureState[i][WINED3DTSS_BUMPENVMAT01          ] = 0;
1263         This->textureState[i][WINED3DTSS_BUMPENVMAT10          ] = 0;
1264         This->textureState[i][WINED3DTSS_BUMPENVMAT11          ] = 0;
1265         This->textureState[i][WINED3DTSS_TEXCOORDINDEX         ] = i;
1266         This->textureState[i][WINED3DTSS_BUMPENVLSCALE         ] = 0;
1267         This->textureState[i][WINED3DTSS_BUMPENVLOFFSET        ] = 0;
1268         This->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS ] = WINED3DTTFF_DISABLE;
1269         This->textureState[i][WINED3DTSS_COLORARG0             ] = WINED3DTA_CURRENT;
1270         This->textureState[i][WINED3DTSS_ALPHAARG0             ] = WINED3DTA_CURRENT;
1271         This->textureState[i][WINED3DTSS_RESULTARG             ] = WINED3DTA_CURRENT;
1272     }
1273     This->lowest_disabled_stage = 1;
1274
1275         /* Sampler states*/
1276     for (i = 0 ; i <  MAX_COMBINED_SAMPLERS; i++) {
1277         TRACE("Setting up default samplers states for sampler %d\n", i);
1278         This->samplerState[i][WINED3DSAMP_ADDRESSU         ] = WINED3DTADDRESS_WRAP;
1279         This->samplerState[i][WINED3DSAMP_ADDRESSV         ] = WINED3DTADDRESS_WRAP;
1280         This->samplerState[i][WINED3DSAMP_ADDRESSW         ] = WINED3DTADDRESS_WRAP;
1281         This->samplerState[i][WINED3DSAMP_BORDERCOLOR      ] = 0x00;
1282         This->samplerState[i][WINED3DSAMP_MAGFILTER        ] = WINED3DTEXF_POINT;
1283         This->samplerState[i][WINED3DSAMP_MINFILTER        ] = WINED3DTEXF_POINT;
1284         This->samplerState[i][WINED3DSAMP_MIPFILTER        ] = WINED3DTEXF_NONE;
1285         This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS    ] = 0;
1286         This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL      ] = 0;
1287         This->samplerState[i][WINED3DSAMP_MAXANISOTROPY    ] = 1;
1288         This->samplerState[i][WINED3DSAMP_SRGBTEXTURE      ] = 0;
1289         This->samplerState[i][WINED3DSAMP_ELEMENTINDEX     ] = 0; /* TODO: Indicates which element of a  multielement texture to use */
1290         This->samplerState[i][WINED3DSAMP_DMAPOFFSET       ] = 0; /* TODO: Vertex offset in the presampled displacement map */
1291     }
1292
1293     for(i = 0; i < GL_LIMITS(textures); i++) {
1294         /* Note: This avoids calling SetTexture, so pretend it has been called */
1295         This->changed.textures |= 1 << i;
1296         This->textures[i]         = NULL;
1297     }
1298
1299     /* check the return values, because the GetBackBuffer call isn't valid for ddraw */
1300     hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain);
1301     if( hr == WINED3D_OK && swapchain != NULL) {
1302         WINED3DVIEWPORT vp;
1303
1304         hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer);
1305         if (SUCCEEDED(hr) && backbuffer)
1306         {
1307             WINED3DSURFACE_DESC desc;
1308             RECT scissorrect;
1309
1310             IWineD3DSurface_GetDesc(backbuffer, &desc);
1311             IWineD3DSurface_Release(backbuffer);
1312
1313             /* Set the default scissor rect values */
1314             scissorrect.left = 0;
1315             scissorrect.right = desc.width;
1316             scissorrect.top = 0;
1317             scissorrect.bottom = desc.height;
1318             hr = IWineD3DDevice_SetScissorRect(device, &scissorrect);
1319             if (FAILED(hr)) ERR("This should never happen, expect rendering issues!\n");
1320         }
1321
1322         /* Set the default viewport */
1323         vp.X      = 0;
1324         vp.Y      = 0;
1325         vp.Width  = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferWidth;
1326         vp.Height = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferHeight;
1327         vp.MinZ   = 0.0f;
1328         vp.MaxZ   = 1.0f;
1329         IWineD3DDevice_SetViewport(device, &vp);
1330
1331         IWineD3DSwapChain_Release(swapchain);
1332     }
1333
1334     TRACE("-----------------------> Device defaults now set up...\n");
1335     return WINED3D_OK;
1336 }
1337
1338 /**********************************************************
1339  * IWineD3DStateBlock VTbl follows
1340  **********************************************************/
1341
1342 static const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl =
1343 {
1344     /* IUnknown */
1345     IWineD3DStateBlockImpl_QueryInterface,
1346     IWineD3DStateBlockImpl_AddRef,
1347     IWineD3DStateBlockImpl_Release,
1348     /* IWineD3DStateBlock */
1349     IWineD3DStateBlockImpl_GetParent,
1350     IWineD3DStateBlockImpl_GetDevice,
1351     IWineD3DStateBlockImpl_Capture,
1352     IWineD3DStateBlockImpl_Apply,
1353     IWineD3DStateBlockImpl_InitStartupStateBlock
1354 };
1355
1356 HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device,
1357         WINED3DSTATEBLOCKTYPE type, IUnknown *parent)
1358 {
1359     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1360     unsigned int i, j;
1361     HRESULT hr;
1362
1363     stateblock->lpVtbl = &IWineD3DStateBlock_Vtbl;
1364     stateblock->ref = 1;
1365     stateblock->parent = parent;
1366     stateblock->wineD3DDevice = device;
1367     stateblock->blockType = type;
1368
1369     for (i = 0; i < LIGHTMAP_SIZE; i++)
1370     {
1371         list_init(&stateblock->lightMap[i]);
1372     }
1373
1374     hr = stateblock_allocate_shader_constants(stateblock);
1375     if (FAILED(hr)) return hr;
1376
1377     /* The WINED3DSBT_INIT stateblock type is used during initialization to
1378      * produce a placeholder stateblock so other functions called can update a
1379      * state block. */
1380     if (type == WINED3DSBT_INIT || type == WINED3DSBT_RECORDED) return WINED3D_OK;
1381
1382     /* Otherwise, might as well set the whole state block to the appropriate values  */
1383     if (device->stateBlock) stateblock_copy(stateblock, device->stateBlock);
1384     else memset(stateblock->streamFreq, 1, sizeof(stateblock->streamFreq));
1385
1386     /* Reset the ref and type after kludging it. */
1387     stateblock->wineD3DDevice = device;
1388     stateblock->ref = 1;
1389     stateblock->blockType = type;
1390
1391     TRACE("Updating changed flags appropriate for type %#x.\n", type);
1392
1393     if (type == WINED3DSBT_ALL)
1394     {
1395         TRACE("ALL => Pretend everything has changed.\n");
1396         stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, TRUE);
1397
1398         /* Lights are not part of the changed / set structure. */
1399         for (i = 0; i < LIGHTMAP_SIZE; ++i)
1400         {
1401             struct list *e;
1402             LIST_FOR_EACH(e, &stateblock->lightMap[i])
1403             {
1404                 PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
1405                 light->changed = TRUE;
1406                 light->enabledChanged = TRUE;
1407             }
1408         }
1409
1410         for (i = 1; i <= WINEHIGHEST_RENDER_STATE; ++i)
1411         {
1412             stateblock->contained_render_states[i - 1] = i;
1413         }
1414         stateblock->num_contained_render_states = WINEHIGHEST_RENDER_STATE;
1415
1416         /* TODO: Filter unused transforms between TEXTURE8 and WORLD0? */
1417         for (i = 1; i <= HIGHEST_TRANSFORMSTATE; ++i)
1418         {
1419             stateblock->contained_transform_states[i - 1] = i;
1420         }
1421         stateblock->num_contained_transform_states = HIGHEST_TRANSFORMSTATE;
1422
1423         for (i = 0; i < gl_info->max_vshader_constantsF; ++i)
1424         {
1425             stateblock->contained_vs_consts_f[i] = i;
1426         }
1427         stateblock->num_contained_vs_consts_f = gl_info->max_vshader_constantsF;
1428
1429         for (i = 0; i < MAX_CONST_I; ++i)
1430         {
1431             stateblock->contained_vs_consts_i[i] = i;
1432         }
1433         stateblock->num_contained_vs_consts_i = MAX_CONST_I;
1434
1435         for (i = 0; i < MAX_CONST_B; ++i)
1436         {
1437             stateblock->contained_vs_consts_b[i] = i;
1438         }
1439         stateblock->num_contained_vs_consts_b = MAX_CONST_B;
1440
1441         for (i = 0; i <  gl_info->max_pshader_constantsF; ++i)
1442         {
1443             stateblock->contained_ps_consts_f[i] = i;
1444         }
1445         stateblock->num_contained_ps_consts_f = gl_info->max_pshader_constantsF;
1446
1447         for (i = 0; i < MAX_CONST_I; ++i)
1448         {
1449             stateblock->contained_ps_consts_i[i] = i;
1450         }
1451         stateblock->num_contained_ps_consts_i = MAX_CONST_I;
1452
1453         for (i = 0; i < MAX_CONST_B; ++i)
1454         {
1455             stateblock->contained_ps_consts_b[i] = i;
1456         }
1457         stateblock->num_contained_ps_consts_b = MAX_CONST_B;
1458
1459         for (i = 0; i < MAX_TEXTURES; ++i)
1460         {
1461             for (j = 0; j <= WINED3D_HIGHEST_TEXTURE_STATE; ++j)
1462             {
1463                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
1464                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
1465                 ++stateblock->num_contained_tss_states;
1466             }
1467         }
1468
1469         for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
1470         {
1471             for (j = 1; j <= WINED3D_HIGHEST_SAMPLER_STATE; ++j)
1472             {
1473                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
1474                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
1475                 ++stateblock->num_contained_sampler_states;
1476             }
1477         }
1478
1479         for (i = 0; i < MAX_STREAMS; ++i)
1480         {
1481             if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
1482         }
1483
1484         if (stateblock->pIndexData) IWineD3DBuffer_AddRef(stateblock->pIndexData);
1485         if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);
1486         if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);
1487     }
1488     else if (type == WINED3DSBT_PIXELSTATE)
1489     {
1490         TRACE("PIXELSTATE => Pretend all pixel states have changed.\n");
1491         stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, FALSE);
1492
1493         /* Pixel Shader Constants. */
1494         for (i = 0; i <  gl_info->max_pshader_constantsF; ++i)
1495         {
1496             stateblock->contained_ps_consts_f[i] = i;
1497             stateblock->changed.pixelShaderConstantsF[i] = TRUE;
1498         }
1499         stateblock->num_contained_ps_consts_f =  gl_info->max_pshader_constantsF;
1500
1501         for (i = 0; i < MAX_CONST_B; ++i)
1502         {
1503             stateblock->contained_ps_consts_b[i] = i;
1504             stateblock->changed.pixelShaderConstantsB |= (1 << i);
1505         }
1506         stateblock->num_contained_ps_consts_b = MAX_CONST_B;
1507
1508         for (i = 0; i < MAX_CONST_I; ++i)
1509         {
1510             stateblock->contained_ps_consts_i[i] = i;
1511             stateblock->changed.pixelShaderConstantsI |= (1 << i);
1512         }
1513         stateblock->num_contained_ps_consts_i = MAX_CONST_I;
1514
1515         for (i = 0; i < NUM_SAVEDPIXELSTATES_R; i++)
1516         {
1517             DWORD rs = SavedPixelStates_R[i];
1518             stateblock->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
1519             stateblock->contained_render_states[i] = rs;
1520         }
1521         stateblock->num_contained_render_states = NUM_SAVEDPIXELSTATES_R;
1522
1523         for (i = 0; i < MAX_TEXTURES; ++i)
1524         {
1525             for (j = 0; j < NUM_SAVEDPIXELSTATES_T; ++j)
1526             {
1527                 DWORD state = SavedPixelStates_T[j];
1528                 stateblock->changed.textureState[i] |= 1 << state;
1529                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
1530                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = state;
1531                 ++stateblock->num_contained_tss_states;
1532             }
1533         }
1534
1535         for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
1536         {
1537             for (j = 0; j < NUM_SAVEDPIXELSTATES_S; ++j)
1538             {
1539                 DWORD state = SavedPixelStates_S[j];
1540                 stateblock->changed.samplerState[i] |= 1 << state;
1541                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
1542                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = state;
1543                 stateblock->num_contained_sampler_states++;
1544             }
1545         }
1546
1547         stateblock->changed.pixelShader = TRUE;
1548         if (stateblock->pixelShader) IWineD3DPixelShader_AddRef(stateblock->pixelShader);
1549
1550         /* Pixel state blocks do not contain vertex buffers. Set them to NULL
1551          * to avoid wrong refcounting on them. This makes releasing the buffer
1552          * easier. */
1553         for (i = 0; i < MAX_STREAMS; ++i)
1554         {
1555             stateblock->streamSource[i] = NULL;
1556         }
1557         stateblock->pIndexData = NULL;
1558         stateblock->vertexShader = NULL;
1559     }
1560     else if (type == WINED3DSBT_VERTEXSTATE)
1561     {
1562         TRACE("VERTEXSTATE => Pretend all vertex shates have changed.\n");
1563         stateblock_savedstates_set((IWineD3DStateBlock *)stateblock, &stateblock->changed, FALSE);
1564
1565         /* Vertex Shader Constants. */
1566         for (i = 0; i <  gl_info->max_vshader_constantsF; ++i)
1567         {
1568             stateblock->changed.vertexShaderConstantsF[i] = TRUE;
1569             stateblock->contained_vs_consts_f[i] = i;
1570         }
1571         stateblock->num_contained_vs_consts_f =  gl_info->max_vshader_constantsF;
1572
1573         for (i = 0; i < MAX_CONST_B; ++i)
1574         {
1575             stateblock->contained_vs_consts_b[i] = i;
1576             stateblock->changed.vertexShaderConstantsB |= (1 << i);
1577         }
1578         stateblock->num_contained_vs_consts_b = MAX_CONST_B;
1579
1580         for (i = 0; i < MAX_CONST_I; ++i)
1581         {
1582             stateblock->contained_vs_consts_i[i] = i;
1583             stateblock->changed.vertexShaderConstantsI |= (1 << i);
1584         }
1585         stateblock->num_contained_vs_consts_i = MAX_CONST_I;
1586
1587         for (i = 0; i < NUM_SAVEDVERTEXSTATES_R; i++)
1588         {
1589             DWORD rs = SavedVertexStates_R[i];
1590             stateblock->changed.renderState[rs >> 5] |= 1 << (rs & 0x1f);
1591             stateblock->contained_render_states[i] = rs;
1592         }
1593         stateblock->num_contained_render_states = NUM_SAVEDVERTEXSTATES_R;
1594
1595         for (i = 0; i < MAX_TEXTURES; ++i)
1596         {
1597             for (j = 0; j < NUM_SAVEDVERTEXSTATES_T; ++j)
1598             {
1599                 DWORD state = SavedVertexStates_T[j];
1600                 stateblock->changed.textureState[i] |= 1 << state;
1601                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
1602                 stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = state;
1603                 ++stateblock->num_contained_tss_states;
1604             }
1605         }
1606
1607         for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
1608         {
1609             for (j = 0; j < NUM_SAVEDVERTEXSTATES_S; ++j)
1610             {
1611                 DWORD state = SavedVertexStates_S[j];
1612                 stateblock->changed.samplerState[i] |= 1 << state;
1613                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
1614                 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = state;
1615                 ++stateblock->num_contained_sampler_states;
1616             }
1617         }
1618
1619         for (i = 0; i < LIGHTMAP_SIZE; ++i)
1620         {
1621             struct list *e;
1622             LIST_FOR_EACH(e, &stateblock->lightMap[i])
1623             {
1624                 PLIGHTINFOEL *light = LIST_ENTRY(e, PLIGHTINFOEL, entry);
1625                 light->changed = TRUE;
1626                 light->enabledChanged = TRUE;
1627             }
1628         }
1629
1630         for (i = 0; i < MAX_STREAMS; ++i)
1631         {
1632             if (stateblock->streamSource[i]) IWineD3DBuffer_AddRef(stateblock->streamSource[i]);
1633         }
1634
1635         stateblock->changed.vertexShader = TRUE;
1636         if (stateblock->vertexShader) IWineD3DVertexShader_AddRef(stateblock->vertexShader);
1637
1638         stateblock->pIndexData = NULL;
1639         stateblock->pixelShader = NULL;
1640     }
1641     else
1642     {
1643         FIXME("Unrecognized state block type %#x.\n", type);
1644     }
1645
1646     return WINED3D_OK;
1647 }