Fixed a race condition on RPC worker thread creation, and a typo.
[wine] / dlls / ddraw / mesa.c
1 /* Direct3D Common functions
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains all MESA common code
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include "windef.h"
24 #include "objbase.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
28
29 #include "mesa_private.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
32
33 GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState)
34 {
35     switch (dwRenderState) {
36         case D3DCMP_NEVER: return GL_NEVER;
37         case D3DCMP_LESS: return GL_LESS;
38         case D3DCMP_EQUAL: return GL_EQUAL;
39         case D3DCMP_LESSEQUAL: return GL_LEQUAL;
40         case D3DCMP_GREATER: return GL_GREATER;
41         case D3DCMP_NOTEQUAL: return GL_NOTEQUAL;
42         case D3DCMP_GREATEREQUAL: return GL_GEQUAL;
43         case D3DCMP_ALWAYS: return GL_ALWAYS;
44         default: ERR("Unexpected compare type %d !\n", dwRenderState);
45     }
46     return GL_ALWAYS;
47 }
48
49 GLenum convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState)
50 {
51     switch (dwRenderState) {
52         case D3DSTENCILOP_KEEP: return GL_KEEP;
53         case D3DSTENCILOP_ZERO: return GL_ZERO;
54         case D3DSTENCILOP_REPLACE: return GL_REPLACE;
55         case D3DSTENCILOP_INCRSAT: return GL_INCR;
56         case D3DSTENCILOP_DECRSAT: return GL_DECR;
57         case D3DSTENCILOP_INVERT: return GL_INVERT;
58         case D3DSTENCILOP_INCR: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR;
59         case D3DSTENCILOP_DECR: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR;
60         default: ERR("Unexpected compare type %d !\n", dwRenderState);      
61     }
62     return GL_KEEP;
63 }
64
65 GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState)
66 {
67     switch ((D3DBLEND) dwRenderState) {
68         case D3DBLEND_ZERO: return GL_ZERO;
69         case D3DBLEND_ONE: return GL_ONE;
70         case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA;
71         case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
72         case D3DBLEND_DESTALPHA: return GL_DST_ALPHA;
73         case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA;
74         case D3DBLEND_DESTCOLOR: return GL_DST_COLOR;
75         case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR;
76         case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
77         case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR;
78         case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
79         default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO;
80     }
81 }
82
83 void set_render_state(IDirect3DDeviceImpl* This,
84                       D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock)
85 {
86     DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
87
88     if (TRACE_ON(ddraw))
89         TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
90
91     /* First, all the stipple patterns */
92     if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
93         (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
94         ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
95     } else {
96         ENTER_GL();
97
98         /* All others state variables */
99         switch (dwRenderStateType) {
100             case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
101                 IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
102                 
103                 LEAVE_GL();
104                 IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
105                                             0, 
106                                             ICOM_INTERFACE(tex, IDirectDrawSurface7));
107                 ENTER_GL();
108             } break;
109               
110             case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
111             case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
112             case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
113                 D3DTEXTURESTAGESTATETYPE d3dTexStageStateType;
114
115                 if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS;
116                 else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
117                 else d3dTexStageStateType = D3DTSS_ADDRESSV;
118
119                 LEAVE_GL();
120                 IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
121                                                       0, d3dTexStageStateType,
122                                                       dwRenderState);
123                 ENTER_GL();
124             } break;
125               
126             case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
127                 if (dwRenderState)
128                     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
129                 else
130                     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
131                 break;
132
133             case D3DRENDERSTATE_WRAPU: /* 5 */
134                 if (dwRenderState)
135                     ERR("WRAPU mode unsupported by OpenGL.. Expect graphical glitches !\n");
136                 break;
137               
138             case D3DRENDERSTATE_WRAPV: /* 6 */
139                 if (dwRenderState)
140                     ERR("WRAPV mode unsupported by OpenGL.. Expect graphical glitches !\n");
141                 break;
142
143             case D3DRENDERSTATE_ZENABLE:          /*  7 */
144                 /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
145                    updated either.. No idea about what happens in D3D.
146                    
147                    Maybe replacing the Z function by ALWAYS would be a better idea. */
148                 if (dwRenderState == D3DZB_TRUE)
149                     glEnable(GL_DEPTH_TEST);
150                 else if (dwRenderState == D3DZB_FALSE)
151                     glDisable(GL_DEPTH_TEST);
152                 else {
153                     glEnable(GL_DEPTH_TEST);
154                     WARN(" w-buffering not supported.\n");
155                 }
156                 break;
157
158             case D3DRENDERSTATE_FILLMODE:           /*  8 */
159                 switch ((D3DFILLMODE) dwRenderState) {
160                     case D3DFILL_POINT:
161                         glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
162                         break;
163                     case D3DFILL_WIREFRAME:
164                         glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
165                         break;
166                     case D3DFILL_SOLID:
167                         glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
168                         break;
169                     default:
170                         ERR("Unhandled fill mode %ld !\n",dwRenderState);
171                  }
172                  break;
173
174             case D3DRENDERSTATE_SHADEMODE:          /*  9 */
175                 switch ((D3DSHADEMODE) dwRenderState) {
176                     case D3DSHADE_FLAT:
177                         glShadeModel(GL_FLAT);
178                         break;
179                     case D3DSHADE_GOURAUD:
180                         glShadeModel(GL_SMOOTH);
181                         break;
182                     default:
183                         ERR("Unhandled shade mode %ld !\n",dwRenderState);
184                 }
185                 break;
186
187             case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
188                 if (dwRenderState)
189                     glDepthMask(GL_TRUE);
190                 else
191                     glDepthMask(GL_FALSE);
192                 break;
193               
194             case D3DRENDERSTATE_ALPHATESTENABLE:  /* 15 */
195                 if (dwRenderState)
196                     glEnable(GL_ALPHA_TEST);
197                 else
198                     glDisable(GL_ALPHA_TEST);
199                 break;
200
201             case D3DRENDERSTATE_TEXTUREMAG: {     /* 17 */
202                 DWORD tex_mag = 0xFFFFFFFF;
203
204                 switch ((D3DTEXTUREFILTER) dwRenderState) {
205                     case D3DFILTER_NEAREST:
206                         tex_mag = D3DTFG_POINT;
207                         break;
208                     case D3DFILTER_LINEAR:
209                         tex_mag = D3DTFG_LINEAR;
210                         break;
211                     default:
212                         ERR("Unhandled texture mag %ld !\n",dwRenderState);
213                 }
214
215                 if (tex_mag != 0xFFFFFFFF) {
216                     LEAVE_GL();
217                     IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
218                     ENTER_GL();
219                 }
220             } break;
221
222             case D3DRENDERSTATE_TEXTUREMIN: {       /* 18 */
223                 DWORD tex_min = 0xFFFFFFFF;
224
225                 switch ((D3DTEXTUREFILTER) dwRenderState) {
226                     case D3DFILTER_NEAREST:
227                         tex_min = D3DTFN_POINT;
228                         break;
229                     case D3DFILTER_LINEAR:
230                         tex_min = D3DTFN_LINEAR;
231                         break;
232                     default:
233                         ERR("Unhandled texture min %ld !\n",dwRenderState);
234                 }
235
236                 if (tex_min != 0xFFFFFFFF) {
237                     LEAVE_GL();
238                     IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
239                     ENTER_GL();
240                 }
241             } break;
242
243             case D3DRENDERSTATE_SRCBLEND:           /* 19 */
244             case D3DRENDERSTATE_DESTBLEND:          /* 20 */
245                 glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]),
246                             convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1]));
247                 break;
248
249             case D3DRENDERSTATE_TEXTUREMAPBLEND:    /* 21 */
250                 switch ((D3DTEXTUREBLEND) dwRenderState) {
251                     case D3DTBLEND_MODULATE:
252                     case D3DTBLEND_MODULATEALPHA:
253                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
254                         break;
255                     default:
256                         ERR("Unhandled texture environment %ld !\n",dwRenderState);
257                 }
258                 break;
259
260             case D3DRENDERSTATE_CULLMODE:           /* 22 */
261                 switch ((D3DCULL) dwRenderState) {
262                     case D3DCULL_NONE:
263                          glDisable(GL_CULL_FACE);
264                          break;
265                     case D3DCULL_CW:
266                          glEnable(GL_CULL_FACE);
267                          glFrontFace(GL_CCW);
268                          glCullFace(GL_BACK);
269                          break;
270                     case D3DCULL_CCW:
271                          glEnable(GL_CULL_FACE);
272                          glFrontFace(GL_CW);
273                          glCullFace(GL_BACK);
274                          break;
275                     default:
276                          ERR("Unhandled cull mode %ld !\n",dwRenderState);
277                 }
278                 break;
279
280             case D3DRENDERSTATE_ZFUNC:            /* 23 */
281                 glDepthFunc(convert_D3D_compare_to_GL(dwRenderState));
282                 break;
283               
284             case D3DRENDERSTATE_ALPHAREF:   /* 24 */
285             case D3DRENDERSTATE_ALPHAFUNC:  /* 25 */
286                 glAlphaFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]),
287                             (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0);
288                 break;
289
290             case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
291                 if (dwRenderState)
292                     glEnable(GL_DITHER);
293                 else
294                     glDisable(GL_DITHER);
295                 break;
296
297             case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
298                 if (dwRenderState) {
299                     glEnable(GL_BLEND);
300                 } else {
301                     glDisable(GL_BLEND);
302                 }
303                 break;
304               
305             case D3DRENDERSTATE_FOGENABLE: /* 28 */
306                 /* Nothing to do here. Only the storage matters :-) */
307                 break;
308
309             case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
310                 if (dwRenderState)
311                     ERR(" Specular Lighting not supported yet.\n");
312                 break;
313               
314             case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
315             case D3DRENDERSTATE_SUBPIXELX: /* 32 */
316                 /* We do not support this anyway, so why protest :-) */
317                 break; 
318
319             case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */
320                 if (dwRenderState)
321                     ERR(" Stippled Alpha not supported yet.\n");
322                 break;
323
324             case D3DRENDERSTATE_FOGCOLOR: { /* 34 */
325                 GLfloat color[4];
326                 color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f;
327                 color[1] = ((dwRenderState >>  8) & 0xFF)/255.0f;
328                 color[2] = ((dwRenderState >>  0) & 0xFF)/255.0f;
329                 color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f;
330                 glFogfv(GL_FOG_COLOR,color);
331                 /* Note: glFogiv does not seem to work */
332             } break;
333
334             case D3DRENDERSTATE_FOGTABLEMODE:  /* 35 */
335             case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */
336             case D3DRENDERSTATE_FOGSTART:      /* 36 */
337             case D3DRENDERSTATE_FOGEND:        /* 37 */
338                 /* Nothing to do here. Only the storage matters :-) */
339                 break;
340
341             case D3DRENDERSTATE_FOGDENSITY:    /* 38 */
342                 glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState);
343                 break;
344
345             case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
346                 /* This needs to be fixed. */
347                 if (dwRenderState)
348                     glEnable(GL_BLEND);
349                 else
350                     glDisable(GL_BLEND);
351                 break;
352
353             case D3DRENDERSTATE_ZBIAS: /* 47 */
354                 /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
355                 if (dwRenderState == 0) {
356                     glDisable(GL_POLYGON_OFFSET_FILL);
357                     glDisable(GL_POLYGON_OFFSET_LINE);
358                     glDisable(GL_POLYGON_OFFSET_POINT);
359                 } else {
360                     glEnable(GL_POLYGON_OFFSET_FILL);
361                     glEnable(GL_POLYGON_OFFSET_LINE);
362                     glEnable(GL_POLYGON_OFFSET_POINT);
363                     glPolygonOffset(1.0, dwRenderState * 1.0);
364                 }
365                 break;
366               
367             case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
368                 break;
369
370             case D3DRENDERSTATE_STENCILENABLE:    /* 52 */
371                 if (dwRenderState)
372                     glEnable(GL_STENCIL_TEST);
373                 else
374                     glDisable(GL_STENCIL_TEST);
375                 break;
376             
377             case D3DRENDERSTATE_STENCILFAIL:      /* 53 */
378             case D3DRENDERSTATE_STENCILZFAIL:     /* 54 */
379             case D3DRENDERSTATE_STENCILPASS:      /* 55 */
380                 glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]),
381                             convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]),
382                             convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1]));
383                 break;
384
385             case D3DRENDERSTATE_STENCILFUNC:      /* 56 */
386             case D3DRENDERSTATE_STENCILREF:       /* 57 */
387             case D3DRENDERSTATE_STENCILMASK:      /* 58 */
388                 glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]),
389                               lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1],
390                               lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]);
391                 break;
392           
393             case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */
394                 glStencilMask(dwRenderState);
395                 break;
396
397             case D3DRENDERSTATE_CLIPPING:          /* 136 */
398             case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */
399                     GLint i;
400                     DWORD mask, runner;
401                     
402                     if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) {
403                         mask = ((dwRenderState) ?
404                                 (This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x0000));
405                     } else {
406                         mask = dwRenderState;
407                     }
408                     for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) {
409                         if (mask & runner) {
410                             glEnable(GL_CLIP_PLANE0 + i);
411                         } else {
412                             glDisable(GL_CLIP_PLANE0 + i);
413                         }
414                     }
415                 }
416                 break;
417
418             case D3DRENDERSTATE_LIGHTING:    /* 137 */
419                 if (dwRenderState)
420                     glEnable(GL_LIGHTING);
421                 else
422                     glDisable(GL_LIGHTING);
423                 break;
424                 
425             case D3DRENDERSTATE_AMBIENT: {            /* 139 */
426                 float light[4];
427
428                 light[0] = ((dwRenderState >> 16) & 0xFF) / 255.0;
429                 light[1] = ((dwRenderState >>  8) & 0xFF) / 255.0;
430                 light[2] = ((dwRenderState >>  0) & 0xFF) / 255.0;
431                 light[3] = ((dwRenderState >> 24) & 0xFF) / 255.0;
432                 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
433             } break;
434
435             case D3DRENDERSTATE_COLORVERTEX:          /* 141 */
436                   /* Nothing to do here.. Only storage matters */
437                   break;
438                   
439             case D3DRENDERSTATE_LOCALVIEWER:          /* 142 */
440                 if (dwRenderState)
441                     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
442                 else
443                     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
444                 break;
445
446             case D3DRENDERSTATE_NORMALIZENORMALS:     /* 143 */
447                 if (dwRenderState) {
448                     glEnable(GL_NORMALIZE);
449                     glEnable(GL_RESCALE_NORMAL);
450                 } else {
451                     glDisable(GL_NORMALIZE);
452                     glDisable(GL_RESCALE_NORMAL);
453                 }
454                 break;
455
456             case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:    /* 145 */
457             case D3DRENDERSTATE_SPECULARMATERIALSOURCE:   /* 146 */
458             case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:    /* 147 */
459             case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:   /* 148 */
460                 /* Nothing to do here. Only the storage matters :-) */
461                 break;
462
463             default:
464                 ERR("Unhandled dwRenderStateType %s (%08x) !\n", _get_renderstate(dwRenderStateType), dwRenderStateType);
465         }
466         LEAVE_GL();
467     }
468 }
469
470 void store_render_state(IDirect3DDeviceImpl *This,
471                         D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock)
472 {
473     TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
474     
475     /* Some special cases first.. */
476     if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) {
477         if (dwRenderState == D3DBLEND_BOTHSRCALPHA) {
478             lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA;
479             lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA;
480             return;
481         } else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) {
482             lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA;
483             lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA;
484             return;
485         }
486     } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) {
487         lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState;
488         lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState;
489     }
490     
491     /* Default case */
492     lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState;
493 }
494
495 void get_render_state(IDirect3DDeviceImpl *This,
496                       D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock)
497 {
498     *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
499     if (TRACE_ON(ddraw))
500         TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
501 }
502
503 void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock)
504 {
505     DWORD i;
506     TRACE("(%p,%p)\n", This, lpStateBlock);
507     for(i = 0; i < HIGHEST_RENDER_STATE; i++)
508         if (lpStateBlock->set_flags.render_state[i])
509             set_render_state(This, i + 1, lpStateBlock);
510 }