winex11: Remove support for owner-displayed clipboard formats.
[wine.git] / dlls / wined3d / stateblock.c
blob2fbfa2ce631e4af867eda5f2941fdcd24f898b38
1 /*
2 * state block implementation
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
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.
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.
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
25 #include "config.h"
26 #include "wine/port.h"
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
31 static const DWORD pixel_states_render[] =
33 WINED3D_RS_ALPHABLENDENABLE,
34 WINED3D_RS_ALPHAFUNC,
35 WINED3D_RS_ALPHAREF,
36 WINED3D_RS_ALPHATESTENABLE,
37 WINED3D_RS_ANTIALIASEDLINEENABLE,
38 WINED3D_RS_BLENDFACTOR,
39 WINED3D_RS_BLENDOP,
40 WINED3D_RS_BLENDOPALPHA,
41 WINED3D_RS_CCW_STENCILFAIL,
42 WINED3D_RS_CCW_STENCILPASS,
43 WINED3D_RS_CCW_STENCILZFAIL,
44 WINED3D_RS_COLORWRITEENABLE,
45 WINED3D_RS_COLORWRITEENABLE1,
46 WINED3D_RS_COLORWRITEENABLE2,
47 WINED3D_RS_COLORWRITEENABLE3,
48 WINED3D_RS_DEPTHBIAS,
49 WINED3D_RS_DESTBLEND,
50 WINED3D_RS_DESTBLENDALPHA,
51 WINED3D_RS_DITHERENABLE,
52 WINED3D_RS_FILLMODE,
53 WINED3D_RS_FOGDENSITY,
54 WINED3D_RS_FOGEND,
55 WINED3D_RS_FOGSTART,
56 WINED3D_RS_LASTPIXEL,
57 WINED3D_RS_SCISSORTESTENABLE,
58 WINED3D_RS_SEPARATEALPHABLENDENABLE,
59 WINED3D_RS_SHADEMODE,
60 WINED3D_RS_SLOPESCALEDEPTHBIAS,
61 WINED3D_RS_SRCBLEND,
62 WINED3D_RS_SRCBLENDALPHA,
63 WINED3D_RS_SRGBWRITEENABLE,
64 WINED3D_RS_STENCILENABLE,
65 WINED3D_RS_STENCILFAIL,
66 WINED3D_RS_STENCILFUNC,
67 WINED3D_RS_STENCILMASK,
68 WINED3D_RS_STENCILPASS,
69 WINED3D_RS_STENCILREF,
70 WINED3D_RS_STENCILWRITEMASK,
71 WINED3D_RS_STENCILZFAIL,
72 WINED3D_RS_TEXTUREFACTOR,
73 WINED3D_RS_TWOSIDEDSTENCILMODE,
74 WINED3D_RS_WRAP0,
75 WINED3D_RS_WRAP1,
76 WINED3D_RS_WRAP10,
77 WINED3D_RS_WRAP11,
78 WINED3D_RS_WRAP12,
79 WINED3D_RS_WRAP13,
80 WINED3D_RS_WRAP14,
81 WINED3D_RS_WRAP15,
82 WINED3D_RS_WRAP2,
83 WINED3D_RS_WRAP3,
84 WINED3D_RS_WRAP4,
85 WINED3D_RS_WRAP5,
86 WINED3D_RS_WRAP6,
87 WINED3D_RS_WRAP7,
88 WINED3D_RS_WRAP8,
89 WINED3D_RS_WRAP9,
90 WINED3D_RS_ZENABLE,
91 WINED3D_RS_ZFUNC,
92 WINED3D_RS_ZWRITEENABLE,
95 static const DWORD pixel_states_texture[] =
97 WINED3D_TSS_ALPHA_ARG0,
98 WINED3D_TSS_ALPHA_ARG1,
99 WINED3D_TSS_ALPHA_ARG2,
100 WINED3D_TSS_ALPHA_OP,
101 WINED3D_TSS_BUMPENV_LOFFSET,
102 WINED3D_TSS_BUMPENV_LSCALE,
103 WINED3D_TSS_BUMPENV_MAT00,
104 WINED3D_TSS_BUMPENV_MAT01,
105 WINED3D_TSS_BUMPENV_MAT10,
106 WINED3D_TSS_BUMPENV_MAT11,
107 WINED3D_TSS_COLOR_ARG0,
108 WINED3D_TSS_COLOR_ARG1,
109 WINED3D_TSS_COLOR_ARG2,
110 WINED3D_TSS_COLOR_OP,
111 WINED3D_TSS_RESULT_ARG,
112 WINED3D_TSS_TEXCOORD_INDEX,
113 WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
116 static const DWORD pixel_states_sampler[] =
118 WINED3D_SAMP_ADDRESS_U,
119 WINED3D_SAMP_ADDRESS_V,
120 WINED3D_SAMP_ADDRESS_W,
121 WINED3D_SAMP_BORDER_COLOR,
122 WINED3D_SAMP_MAG_FILTER,
123 WINED3D_SAMP_MIN_FILTER,
124 WINED3D_SAMP_MIP_FILTER,
125 WINED3D_SAMP_MIPMAP_LOD_BIAS,
126 WINED3D_SAMP_MAX_MIP_LEVEL,
127 WINED3D_SAMP_MAX_ANISOTROPY,
128 WINED3D_SAMP_SRGB_TEXTURE,
129 WINED3D_SAMP_ELEMENT_INDEX,
132 static const DWORD vertex_states_render[] =
134 WINED3D_RS_ADAPTIVETESS_W,
135 WINED3D_RS_ADAPTIVETESS_X,
136 WINED3D_RS_ADAPTIVETESS_Y,
137 WINED3D_RS_ADAPTIVETESS_Z,
138 WINED3D_RS_AMBIENT,
139 WINED3D_RS_AMBIENTMATERIALSOURCE,
140 WINED3D_RS_CLIPPING,
141 WINED3D_RS_CLIPPLANEENABLE,
142 WINED3D_RS_COLORVERTEX,
143 WINED3D_RS_CULLMODE,
144 WINED3D_RS_DIFFUSEMATERIALSOURCE,
145 WINED3D_RS_EMISSIVEMATERIALSOURCE,
146 WINED3D_RS_ENABLEADAPTIVETESSELLATION,
147 WINED3D_RS_FOGCOLOR,
148 WINED3D_RS_FOGDENSITY,
149 WINED3D_RS_FOGENABLE,
150 WINED3D_RS_FOGEND,
151 WINED3D_RS_FOGSTART,
152 WINED3D_RS_FOGTABLEMODE,
153 WINED3D_RS_FOGVERTEXMODE,
154 WINED3D_RS_INDEXEDVERTEXBLENDENABLE,
155 WINED3D_RS_LIGHTING,
156 WINED3D_RS_LOCALVIEWER,
157 WINED3D_RS_MAXTESSELLATIONLEVEL,
158 WINED3D_RS_MINTESSELLATIONLEVEL,
159 WINED3D_RS_MULTISAMPLEANTIALIAS,
160 WINED3D_RS_MULTISAMPLEMASK,
161 WINED3D_RS_NORMALDEGREE,
162 WINED3D_RS_NORMALIZENORMALS,
163 WINED3D_RS_PATCHEDGESTYLE,
164 WINED3D_RS_POINTSCALE_A,
165 WINED3D_RS_POINTSCALE_B,
166 WINED3D_RS_POINTSCALE_C,
167 WINED3D_RS_POINTSCALEENABLE,
168 WINED3D_RS_POINTSIZE,
169 WINED3D_RS_POINTSIZE_MAX,
170 WINED3D_RS_POINTSIZE_MIN,
171 WINED3D_RS_POINTSPRITEENABLE,
172 WINED3D_RS_POSITIONDEGREE,
173 WINED3D_RS_RANGEFOGENABLE,
174 WINED3D_RS_SHADEMODE,
175 WINED3D_RS_SPECULARENABLE,
176 WINED3D_RS_SPECULARMATERIALSOURCE,
177 WINED3D_RS_TWEENFACTOR,
178 WINED3D_RS_VERTEXBLEND,
181 static const DWORD vertex_states_texture[] =
183 WINED3D_TSS_TEXCOORD_INDEX,
184 WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS,
187 static const DWORD vertex_states_sampler[] =
189 WINED3D_SAMP_DMAP_OFFSET,
192 static inline void stateblock_set_bits(DWORD *map, UINT map_size)
194 DWORD mask = (1u << (map_size & 0x1f)) - 1;
195 memset(map, 0xff, (map_size >> 5) * sizeof(*map));
196 if (mask) map[map_size >> 5] = mask;
199 /* Set all members of a stateblock savedstate to the given value */
200 static void stateblock_savedstates_set_all(struct wined3d_saved_states *states, DWORD vs_consts, DWORD ps_consts)
202 unsigned int i;
204 /* Single values */
205 states->primitive_type = 1;
206 states->indices = 1;
207 states->material = 1;
208 states->viewport = 1;
209 states->vertexDecl = 1;
210 states->pixelShader = 1;
211 states->vertexShader = 1;
212 states->scissorRect = 1;
214 /* Fixed size arrays */
215 states->streamSource = 0xffff;
216 states->streamFreq = 0xffff;
217 states->textures = 0xfffff;
218 stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1);
219 stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1);
220 for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff;
221 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3ffe;
222 states->clipplane = 0xffffffff;
223 states->pixelShaderConstantsB = 0xffff;
224 states->pixelShaderConstantsI = 0xffff;
225 states->vertexShaderConstantsB = 0xffff;
226 states->vertexShaderConstantsI = 0xffff;
228 /* Dynamically sized arrays */
229 memset(states->ps_consts_f, TRUE, sizeof(BOOL) * ps_consts);
230 memset(states->vs_consts_f, TRUE, sizeof(BOOL) * vs_consts);
233 static void stateblock_savedstates_set_pixel(struct wined3d_saved_states *states, const DWORD num_constants)
235 DWORD texture_mask = 0;
236 WORD sampler_mask = 0;
237 unsigned int i;
239 states->pixelShader = 1;
241 for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i)
243 DWORD rs = pixel_states_render[i];
244 states->renderState[rs >> 5] |= 1u << (rs & 0x1f);
247 for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i)
248 texture_mask |= 1u << pixel_states_texture[i];
249 for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
250 for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i)
251 sampler_mask |= 1u << pixel_states_sampler[i];
252 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
253 states->pixelShaderConstantsB = 0xffff;
254 states->pixelShaderConstantsI = 0xffff;
256 memset(states->ps_consts_f, TRUE, sizeof(BOOL) * num_constants);
259 static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *states, const DWORD num_constants)
261 DWORD texture_mask = 0;
262 WORD sampler_mask = 0;
263 unsigned int i;
265 states->vertexDecl = 1;
266 states->vertexShader = 1;
268 for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i)
270 DWORD rs = vertex_states_render[i];
271 states->renderState[rs >> 5] |= 1u << (rs & 0x1f);
274 for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i)
275 texture_mask |= 1u << vertex_states_texture[i];
276 for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask;
277 for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i)
278 sampler_mask |= 1u << vertex_states_sampler[i];
279 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask;
280 states->vertexShaderConstantsB = 0xffff;
281 states->vertexShaderConstantsI = 0xffff;
283 memset(states->vs_consts_f, TRUE, sizeof(BOOL) * num_constants);
286 void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
288 const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
289 unsigned int i, j;
291 for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i)
293 DWORD map = stateblock->changed.renderState[i];
294 for (j = 0; map; map >>= 1, ++j)
296 if (!(map & 1)) continue;
298 stateblock->contained_render_states[stateblock->num_contained_render_states] = (i << 5) | j;
299 ++stateblock->num_contained_render_states;
303 for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i)
305 DWORD map = stateblock->changed.transform[i];
306 for (j = 0; map; map >>= 1, ++j)
308 if (!(map & 1)) continue;
310 stateblock->contained_transform_states[stateblock->num_contained_transform_states] = (i << 5) | j;
311 ++stateblock->num_contained_transform_states;
315 for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
317 if (stateblock->changed.vs_consts_f[i])
319 stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i;
320 ++stateblock->num_contained_vs_consts_f;
324 for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
326 if (stateblock->changed.vertexShaderConstantsI & (1u << i))
328 stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i;
329 ++stateblock->num_contained_vs_consts_i;
333 for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
335 if (stateblock->changed.vertexShaderConstantsB & (1u << i))
337 stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i;
338 ++stateblock->num_contained_vs_consts_b;
342 for (i = 0; i < d3d_info->limits.ps_uniform_count; ++i)
344 if (stateblock->changed.ps_consts_f[i])
346 stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i;
347 ++stateblock->num_contained_ps_consts_f;
351 for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i)
353 if (stateblock->changed.pixelShaderConstantsI & (1u << i))
355 stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i;
356 ++stateblock->num_contained_ps_consts_i;
360 for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i)
362 if (stateblock->changed.pixelShaderConstantsB & (1u << i))
364 stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i;
365 ++stateblock->num_contained_ps_consts_b;
369 for (i = 0; i < MAX_TEXTURES; ++i)
371 DWORD map = stateblock->changed.textureState[i];
373 for(j = 0; map; map >>= 1, ++j)
375 if (!(map & 1)) continue;
377 stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i;
378 stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j;
379 ++stateblock->num_contained_tss_states;
383 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
385 DWORD map = stateblock->changed.samplerState[i];
387 for (j = 0; map; map >>= 1, ++j)
389 if (!(map & 1)) continue;
391 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i;
392 stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j;
393 ++stateblock->num_contained_sampler_states;
398 static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct list *light_map)
400 unsigned int i;
402 for (i = 0; i < LIGHTMAP_SIZE; ++i)
404 const struct wined3d_light_info *src_light;
406 LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry)
408 struct wined3d_light_info *dst_light = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_light));
410 *dst_light = *src_light;
411 list_add_tail(&stateblock->state.light_map[i], &dst_light->entry);
416 ULONG CDECL wined3d_stateblock_incref(struct wined3d_stateblock *stateblock)
418 ULONG refcount = InterlockedIncrement(&stateblock->ref);
420 TRACE("%p increasing refcount to %u.\n", stateblock, refcount);
422 return refcount;
425 void state_unbind_resources(struct wined3d_state *state)
427 struct wined3d_shader_resource_view *srv;
428 struct wined3d_vertex_declaration *decl;
429 struct wined3d_sampler *sampler;
430 struct wined3d_texture *texture;
431 struct wined3d_buffer *buffer;
432 struct wined3d_shader *shader;
433 unsigned int i, j;
435 if ((decl = state->vertex_declaration))
437 state->vertex_declaration = NULL;
438 wined3d_vertex_declaration_decref(decl);
441 for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
443 if ((texture = state->textures[i]))
445 state->textures[i] = NULL;
446 wined3d_texture_decref(texture);
450 for (i = 0; i < MAX_STREAM_OUT; ++i)
452 if ((buffer = state->stream_output[i].buffer))
454 state->stream_output[i].buffer = NULL;
455 wined3d_buffer_decref(buffer);
459 for (i = 0; i < MAX_STREAMS; ++i)
461 if ((buffer = state->streams[i].buffer))
463 state->streams[i].buffer = NULL;
464 wined3d_buffer_decref(buffer);
468 if ((buffer = state->index_buffer))
470 state->index_buffer = NULL;
471 wined3d_buffer_decref(buffer);
474 for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
476 if ((shader = state->shader[i]))
478 state->shader[i] = NULL;
479 wined3d_shader_decref(shader);
482 for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j)
484 if ((buffer = state->cb[i][j]))
486 state->cb[i][j] = NULL;
487 wined3d_buffer_decref(buffer);
491 for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j)
493 if ((sampler = state->sampler[i][j]))
495 state->sampler[i][j] = NULL;
496 wined3d_sampler_decref(sampler);
500 for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j)
502 if ((srv = state->shader_resource_view[i][j]))
504 state->shader_resource_view[i][j] = NULL;
505 wined3d_shader_resource_view_decref(srv);
511 void state_cleanup(struct wined3d_state *state)
513 unsigned int counter;
515 if (!(state->flags & WINED3D_STATE_NO_REF))
516 state_unbind_resources(state);
518 for (counter = 0; counter < MAX_ACTIVE_LIGHTS; ++counter)
520 state->lights[counter] = NULL;
523 for (counter = 0; counter < LIGHTMAP_SIZE; ++counter)
525 struct list *e1, *e2;
526 LIST_FOR_EACH_SAFE(e1, e2, &state->light_map[counter])
528 struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry);
529 list_remove(&light->entry);
530 HeapFree(GetProcessHeap(), 0, light);
535 ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
537 ULONG refcount = InterlockedDecrement(&stateblock->ref);
539 TRACE("%p decreasing refcount to %u\n", stateblock, refcount);
541 if (!refcount)
543 state_cleanup(&stateblock->state);
544 HeapFree(GetProcessHeap(), 0, stateblock);
547 return refcount;
550 static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state)
552 UINT i;
554 /* Lights... For a recorded state block, we just had a chain of actions
555 * to perform, so we need to walk that chain and update any actions which
556 * differ. */
557 for (i = 0; i < LIGHTMAP_SIZE; ++i)
559 struct list *e, *f;
560 LIST_FOR_EACH(e, &dst_state->light_map[i])
562 BOOL updated = FALSE;
563 struct wined3d_light_info *src = LIST_ENTRY(e, struct wined3d_light_info, entry), *realLight;
565 /* Look up the light in the destination */
566 LIST_FOR_EACH(f, &src_state->light_map[i])
568 realLight = LIST_ENTRY(f, struct wined3d_light_info, entry);
569 if (realLight->OriginalIndex == src->OriginalIndex)
571 src->OriginalParms = realLight->OriginalParms;
573 if (realLight->glIndex == -1 && src->glIndex != -1)
575 /* Light disabled */
576 dst_state->lights[src->glIndex] = NULL;
578 else if (realLight->glIndex != -1 && src->glIndex == -1)
580 /* Light enabled */
581 dst_state->lights[realLight->glIndex] = src;
583 src->glIndex = realLight->glIndex;
584 updated = TRUE;
585 break;
589 if (!updated)
591 /* This can happen if the light was originally created as a
592 * default light for SetLightEnable() while recording. */
593 WARN("Light %u in dst_state %p does not exist in src_state %p.\n",
594 src->OriginalIndex, dst_state, src_state);
596 src->OriginalParms = WINED3D_default_light;
597 if (src->glIndex != -1)
599 dst_state->lights[src->glIndex] = NULL;
600 src->glIndex = -1;
607 void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock)
609 const struct wined3d_state *src_state = &stateblock->device->state;
610 unsigned int i;
611 DWORD map;
613 TRACE("stateblock %p.\n", stateblock);
615 TRACE("Capturing state %p.\n", src_state);
617 if (stateblock->changed.vertexShader && stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]
618 != src_state->shader[WINED3D_SHADER_TYPE_VERTEX])
620 TRACE("Updating vertex shader from %p to %p\n",
621 stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX],
622 src_state->shader[WINED3D_SHADER_TYPE_VERTEX]);
624 if (src_state->shader[WINED3D_SHADER_TYPE_VERTEX])
625 wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_VERTEX]);
626 if (stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX])
627 wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]);
628 stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] = src_state->shader[WINED3D_SHADER_TYPE_VERTEX];
631 /* Vertex shader float constants. */
632 for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
634 unsigned int idx = stateblock->contained_vs_consts_f[i];
636 TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->vs_consts_f[idx]));
638 stateblock->state.vs_consts_f[idx] = src_state->vs_consts_f[idx];
641 /* Vertex shader integer constants. */
642 for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
644 unsigned int idx = stateblock->contained_vs_consts_i[i];
646 TRACE("Setting vs_consts[%u] to %s.\n", idx, debug_ivec4(&src_state->vs_consts_i[idx]));
648 stateblock->state.vs_consts_i[idx] = src_state->vs_consts_i[idx];
651 /* Vertex shader boolean constants. */
652 for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
654 unsigned int idx = stateblock->contained_vs_consts_b[i];
656 TRACE("Setting vs_consts_b[%u] to %s.\n",
657 idx, src_state->vs_consts_b[idx] ? "TRUE" : "FALSE");
659 stateblock->state.vs_consts_b[idx] = src_state->vs_consts_b[idx];
662 /* Pixel shader float constants. */
663 for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
665 unsigned int idx = stateblock->contained_ps_consts_f[i];
667 TRACE("Setting ps_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->ps_consts_f[idx]));
669 stateblock->state.ps_consts_f[idx] = src_state->ps_consts_f[idx];
672 /* Pixel shader integer constants. */
673 for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
675 unsigned int idx = stateblock->contained_ps_consts_i[i];
677 TRACE("Setting ps_consts_i[%u] to %s.\n", idx, debug_ivec4(&src_state->ps_consts_i[idx]));
679 stateblock->state.ps_consts_i[idx] = src_state->ps_consts_i[idx];
682 /* Pixel shader boolean constants. */
683 for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
685 unsigned int idx = stateblock->contained_ps_consts_b[i];
686 TRACE("Setting ps_consts_b[%u] to %s.\n",
687 idx, src_state->ps_consts_b[idx] ? "TRUE" : "FALSE");
689 stateblock->state.ps_consts_b[idx] = src_state->ps_consts_b[idx];
692 /* Others + Render & Texture */
693 for (i = 0; i < stateblock->num_contained_transform_states; ++i)
695 enum wined3d_transform_state transform = stateblock->contained_transform_states[i];
697 TRACE("Updating transform %#x.\n", transform);
699 stateblock->state.transforms[transform] = src_state->transforms[transform];
702 if (stateblock->changed.primitive_type)
703 stateblock->state.gl_primitive_type = src_state->gl_primitive_type;
705 if (stateblock->changed.indices
706 && ((stateblock->state.index_buffer != src_state->index_buffer)
707 || (stateblock->state.base_vertex_index != src_state->base_vertex_index)
708 || (stateblock->state.index_format != src_state->index_format)
709 || (stateblock->state.index_offset != src_state->index_offset)))
711 TRACE("Updating index buffer to %p, base vertex index to %d.\n",
712 src_state->index_buffer, src_state->base_vertex_index);
714 if (src_state->index_buffer)
715 wined3d_buffer_incref(src_state->index_buffer);
716 if (stateblock->state.index_buffer)
717 wined3d_buffer_decref(stateblock->state.index_buffer);
718 stateblock->state.index_buffer = src_state->index_buffer;
719 stateblock->state.base_vertex_index = src_state->base_vertex_index;
720 stateblock->state.index_format = src_state->index_format;
721 stateblock->state.index_offset = src_state->index_offset;
724 if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration != src_state->vertex_declaration)
726 TRACE("Updating vertex declaration from %p to %p.\n",
727 stateblock->state.vertex_declaration, src_state->vertex_declaration);
729 if (src_state->vertex_declaration)
730 wined3d_vertex_declaration_incref(src_state->vertex_declaration);
731 if (stateblock->state.vertex_declaration)
732 wined3d_vertex_declaration_decref(stateblock->state.vertex_declaration);
733 stateblock->state.vertex_declaration = src_state->vertex_declaration;
736 if (stateblock->changed.material
737 && memcmp(&src_state->material, &stateblock->state.material, sizeof(stateblock->state.material)))
739 TRACE("Updating material.\n");
741 stateblock->state.material = src_state->material;
744 if (stateblock->changed.viewport
745 && memcmp(&src_state->viewport, &stateblock->state.viewport, sizeof(stateblock->state.viewport)))
747 TRACE("Updating viewport.\n");
749 stateblock->state.viewport = src_state->viewport;
752 if (stateblock->changed.scissorRect && memcmp(&src_state->scissor_rect,
753 &stateblock->state.scissor_rect, sizeof(stateblock->state.scissor_rect)))
755 TRACE("Updating scissor rect.\n");
757 stateblock->state.scissor_rect = src_state->scissor_rect;
760 map = stateblock->changed.streamSource;
761 for (i = 0; map; map >>= 1, ++i)
763 if (!(map & 1)) continue;
765 if (stateblock->state.streams[i].stride != src_state->streams[i].stride
766 || stateblock->state.streams[i].buffer != src_state->streams[i].buffer)
768 TRACE("Updating stream source %u to %p, stride to %u.\n",
769 i, src_state->streams[i].buffer,
770 src_state->streams[i].stride);
772 stateblock->state.streams[i].stride = src_state->streams[i].stride;
773 if (src_state->streams[i].buffer)
774 wined3d_buffer_incref(src_state->streams[i].buffer);
775 if (stateblock->state.streams[i].buffer)
776 wined3d_buffer_decref(stateblock->state.streams[i].buffer);
777 stateblock->state.streams[i].buffer = src_state->streams[i].buffer;
781 map = stateblock->changed.streamFreq;
782 for (i = 0; map; map >>= 1, ++i)
784 if (!(map & 1)) continue;
786 if (stateblock->state.streams[i].frequency != src_state->streams[i].frequency
787 || stateblock->state.streams[i].flags != src_state->streams[i].flags)
789 TRACE("Updating stream frequency %u to %u flags to %#x.\n",
790 i, src_state->streams[i].frequency, src_state->streams[i].flags);
792 stateblock->state.streams[i].frequency = src_state->streams[i].frequency;
793 stateblock->state.streams[i].flags = src_state->streams[i].flags;
797 map = stateblock->changed.clipplane;
798 for (i = 0; map; map >>= 1, ++i)
800 if (!(map & 1)) continue;
802 if (memcmp(&stateblock->state.clip_planes[i], &src_state->clip_planes[i], sizeof(src_state->clip_planes[i])))
804 TRACE("Updating clipplane %u.\n", i);
805 stateblock->state.clip_planes[i] = src_state->clip_planes[i];
809 /* Render */
810 for (i = 0; i < stateblock->num_contained_render_states; ++i)
812 enum wined3d_render_state rs = stateblock->contained_render_states[i];
814 TRACE("Updating render state %#x to %u.\n", rs, src_state->render_states[rs]);
816 stateblock->state.render_states[rs] = src_state->render_states[rs];
819 /* Texture states */
820 for (i = 0; i < stateblock->num_contained_tss_states; ++i)
822 DWORD stage = stateblock->contained_tss_states[i].stage;
823 DWORD state = stateblock->contained_tss_states[i].state;
825 TRACE("Updating texturestage state %u, %u to %#x (was %#x).\n", stage, state,
826 src_state->texture_states[stage][state], stateblock->state.texture_states[stage][state]);
828 stateblock->state.texture_states[stage][state] = src_state->texture_states[stage][state];
831 /* Samplers */
832 map = stateblock->changed.textures;
833 for (i = 0; map; map >>= 1, ++i)
835 if (!(map & 1)) continue;
837 TRACE("Updating texture %u to %p (was %p).\n",
838 i, src_state->textures[i], stateblock->state.textures[i]);
840 if (src_state->textures[i])
841 wined3d_texture_incref(src_state->textures[i]);
842 if (stateblock->state.textures[i])
843 wined3d_texture_decref(stateblock->state.textures[i]);
844 stateblock->state.textures[i] = src_state->textures[i];
847 for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
849 DWORD stage = stateblock->contained_sampler_states[i].stage;
850 DWORD state = stateblock->contained_sampler_states[i].state;
852 TRACE("Updating sampler state %u, %u to %#x (was %#x).\n", stage, state,
853 src_state->sampler_states[stage][state], stateblock->state.sampler_states[stage][state]);
855 stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state];
858 if (stateblock->changed.pixelShader && stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]
859 != src_state->shader[WINED3D_SHADER_TYPE_PIXEL])
861 if (src_state->shader[WINED3D_SHADER_TYPE_PIXEL])
862 wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_PIXEL]);
863 if (stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL])
864 wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]);
865 stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] = src_state->shader[WINED3D_SHADER_TYPE_PIXEL];
868 wined3d_state_record_lights(&stateblock->state, src_state);
870 TRACE("Capture done.\n");
873 static void apply_lights(struct wined3d_device *device, const struct wined3d_state *state)
875 UINT i;
877 for (i = 0; i < LIGHTMAP_SIZE; ++i)
879 struct list *e;
881 LIST_FOR_EACH(e, &state->light_map[i])
883 const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry);
885 wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
886 wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1);
891 void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock)
893 struct wined3d_device *device = stateblock->device;
894 unsigned int i;
895 DWORD map;
897 TRACE("Applying stateblock %p to device %p.\n", stateblock, device);
899 if (stateblock->changed.vertexShader)
900 wined3d_device_set_vertex_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]);
902 /* Vertex Shader Constants. */
903 for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i)
905 wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i],
906 1, &stateblock->state.vs_consts_f[stateblock->contained_vs_consts_f[i]]);
908 for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i)
910 wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i],
911 1, &stateblock->state.vs_consts_i[stateblock->contained_vs_consts_i[i]]);
913 for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i)
915 wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i],
916 1, &stateblock->state.vs_consts_b[stateblock->contained_vs_consts_b[i]]);
919 apply_lights(device, &stateblock->state);
921 if (stateblock->changed.pixelShader)
922 wined3d_device_set_pixel_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]);
924 /* Pixel Shader Constants. */
925 for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i)
927 wined3d_device_set_ps_consts_f(device, stateblock->contained_ps_consts_f[i],
928 1, &stateblock->state.ps_consts_f[stateblock->contained_ps_consts_f[i]]);
930 for (i = 0; i < stateblock->num_contained_ps_consts_i; ++i)
932 wined3d_device_set_ps_consts_i(device, stateblock->contained_ps_consts_i[i],
933 1, &stateblock->state.ps_consts_i[stateblock->contained_ps_consts_i[i]]);
935 for (i = 0; i < stateblock->num_contained_ps_consts_b; ++i)
937 wined3d_device_set_ps_consts_b(device, stateblock->contained_ps_consts_b[i],
938 1, &stateblock->state.ps_consts_b[stateblock->contained_ps_consts_b[i]]);
941 /* Render states. */
942 for (i = 0; i < stateblock->num_contained_render_states; ++i)
944 wined3d_device_set_render_state(device, stateblock->contained_render_states[i],
945 stateblock->state.render_states[stateblock->contained_render_states[i]]);
948 /* Texture states. */
949 for (i = 0; i < stateblock->num_contained_tss_states; ++i)
951 DWORD stage = stateblock->contained_tss_states[i].stage;
952 DWORD state = stateblock->contained_tss_states[i].state;
954 wined3d_device_set_texture_stage_state(device, stage, state, stateblock->state.texture_states[stage][state]);
957 /* Sampler states. */
958 for (i = 0; i < stateblock->num_contained_sampler_states; ++i)
960 DWORD stage = stateblock->contained_sampler_states[i].stage;
961 DWORD state = stateblock->contained_sampler_states[i].state;
962 DWORD value = stateblock->state.sampler_states[stage][state];
964 if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS;
965 wined3d_device_set_sampler_state(device, stage, state, value);
968 /* Transform states. */
969 for (i = 0; i < stateblock->num_contained_transform_states; ++i)
971 wined3d_device_set_transform(device, stateblock->contained_transform_states[i],
972 &stateblock->state.transforms[stateblock->contained_transform_states[i]]);
975 if (stateblock->changed.primitive_type)
977 GLenum gl_primitive_type, prev;
979 if (device->recording)
980 device->recording->changed.primitive_type = TRUE;
981 gl_primitive_type = stateblock->state.gl_primitive_type;
982 prev = device->update_state->gl_primitive_type;
983 device->update_state->gl_primitive_type = gl_primitive_type;
984 if (gl_primitive_type != prev && (gl_primitive_type == GL_POINTS || prev == GL_POINTS))
985 device_invalidate_state(device, STATE_POINT_ENABLE);
988 if (stateblock->changed.indices)
990 wined3d_device_set_index_buffer(device, stateblock->state.index_buffer,
991 stateblock->state.index_format, stateblock->state.index_offset);
992 wined3d_device_set_base_vertex_index(device, stateblock->state.base_vertex_index);
995 if (stateblock->changed.vertexDecl && stateblock->state.vertex_declaration)
996 wined3d_device_set_vertex_declaration(device, stateblock->state.vertex_declaration);
998 if (stateblock->changed.material)
999 wined3d_device_set_material(device, &stateblock->state.material);
1001 if (stateblock->changed.viewport)
1002 wined3d_device_set_viewport(device, &stateblock->state.viewport);
1004 if (stateblock->changed.scissorRect)
1005 wined3d_device_set_scissor_rect(device, &stateblock->state.scissor_rect);
1007 map = stateblock->changed.streamSource;
1008 for (i = 0; map; map >>= 1, ++i)
1010 if (map & 1)
1011 wined3d_device_set_stream_source(device, i,
1012 stateblock->state.streams[i].buffer,
1013 0, stateblock->state.streams[i].stride);
1016 map = stateblock->changed.streamFreq;
1017 for (i = 0; map; map >>= 1, ++i)
1019 if (map & 1)
1020 wined3d_device_set_stream_source_freq(device, i,
1021 stateblock->state.streams[i].frequency | stateblock->state.streams[i].flags);
1024 map = stateblock->changed.textures;
1025 for (i = 0; map; map >>= 1, ++i)
1027 DWORD stage;
1029 if (!(map & 1)) continue;
1031 stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS;
1032 wined3d_device_set_texture(device, stage, stateblock->state.textures[i]);
1035 map = stateblock->changed.clipplane;
1036 for (i = 0; map; map >>= 1, ++i)
1038 if (!(map & 1)) continue;
1040 wined3d_device_set_clip_plane(device, i, &stateblock->state.clip_planes[i]);
1043 TRACE("Applied stateblock %p.\n", stateblock);
1046 static void state_init_default(struct wined3d_state *state, const struct wined3d_gl_info *gl_info)
1048 union
1050 struct wined3d_line_pattern lp;
1051 DWORD d;
1052 } lp;
1053 union {
1054 float f;
1055 DWORD d;
1056 } tmpfloat;
1057 unsigned int i;
1058 struct wined3d_matrix identity;
1060 TRACE("state %p, gl_info %p.\n", state, gl_info);
1062 get_identity_matrix(&identity);
1063 state->gl_primitive_type = ~0u;
1065 /* Set some of the defaults for lights, transforms etc */
1066 state->transforms[WINED3D_TS_PROJECTION] = identity;
1067 state->transforms[WINED3D_TS_VIEW] = identity;
1068 for (i = 0; i < 256; ++i)
1070 state->transforms[WINED3D_TS_WORLD_MATRIX(i)] = identity;
1073 TRACE("Render states\n");
1074 /* Render states: */
1075 state->render_states[WINED3D_RS_ZENABLE] = WINED3D_ZB_TRUE;
1076 state->render_states[WINED3D_RS_FILLMODE] = WINED3D_FILL_SOLID;
1077 state->render_states[WINED3D_RS_SHADEMODE] = WINED3D_SHADE_GOURAUD;
1078 lp.lp.repeat_factor = 0;
1079 lp.lp.line_pattern = 0;
1080 state->render_states[WINED3D_RS_LINEPATTERN] = lp.d;
1081 state->render_states[WINED3D_RS_ZWRITEENABLE] = TRUE;
1082 state->render_states[WINED3D_RS_ALPHATESTENABLE] = FALSE;
1083 state->render_states[WINED3D_RS_LASTPIXEL] = TRUE;
1084 state->render_states[WINED3D_RS_SRCBLEND] = WINED3D_BLEND_ONE;
1085 state->render_states[WINED3D_RS_DESTBLEND] = WINED3D_BLEND_ZERO;
1086 state->render_states[WINED3D_RS_CULLMODE] = WINED3D_CULL_BACK;
1087 state->render_states[WINED3D_RS_ZFUNC] = WINED3D_CMP_LESSEQUAL;
1088 state->render_states[WINED3D_RS_ALPHAFUNC] = WINED3D_CMP_ALWAYS;
1089 state->render_states[WINED3D_RS_ALPHAREF] = 0;
1090 state->render_states[WINED3D_RS_DITHERENABLE] = FALSE;
1091 state->render_states[WINED3D_RS_ALPHABLENDENABLE] = FALSE;
1092 state->render_states[WINED3D_RS_FOGENABLE] = FALSE;
1093 state->render_states[WINED3D_RS_SPECULARENABLE] = FALSE;
1094 state->render_states[WINED3D_RS_ZVISIBLE] = 0;
1095 state->render_states[WINED3D_RS_FOGCOLOR] = 0;
1096 state->render_states[WINED3D_RS_FOGTABLEMODE] = WINED3D_FOG_NONE;
1097 tmpfloat.f = 0.0f;
1098 state->render_states[WINED3D_RS_FOGSTART] = tmpfloat.d;
1099 tmpfloat.f = 1.0f;
1100 state->render_states[WINED3D_RS_FOGEND] = tmpfloat.d;
1101 tmpfloat.f = 1.0f;
1102 state->render_states[WINED3D_RS_FOGDENSITY] = tmpfloat.d;
1103 state->render_states[WINED3D_RS_EDGEANTIALIAS] = FALSE;
1104 state->render_states[WINED3D_RS_RANGEFOGENABLE] = FALSE;
1105 state->render_states[WINED3D_RS_STENCILENABLE] = FALSE;
1106 state->render_states[WINED3D_RS_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
1107 state->render_states[WINED3D_RS_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
1108 state->render_states[WINED3D_RS_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
1109 state->render_states[WINED3D_RS_STENCILREF] = 0;
1110 state->render_states[WINED3D_RS_STENCILMASK] = 0xffffffff;
1111 state->render_states[WINED3D_RS_STENCILFUNC] = WINED3D_CMP_ALWAYS;
1112 state->render_states[WINED3D_RS_STENCILWRITEMASK] = 0xffffffff;
1113 state->render_states[WINED3D_RS_TEXTUREFACTOR] = 0xffffffff;
1114 state->render_states[WINED3D_RS_WRAP0] = 0;
1115 state->render_states[WINED3D_RS_WRAP1] = 0;
1116 state->render_states[WINED3D_RS_WRAP2] = 0;
1117 state->render_states[WINED3D_RS_WRAP3] = 0;
1118 state->render_states[WINED3D_RS_WRAP4] = 0;
1119 state->render_states[WINED3D_RS_WRAP5] = 0;
1120 state->render_states[WINED3D_RS_WRAP6] = 0;
1121 state->render_states[WINED3D_RS_WRAP7] = 0;
1122 state->render_states[WINED3D_RS_CLIPPING] = TRUE;
1123 state->render_states[WINED3D_RS_LIGHTING] = TRUE;
1124 state->render_states[WINED3D_RS_AMBIENT] = 0;
1125 state->render_states[WINED3D_RS_FOGVERTEXMODE] = WINED3D_FOG_NONE;
1126 state->render_states[WINED3D_RS_COLORVERTEX] = TRUE;
1127 state->render_states[WINED3D_RS_LOCALVIEWER] = TRUE;
1128 state->render_states[WINED3D_RS_NORMALIZENORMALS] = FALSE;
1129 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] = WINED3D_MCS_COLOR1;
1130 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] = WINED3D_MCS_COLOR2;
1131 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
1132 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] = WINED3D_MCS_MATERIAL;
1133 state->render_states[WINED3D_RS_VERTEXBLEND] = WINED3D_VBF_DISABLE;
1134 state->render_states[WINED3D_RS_CLIPPLANEENABLE] = 0;
1135 state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING] = FALSE;
1136 tmpfloat.f = 1.0f;
1137 state->render_states[WINED3D_RS_POINTSIZE] = tmpfloat.d;
1138 tmpfloat.f = 1.0f;
1139 state->render_states[WINED3D_RS_POINTSIZE_MIN] = tmpfloat.d;
1140 state->render_states[WINED3D_RS_POINTSPRITEENABLE] = FALSE;
1141 state->render_states[WINED3D_RS_POINTSCALEENABLE] = FALSE;
1142 tmpfloat.f = 1.0f;
1143 state->render_states[WINED3D_RS_POINTSCALE_A] = tmpfloat.d;
1144 tmpfloat.f = 0.0f;
1145 state->render_states[WINED3D_RS_POINTSCALE_B] = tmpfloat.d;
1146 tmpfloat.f = 0.0f;
1147 state->render_states[WINED3D_RS_POINTSCALE_C] = tmpfloat.d;
1148 state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS] = TRUE;
1149 state->render_states[WINED3D_RS_MULTISAMPLEMASK] = 0xffffffff;
1150 state->render_states[WINED3D_RS_PATCHEDGESTYLE] = WINED3D_PATCH_EDGE_DISCRETE;
1151 tmpfloat.f = 1.0f;
1152 state->render_states[WINED3D_RS_PATCHSEGMENTS] = tmpfloat.d;
1153 state->render_states[WINED3D_RS_DEBUGMONITORTOKEN] = 0xbaadcafe;
1154 tmpfloat.f = gl_info->limits.pointsize_max;
1155 state->render_states[WINED3D_RS_POINTSIZE_MAX] = tmpfloat.d;
1156 state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] = FALSE;
1157 state->render_states[WINED3D_RS_COLORWRITEENABLE] = 0x0000000f;
1158 tmpfloat.f = 0.0f;
1159 state->render_states[WINED3D_RS_TWEENFACTOR] = tmpfloat.d;
1160 state->render_states[WINED3D_RS_BLENDOP] = WINED3D_BLEND_OP_ADD;
1161 state->render_states[WINED3D_RS_POSITIONDEGREE] = WINED3D_DEGREE_CUBIC;
1162 state->render_states[WINED3D_RS_NORMALDEGREE] = WINED3D_DEGREE_LINEAR;
1163 /* states new in d3d9 */
1164 state->render_states[WINED3D_RS_SCISSORTESTENABLE] = FALSE;
1165 state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS] = 0;
1166 tmpfloat.f = 1.0f;
1167 state->render_states[WINED3D_RS_MINTESSELLATIONLEVEL] = tmpfloat.d;
1168 state->render_states[WINED3D_RS_MAXTESSELLATIONLEVEL] = tmpfloat.d;
1169 state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE] = FALSE;
1170 tmpfloat.f = 0.0f;
1171 state->render_states[WINED3D_RS_ADAPTIVETESS_X] = tmpfloat.d;
1172 state->render_states[WINED3D_RS_ADAPTIVETESS_Y] = tmpfloat.d;
1173 tmpfloat.f = 1.0f;
1174 state->render_states[WINED3D_RS_ADAPTIVETESS_Z] = tmpfloat.d;
1175 tmpfloat.f = 0.0f;
1176 state->render_states[WINED3D_RS_ADAPTIVETESS_W] = tmpfloat.d;
1177 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION] = FALSE;
1178 state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE] = FALSE;
1179 state->render_states[WINED3D_RS_CCW_STENCILFAIL] = WINED3D_STENCIL_OP_KEEP;
1180 state->render_states[WINED3D_RS_CCW_STENCILZFAIL] = WINED3D_STENCIL_OP_KEEP;
1181 state->render_states[WINED3D_RS_CCW_STENCILPASS] = WINED3D_STENCIL_OP_KEEP;
1182 state->render_states[WINED3D_RS_CCW_STENCILFUNC] = WINED3D_CMP_ALWAYS;
1183 state->render_states[WINED3D_RS_COLORWRITEENABLE1] = 0x0000000f;
1184 state->render_states[WINED3D_RS_COLORWRITEENABLE2] = 0x0000000f;
1185 state->render_states[WINED3D_RS_COLORWRITEENABLE3] = 0x0000000f;
1186 state->render_states[WINED3D_RS_BLENDFACTOR] = 0xffffffff;
1187 state->render_states[WINED3D_RS_SRGBWRITEENABLE] = 0;
1188 state->render_states[WINED3D_RS_DEPTHBIAS] = 0;
1189 state->render_states[WINED3D_RS_WRAP8] = 0;
1190 state->render_states[WINED3D_RS_WRAP9] = 0;
1191 state->render_states[WINED3D_RS_WRAP10] = 0;
1192 state->render_states[WINED3D_RS_WRAP11] = 0;
1193 state->render_states[WINED3D_RS_WRAP12] = 0;
1194 state->render_states[WINED3D_RS_WRAP13] = 0;
1195 state->render_states[WINED3D_RS_WRAP14] = 0;
1196 state->render_states[WINED3D_RS_WRAP15] = 0;
1197 state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE] = FALSE;
1198 state->render_states[WINED3D_RS_SRCBLENDALPHA] = WINED3D_BLEND_ONE;
1199 state->render_states[WINED3D_RS_DESTBLENDALPHA] = WINED3D_BLEND_ZERO;
1200 state->render_states[WINED3D_RS_BLENDOPALPHA] = WINED3D_BLEND_OP_ADD;
1202 /* Texture Stage States - Put directly into state block, we will call function below */
1203 for (i = 0; i < MAX_TEXTURES; ++i)
1205 TRACE("Setting up default texture states for texture Stage %u.\n", i);
1206 state->transforms[WINED3D_TS_TEXTURE0 + i] = identity;
1207 state->texture_states[i][WINED3D_TSS_COLOR_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_MODULATE;
1208 state->texture_states[i][WINED3D_TSS_COLOR_ARG1] = WINED3DTA_TEXTURE;
1209 state->texture_states[i][WINED3D_TSS_COLOR_ARG2] = WINED3DTA_CURRENT;
1210 state->texture_states[i][WINED3D_TSS_ALPHA_OP] = i ? WINED3D_TOP_DISABLE : WINED3D_TOP_SELECT_ARG1;
1211 state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] = WINED3DTA_TEXTURE;
1212 state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] = WINED3DTA_CURRENT;
1213 state->texture_states[i][WINED3D_TSS_BUMPENV_MAT00] = 0;
1214 state->texture_states[i][WINED3D_TSS_BUMPENV_MAT01] = 0;
1215 state->texture_states[i][WINED3D_TSS_BUMPENV_MAT10] = 0;
1216 state->texture_states[i][WINED3D_TSS_BUMPENV_MAT11] = 0;
1217 state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] = i;
1218 state->texture_states[i][WINED3D_TSS_BUMPENV_LSCALE] = 0;
1219 state->texture_states[i][WINED3D_TSS_BUMPENV_LOFFSET] = 0;
1220 state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS] = WINED3D_TTFF_DISABLE;
1221 state->texture_states[i][WINED3D_TSS_COLOR_ARG0] = WINED3DTA_CURRENT;
1222 state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] = WINED3DTA_CURRENT;
1223 state->texture_states[i][WINED3D_TSS_RESULT_ARG] = WINED3DTA_CURRENT;
1226 for (i = 0 ; i < MAX_COMBINED_SAMPLERS; ++i)
1228 TRACE("Setting up default samplers states for sampler %u.\n", i);
1229 state->sampler_states[i][WINED3D_SAMP_ADDRESS_U] = WINED3D_TADDRESS_WRAP;
1230 state->sampler_states[i][WINED3D_SAMP_ADDRESS_V] = WINED3D_TADDRESS_WRAP;
1231 state->sampler_states[i][WINED3D_SAMP_ADDRESS_W] = WINED3D_TADDRESS_WRAP;
1232 state->sampler_states[i][WINED3D_SAMP_BORDER_COLOR] = 0;
1233 state->sampler_states[i][WINED3D_SAMP_MAG_FILTER] = WINED3D_TEXF_POINT;
1234 state->sampler_states[i][WINED3D_SAMP_MIN_FILTER] = WINED3D_TEXF_POINT;
1235 state->sampler_states[i][WINED3D_SAMP_MIP_FILTER] = WINED3D_TEXF_NONE;
1236 state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] = 0;
1237 state->sampler_states[i][WINED3D_SAMP_MAX_MIP_LEVEL] = 0;
1238 state->sampler_states[i][WINED3D_SAMP_MAX_ANISOTROPY] = 1;
1239 state->sampler_states[i][WINED3D_SAMP_SRGB_TEXTURE] = 0;
1240 /* TODO: Indicates which element of a multielement texture to use. */
1241 state->sampler_states[i][WINED3D_SAMP_ELEMENT_INDEX] = 0;
1242 /* TODO: Vertex offset in the presampled displacement map. */
1243 state->sampler_states[i][WINED3D_SAMP_DMAP_OFFSET] = 0;
1247 void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb,
1248 const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
1249 DWORD flags)
1251 unsigned int i;
1253 state->flags = flags;
1254 state->fb = fb;
1256 for (i = 0; i < LIGHTMAP_SIZE; i++)
1258 list_init(&state->light_map[i]);
1261 if (flags & WINED3D_STATE_INIT_DEFAULT)
1262 state_init_default(state, gl_info);
1265 static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
1266 struct wined3d_device *device, enum wined3d_stateblock_type type)
1268 const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
1270 stateblock->ref = 1;
1271 stateblock->device = device;
1272 state_init(&stateblock->state, NULL, &device->adapter->gl_info, d3d_info, 0);
1274 if (type == WINED3D_SBT_RECORDED)
1275 return WINED3D_OK;
1277 TRACE("Updating changed flags appropriate for type %#x.\n", type);
1279 switch (type)
1281 case WINED3D_SBT_ALL:
1282 stateblock_init_lights(stateblock, device->state.light_map);
1283 stateblock_savedstates_set_all(&stateblock->changed,
1284 d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
1285 break;
1287 case WINED3D_SBT_PIXEL_STATE:
1288 stateblock_savedstates_set_pixel(&stateblock->changed,
1289 d3d_info->limits.ps_uniform_count);
1290 break;
1292 case WINED3D_SBT_VERTEX_STATE:
1293 stateblock_init_lights(stateblock, device->state.light_map);
1294 stateblock_savedstates_set_vertex(&stateblock->changed,
1295 d3d_info->limits.vs_uniform_count);
1296 break;
1298 default:
1299 FIXME("Unrecognized state block type %#x.\n", type);
1300 break;
1303 stateblock_init_contained_states(stateblock);
1304 wined3d_stateblock_capture(stateblock);
1306 return WINED3D_OK;
1309 HRESULT CDECL wined3d_stateblock_create(struct wined3d_device *device,
1310 enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock)
1312 struct wined3d_stateblock *object;
1313 HRESULT hr;
1315 TRACE("device %p, type %#x, stateblock %p.\n",
1316 device, type, stateblock);
1318 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1319 if (!object)
1320 return E_OUTOFMEMORY;
1322 hr = stateblock_init(object, device, type);
1323 if (FAILED(hr))
1325 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1326 HeapFree(GetProcessHeap(), 0, object);
1327 return hr;
1330 TRACE("Created stateblock %p.\n", object);
1331 *stateblock = object;
1333 return WINED3D_OK;