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