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