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