Commit | Line | Data |
---|---|---|
447d5ed0 JE |
1 | /* |
2 | * state block implementation | |
3 | * | |
4 | * Copyright 2002 Raphael Junqueira | |
16e86890 OS |
5 | * Copyright 2004 Jason Edmeades |
6 | * Copyright 2005 Oliver Stieber | |
6cfef95c | 7 | * Copyright 2007 Stefan Dösinger for CodeWeavers |
709aedf5 | 8 | * Copyright 2009 Henri Verbeet for CodeWeavers |
447d5ed0 JE |
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 | |
360a3f91 | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
447d5ed0 JE |
23 | */ |
24 | ||
25 | #include "config.h" | |
26 | #include "wined3d_private.h" | |
27 | ||
28 | WINE_DEFAULT_DEBUG_CHANNEL(d3d); | |
29 | ||
048c9450 | 30 | static const DWORD pixel_states_render[] = |
8b3f8687 HV |
31 | { |
32 | WINED3DRS_ALPHABLENDENABLE, | |
33 | WINED3DRS_ALPHAFUNC, | |
34 | WINED3DRS_ALPHAREF, | |
35 | WINED3DRS_ALPHATESTENABLE, | |
3dbfda1a HV |
36 | WINED3DRS_ANTIALIASEDLINEENABLE, |
37 | WINED3DRS_BLENDFACTOR, | |
8b3f8687 | 38 | WINED3DRS_BLENDOP, |
3dbfda1a HV |
39 | WINED3DRS_BLENDOPALPHA, |
40 | WINED3DRS_CCW_STENCILFAIL, | |
41 | WINED3DRS_CCW_STENCILPASS, | |
42 | WINED3DRS_CCW_STENCILZFAIL, | |
8b3f8687 | 43 | WINED3DRS_COLORWRITEENABLE, |
3dbfda1a HV |
44 | WINED3DRS_COLORWRITEENABLE1, |
45 | WINED3DRS_COLORWRITEENABLE2, | |
46 | WINED3DRS_COLORWRITEENABLE3, | |
47 | WINED3DRS_DEPTHBIAS, | |
8b3f8687 | 48 | WINED3DRS_DESTBLEND, |
3dbfda1a | 49 | WINED3DRS_DESTBLENDALPHA, |
8b3f8687 HV |
50 | WINED3DRS_DITHERENABLE, |
51 | WINED3DRS_FILLMODE, | |
52 | WINED3DRS_FOGDENSITY, | |
53 | WINED3DRS_FOGEND, | |
54 | WINED3DRS_FOGSTART, | |
55 | WINED3DRS_LASTPIXEL, | |
3dbfda1a HV |
56 | WINED3DRS_SCISSORTESTENABLE, |
57 | WINED3DRS_SEPARATEALPHABLENDENABLE, | |
8b3f8687 | 58 | WINED3DRS_SHADEMODE, |
3dbfda1a | 59 | WINED3DRS_SLOPESCALEDEPTHBIAS, |
8b3f8687 | 60 | WINED3DRS_SRCBLEND, |
3dbfda1a HV |
61 | WINED3DRS_SRCBLENDALPHA, |
62 | WINED3DRS_SRGBWRITEENABLE, | |
8b3f8687 HV |
63 | WINED3DRS_STENCILENABLE, |
64 | WINED3DRS_STENCILFAIL, | |
65 | WINED3DRS_STENCILFUNC, | |
66 | WINED3DRS_STENCILMASK, | |
67 | WINED3DRS_STENCILPASS, | |
68 | WINED3DRS_STENCILREF, | |
69 | WINED3DRS_STENCILWRITEMASK, | |
70 | WINED3DRS_STENCILZFAIL, | |
71 | WINED3DRS_TEXTUREFACTOR, | |
3dbfda1a | 72 | WINED3DRS_TWOSIDEDSTENCILMODE, |
8b3f8687 HV |
73 | WINED3DRS_WRAP0, |
74 | WINED3DRS_WRAP1, | |
3dbfda1a HV |
75 | WINED3DRS_WRAP10, |
76 | WINED3DRS_WRAP11, | |
77 | WINED3DRS_WRAP12, | |
78 | WINED3DRS_WRAP13, | |
79 | WINED3DRS_WRAP14, | |
80 | WINED3DRS_WRAP15, | |
8b3f8687 HV |
81 | WINED3DRS_WRAP2, |
82 | WINED3DRS_WRAP3, | |
83 | WINED3DRS_WRAP4, | |
84 | WINED3DRS_WRAP5, | |
85 | WINED3DRS_WRAP6, | |
86 | WINED3DRS_WRAP7, | |
3dbfda1a HV |
87 | WINED3DRS_WRAP8, |
88 | WINED3DRS_WRAP9, | |
8b3f8687 HV |
89 | WINED3DRS_ZENABLE, |
90 | WINED3DRS_ZFUNC, | |
91 | WINED3DRS_ZWRITEENABLE, | |
92 | }; | |
93 | ||
048c9450 | 94 | static const DWORD pixel_states_texture[] = |
8b3f8687 HV |
95 | { |
96 | WINED3DTSS_ALPHAARG0, | |
97 | WINED3DTSS_ALPHAARG1, | |
98 | WINED3DTSS_ALPHAARG2, | |
99 | WINED3DTSS_ALPHAOP, | |
100 | WINED3DTSS_BUMPENVLOFFSET, | |
101 | WINED3DTSS_BUMPENVLSCALE, | |
102 | WINED3DTSS_BUMPENVMAT00, | |
103 | WINED3DTSS_BUMPENVMAT01, | |
104 | WINED3DTSS_BUMPENVMAT10, | |
105 | WINED3DTSS_BUMPENVMAT11, | |
106 | WINED3DTSS_COLORARG0, | |
107 | WINED3DTSS_COLORARG1, | |
108 | WINED3DTSS_COLORARG2, | |
109 | WINED3DTSS_COLOROP, | |
110 | WINED3DTSS_RESULTARG, | |
111 | WINED3DTSS_TEXCOORDINDEX, | |
112 | WINED3DTSS_TEXTURETRANSFORMFLAGS, | |
113 | }; | |
114 | ||
048c9450 | 115 | static const DWORD pixel_states_sampler[] = |
8b3f8687 HV |
116 | { |
117 | WINED3DSAMP_ADDRESSU, | |
118 | WINED3DSAMP_ADDRESSV, | |
119 | WINED3DSAMP_ADDRESSW, | |
120 | WINED3DSAMP_BORDERCOLOR, | |
121 | WINED3DSAMP_MAGFILTER, | |
122 | WINED3DSAMP_MINFILTER, | |
123 | WINED3DSAMP_MIPFILTER, | |
124 | WINED3DSAMP_MIPMAPLODBIAS, | |
125 | WINED3DSAMP_MAXMIPLEVEL, | |
126 | WINED3DSAMP_MAXANISOTROPY, | |
127 | WINED3DSAMP_SRGBTEXTURE, | |
128 | WINED3DSAMP_ELEMENTINDEX, | |
129 | }; | |
130 | ||
048c9450 | 131 | static const DWORD vertex_states_render[] = |
8b3f8687 | 132 | { |
3dbfda1a HV |
133 | WINED3DRS_ADAPTIVETESS_W, |
134 | WINED3DRS_ADAPTIVETESS_X, | |
135 | WINED3DRS_ADAPTIVETESS_Y, | |
136 | WINED3DRS_ADAPTIVETESS_Z, | |
8b3f8687 HV |
137 | WINED3DRS_AMBIENT, |
138 | WINED3DRS_AMBIENTMATERIALSOURCE, | |
139 | WINED3DRS_CLIPPING, | |
140 | WINED3DRS_CLIPPLANEENABLE, | |
141 | WINED3DRS_COLORVERTEX, | |
3dbfda1a | 142 | WINED3DRS_CULLMODE, |
8b3f8687 HV |
143 | WINED3DRS_DIFFUSEMATERIALSOURCE, |
144 | WINED3DRS_EMISSIVEMATERIALSOURCE, | |
3dbfda1a HV |
145 | WINED3DRS_ENABLEADAPTIVETESSELLATION, |
146 | WINED3DRS_FOGCOLOR, | |
8b3f8687 | 147 | WINED3DRS_FOGDENSITY, |
3dbfda1a | 148 | WINED3DRS_FOGENABLE, |
8b3f8687 HV |
149 | WINED3DRS_FOGEND, |
150 | WINED3DRS_FOGSTART, | |
151 | WINED3DRS_FOGTABLEMODE, | |
152 | WINED3DRS_FOGVERTEXMODE, | |
153 | WINED3DRS_INDEXEDVERTEXBLENDENABLE, | |
154 | WINED3DRS_LIGHTING, | |
155 | WINED3DRS_LOCALVIEWER, | |
3dbfda1a HV |
156 | WINED3DRS_MAXTESSELLATIONLEVEL, |
157 | WINED3DRS_MINTESSELLATIONLEVEL, | |
8b3f8687 HV |
158 | WINED3DRS_MULTISAMPLEANTIALIAS, |
159 | WINED3DRS_MULTISAMPLEMASK, | |
3dbfda1a | 160 | WINED3DRS_NORMALDEGREE, |
8b3f8687 HV |
161 | WINED3DRS_NORMALIZENORMALS, |
162 | WINED3DRS_PATCHEDGESTYLE, | |
163 | WINED3DRS_POINTSCALE_A, | |
164 | WINED3DRS_POINTSCALE_B, | |
165 | WINED3DRS_POINTSCALE_C, | |
166 | WINED3DRS_POINTSCALEENABLE, | |
167 | WINED3DRS_POINTSIZE, | |
168 | WINED3DRS_POINTSIZE_MAX, | |
169 | WINED3DRS_POINTSIZE_MIN, | |
170 | WINED3DRS_POINTSPRITEENABLE, | |
3dbfda1a | 171 | WINED3DRS_POSITIONDEGREE, |
8b3f8687 | 172 | WINED3DRS_RANGEFOGENABLE, |
3dbfda1a HV |
173 | WINED3DRS_SHADEMODE, |
174 | WINED3DRS_SPECULARENABLE, | |
8b3f8687 HV |
175 | WINED3DRS_SPECULARMATERIALSOURCE, |
176 | WINED3DRS_TWEENFACTOR, | |
177 | WINED3DRS_VERTEXBLEND, | |
8b3f8687 HV |
178 | }; |
179 | ||
048c9450 | 180 | static const DWORD vertex_states_texture[] = |
8b3f8687 HV |
181 | { |
182 | WINED3DTSS_TEXCOORDINDEX, | |
183 | WINED3DTSS_TEXTURETRANSFORMFLAGS, | |
184 | }; | |
185 | ||
048c9450 | 186 | static const DWORD vertex_states_sampler[] = |
8b3f8687 HV |
187 | { |
188 | WINED3DSAMP_DMAPOFFSET, | |
189 | }; | |
718716b7 | 190 | |
560d6354 | 191 | /* Allocates the correct amount of space for pixel and vertex shader constants, |
718716b7 JG |
192 | * along with their set/changed flags on the given stateblock object |
193 | */ | |
664057ce | 194 | static HRESULT stateblock_allocate_shader_constants(IWineD3DStateBlockImpl *object) |
560d6354 | 195 | { |
b3defd4c | 196 | IWineD3DDeviceImpl *device = object->device; |
718716b7 | 197 | |
718716b7 | 198 | /* Allocate space for floating point constants */ |
6be41fd5 | 199 | object->pixelShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
70d6304a | 200 | sizeof(float) * device->d3d_pshader_constantF * 4); |
3e035ddf HV |
201 | if (!object->pixelShaderConstantF) goto fail; |
202 | ||
6be41fd5 | 203 | object->changed.pixelShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
70d6304a | 204 | sizeof(BOOL) * device->d3d_pshader_constantF); |
3e035ddf HV |
205 | if (!object->changed.pixelShaderConstantsF) goto fail; |
206 | ||
6be41fd5 | 207 | object->vertexShaderConstantF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
70d6304a | 208 | sizeof(float) * device->d3d_vshader_constantF * 4); |
3e035ddf HV |
209 | if (!object->vertexShaderConstantF) goto fail; |
210 | ||
6be41fd5 | 211 | object->changed.vertexShaderConstantsF = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
70d6304a | 212 | sizeof(BOOL) * device->d3d_vshader_constantF); |
3e035ddf HV |
213 | if (!object->changed.vertexShaderConstantsF) goto fail; |
214 | ||
6be41fd5 | 215 | object->contained_vs_consts_f = HeapAlloc(GetProcessHeap(), 0, |
70d6304a | 216 | sizeof(DWORD) * device->d3d_vshader_constantF); |
3e035ddf HV |
217 | if (!object->contained_vs_consts_f) goto fail; |
218 | ||
6be41fd5 | 219 | object->contained_ps_consts_f = HeapAlloc(GetProcessHeap(), 0, |
70d6304a | 220 | sizeof(DWORD) * device->d3d_pshader_constantF); |
3e035ddf | 221 | if (!object->contained_ps_consts_f) goto fail; |
718716b7 | 222 | |
718716b7 | 223 | return WINED3D_OK; |
3e035ddf HV |
224 | |
225 | fail: | |
226 | ERR("Failed to allocate memory\n"); | |
227 | HeapFree(GetProcessHeap(), 0, object->pixelShaderConstantF); | |
228 | HeapFree(GetProcessHeap(), 0, object->changed.pixelShaderConstantsF); | |
229 | HeapFree(GetProcessHeap(), 0, object->vertexShaderConstantF); | |
230 | HeapFree(GetProcessHeap(), 0, object->changed.vertexShaderConstantsF); | |
231 | HeapFree(GetProcessHeap(), 0, object->contained_vs_consts_f); | |
232 | HeapFree(GetProcessHeap(), 0, object->contained_ps_consts_f); | |
233 | return E_OUTOFMEMORY; | |
718716b7 JG |
234 | } |
235 | ||
fc39831e HV |
236 | static inline void stateblock_set_bits(DWORD *map, UINT map_size) |
237 | { | |
238 | DWORD mask = (1 << (map_size & 0x1f)) - 1; | |
239 | memset(map, 0xff, (map_size >> 5) * sizeof(*map)); | |
240 | if (mask) map[map_size >> 5] = mask; | |
241 | } | |
242 | ||
5737efe7 | 243 | /* Set all members of a stateblock savedstate to the given value */ |
70d6304a | 244 | static void stateblock_savedstates_set_all(SAVEDSTATES *states, DWORD vs_consts, DWORD ps_consts) |
560d6354 | 245 | { |
c5029f83 HV |
246 | unsigned int i; |
247 | ||
75950b5b | 248 | /* Single values */ |
c5029f83 HV |
249 | states->primitive_type = 1; |
250 | states->indices = 1; | |
251 | states->material = 1; | |
252 | states->viewport = 1; | |
253 | states->vertexDecl = 1; | |
254 | states->pixelShader = 1; | |
255 | states->vertexShader = 1; | |
256 | states->scissorRect = 1; | |
75950b5b JG |
257 | |
258 | /* Fixed size arrays */ | |
c5029f83 HV |
259 | states->streamSource = 0xffff; |
260 | states->streamFreq = 0xffff; | |
261 | states->textures = 0xfffff; | |
262 | stateblock_set_bits(states->transform, HIGHEST_TRANSFORMSTATE + 1); | |
263 | stateblock_set_bits(states->renderState, WINEHIGHEST_RENDER_STATE + 1); | |
264 | for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = 0x3ffff; | |
265 | for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = 0x3fff; | |
266 | states->clipplane = 0xffffffff; | |
267 | states->pixelShaderConstantsB = 0xffff; | |
268 | states->pixelShaderConstantsI = 0xffff; | |
269 | states->vertexShaderConstantsB = 0xffff; | |
270 | states->vertexShaderConstantsI = 0xffff; | |
75950b5b JG |
271 | |
272 | /* Dynamically sized arrays */ | |
70d6304a SD |
273 | memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * ps_consts); |
274 | memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * vs_consts); | |
75950b5b JG |
275 | } |
276 | ||
70d6304a | 277 | static void stateblock_savedstates_set_pixel(SAVEDSTATES *states, const DWORD num_constants) |
5a01619d HV |
278 | { |
279 | DWORD texture_mask = 0; | |
280 | WORD sampler_mask = 0; | |
281 | unsigned int i; | |
282 | ||
283 | states->pixelShader = 1; | |
284 | ||
048c9450 | 285 | for (i = 0; i < sizeof(pixel_states_render) / sizeof(*pixel_states_render); ++i) |
5a01619d | 286 | { |
8b3f8687 | 287 | DWORD rs = pixel_states_render[i]; |
5a01619d HV |
288 | states->renderState[rs >> 5] |= 1 << (rs & 0x1f); |
289 | } | |
290 | ||
048c9450 HV |
291 | for (i = 0; i < sizeof(pixel_states_texture) / sizeof(*pixel_states_texture); ++i) |
292 | texture_mask |= 1 << pixel_states_texture[i]; | |
5a01619d | 293 | for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; |
048c9450 HV |
294 | for (i = 0; i < sizeof(pixel_states_sampler) / sizeof(*pixel_states_sampler); ++i) |
295 | sampler_mask |= 1 << pixel_states_sampler[i]; | |
5a01619d HV |
296 | for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; |
297 | states->pixelShaderConstantsB = 0xffff; | |
298 | states->pixelShaderConstantsI = 0xffff; | |
299 | ||
70d6304a | 300 | memset(states->pixelShaderConstantsF, TRUE, sizeof(BOOL) * num_constants); |
5a01619d HV |
301 | } |
302 | ||
70d6304a | 303 | static void stateblock_savedstates_set_vertex(SAVEDSTATES *states, const DWORD num_constants) |
d500c9b7 HV |
304 | { |
305 | DWORD texture_mask = 0; | |
306 | WORD sampler_mask = 0; | |
307 | unsigned int i; | |
308 | ||
52683906 | 309 | states->vertexDecl = 1; |
d500c9b7 HV |
310 | states->vertexShader = 1; |
311 | ||
048c9450 | 312 | for (i = 0; i < sizeof(vertex_states_render) / sizeof(*vertex_states_render); ++i) |
d500c9b7 | 313 | { |
8b3f8687 | 314 | DWORD rs = vertex_states_render[i]; |
d500c9b7 HV |
315 | states->renderState[rs >> 5] |= 1 << (rs & 0x1f); |
316 | } | |
317 | ||
048c9450 HV |
318 | for (i = 0; i < sizeof(vertex_states_texture) / sizeof(*vertex_states_texture); ++i) |
319 | texture_mask |= 1 << vertex_states_texture[i]; | |
d500c9b7 | 320 | for (i = 0; i < MAX_TEXTURES; ++i) states->textureState[i] = texture_mask; |
048c9450 HV |
321 | for (i = 0; i < sizeof(vertex_states_sampler) / sizeof(*vertex_states_sampler); ++i) |
322 | sampler_mask |= 1 << vertex_states_sampler[i]; | |
d500c9b7 HV |
323 | for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) states->samplerState[i] = sampler_mask; |
324 | states->vertexShaderConstantsB = 0xffff; | |
325 | states->vertexShaderConstantsI = 0xffff; | |
326 | ||
70d6304a | 327 | memset(states->vertexShaderConstantsF, TRUE, sizeof(BOOL) * num_constants); |
d500c9b7 HV |
328 | } |
329 | ||
be0b7355 HV |
330 | void stateblock_init_contained_states(IWineD3DStateBlockImpl *stateblock) |
331 | { | |
b3defd4c | 332 | IWineD3DDeviceImpl *device = stateblock->device; |
be0b7355 HV |
333 | unsigned int i, j; |
334 | ||
335 | for (i = 0; i <= WINEHIGHEST_RENDER_STATE >> 5; ++i) | |
336 | { | |
337 | DWORD map = stateblock->changed.renderState[i]; | |
338 | for (j = 0; map; map >>= 1, ++j) | |
339 | { | |
340 | if (!(map & 1)) continue; | |
341 | ||
342 | stateblock->contained_render_states[stateblock->num_contained_render_states] = (i << 5) | j; | |
343 | ++stateblock->num_contained_render_states; | |
344 | } | |
345 | } | |
346 | ||
347 | for (i = 0; i <= HIGHEST_TRANSFORMSTATE >> 5; ++i) | |
348 | { | |
349 | DWORD map = stateblock->changed.transform[i]; | |
350 | for (j = 0; map; map >>= 1, ++j) | |
351 | { | |
352 | if (!(map & 1)) continue; | |
353 | ||
354 | stateblock->contained_transform_states[stateblock->num_contained_transform_states] = (i << 5) | j; | |
355 | ++stateblock->num_contained_transform_states; | |
356 | } | |
357 | } | |
358 | ||
70d6304a | 359 | for (i = 0; i < device->d3d_vshader_constantF; ++i) |
be0b7355 HV |
360 | { |
361 | if (stateblock->changed.vertexShaderConstantsF[i]) | |
362 | { | |
363 | stateblock->contained_vs_consts_f[stateblock->num_contained_vs_consts_f] = i; | |
364 | ++stateblock->num_contained_vs_consts_f; | |
365 | } | |
366 | } | |
367 | ||
368 | for (i = 0; i < MAX_CONST_I; ++i) | |
369 | { | |
370 | if (stateblock->changed.vertexShaderConstantsI & (1 << i)) | |
371 | { | |
372 | stateblock->contained_vs_consts_i[stateblock->num_contained_vs_consts_i] = i; | |
373 | ++stateblock->num_contained_vs_consts_i; | |
374 | } | |
375 | } | |
376 | ||
377 | for (i = 0; i < MAX_CONST_B; ++i) | |
378 | { | |
379 | if (stateblock->changed.vertexShaderConstantsB & (1 << i)) | |
380 | { | |
381 | stateblock->contained_vs_consts_b[stateblock->num_contained_vs_consts_b] = i; | |
382 | ++stateblock->num_contained_vs_consts_b; | |
383 | } | |
384 | } | |
385 | ||
70d6304a | 386 | for (i = 0; i < device->d3d_pshader_constantF; ++i) |
be0b7355 HV |
387 | { |
388 | if (stateblock->changed.pixelShaderConstantsF[i]) | |
389 | { | |
390 | stateblock->contained_ps_consts_f[stateblock->num_contained_ps_consts_f] = i; | |
391 | ++stateblock->num_contained_ps_consts_f; | |
392 | } | |
393 | } | |
394 | ||
395 | for (i = 0; i < MAX_CONST_I; ++i) | |
396 | { | |
397 | if (stateblock->changed.pixelShaderConstantsI & (1 << i)) | |
398 | { | |
399 | stateblock->contained_ps_consts_i[stateblock->num_contained_ps_consts_i] = i; | |
400 | ++stateblock->num_contained_ps_consts_i; | |
401 | } | |
402 | } | |
403 | ||
404 | for (i = 0; i < MAX_CONST_B; ++i) | |
405 | { | |
406 | if (stateblock->changed.pixelShaderConstantsB & (1 << i)) | |
407 | { | |
408 | stateblock->contained_ps_consts_b[stateblock->num_contained_ps_consts_b] = i; | |
409 | ++stateblock->num_contained_ps_consts_b; | |
410 | } | |
411 | } | |
412 | ||
413 | for (i = 0; i < MAX_TEXTURES; ++i) | |
414 | { | |
415 | DWORD map = stateblock->changed.textureState[i]; | |
416 | ||
417 | for(j = 0; map; map >>= 1, ++j) | |
418 | { | |
419 | if (!(map & 1)) continue; | |
420 | ||
421 | stateblock->contained_tss_states[stateblock->num_contained_tss_states].stage = i; | |
422 | stateblock->contained_tss_states[stateblock->num_contained_tss_states].state = j; | |
423 | ++stateblock->num_contained_tss_states; | |
424 | } | |
425 | } | |
426 | ||
427 | for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) | |
428 | { | |
429 | DWORD map = stateblock->changed.samplerState[i]; | |
430 | ||
431 | for (j = 0; map; map >>= 1, ++j) | |
432 | { | |
433 | if (!(map & 1)) continue; | |
434 | ||
435 | stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].stage = i; | |
436 | stateblock->contained_sampler_states[stateblock->num_contained_sampler_states].state = j; | |
437 | ++stateblock->num_contained_sampler_states; | |
438 | } | |
439 | } | |
440 | } | |
441 | ||
580cd8c5 HV |
442 | static void stateblock_init_lights(IWineD3DStateBlockImpl *stateblock, struct list *light_map) |
443 | { | |
444 | unsigned int i; | |
445 | ||
446 | for (i = 0; i < LIGHTMAP_SIZE; ++i) | |
447 | { | |
3bc9d189 | 448 | const struct wined3d_light_info *src_light; |
580cd8c5 | 449 | |
3bc9d189 | 450 | LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry) |
580cd8c5 | 451 | { |
3bc9d189 | 452 | struct wined3d_light_info *dst_light = HeapAlloc(GetProcessHeap(), 0, sizeof(*dst_light)); |
580cd8c5 HV |
453 | |
454 | *dst_light = *src_light; | |
580cd8c5 HV |
455 | list_add_tail(&stateblock->lightMap[i], &dst_light->entry); |
456 | } | |
457 | } | |
458 | } | |
459 | ||
16e86890 OS |
460 | /********************************************************** |
461 | * IWineD3DStateBlockImpl IUnknown parts follows | |
462 | **********************************************************/ | |
e9cbc66e | 463 | static HRESULT WINAPI IWineD3DStateBlockImpl_QueryInterface(IWineD3DStateBlock *iface,REFIID riid,LPVOID *ppobj) |
16e86890 OS |
464 | { |
465 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; | |
466 | TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); | |
467 | if (IsEqualGUID(riid, &IID_IUnknown) | |
a389fe55 HV |
468 | || IsEqualGUID(riid, &IID_IWineD3DStateBlock)) |
469 | { | |
16e86890 OS |
470 | IUnknown_AddRef(iface); |
471 | *ppobj = This; | |
07f4f704 | 472 | return S_OK; |
16e86890 | 473 | } |
07f4f704 | 474 | *ppobj = NULL; |
16e86890 OS |
475 | return E_NOINTERFACE; |
476 | } | |
477 | ||
e9cbc66e | 478 | static ULONG WINAPI IWineD3DStateBlockImpl_AddRef(IWineD3DStateBlock *iface) { |
16e86890 OS |
479 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; |
480 | ULONG refCount = InterlockedIncrement(&This->ref); | |
481 | ||
3dcd3681 | 482 | TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1); |
16e86890 OS |
483 | return refCount; |
484 | } | |
485 | ||
e9cbc66e | 486 | static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { |
16e86890 OS |
487 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; |
488 | ULONG refCount = InterlockedDecrement(&This->ref); | |
489 | ||
3dcd3681 | 490 | TRACE("(%p) : Releasing from %d\n", This, refCount + 1); |
16e86890 OS |
491 | |
492 | if (!refCount) { | |
acadf3f2 | 493 | int counter; |
09eb0c40 | 494 | |
dca3c6e7 HV |
495 | if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl); |
496 | ||
709aedf5 HV |
497 | for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++) |
498 | { | |
499 | if (This->textures[counter]) IWineD3DBaseTexture_Release(This->textures[counter]); | |
d170aabe | 500 | } |
7cb748fe | 501 | |
d170aabe SD |
502 | for (counter = 0; counter < MAX_STREAMS; counter++) { |
503 | if(This->streamSource[counter]) { | |
aa3027a6 HV |
504 | if (IWineD3DBuffer_Release(This->streamSource[counter])) |
505 | { | |
d170aabe SD |
506 | TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]); |
507 | } | |
508 | } | |
7cb748fe | 509 | } |
513a493f | 510 | if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData); |
36aef3dc SD |
511 | if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader); |
512 | if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader); | |
efa5f785 | 513 | |
acadf3f2 SD |
514 | for(counter = 0; counter < LIGHTMAP_SIZE; counter++) { |
515 | struct list *e1, *e2; | |
3bc9d189 HV |
516 | LIST_FOR_EACH_SAFE(e1, e2, &This->lightMap[counter]) |
517 | { | |
518 | struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry); | |
acadf3f2 SD |
519 | list_remove(&light->entry); |
520 | HeapFree(GetProcessHeap(), 0, light); | |
521 | } | |
522 | } | |
523 | ||
efa5f785 | 524 | HeapFree(GetProcessHeap(), 0, This->vertexShaderConstantF); |
efa5f785 V |
525 | HeapFree(GetProcessHeap(), 0, This->changed.vertexShaderConstantsF); |
526 | HeapFree(GetProcessHeap(), 0, This->pixelShaderConstantF); | |
efa5f785 | 527 | HeapFree(GetProcessHeap(), 0, This->changed.pixelShaderConstantsF); |
b21c7854 SD |
528 | HeapFree(GetProcessHeap(), 0, This->contained_vs_consts_f); |
529 | HeapFree(GetProcessHeap(), 0, This->contained_ps_consts_f); | |
16e86890 OS |
530 | HeapFree(GetProcessHeap(), 0, This); |
531 | } | |
532 | return refCount; | |
533 | } | |
534 | ||
535 | /********************************************************** | |
536 | * IWineD3DStateBlockImpl parts follows | |
537 | **********************************************************/ | |
844dda20 HV |
538 | static void record_lights(IWineD3DStateBlockImpl *This, const IWineD3DStateBlockImpl *targetStateBlock) |
539 | { | |
76195d9a SD |
540 | UINT i; |
541 | ||
542 | /* Lights... For a recorded state block, we just had a chain of actions to perform, | |
543 | * so we need to walk that chain and update any actions which differ | |
544 | */ | |
545 | for(i = 0; i < LIGHTMAP_SIZE; i++) { | |
546 | struct list *e, *f; | |
547 | LIST_FOR_EACH(e, &This->lightMap[i]) { | |
548 | BOOL updated = FALSE; | |
3bc9d189 | 549 | struct wined3d_light_info *src = LIST_ENTRY(e, struct wined3d_light_info, entry), *realLight; |
76195d9a SD |
550 | |
551 | /* Look up the light in the destination */ | |
552 | LIST_FOR_EACH(f, &targetStateBlock->lightMap[i]) { | |
3bc9d189 | 553 | realLight = LIST_ENTRY(f, struct wined3d_light_info, entry); |
a24d1479 HV |
554 | if (realLight->OriginalIndex == src->OriginalIndex) |
555 | { | |
556 | src->OriginalParms = realLight->OriginalParms; | |
557 | ||
558 | if (realLight->glIndex == -1 && src->glIndex != -1) | |
559 | { | |
560 | /* Light disabled */ | |
561 | This->activeLights[src->glIndex] = NULL; | |
76195d9a | 562 | } |
a24d1479 HV |
563 | else if (realLight->glIndex != -1 && src->glIndex == -1) |
564 | { | |
565 | /* Light enabled */ | |
566 | This->activeLights[realLight->glIndex] = src; | |
76195d9a | 567 | } |
a24d1479 | 568 | src->glIndex = realLight->glIndex; |
76195d9a SD |
569 | updated = TRUE; |
570 | break; | |
571 | } | |
572 | } | |
573 | ||
a24d1479 HV |
574 | if (!updated) |
575 | { | |
f5c8153e HV |
576 | /* This can happen if the light was originally created as a |
577 | * default light for SetLightEnable() while recording. */ | |
578 | WARN("Light %u in stateblock %p does not exist in device stateblock %p.\n", | |
a24d1479 | 579 | src->OriginalIndex, This, targetStateBlock); |
f5c8153e HV |
580 | |
581 | src->OriginalParms = WINED3D_default_light; | |
582 | if (src->glIndex != -1) | |
583 | { | |
584 | This->activeLights[src->glIndex] = NULL; | |
585 | src->glIndex = -1; | |
586 | } | |
76195d9a SD |
587 | } |
588 | } | |
589 | } | |
590 | } | |
591 | ||
1f029a30 HV |
592 | static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) |
593 | { | |
594 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; | |
b3defd4c | 595 | IWineD3DStateBlockImpl *targetStateBlock = This->device->stateBlock; |
1f029a30 | 596 | unsigned int i; |
3b5c75d9 | 597 | DWORD map; |
abb11f30 | 598 | |
0edbaf7e | 599 | TRACE("(%p) : Updating state block %p ------------------v\n", targetStateBlock, This); |
abb11f30 | 600 | |
1f029a30 HV |
601 | if (This->changed.vertexShader && This->vertexShader != targetStateBlock->vertexShader) |
602 | { | |
603 | TRACE("Updating vertex shader from %p to %p\n", This->vertexShader, targetStateBlock->vertexShader); | |
c6515ab3 | 604 | |
1f029a30 HV |
605 | if (targetStateBlock->vertexShader) IWineD3DVertexShader_AddRef(targetStateBlock->vertexShader); |
606 | if (This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader); | |
607 | This->vertexShader = targetStateBlock->vertexShader; | |
608 | } | |
abb11f30 | 609 | |
1f029a30 HV |
610 | /* Vertex Shader Float Constants */ |
611 | for (i = 0; i < This->num_contained_vs_consts_f; ++i) | |
612 | { | |
613 | unsigned int idx = This->contained_vs_consts_f[i]; | |
614 | ||
615 | TRACE("Setting %p from %p %u to {%.8e, %.8e, %.8e, %.8e}.\n", | |
616 | This, targetStateBlock, idx, | |
617 | targetStateBlock->vertexShaderConstantF[idx * 4 + 0], | |
618 | targetStateBlock->vertexShaderConstantF[idx * 4 + 1], | |
619 | targetStateBlock->vertexShaderConstantF[idx * 4 + 2], | |
620 | targetStateBlock->vertexShaderConstantF[idx * 4 + 3]); | |
621 | ||
622 | This->vertexShaderConstantF[idx * 4 + 0] = targetStateBlock->vertexShaderConstantF[idx * 4 + 0]; | |
623 | This->vertexShaderConstantF[idx * 4 + 1] = targetStateBlock->vertexShaderConstantF[idx * 4 + 1]; | |
624 | This->vertexShaderConstantF[idx * 4 + 2] = targetStateBlock->vertexShaderConstantF[idx * 4 + 2]; | |
625 | This->vertexShaderConstantF[idx * 4 + 3] = targetStateBlock->vertexShaderConstantF[idx * 4 + 3]; | |
626 | } | |
76195d9a | 627 | |
1f029a30 HV |
628 | /* Vertex Shader Integer Constants */ |
629 | for (i = 0; i < This->num_contained_vs_consts_i; ++i) | |
630 | { | |
631 | unsigned int idx = This->contained_vs_consts_i[i]; | |
632 | ||
633 | TRACE("Setting %p from %p %u to {%d, %d, %d, %d}.\n", | |
634 | This, targetStateBlock, idx, | |
635 | targetStateBlock->vertexShaderConstantI[idx * 4 + 0], | |
636 | targetStateBlock->vertexShaderConstantI[idx * 4 + 1], | |
637 | targetStateBlock->vertexShaderConstantI[idx * 4 + 2], | |
638 | targetStateBlock->vertexShaderConstantI[idx * 4 + 3]); | |
639 | ||
640 | This->vertexShaderConstantI[idx * 4 + 0] = targetStateBlock->vertexShaderConstantI[idx * 4 + 0]; | |
641 | This->vertexShaderConstantI[idx * 4 + 1] = targetStateBlock->vertexShaderConstantI[idx * 4 + 1]; | |
642 | This->vertexShaderConstantI[idx * 4 + 2] = targetStateBlock->vertexShaderConstantI[idx * 4 + 2]; | |
643 | This->vertexShaderConstantI[idx * 4 + 3] = targetStateBlock->vertexShaderConstantI[idx * 4 + 3]; | |
644 | } | |
4673b1c6 | 645 | |
1f029a30 HV |
646 | /* Vertex Shader Boolean Constants */ |
647 | for (i = 0; i < This->num_contained_vs_consts_b; ++i) | |
648 | { | |
649 | unsigned int idx = This->contained_vs_consts_b[i]; | |
5f5969b3 | 650 | |
1f029a30 HV |
651 | TRACE("Setting %p from %p %u to %s.\n", |
652 | This, targetStateBlock, idx, | |
653 | targetStateBlock->vertexShaderConstantB[idx] ? "TRUE" : "FALSE"); | |
acadf3f2 | 654 | |
1f029a30 HV |
655 | This->vertexShaderConstantB[idx] = targetStateBlock->vertexShaderConstantB[idx]; |
656 | } | |
865b82af | 657 | |
1f029a30 HV |
658 | /* Pixel Shader Float Constants */ |
659 | for (i = 0; i < This->num_contained_ps_consts_f; ++i) | |
660 | { | |
661 | unsigned int idx = This->contained_ps_consts_f[i]; | |
662 | ||
663 | TRACE("Setting %p from %p %u to {%.8e, %.8e, %.8e, %.8e}.\n", | |
664 | This, targetStateBlock, idx, | |
665 | targetStateBlock->pixelShaderConstantF[idx * 4 + 0], | |
666 | targetStateBlock->pixelShaderConstantF[idx * 4 + 1], | |
667 | targetStateBlock->pixelShaderConstantF[idx * 4 + 2], | |
668 | targetStateBlock->pixelShaderConstantF[idx * 4 + 3]); | |
669 | ||
670 | This->pixelShaderConstantF[idx * 4 + 0] = targetStateBlock->pixelShaderConstantF[idx * 4 + 0]; | |
671 | This->pixelShaderConstantF[idx * 4 + 1] = targetStateBlock->pixelShaderConstantF[idx * 4 + 1]; | |
672 | This->pixelShaderConstantF[idx * 4 + 2] = targetStateBlock->pixelShaderConstantF[idx * 4 + 2]; | |
673 | This->pixelShaderConstantF[idx * 4 + 3] = targetStateBlock->pixelShaderConstantF[idx * 4 + 3]; | |
674 | } | |
865b82af | 675 | |
1f029a30 HV |
676 | /* Pixel Shader Integer Constants */ |
677 | for (i = 0; i < This->num_contained_ps_consts_i; ++i) | |
678 | { | |
679 | unsigned int idx = This->contained_ps_consts_i[i]; | |
680 | TRACE("Setting %p from %p %u to {%d, %d, %d, %d}.\n", | |
681 | This, targetStateBlock, idx, | |
682 | targetStateBlock->pixelShaderConstantI[idx * 4 + 0], | |
683 | targetStateBlock->pixelShaderConstantI[idx * 4 + 1], | |
684 | targetStateBlock->pixelShaderConstantI[idx * 4 + 2], | |
685 | targetStateBlock->pixelShaderConstantI[idx * 4 + 3]); | |
686 | ||
687 | This->pixelShaderConstantI[idx * 4 + 0] = targetStateBlock->pixelShaderConstantI[idx * 4 + 0]; | |
688 | This->pixelShaderConstantI[idx * 4 + 1] = targetStateBlock->pixelShaderConstantI[idx * 4 + 1]; | |
689 | This->pixelShaderConstantI[idx * 4 + 2] = targetStateBlock->pixelShaderConstantI[idx * 4 + 2]; | |
690 | This->pixelShaderConstantI[idx * 4 + 3] = targetStateBlock->pixelShaderConstantI[idx * 4 + 3]; | |
691 | } | |
5f5969b3 | 692 | |
1f029a30 HV |
693 | /* Pixel Shader Boolean Constants */ |
694 | for (i = 0; i < This->num_contained_ps_consts_b; ++i) | |
695 | { | |
696 | unsigned int idx = This->contained_ps_consts_b[i]; | |
697 | TRACE("Setting %p from %p %u to %s.\n", This, targetStateBlock, idx, | |
698 | targetStateBlock->pixelShaderConstantB[idx] ? "TRUE" : "FALSE"); | |
abb11f30 | 699 | |
1f029a30 HV |
700 | This->pixelShaderConstantB[idx] = targetStateBlock->pixelShaderConstantB[idx]; |
701 | } | |
abb11f30 | 702 | |
1f029a30 HV |
703 | /* Others + Render & Texture */ |
704 | for (i = 0; i < This->num_contained_transform_states; ++i) | |
705 | { | |
706 | WINED3DTRANSFORMSTATETYPE transform = This->contained_transform_states[i]; | |
abb11f30 | 707 | |
1f029a30 | 708 | TRACE("Updating transform %#x.\n", transform); |
c6515ab3 | 709 | |
1f029a30 HV |
710 | This->transforms[transform] = targetStateBlock->transforms[transform]; |
711 | } | |
abb11f30 | 712 | |
1f029a30 | 713 | if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type; |
abb11f30 | 714 | |
1f029a30 HV |
715 | if (This->changed.indices |
716 | && ((This->pIndexData != targetStateBlock->pIndexData) | |
717 | || (This->baseVertexIndex != targetStateBlock->baseVertexIndex) | |
718 | || (This->IndexFmt != targetStateBlock->IndexFmt))) | |
719 | { | |
720 | TRACE("Updating pIndexData to %p, baseVertexIndex to %d.\n", | |
721 | targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex); | |
abb11f30 | 722 | |
1f029a30 HV |
723 | if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData); |
724 | if (This->pIndexData) IWineD3DBuffer_Release(This->pIndexData); | |
725 | This->pIndexData = targetStateBlock->pIndexData; | |
726 | This->baseVertexIndex = targetStateBlock->baseVertexIndex; | |
727 | This->IndexFmt = targetStateBlock->IndexFmt; | |
728 | } | |
d4b63bbd | 729 | |
79a20453 | 730 | if (This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl) |
1f029a30 HV |
731 | { |
732 | TRACE("Updating vertex declaration from %p to %p.\n", This->vertexDecl, targetStateBlock->vertexDecl); | |
52a900d4 | 733 | |
1f029a30 HV |
734 | if (targetStateBlock->vertexDecl) IWineD3DVertexDeclaration_AddRef(targetStateBlock->vertexDecl); |
735 | if (This->vertexDecl) IWineD3DVertexDeclaration_Release(This->vertexDecl); | |
736 | This->vertexDecl = targetStateBlock->vertexDecl; | |
737 | } | |
52a900d4 | 738 | |
1f029a30 HV |
739 | if (This->changed.material |
740 | && memcmp(&targetStateBlock->material, &This->material, sizeof(This->material))) | |
741 | { | |
742 | TRACE("Updating material.\n"); | |
abb11f30 | 743 | |
1f029a30 HV |
744 | This->material = targetStateBlock->material; |
745 | } | |
abb11f30 | 746 | |
1f029a30 HV |
747 | if (This->changed.viewport |
748 | && memcmp(&targetStateBlock->viewport, &This->viewport, sizeof(This->viewport))) | |
749 | { | |
750 | TRACE("Updating viewport.\n"); | |
3b5c75d9 | 751 | |
1f029a30 HV |
752 | This->viewport = targetStateBlock->viewport; |
753 | } | |
abb11f30 | 754 | |
1f029a30 HV |
755 | if(This->changed.scissorRect |
756 | && memcmp(&targetStateBlock->scissorRect, &This->scissorRect, sizeof(This->scissorRect))) | |
757 | { | |
758 | TRACE("Updating scissor rect.\n"); | |
abb11f30 | 759 | |
1f029a30 HV |
760 | targetStateBlock->scissorRect = This->scissorRect; |
761 | } | |
03ffb734 | 762 | |
1f029a30 HV |
763 | map = This->changed.streamSource; |
764 | for (i = 0; map; map >>= 1, ++i) | |
765 | { | |
766 | if (!(map & 1)) continue; | |
abb11f30 | 767 | |
1f029a30 HV |
768 | if (This->streamStride[i] != targetStateBlock->streamStride[i] |
769 | || This->streamSource[i] != targetStateBlock->streamSource[i]) | |
9a889f6b | 770 | { |
1f029a30 HV |
771 | TRACE("Updating stream source %u to %p, stride to %u.\n", |
772 | i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]); | |
9a889f6b | 773 | |
1f029a30 HV |
774 | This->streamStride[i] = targetStateBlock->streamStride[i]; |
775 | if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]); | |
776 | if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]); | |
777 | This->streamSource[i] = targetStateBlock->streamSource[i]; | |
59fb2928 | 778 | } |
1f029a30 | 779 | } |
59fb2928 | 780 | |
1f029a30 HV |
781 | map = This->changed.streamFreq; |
782 | for (i = 0; map; map >>= 1, ++i) | |
783 | { | |
784 | if (!(map & 1)) continue; | |
76195d9a | 785 | |
1f029a30 HV |
786 | if (This->streamFreq[i] != targetStateBlock->streamFreq[i] |
787 | || This->streamFlags[i] != targetStateBlock->streamFlags[i]) | |
dca3c6e7 | 788 | { |
1f029a30 HV |
789 | TRACE("Updating stream frequency %u to %u flags to %#x.\n", |
790 | i, targetStateBlock->streamFreq[i], targetStateBlock->streamFlags[i]); | |
dca3c6e7 | 791 | |
1f029a30 HV |
792 | This->streamFreq[i] = targetStateBlock->streamFreq[i]; |
793 | This->streamFlags[i] = targetStateBlock->streamFlags[i]; | |
709aedf5 | 794 | } |
1f029a30 | 795 | } |
709aedf5 | 796 | |
1f029a30 HV |
797 | map = This->changed.clipplane; |
798 | for (i = 0; map; map >>= 1, ++i) | |
799 | { | |
800 | if (!(map & 1)) continue; | |
801 | ||
802 | if (memcmp(targetStateBlock->clipplane[i], This->clipplane[i], sizeof(*This->clipplane))) | |
048c9450 | 803 | { |
1f029a30 HV |
804 | TRACE("Updating clipplane %u.\n", i); |
805 | memcpy(This->clipplane[i], targetStateBlock->clipplane[i], sizeof(*This->clipplane)); | |
36aef3dc | 806 | } |
abb11f30 OS |
807 | } |
808 | ||
1f029a30 HV |
809 | /* Render */ |
810 | for (i = 0; i < This->num_contained_render_states; ++i) | |
811 | { | |
812 | WINED3DRENDERSTATETYPE rs = This->contained_render_states[i]; | |
813 | ||
814 | TRACE("Updating renderState %#x to %u.\n", rs, targetStateBlock->renderState[rs]); | |
815 | ||
816 | This->renderState[rs] = targetStateBlock->renderState[rs]; | |
817 | } | |
818 | ||
819 | /* Texture states */ | |
820 | for (i = 0; i < This->num_contained_tss_states; ++i) | |
821 | { | |
822 | DWORD stage = This->contained_tss_states[i].stage; | |
823 | DWORD state = This->contained_tss_states[i].state; | |
824 | ||
825 | TRACE("Updating texturestage state %u, %u to %u (was %u).\n", stage, state, | |
826 | targetStateBlock->textureState[stage][state], This->textureState[stage][state]); | |
827 | ||
828 | This->textureState[stage][state] = targetStateBlock->textureState[stage][state]; | |
829 | } | |
830 | ||
831 | /* Samplers */ | |
832 | map = This->changed.textures; | |
833 | for (i = 0; map; map >>= 1, ++i) | |
834 | { | |
835 | if (!(map & 1)) continue; | |
836 | ||
837 | TRACE("Updating texture %u to %p (was %p).\n", i, targetStateBlock->textures[i], This->textures[i]); | |
838 | ||
839 | if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]); | |
840 | if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]); | |
841 | This->textures[i] = targetStateBlock->textures[i]; | |
842 | } | |
843 | ||
844 | for (i = 0; i < This->num_contained_sampler_states; ++i) | |
845 | { | |
846 | DWORD stage = This->contained_sampler_states[i].stage; | |
847 | DWORD state = This->contained_sampler_states[i].state; | |
848 | ||
849 | TRACE("Updating sampler state %u, %u to %u (was %u).\n", stage, state, | |
850 | targetStateBlock->samplerState[stage][state], This->samplerState[stage][state]); | |
851 | ||
852 | This->samplerState[stage][state] = targetStateBlock->samplerState[stage][state]; | |
853 | } | |
854 | ||
855 | if (This->changed.pixelShader && This->pixelShader != targetStateBlock->pixelShader) | |
856 | { | |
857 | if (targetStateBlock->pixelShader) IWineD3DPixelShader_AddRef(targetStateBlock->pixelShader); | |
858 | if (This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader); | |
859 | This->pixelShader = targetStateBlock->pixelShader; | |
860 | } | |
861 | ||
862 | record_lights(This, targetStateBlock); | |
863 | ||
abb11f30 OS |
864 | TRACE("(%p) : Updated state block %p ------------------^\n", targetStateBlock, This); |
865 | ||
9d67b428 | 866 | return WINED3D_OK; |
abb11f30 OS |
867 | } |
868 | ||
844dda20 HV |
869 | static void apply_lights(IWineD3DDevice *pDevice, const IWineD3DStateBlockImpl *This) |
870 | { | |
f5e6313c SD |
871 | UINT i; |
872 | for(i = 0; i < LIGHTMAP_SIZE; i++) { | |
873 | struct list *e; | |
874 | ||
3bc9d189 HV |
875 | LIST_FOR_EACH(e, &This->lightMap[i]) |
876 | { | |
877 | const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry); | |
f5e6313c | 878 | |
a24d1479 HV |
879 | IWineD3DDevice_SetLight(pDevice, light->OriginalIndex, &light->OriginalParms); |
880 | IWineD3DDevice_SetLightEnable(pDevice, light->OriginalIndex, light->glIndex != -1); | |
f5e6313c SD |
881 | } |
882 | } | |
883 | } | |
884 | ||
594497f4 HV |
885 | static HRESULT WINAPI IWineD3DStateBlockImpl_Apply(IWineD3DStateBlock *iface) |
886 | { | |
abb11f30 | 887 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; |
b3defd4c | 888 | IWineD3DDevice *pDevice = (IWineD3DDevice *)This->device; |
594497f4 | 889 | unsigned int i; |
3b5c75d9 | 890 | DWORD map; |
abb11f30 OS |
891 | |
892 | TRACE("(%p) : Applying state block %p ------------------v\n", This, pDevice); | |
893 | ||
03ffb734 | 894 | TRACE("Blocktype: %d\n", This->blockType); |
abb11f30 | 895 | |
594497f4 | 896 | if (This->changed.vertexShader) IWineD3DDevice_SetVertexShader(pDevice, This->vertexShader); |
abb11f30 | 897 | |
594497f4 HV |
898 | /* Vertex Shader Constants */ |
899 | for (i = 0; i < This->num_contained_vs_consts_f; ++i) | |
900 | { | |
901 | IWineD3DDevice_SetVertexShaderConstantF(pDevice, This->contained_vs_consts_f[i], | |
902 | This->vertexShaderConstantF + This->contained_vs_consts_f[i] * 4, 1); | |
903 | } | |
904 | for (i = 0; i < This->num_contained_vs_consts_i; ++i) | |
905 | { | |
906 | IWineD3DDevice_SetVertexShaderConstantI(pDevice, This->contained_vs_consts_i[i], | |
907 | This->vertexShaderConstantI + This->contained_vs_consts_i[i] * 4, 1); | |
908 | } | |
909 | for (i = 0; i < This->num_contained_vs_consts_b; ++i) | |
910 | { | |
911 | IWineD3DDevice_SetVertexShaderConstantB(pDevice, This->contained_vs_consts_b[i], | |
912 | This->vertexShaderConstantB + This->contained_vs_consts_b[i], 1); | |
913 | } | |
702eeb6b | 914 | |
594497f4 | 915 | apply_lights(pDevice, This); |
abb11f30 | 916 | |
594497f4 | 917 | if (This->changed.pixelShader) IWineD3DDevice_SetPixelShader(pDevice, This->pixelShader); |
f5e6313c | 918 | |
594497f4 HV |
919 | /* Pixel Shader Constants */ |
920 | for (i = 0; i < This->num_contained_ps_consts_f; ++i) | |
921 | { | |
922 | IWineD3DDevice_SetPixelShaderConstantF(pDevice, This->contained_ps_consts_f[i], | |
923 | This->pixelShaderConstantF + This->contained_ps_consts_f[i] * 4, 1); | |
924 | } | |
925 | for (i = 0; i < This->num_contained_ps_consts_i; ++i) | |
926 | { | |
927 | IWineD3DDevice_SetPixelShaderConstantI(pDevice, This->contained_ps_consts_i[i], | |
928 | This->pixelShaderConstantI + This->contained_ps_consts_i[i] * 4, 1); | |
929 | } | |
930 | for (i = 0; i < This->num_contained_ps_consts_b; ++i) | |
931 | { | |
932 | IWineD3DDevice_SetPixelShaderConstantB(pDevice, This->contained_ps_consts_b[i], | |
933 | This->pixelShaderConstantB + This->contained_ps_consts_b[i], 1); | |
934 | } | |
abb11f30 | 935 | |
594497f4 HV |
936 | /* Render */ |
937 | for (i = 0; i < This->num_contained_render_states; ++i) | |
938 | { | |
939 | IWineD3DDevice_SetRenderState(pDevice, This->contained_render_states[i], | |
940 | This->renderState[This->contained_render_states[i]]); | |
941 | } | |
abb11f30 | 942 | |
594497f4 HV |
943 | /* Texture states */ |
944 | for (i = 0; i < This->num_contained_tss_states; ++i) | |
945 | { | |
946 | DWORD stage = This->contained_tss_states[i].stage; | |
947 | DWORD state = This->contained_tss_states[i].state; | |
d4b63bbd | 948 | |
594497f4 HV |
949 | IWineD3DDevice_SetTextureStageState(pDevice, stage, state, This->textureState[stage][state]); |
950 | } | |
abb11f30 | 951 | |
594497f4 HV |
952 | /* Sampler states */ |
953 | for (i = 0; i < This->num_contained_sampler_states; ++i) | |
954 | { | |
955 | DWORD stage = This->contained_sampler_states[i].stage; | |
956 | DWORD state = This->contained_sampler_states[i].state; | |
957 | DWORD value = This->samplerState[stage][state]; | |
9a889f6b | 958 | |
594497f4 HV |
959 | if (stage >= MAX_FRAGMENT_SAMPLERS) stage += WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS; |
960 | IWineD3DDevice_SetSamplerState(pDevice, stage, state, value); | |
961 | } | |
9a889f6b | 962 | |
594497f4 HV |
963 | for (i = 0; i < This->num_contained_transform_states; ++i) |
964 | { | |
965 | IWineD3DDevice_SetTransform(pDevice, This->contained_transform_states[i], | |
966 | &This->transforms[This->contained_transform_states[i]]); | |
967 | } | |
abb11f30 | 968 | |
594497f4 HV |
969 | if (This->changed.primitive_type) |
970 | { | |
b3defd4c HV |
971 | This->device->updateStateBlock->changed.primitive_type = TRUE; |
972 | This->device->updateStateBlock->gl_primitive_type = This->gl_primitive_type; | |
594497f4 | 973 | } |
3b5c75d9 | 974 | |
594497f4 HV |
975 | if (This->changed.indices) |
976 | { | |
977 | IWineD3DDevice_SetIndexBuffer(pDevice, This->pIndexData, This->IndexFmt); | |
978 | IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex); | |
979 | } | |
abb11f30 | 980 | |
79a20453 | 981 | if (This->changed.vertexDecl && This->vertexDecl) |
594497f4 | 982 | { |
52683906 | 983 | IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl); |
594497f4 | 984 | } |
f5e6313c | 985 | |
594497f4 HV |
986 | if (This->changed.material) |
987 | { | |
988 | IWineD3DDevice_SetMaterial(pDevice, &This->material); | |
989 | } | |
f5e6313c | 990 | |
594497f4 HV |
991 | if (This->changed.viewport) |
992 | { | |
993 | IWineD3DDevice_SetViewport(pDevice, &This->viewport); | |
994 | } | |
abb11f30 | 995 | |
594497f4 HV |
996 | if (This->changed.scissorRect) |
997 | { | |
998 | IWineD3DDevice_SetScissorRect(pDevice, &This->scissorRect); | |
999 | } | |
abb11f30 | 1000 | |
594497f4 HV |
1001 | map = This->changed.streamSource; |
1002 | for (i = 0; map; map >>= 1, ++i) | |
1003 | { | |
1004 | if (map & 1) IWineD3DDevice_SetStreamSource(pDevice, i, This->streamSource[i], 0, This->streamStride[i]); | |
1005 | } | |
abb11f30 | 1006 | |
594497f4 HV |
1007 | map = This->changed.streamFreq; |
1008 | for (i = 0; map; map >>= 1, ++i) | |
1009 | { | |
1010 | if (map & 1) IWineD3DDevice_SetStreamSourceFreq(pDevice, i, This->streamFreq[i] | This->streamFlags[i]); | |
1011 | } | |
93155ea0 | 1012 | |
594497f4 HV |
1013 | map = This->changed.textures; |
1014 | for (i = 0; map; map >>= 1, ++i) | |
1015 | { | |
1016 | DWORD stage; | |
f5e6313c | 1017 | |
594497f4 | 1018 | if (!(map & 1)) continue; |
f5e6313c | 1019 | |
594497f4 HV |
1020 | stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS; |
1021 | IWineD3DDevice_SetTexture(pDevice, stage, This->textures[i]); | |
1022 | } | |
f5e6313c | 1023 | |
594497f4 HV |
1024 | map = This->changed.clipplane; |
1025 | for (i = 0; map; map >>= 1, ++i) | |
1026 | { | |
1027 | float clip[4]; | |
f5e6313c | 1028 | |
594497f4 | 1029 | if (!(map & 1)) continue; |
f5e6313c | 1030 | |
594497f4 HV |
1031 | clip[0] = This->clipplane[i][0]; |
1032 | clip[1] = This->clipplane[i][1]; | |
1033 | clip[2] = This->clipplane[i][2]; | |
1034 | clip[3] = This->clipplane[i][3]; | |
1035 | IWineD3DDevice_SetClipPlane(pDevice, i, clip); | |
59fb2928 | 1036 | } |
93155ea0 | 1037 | |
b3defd4c | 1038 | This->device->stateBlock->lowest_disabled_stage = MAX_TEXTURES - 1; |
594497f4 HV |
1039 | for (i = 0; i < MAX_TEXTURES - 1; ++i) |
1040 | { | |
b3defd4c | 1041 | if (This->device->stateBlock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) |
594497f4 | 1042 | { |
b3defd4c | 1043 | This->device->stateBlock->lowest_disabled_stage = i; |
762af471 SD |
1044 | break; |
1045 | } | |
1046 | } | |
abb11f30 OS |
1047 | TRACE("(%p) : Applied state block %p ------------------^\n", This, pDevice); |
1048 | ||
9d67b428 | 1049 | return WINED3D_OK; |
abb11f30 OS |
1050 | } |
1051 | ||
e9cbc66e | 1052 | static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) { |
447d5ed0 | 1053 | IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface; |
b3defd4c | 1054 | IWineD3DDevice *device = (IWineD3DDevice *)This->device; |
abb11f30 | 1055 | IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)device; |
b3defd4c | 1056 | const struct wined3d_gl_info *gl_info = &ThisDevice->adapter->gl_info; |
2003c7ab | 1057 | union { |
4934b7ae | 1058 | WINED3DLINEPATTERN lp; |
2003c7ab JE |
1059 | DWORD d; |
1060 | } lp; | |
1061 | union { | |
1062 | float f; | |
1063 | DWORD d; | |
1064 | } tmpfloat; | |
1065 | unsigned int i; | |
525e30e6 RS |
1066 | IWineD3DSwapChain *swapchain; |
1067 | IWineD3DSurface *backbuffer; | |
525e30e6 | 1068 | HRESULT hr; |
447d5ed0 JE |
1069 | |
1070 | /* Note this may have a large overhead but it should only be executed | |
9253e0e3 | 1071 | once, in order to initialize the complete state of the device and |
447d5ed0 | 1072 | all opengl equivalents */ |
b3defd4c | 1073 | TRACE("(%p) -----------------------> Setting up device defaults... %p\n", This, ThisDevice); |
7cb748fe OS |
1074 | /* TODO: make a special stateblock type for the primary stateblock (it never gets applied so it doesn't need a real type) */ |
1075 | This->blockType = WINED3DSBT_INIT; | |
447d5ed0 | 1076 | |
7cb748fe | 1077 | /* Set some of the defaults for lights, transforms etc */ |
0064976d AT |
1078 | memcpy(&This->transforms[WINED3DTS_PROJECTION], identity, sizeof(identity)); |
1079 | memcpy(&This->transforms[WINED3DTS_VIEW], identity, sizeof(identity)); | |
2003c7ab | 1080 | for (i = 0; i < 256; ++i) { |
0064976d | 1081 | memcpy(&This->transforms[WINED3DTS_WORLDMATRIX(i)], identity, sizeof(identity)); |
2003c7ab | 1082 | } |
abb11f30 OS |
1083 | |
1084 | TRACE("Render states\n"); | |
2003c7ab | 1085 | /* Render states: */ |
e4f8a2da | 1086 | if (ThisDevice->auto_depth_stencil_buffer != NULL) { |
5f79e808 | 1087 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_TRUE); |
2003c7ab | 1088 | } else { |
5f79e808 | 1089 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZENABLE, WINED3DZB_FALSE); |
2003c7ab | 1090 | } |
f5cc6128 | 1091 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FILLMODE, WINED3DFILL_SOLID); |
16767d21 | 1092 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SHADEMODE, WINED3DSHADE_GOURAUD); |
abb11f30 OS |
1093 | lp.lp.wRepeatFactor = 0; |
1094 | lp.lp.wLinePattern = 0; | |
1095 | IWineD3DDevice_SetRenderState(device, WINED3DRS_LINEPATTERN, lp.d); | |
1096 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZWRITEENABLE, TRUE); | |
1097 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHATESTENABLE, FALSE); | |
1098 | IWineD3DDevice_SetRenderState(device, WINED3DRS_LASTPIXEL, TRUE); | |
10cbffb3 IG |
1099 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLEND, WINED3DBLEND_ONE); |
1100 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLEND, WINED3DBLEND_ZERO); | |
02fb9f6f | 1101 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CULLMODE, WINED3DCULL_CCW); |
206d248e IG |
1102 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZFUNC, WINED3DCMP_LESSEQUAL); |
1103 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAFUNC, WINED3DCMP_ALWAYS); | |
99272f0d | 1104 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHAREF, 0); |
abb11f30 OS |
1105 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DITHERENABLE, FALSE); |
1106 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ALPHABLENDENABLE, FALSE); | |
1107 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGENABLE, FALSE); | |
1108 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARENABLE, FALSE); | |
1109 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZVISIBLE, 0); | |
1110 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGCOLOR, 0); | |
4eced8ea | 1111 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGTABLEMODE, WINED3DFOG_NONE); |
2003c7ab | 1112 | tmpfloat.f = 0.0f; |
abb11f30 | 1113 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGSTART, tmpfloat.d); |
2003c7ab | 1114 | tmpfloat.f = 1.0f; |
abb11f30 | 1115 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGEND, tmpfloat.d); |
2003c7ab | 1116 | tmpfloat.f = 1.0f; |
abb11f30 OS |
1117 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGDENSITY, tmpfloat.d); |
1118 | IWineD3DDevice_SetRenderState(device, WINED3DRS_EDGEANTIALIAS, FALSE); | |
1119 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ZBIAS, 0); | |
1120 | IWineD3DDevice_SetRenderState(device, WINED3DRS_RANGEFOGENABLE, FALSE); | |
1121 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILENABLE, FALSE); | |
2b6deb86 IG |
1122 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFAIL, WINED3DSTENCILOP_KEEP); |
1123 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILZFAIL, WINED3DSTENCILOP_KEEP); | |
1124 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILPASS, WINED3DSTENCILOP_KEEP); | |
f41ab3be SD |
1125 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILREF, 0); |
1126 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILMASK, 0xFFFFFFFF); | |
206d248e | 1127 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILFUNC, WINED3DCMP_ALWAYS); |
abb11f30 OS |
1128 | IWineD3DDevice_SetRenderState(device, WINED3DRS_STENCILWRITEMASK, 0xFFFFFFFF); |
1129 | IWineD3DDevice_SetRenderState(device, WINED3DRS_TEXTUREFACTOR, 0xFFFFFFFF); | |
1130 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP0, 0); | |
1131 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP1, 0); | |
1132 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP2, 0); | |
1133 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP3, 0); | |
1134 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP4, 0); | |
1135 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP5, 0); | |
1136 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP6, 0); | |
1137 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP7, 0); | |
1138 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPING, TRUE); | |
1139 | IWineD3DDevice_SetRenderState(device, WINED3DRS_LIGHTING, TRUE); | |
1140 | IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENT, 0); | |
4eced8ea | 1141 | IWineD3DDevice_SetRenderState(device, WINED3DRS_FOGVERTEXMODE, WINED3DFOG_NONE); |
abb11f30 OS |
1142 | IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORVERTEX, TRUE); |
1143 | IWineD3DDevice_SetRenderState(device, WINED3DRS_LOCALVIEWER, TRUE); | |
1144 | IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALIZENORMALS, FALSE); | |
908853f6 IG |
1145 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DIFFUSEMATERIALSOURCE, WINED3DMCS_COLOR1); |
1146 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SPECULARMATERIALSOURCE, WINED3DMCS_COLOR2); | |
1147 | IWineD3DDevice_SetRenderState(device, WINED3DRS_AMBIENTMATERIALSOURCE, WINED3DMCS_MATERIAL); | |
1148 | IWineD3DDevice_SetRenderState(device, WINED3DRS_EMISSIVEMATERIALSOURCE, WINED3DMCS_MATERIAL); | |
6f0bb0f6 | 1149 | IWineD3DDevice_SetRenderState(device, WINED3DRS_VERTEXBLEND, WINED3DVBF_DISABLE); |
abb11f30 OS |
1150 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CLIPPLANEENABLE, 0); |
1151 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SOFTWAREVERTEXPROCESSING, FALSE); | |
2003c7ab | 1152 | tmpfloat.f = 1.0f; |
abb11f30 | 1153 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE, tmpfloat.d); |
8eef221d | 1154 | tmpfloat.f = 1.0f; |
abb11f30 OS |
1155 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MIN, tmpfloat.d); |
1156 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSPRITEENABLE, FALSE); | |
1157 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALEENABLE, FALSE); | |
99272f0d IG |
1158 | tmpfloat.f = 1.0f; |
1159 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_A, tmpfloat.d); | |
1160 | tmpfloat.f = 0.0f; | |
1161 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_B, tmpfloat.d); | |
1162 | tmpfloat.f = 0.0f; | |
1163 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSCALE_C, tmpfloat.d); | |
abb11f30 OS |
1164 | IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEANTIALIAS, TRUE); |
1165 | IWineD3DDevice_SetRenderState(device, WINED3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); | |
50130fdf | 1166 | IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHEDGESTYLE, WINED3DPATCHEDGE_DISCRETE); |
2003c7ab | 1167 | tmpfloat.f = 1.0f; |
abb11f30 | 1168 | IWineD3DDevice_SetRenderState(device, WINED3DRS_PATCHSEGMENTS, tmpfloat.d); |
99272f0d | 1169 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DEBUGMONITORTOKEN, 0xbaadcafe); |
48e03bc1 | 1170 | tmpfloat.f = gl_info->limits.pointsize_max; |
abb11f30 OS |
1171 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POINTSIZE_MAX, tmpfloat.d); |
1172 | IWineD3DDevice_SetRenderState(device, WINED3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); | |
1173 | IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE, 0x0000000F); | |
1174 | tmpfloat.f = 0.0f; | |
1175 | IWineD3DDevice_SetRenderState(device, WINED3DRS_TWEENFACTOR, tmpfloat.d); | |
042fa7be | 1176 | IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOP, WINED3DBLENDOP_ADD); |
abb11f30 OS |
1177 | IWineD3DDevice_SetRenderState(device, WINED3DRS_POSITIONDEGREE, WINED3DDEGREE_CUBIC); |
1178 | IWineD3DDevice_SetRenderState(device, WINED3DRS_NORMALDEGREE, WINED3DDEGREE_LINEAR); | |
1179 | /* states new in d3d9 */ | |
1180 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SCISSORTESTENABLE, FALSE); | |
1181 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SLOPESCALEDEPTHBIAS, 0); | |
1182 | tmpfloat.f = 1.0f; | |
1183 | IWineD3DDevice_SetRenderState(device, WINED3DRS_MINTESSELLATIONLEVEL, tmpfloat.d); | |
1184 | IWineD3DDevice_SetRenderState(device, WINED3DRS_MAXTESSELLATIONLEVEL, tmpfloat.d); | |
1185 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ANTIALIASEDLINEENABLE, FALSE); | |
1186 | tmpfloat.f = 0.0f; | |
1187 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_X, tmpfloat.d); | |
1188 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Y, tmpfloat.d); | |
1189 | tmpfloat.f = 1.0f; | |
1190 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_Z, tmpfloat.d); | |
2003c7ab | 1191 | tmpfloat.f = 0.0f; |
abb11f30 OS |
1192 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ADAPTIVETESS_W, tmpfloat.d); |
1193 | IWineD3DDevice_SetRenderState(device, WINED3DRS_ENABLEADAPTIVETESSELLATION, FALSE); | |
1194 | IWineD3DDevice_SetRenderState(device, WINED3DRS_TWOSIDEDSTENCILMODE, FALSE); | |
2b6deb86 IG |
1195 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFAIL, WINED3DSTENCILOP_KEEP); |
1196 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILZFAIL, WINED3DSTENCILOP_KEEP); | |
1197 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILPASS, WINED3DSTENCILOP_KEEP); | |
206d248e | 1198 | IWineD3DDevice_SetRenderState(device, WINED3DRS_CCW_STENCILFUNC, WINED3DCMP_ALWAYS); |
abb11f30 OS |
1199 | IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE1, 0x0000000F); |
1200 | IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE2, 0x0000000F); | |
1201 | IWineD3DDevice_SetRenderState(device, WINED3DRS_COLORWRITEENABLE3, 0x0000000F); | |
1202 | IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDFACTOR, 0xFFFFFFFF); | |
1203 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SRGBWRITEENABLE, 0); | |
1204 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DEPTHBIAS, 0); | |
1205 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP8, 0); | |
1206 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP9, 0); | |
1207 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP10, 0); | |
1208 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP11, 0); | |
1209 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP12, 0); | |
1210 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP13, 0); | |
1211 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP14, 0); | |
1212 | IWineD3DDevice_SetRenderState(device, WINED3DRS_WRAP15, 0); | |
1213 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SEPARATEALPHABLENDENABLE, FALSE); | |
10cbffb3 IG |
1214 | IWineD3DDevice_SetRenderState(device, WINED3DRS_SRCBLENDALPHA, WINED3DBLEND_ONE); |
1215 | IWineD3DDevice_SetRenderState(device, WINED3DRS_DESTBLENDALPHA, WINED3DBLEND_ZERO); | |
042fa7be | 1216 | IWineD3DDevice_SetRenderState(device, WINED3DRS_BLENDOPALPHA, WINED3DBLENDOP_ADD); |
2003c7ab | 1217 | |
abb11f30 | 1218 | /* clipping status */ |
2003c7ab JE |
1219 | This->clip_status.ClipUnion = 0; |
1220 | This->clip_status.ClipIntersection = 0xFFFFFFFF; | |
abb11f30 | 1221 | |
2003c7ab | 1222 | /* Texture Stage States - Put directly into state block, we will call function below */ |
440ca846 | 1223 | for (i = 0; i < MAX_TEXTURES; i++) { |
2003c7ab | 1224 | TRACE("Setting up default texture states for texture Stage %d\n", i); |
0064976d | 1225 | memcpy(&This->transforms[WINED3DTS_TEXTURE0 + i], identity, sizeof(identity)); |
c912032a | 1226 | This->textureState[i][WINED3DTSS_COLOROP ] = (i==0)? WINED3DTOP_MODULATE : WINED3DTOP_DISABLE; |
4f611bc0 IG |
1227 | This->textureState[i][WINED3DTSS_COLORARG1 ] = WINED3DTA_TEXTURE; |
1228 | This->textureState[i][WINED3DTSS_COLORARG2 ] = WINED3DTA_CURRENT; | |
c912032a | 1229 | This->textureState[i][WINED3DTSS_ALPHAOP ] = (i==0)? WINED3DTOP_SELECTARG1 : WINED3DTOP_DISABLE; |
4f611bc0 IG |
1230 | This->textureState[i][WINED3DTSS_ALPHAARG1 ] = WINED3DTA_TEXTURE; |
1231 | This->textureState[i][WINED3DTSS_ALPHAARG2 ] = WINED3DTA_CURRENT; | |
efeab9d2 MS |
1232 | This->textureState[i][WINED3DTSS_BUMPENVMAT00 ] = 0; |
1233 | This->textureState[i][WINED3DTSS_BUMPENVMAT01 ] = 0; | |
1234 | This->textureState[i][WINED3DTSS_BUMPENVMAT10 ] = 0; | |
1235 | This->textureState[i][WINED3DTSS_BUMPENVMAT11 ] = 0; | |
837027fc | 1236 | This->textureState[i][WINED3DTSS_TEXCOORDINDEX ] = i; |
efeab9d2 MS |
1237 | This->textureState[i][WINED3DTSS_BUMPENVLSCALE ] = 0; |
1238 | This->textureState[i][WINED3DTSS_BUMPENVLOFFSET ] = 0; | |
98466024 | 1239 | This->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS ] = WINED3DTTFF_DISABLE; |
4f611bc0 IG |
1240 | This->textureState[i][WINED3DTSS_COLORARG0 ] = WINED3DTA_CURRENT; |
1241 | This->textureState[i][WINED3DTSS_ALPHAARG0 ] = WINED3DTA_CURRENT; | |
1242 | This->textureState[i][WINED3DTSS_RESULTARG ] = WINED3DTA_CURRENT; | |
2003c7ab | 1243 | } |
762af471 | 1244 | This->lowest_disabled_stage = 1; |
2003c7ab | 1245 | |
abb11f30 | 1246 | /* Sampler states*/ |
5b7758f8 | 1247 | for (i = 0 ; i < MAX_COMBINED_SAMPLERS; i++) { |
9253e0e3 | 1248 | TRACE("Setting up default samplers states for sampler %d\n", i); |
997e670e IG |
1249 | This->samplerState[i][WINED3DSAMP_ADDRESSU ] = WINED3DTADDRESS_WRAP; |
1250 | This->samplerState[i][WINED3DSAMP_ADDRESSV ] = WINED3DTADDRESS_WRAP; | |
1251 | This->samplerState[i][WINED3DSAMP_ADDRESSW ] = WINED3DTADDRESS_WRAP; | |
abb11f30 | 1252 | This->samplerState[i][WINED3DSAMP_BORDERCOLOR ] = 0x00; |
63fd9a7a SD |
1253 | This->samplerState[i][WINED3DSAMP_MAGFILTER ] = WINED3DTEXF_POINT; |
1254 | This->samplerState[i][WINED3DSAMP_MINFILTER ] = WINED3DTEXF_POINT; | |
1255 | This->samplerState[i][WINED3DSAMP_MIPFILTER ] = WINED3DTEXF_NONE; | |
abb11f30 OS |
1256 | This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS ] = 0; |
1257 | This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL ] = 0; | |
1258 | This->samplerState[i][WINED3DSAMP_MAXANISOTROPY ] = 1; | |
622f62d3 | 1259 | This->samplerState[i][WINED3DSAMP_SRGBTEXTURE ] = 0; |
abb11f30 | 1260 | This->samplerState[i][WINED3DSAMP_ELEMENTINDEX ] = 0; /* TODO: Indicates which element of a multielement texture to use */ |
a648d4e3 | 1261 | This->samplerState[i][WINED3DSAMP_DMAPOFFSET ] = 0; /* TODO: Vertex offset in the presampled displacement map */ |
abb11f30 OS |
1262 | } |
1263 | ||
48e03bc1 | 1264 | for (i = 0; i < gl_info->limits.textures; ++i) |
6be41fd5 | 1265 | { |
6e59cd2c | 1266 | /* Note: This avoids calling SetTexture, so pretend it has been called */ |
9a889f6b | 1267 | This->changed.textures |= 1 << i; |
1e264e5d | 1268 | This->textures[i] = NULL; |
cd7ed61c | 1269 | } |
2003c7ab | 1270 | |
525e30e6 RS |
1271 | /* check the return values, because the GetBackBuffer call isn't valid for ddraw */ |
1272 | hr = IWineD3DDevice_GetSwapChain(device, 0, &swapchain); | |
1273 | if( hr == WINED3D_OK && swapchain != NULL) { | |
ef7365a4 HV |
1274 | WINED3DVIEWPORT vp; |
1275 | ||
525e30e6 | 1276 | hr = IWineD3DSwapChain_GetBackBuffer(swapchain, 0, WINED3DBACKBUFFER_TYPE_MONO, &backbuffer); |
88162fab HV |
1277 | if (SUCCEEDED(hr) && backbuffer) |
1278 | { | |
1279 | WINED3DSURFACE_DESC desc; | |
1280 | RECT scissorrect; | |
1281 | ||
525e30e6 RS |
1282 | IWineD3DSurface_GetDesc(backbuffer, &desc); |
1283 | IWineD3DSurface_Release(backbuffer); | |
1284 | ||
88162fab | 1285 | /* Set the default scissor rect values */ |
525e30e6 | 1286 | scissorrect.left = 0; |
88162fab | 1287 | scissorrect.right = desc.width; |
525e30e6 | 1288 | scissorrect.top = 0; |
88162fab | 1289 | scissorrect.bottom = desc.height; |
525e30e6 | 1290 | hr = IWineD3DDevice_SetScissorRect(device, &scissorrect); |
88162fab | 1291 | if (FAILED(hr)) ERR("This should never happen, expect rendering issues!\n"); |
525e30e6 | 1292 | } |
ef7365a4 HV |
1293 | |
1294 | /* Set the default viewport */ | |
1295 | vp.X = 0; | |
1296 | vp.Y = 0; | |
1297 | vp.Width = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferWidth; | |
1298 | vp.Height = ((IWineD3DSwapChainImpl *)swapchain)->presentParms.BackBufferHeight; | |
1299 | vp.MinZ = 0.0f; | |
1300 | vp.MaxZ = 1.0f; | |
1301 | IWineD3DDevice_SetViewport(device, &vp); | |
1302 | ||
525e30e6 RS |
1303 | IWineD3DSwapChain_Release(swapchain); |
1304 | } | |
1305 | ||
447d5ed0 | 1306 | TRACE("-----------------------> Device defaults now set up...\n"); |
9d67b428 | 1307 | return WINED3D_OK; |
447d5ed0 JE |
1308 | } |
1309 | ||
447d5ed0 JE |
1310 | /********************************************************** |
1311 | * IWineD3DStateBlock VTbl follows | |
1312 | **********************************************************/ | |
1313 | ||
664057ce | 1314 | static const IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl = |
447d5ed0 | 1315 | { |
9253e0e3 | 1316 | /* IUnknown */ |
447d5ed0 JE |
1317 | IWineD3DStateBlockImpl_QueryInterface, |
1318 | IWineD3DStateBlockImpl_AddRef, | |
1319 | IWineD3DStateBlockImpl_Release, | |
9253e0e3 | 1320 | /* IWineD3DStateBlock */ |
abb11f30 OS |
1321 | IWineD3DStateBlockImpl_Capture, |
1322 | IWineD3DStateBlockImpl_Apply, | |
447d5ed0 JE |
1323 | IWineD3DStateBlockImpl_InitStartupStateBlock |
1324 | }; | |
664057ce | 1325 | |
dd5fc79f | 1326 | HRESULT stateblock_init(IWineD3DStateBlockImpl *stateblock, IWineD3DDeviceImpl *device, WINED3DSTATEBLOCKTYPE type) |
664057ce | 1327 | { |
15d4eee5 | 1328 | unsigned int i; |
664057ce HV |
1329 | HRESULT hr; |
1330 | ||
1331 | stateblock->lpVtbl = &IWineD3DStateBlock_Vtbl; | |
1332 | stateblock->ref = 1; | |
b3defd4c | 1333 | stateblock->device = device; |
664057ce HV |
1334 | stateblock->blockType = type; |
1335 | ||
1336 | for (i = 0; i < LIGHTMAP_SIZE; i++) | |
1337 | { | |
1338 | list_init(&stateblock->lightMap[i]); | |
1339 | } | |
1340 | ||
1341 | hr = stateblock_allocate_shader_constants(stateblock); | |
1342 | if (FAILED(hr)) return hr; | |
1343 | ||
1344 | /* The WINED3DSBT_INIT stateblock type is used during initialization to | |
1345 | * produce a placeholder stateblock so other functions called can update a | |
1346 | * state block. */ | |
1347 | if (type == WINED3DSBT_INIT || type == WINED3DSBT_RECORDED) return WINED3D_OK; | |
1348 | ||
664057ce HV |
1349 | TRACE("Updating changed flags appropriate for type %#x.\n", type); |
1350 | ||
580cd8c5 | 1351 | switch (type) |
664057ce | 1352 | { |
580cd8c5 HV |
1353 | case WINED3DSBT_ALL: |
1354 | stateblock_init_lights(stateblock, device->stateBlock->lightMap); | |
70d6304a SD |
1355 | stateblock_savedstates_set_all(&stateblock->changed, device->d3d_vshader_constantF, |
1356 | device->d3d_pshader_constantF); | |
580cd8c5 | 1357 | break; |
664057ce | 1358 | |
580cd8c5 | 1359 | case WINED3DSBT_PIXELSTATE: |
70d6304a | 1360 | stateblock_savedstates_set_pixel(&stateblock->changed, device->d3d_pshader_constantF); |
580cd8c5 | 1361 | break; |
442beb1d | 1362 | |
580cd8c5 HV |
1363 | case WINED3DSBT_VERTEXSTATE: |
1364 | stateblock_init_lights(stateblock, device->stateBlock->lightMap); | |
70d6304a | 1365 | stateblock_savedstates_set_vertex(&stateblock->changed, device->d3d_vshader_constantF); |
580cd8c5 | 1366 | break; |
442beb1d | 1367 | |
580cd8c5 HV |
1368 | default: |
1369 | FIXME("Unrecognized state block type %#x.\n", type); | |
1370 | break; | |
664057ce | 1371 | } |
664057ce | 1372 | |
580cd8c5 HV |
1373 | stateblock_init_contained_states(stateblock); |
1374 | IWineD3DStateBlockImpl_Capture((IWineD3DStateBlock *)stateblock); | |
664057ce HV |
1375 | |
1376 | return WINED3D_OK; | |
1377 | } |