VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/stateblock.c@ 21731

Last change on this file since 21731 was 21731, checked in by vboxsync, 15 years ago

crOpenGL: update to wine 1.1.26

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette