wined3d: Move more fog stuff to the vertex states.
[wine] / dlls / wined3d / context.c
1 /*
2  * Context and render target management in wined3d
3  *
4  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include <stdio.h>
23 #ifdef HAVE_FLOAT_H
24 # include <float.h>
25 #endif
26 #include "wined3d_private.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
29
30 #define GLINFO_LOCATION This->adapter->gl_info
31
32 /*****************************************************************************
33  * Context_MarkStateDirty
34  *
35  * Marks a state in a context dirty. Only one context, opposed to
36  * IWineD3DDeviceImpl_MarkStateDirty, which marks the state dirty in all
37  * contexts
38  *
39  * Params:
40  *  context: Context to mark the state dirty in
41  *  state: State to mark dirty
42  *  StateTable: Pointer to the state table in use(for state grouping)
43  *
44  *****************************************************************************/
45 static void Context_MarkStateDirty(WineD3DContext *context, DWORD state, const struct StateEntry *StateTable) {
46     DWORD rep = StateTable[state].representative;
47     DWORD idx;
48     BYTE shift;
49
50     if(!rep || isStateDirty(context, rep)) return;
51
52     context->dirtyArray[context->numDirtyEntries++] = rep;
53     idx = rep >> 5;
54     shift = rep & 0x1f;
55     context->isStateDirty[idx] |= (1 << shift);
56 }
57
58 /*****************************************************************************
59  * AddContextToArray
60  *
61  * Adds a context to the context array. Helper function for CreateContext
62  *
63  * This method is not called in performance-critical code paths, only when a
64  * new render target or swapchain is created. Thus performance is not an issue
65  * here.
66  *
67  * Params:
68  *  This: Device to add the context for
69  *  hdc: device context
70  *  glCtx: WGL context to add
71  *  pbuffer: optional pbuffer used with this context
72  *
73  *****************************************************************************/
74 static WineD3DContext *AddContextToArray(IWineD3DDeviceImpl *This, HWND win_handle, HDC hdc, HGLRC glCtx, HPBUFFERARB pbuffer) {
75     WineD3DContext **oldArray = This->contexts;
76     DWORD state;
77
78     This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * (This->numContexts + 1));
79     if(This->contexts == NULL) {
80         ERR("Unable to grow the context array\n");
81         This->contexts = oldArray;
82         return NULL;
83     }
84     if(oldArray) {
85         memcpy(This->contexts, oldArray, sizeof(*This->contexts) * This->numContexts);
86     }
87
88     This->contexts[This->numContexts] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WineD3DContext));
89     if(This->contexts[This->numContexts] == NULL) {
90         ERR("Unable to allocate a new context\n");
91         HeapFree(GetProcessHeap(), 0, This->contexts);
92         This->contexts = oldArray;
93         return NULL;
94     }
95
96     This->contexts[This->numContexts]->hdc = hdc;
97     This->contexts[This->numContexts]->glCtx = glCtx;
98     This->contexts[This->numContexts]->pbuffer = pbuffer;
99     This->contexts[This->numContexts]->win_handle = win_handle;
100     HeapFree(GetProcessHeap(), 0, oldArray);
101
102     /* Mark all states dirty to force a proper initialization of the states on the first use of the context
103      */
104     for(state = 0; state <= STATE_HIGHEST; state++) {
105         Context_MarkStateDirty(This->contexts[This->numContexts], state, This->StateTable);
106     }
107
108     This->numContexts++;
109     TRACE("Created context %p\n", This->contexts[This->numContexts - 1]);
110     return This->contexts[This->numContexts - 1];
111 }
112
113 /* This function takes care of WineD3D pixel format selection. */
114 static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc, WINED3DFORMAT ColorFormat, WINED3DFORMAT DepthStencilFormat, BOOL auxBuffers, int numSamples, BOOL pbuffer, BOOL findCompatible)
115 {
116     int iPixelFormat=0;
117     short redBits, greenBits, blueBits, alphaBits, colorBits;
118     short depthBits=0, stencilBits=0;
119
120     int i = 0;
121     int nCfgs = This->adapter->nCfgs;
122     WineD3D_PixelFormat *cfgs = This->adapter->cfgs;
123
124     TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, pbuffer=%d, findCompatible=%d\n",
125           debug_d3dformat(ColorFormat), debug_d3dformat(DepthStencilFormat), auxBuffers, numSamples, pbuffer, findCompatible);
126
127     if(!getColorBits(ColorFormat, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits)) {
128         ERR("Unable to get color bits for format %s (%#x)!\n", debug_d3dformat(ColorFormat), ColorFormat);
129         return 0;
130     }
131
132     /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
133      * You are able to add a depth + stencil surface at a later stage when you need it.
134      * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
135      * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
136      * context, need torecreate shaders, textures and other resources.
137      *
138      * The context manager already takes care of the state problem and for the other tasks code from Reset
139      * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
140      * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
141      * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
142      * issue needs to be fixed. */
143     if(DepthStencilFormat != WINED3DFMT_D24S8)
144         FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n");
145
146     DepthStencilFormat = WINED3DFMT_D24S8;
147
148     if(DepthStencilFormat) {
149         getDepthStencilBits(DepthStencilFormat, &depthBits, &stencilBits);
150     }
151
152     /* Find a pixel format which EXACTLY matches our requirements (except for depth) */
153     for(i=0; i<nCfgs; i++) {
154         BOOL exactDepthMatch = TRUE;
155         cfgs = &This->adapter->cfgs[i];
156
157         /* For now only accept RGBA formats. Perhaps some day we will
158          * allow floating point formats for pbuffers. */
159         if(cfgs->iPixelType != WGL_TYPE_RGBA_ARB)
160             continue;
161
162         /* In window mode (!pbuffer) we need a window drawable format and double buffering. */
163         if(!pbuffer && !(cfgs->windowDrawable && cfgs->doubleBuffer))
164             continue;
165
166         /* We like to have aux buffers in backbuffer mode */
167         if(auxBuffers && !cfgs->auxBuffers)
168             continue;
169
170         /* In pbuffer-mode we need a pbuffer-capable format but we don't want double buffering */
171         if(pbuffer && (!cfgs->pbufferDrawable || cfgs->doubleBuffer))
172             continue;
173
174         if(cfgs->redSize != redBits)
175             continue;
176         if(cfgs->greenSize != greenBits)
177             continue;
178         if(cfgs->blueSize != blueBits)
179             continue;
180         if(cfgs->alphaSize != alphaBits)
181             continue;
182
183         /* We try to locate a format which matches our requirements exactly. In case of
184          * depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
185         if(cfgs->depthSize < depthBits)
186             continue;
187         else if(cfgs->depthSize > depthBits)
188             exactDepthMatch = FALSE;
189
190         /* In all cases make sure the number of stencil bits matches our requirements
191          * even when we don't need stencil because it could affect performance EXCEPT
192          * on cards which don't offer depth formats without stencil like the i915 drivers
193          * on Linux. */
194         if(stencilBits != cfgs->stencilSize && !(This->adapter->brokenStencil && stencilBits <= cfgs->stencilSize))
195             continue;
196
197         /* Check multisampling support */
198         if(cfgs->numSamples != numSamples)
199             continue;
200
201         /* When we have passed all the checks then we have found a format which matches our
202          * requirements. Note that we only check for a limit number of capabilities right now,
203          * so there can easily be a dozen of pixel formats which appear to be the 'same' but
204          * can still differ in things like multisampling, stereo, SRGB and other flags.
205          */
206
207         /* Exit the loop as we have found a format :) */
208         if(exactDepthMatch) {
209             iPixelFormat = cfgs->iPixelFormat;
210             break;
211         } else if(!iPixelFormat) {
212             /* In the end we might end up with a format which doesn't exactly match our depth
213              * requirements. Accept the first format we found because formats with higher iPixelFormat
214              * values tend to have more extended capabilities (e.g. multisampling) which we don't need. */
215             iPixelFormat = cfgs->iPixelFormat;
216         }
217     }
218
219     /* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */
220     if(!iPixelFormat && !findCompatible) {
221         ERR("Can't find a suitable iPixelFormat\n");
222         return FALSE;
223     } else if(!iPixelFormat) {
224         PIXELFORMATDESCRIPTOR pfd;
225
226         TRACE("Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel format\n");
227         /* PixelFormat selection */
228         ZeroMemory(&pfd, sizeof(pfd));
229         pfd.nSize      = sizeof(pfd);
230         pfd.nVersion   = 1;
231         pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
232         pfd.iPixelType = PFD_TYPE_RGBA;
233         pfd.cAlphaBits = alphaBits;
234         pfd.cColorBits = colorBits;
235         pfd.cDepthBits = depthBits;
236         pfd.cStencilBits = stencilBits;
237         pfd.iLayerType = PFD_MAIN_PLANE;
238
239         iPixelFormat = ChoosePixelFormat(hdc, &pfd);
240         if(!iPixelFormat) {
241             /* If this happens something is very wrong as ChoosePixelFormat barely fails */
242             ERR("Can't find a suitable iPixelFormat\n");
243             return FALSE;
244         }
245     }
246
247     TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s\n", iPixelFormat, debug_d3dformat(ColorFormat), debug_d3dformat(DepthStencilFormat));
248     return iPixelFormat;
249 }
250
251 /*****************************************************************************
252  * CreateContext
253  *
254  * Creates a new context for a window, or a pbuffer context.
255  *
256  * * Params:
257  *  This: Device to activate the context for
258  *  target: Surface this context will render to
259  *  win_handle: handle to the window which we are drawing to
260  *  create_pbuffer: tells whether to create a pbuffer or not
261  *  pPresentParameters: contains the pixelformats to use for onscreen rendering
262  *
263  *****************************************************************************/
264 WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win_handle, BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) {
265     HDC oldDrawable, hdc;
266     HPBUFFERARB pbuffer = NULL;
267     HGLRC ctx = NULL, oldCtx;
268     WineD3DContext *ret = NULL;
269     int s;
270
271     TRACE("(%p): Creating a %s context for render target %p\n", This, create_pbuffer ? "offscreen" : "onscreen", target);
272
273     if(create_pbuffer) {
274         HDC hdc_parent = GetDC(win_handle);
275         int iPixelFormat = 0;
276
277         IWineD3DSurface *StencilSurface = This->stencilBufferTarget;
278         WINED3DFORMAT StencilBufferFormat = (NULL != StencilSurface) ? ((IWineD3DSurfaceImpl *) StencilSurface)->resource.format : 0;
279
280         /* Try to find a pixel format with pbuffer support. */
281         iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffers */, 0 /* numSamples */, TRUE /* PBUFFER */, FALSE /* findCompatible */);
282         if(!iPixelFormat) {
283             TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
284
285             /* For some reason we weren't able to find a format, try to find something instead of crashing.
286              * A reason for failure could have been wglChoosePixelFormatARB strictness. */
287             iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc_parent, target->resource.format, StencilBufferFormat, FALSE /* auxBuffer */, 0 /* numSamples */, TRUE /* PBUFFER */, TRUE /* findCompatible */);
288         }
289
290         /* This shouldn't happen as ChoosePixelFormat always returns something */
291         if(!iPixelFormat) {
292             ERR("Unable to locate a pixel format for a pbuffer\n");
293             ReleaseDC(win_handle, hdc_parent);
294             goto out;
295         }
296
297         TRACE("Creating a pBuffer drawable for the new context\n");
298         pbuffer = GL_EXTCALL(wglCreatePbufferARB(hdc_parent, iPixelFormat, target->currentDesc.Width, target->currentDesc.Height, 0));
299         if(!pbuffer) {
300             ERR("Cannot create a pbuffer\n");
301             ReleaseDC(win_handle, hdc_parent);
302             goto out;
303         }
304
305         /* In WGL a pbuffer is 'wrapped' inside a HDC to 'fool' wglMakeCurrent */
306         hdc = GL_EXTCALL(wglGetPbufferDCARB(pbuffer));
307         if(!hdc) {
308             ERR("Cannot get a HDC for pbuffer (%p)\n", pbuffer);
309             GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
310             ReleaseDC(win_handle, hdc_parent);
311             goto out;
312         }
313         ReleaseDC(win_handle, hdc_parent);
314     } else {
315         PIXELFORMATDESCRIPTOR pfd;
316         int iPixelFormat;
317         int res;
318         WINED3DFORMAT ColorFormat = target->resource.format;
319         WINED3DFORMAT DepthStencilFormat = 0;
320         BOOL auxBuffers = FALSE;
321         int numSamples = 0;
322
323         hdc = GetDC(win_handle);
324         if(hdc == NULL) {
325             ERR("Cannot retrieve a device context!\n");
326             goto out;
327         }
328
329         /* In case of ORM_BACKBUFFER, make sure to request an alpha component for X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */
330         if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
331             auxBuffers = TRUE;
332
333             if(target->resource.format == WINED3DFMT_X4R4G4B4)
334                 ColorFormat = WINED3DFMT_A4R4G4B4;
335             else if(target->resource.format == WINED3DFMT_X8R8G8B8)
336                 ColorFormat = WINED3DFMT_A8R8G8B8;
337         }
338
339         /* DirectDraw supports 8bit paletted render targets and these are used by old games like Starcraft and C&C.
340          * Most modern hardware doesn't support 8bit natively so we perform some form of 8bit -> 32bit conversion.
341          * The conversion (ab)uses the alpha component for storing the palette index. For this reason we require
342          * a format with 8bit alpha, so request A8R8G8B8. */
343         if(ColorFormat == WINED3DFMT_P8)
344             ColorFormat = WINED3DFMT_A8R8G8B8;
345
346         /* Retrieve the depth stencil format from the present parameters.
347          * The choice of the proper format can give a nice performance boost
348          * in case of GPU limited programs. */
349         if(pPresentParms->EnableAutoDepthStencil) {
350             TRACE("pPresentParms->EnableAutoDepthStencil=enabled; using AutoDepthStencilFormat=%s\n", debug_d3dformat(pPresentParms->AutoDepthStencilFormat));
351             DepthStencilFormat = pPresentParms->AutoDepthStencilFormat;
352         }
353
354         /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD */
355         if(pPresentParms->MultiSampleType && (pPresentParms->SwapEffect == WINED3DSWAPEFFECT_DISCARD)) {
356             if(!GL_SUPPORT(ARB_MULTISAMPLE))
357                 ERR("The program is requesting multisampling without support!\n");
358             else {
359                 ERR("Requesting MultiSampleType=%d\n", pPresentParms->MultiSampleType);
360                 numSamples = pPresentParms->MultiSampleType;
361             }
362         }
363
364         /* Try to find a pixel format which matches our requirements */
365         iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, numSamples, FALSE /* PBUFFER */, FALSE /* findCompatible */);
366
367         /* Try to locate a compatible format if we weren't able to find anything */
368         if(!iPixelFormat) {
369             TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
370             iPixelFormat = WineD3D_ChoosePixelFormat(This, hdc, ColorFormat, DepthStencilFormat, auxBuffers, 0 /* numSamples */, FALSE /* PBUFFER */, TRUE /* findCompatible */ );
371         }
372
373         /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
374         if(!iPixelFormat) {
375             ERR("Can't find a suitable iPixelFormat\n");
376             return FALSE;
377         }
378
379         DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd);
380         res = SetPixelFormat(hdc, iPixelFormat, NULL);
381         if(!res) {
382             int oldPixelFormat = GetPixelFormat(hdc);
383
384             /* By default WGL doesn't allow pixel format adjustments but we need it here.
385              * For this reason there is a WINE-specific wglSetPixelFormat which allows you to
386              * set the pixel format multiple times. Only use it when it is really needed. */
387
388             if(oldPixelFormat == iPixelFormat) {
389                 /* We don't have to do anything as the formats are the same :) */
390             } else if(oldPixelFormat && GL_SUPPORT(WGL_WINE_PIXEL_FORMAT_PASSTHROUGH)) {
391                 res = GL_EXTCALL(wglSetPixelFormatWINE(hdc, iPixelFormat, NULL));
392
393                 if(!res) {
394                     ERR("wglSetPixelFormatWINE failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
395                     return FALSE;
396                 }
397             } else if(oldPixelFormat) {
398                 /* OpenGL doesn't allow pixel format adjustments. Print an error and continue using the old format.
399                  * There's a big chance that the old format works although with a performance hit and perhaps rendering errors. */
400                 ERR("HDC=%p is already set to iPixelFormat=%d and OpenGL doesn't allow changes!\n", hdc, oldPixelFormat);
401             } else {
402                 ERR("SetPixelFormat failed on HDC=%p for iPixelFormat=%d\n", hdc, iPixelFormat);
403                 return FALSE;
404             }
405         }
406     }
407
408     ctx = pwglCreateContext(hdc);
409     if(This->numContexts) pwglShareLists(This->contexts[0]->glCtx, ctx);
410
411     if(!ctx) {
412         ERR("Failed to create a WGL context\n");
413         if(create_pbuffer) {
414             GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
415             GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
416         }
417         goto out;
418     }
419     ret = AddContextToArray(This, win_handle, hdc, ctx, pbuffer);
420     if(!ret) {
421         ERR("Failed to add the newly created context to the context list\n");
422         pwglDeleteContext(ctx);
423         if(create_pbuffer) {
424             GL_EXTCALL(wglReleasePbufferDCARB(pbuffer, hdc));
425             GL_EXTCALL(wglDestroyPbufferARB(pbuffer));
426         }
427         goto out;
428     }
429     ret->surface = (IWineD3DSurface *) target;
430     ret->isPBuffer = create_pbuffer;
431     ret->tid = GetCurrentThreadId();
432     if(This->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) This)) {
433         /* Create the dirty constants array and initialize them to dirty */
434         ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
435                 sizeof(*ret->vshader_const_dirty) * GL_LIMITS(vshader_constantsF));
436         ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
437                 sizeof(*ret->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
438         memset(ret->vshader_const_dirty, 1,
439                sizeof(*ret->vshader_const_dirty) * GL_LIMITS(vshader_constantsF));
440         memset(ret->pshader_const_dirty, 1,
441                 sizeof(*ret->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
442     }
443
444     TRACE("Successfully created new context %p\n", ret);
445
446     /* Set up the context defaults */
447     oldCtx  = pwglGetCurrentContext();
448     oldDrawable = pwglGetCurrentDC();
449     if(oldCtx && oldDrawable) {
450         /* See comment in ActivateContext context switching */
451         This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
452     }
453     if(pwglMakeCurrent(hdc, ctx) == FALSE) {
454         ERR("Cannot activate context to set up defaults\n");
455         goto out;
456     }
457
458     ENTER_GL();
459
460     glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers);
461
462     TRACE("Setting up the screen\n");
463     /* Clear the screen */
464     glClearColor(1.0, 0.0, 0.0, 0.0);
465     checkGLcall("glClearColor");
466     glClearIndex(0);
467     glClearDepth(1);
468     glClearStencil(0xffff);
469
470     checkGLcall("glClear");
471
472     glColor3f(1.0, 1.0, 1.0);
473     checkGLcall("glColor3f");
474
475     glEnable(GL_LIGHTING);
476     checkGLcall("glEnable");
477
478     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
479     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
480
481     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
482     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
483
484     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
485     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
486
487     glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);
488     checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, This->surface_alignment);");
489     glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);
490     checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, This->surface_alignment);");
491
492     if(GL_SUPPORT(APPLE_CLIENT_STORAGE)) {
493         /* Most textures will use client storage if supported. Exceptions are non-native power of 2 textures
494          * and textures in DIB sections(due to the memory protection).
495          */
496         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
497         checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
498     }
499     if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
500         /* Direct3D always uses n-1 weights for n world matrices and uses 1 - sum for the last one
501          * this is equal to GL_WEIGHT_SUM_UNITY_ARB. Enabling it doesn't do anything unless
502          * GL_VERTEX_BLEND_ARB isn't enabled too
503          */
504         glEnable(GL_WEIGHT_SUM_UNITY_ARB);
505         checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
506     }
507     if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
508         glEnable(GL_TEXTURE_SHADER_NV);
509         checkGLcall("glEnable(GL_TEXTURE_SHADER_NV)");
510
511         /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
512          * the previous texture where to source the offset from is always unit - 1.
513          */
514         for(s = 1; s < GL_LIMITS(textures); s++) {
515             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
516             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
517             checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...\n");
518         }
519     }
520
521     if(GL_SUPPORT(ARB_POINT_SPRITE)) {
522         for(s = 0; s < GL_LIMITS(textures); s++) {
523             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
524             glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
525             checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)\n");
526         }
527     }
528     LEAVE_GL();
529
530     /* Never keep GL_FRAGMENT_SHADER_ATI enabled on a context that we switch away from,
531      * but enable it for the first context we create, and reenable it on the old context
532      */
533     if(oldDrawable && oldCtx) {
534         pwglMakeCurrent(oldDrawable, oldCtx);
535     }
536     This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
537
538 out:
539     return ret;
540 }
541
542 /*****************************************************************************
543  * RemoveContextFromArray
544  *
545  * Removes a context from the context manager. The opengl context is not
546  * destroyed or unset. context is not a valid pointer after that call.
547  *
548  * Similar to the former call this isn't a performance critical function. A
549  * helper function for DestroyContext.
550  *
551  * Params:
552  *  This: Device to activate the context for
553  *  context: Context to remove
554  *
555  *****************************************************************************/
556 static void RemoveContextFromArray(IWineD3DDeviceImpl *This, WineD3DContext *context) {
557     UINT t, s;
558     WineD3DContext **oldArray = This->contexts;
559
560     TRACE("Removing ctx %p\n", context);
561
562     This->numContexts--;
563
564     if(This->numContexts) {
565         This->contexts = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->contexts) * This->numContexts);
566         if(!This->contexts) {
567             ERR("Cannot allocate a new context array, PANIC!!!\n");
568         }
569         t = 0;
570         /* Note that we decreased numContexts a few lines up, so use '<=' instead of '<' */
571         for(s = 0; s <= This->numContexts; s++) {
572             if(oldArray[s] == context) continue;
573             This->contexts[t] = oldArray[s];
574             t++;
575         }
576     } else {
577         This->contexts = NULL;
578     }
579
580     HeapFree(GetProcessHeap(), 0, context);
581     HeapFree(GetProcessHeap(), 0, oldArray);
582 }
583
584 /*****************************************************************************
585  * DestroyContext
586  *
587  * Destroys a wineD3DContext
588  *
589  * Params:
590  *  This: Device to activate the context for
591  *  context: Context to destroy
592  *
593  *****************************************************************************/
594 void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context) {
595
596     /* check that we are the current context first */
597     TRACE("Destroying ctx %p\n", context);
598     if(pwglGetCurrentContext() == context->glCtx){
599         pwglMakeCurrent(NULL, NULL);
600     }
601
602     if(context->isPBuffer) {
603         GL_EXTCALL(wglReleasePbufferDCARB(context->pbuffer, context->hdc));
604         GL_EXTCALL(wglDestroyPbufferARB(context->pbuffer));
605     } else ReleaseDC(context->win_handle, context->hdc);
606     pwglDeleteContext(context->glCtx);
607
608     HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
609     HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
610     RemoveContextFromArray(This, context);
611 }
612
613 static inline void set_blit_dimension(UINT width, UINT height) {
614     glMatrixMode(GL_PROJECTION);
615     checkGLcall("glMatrixMode(GL_PROJECTION)");
616     glLoadIdentity();
617     checkGLcall("glLoadIdentity()");
618     glOrtho(0, width, height, 0, 0.0, -1.0);
619     checkGLcall("glOrtho");
620     glViewport(0, 0, width, height);
621     checkGLcall("glViewport");
622 }
623
624 /*****************************************************************************
625  * SetupForBlit
626  *
627  * Sets up a context for DirectDraw blitting.
628  * All texture units are disabled, texture unit 0 is set as current unit
629  * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
630  * color writing enabled for all channels
631  * register combiners disabled, shaders disabled
632  * world matrix is set to identity, texture matrix 0 too
633  * projection matrix is setup for drawing screen coordinates
634  *
635  * Params:
636  *  This: Device to activate the context for
637  *  context: Context to setup
638  *  width: render target width
639  *  height: render target height
640  *
641  *****************************************************************************/
642 static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *context, UINT width, UINT height) {
643     int i;
644     const struct StateEntry *StateTable = This->StateTable;
645
646     TRACE("Setting up context %p for blitting\n", context);
647     if(context->last_was_blit) {
648         if(context->blit_w != width || context->blit_h != height) {
649             set_blit_dimension(width, height);
650             context->blit_w = width; context->blit_h = height;
651             /* No need to dirtify here, the states are still dirtified because they weren't
652              * applied since the last SetupForBlit call. Otherwise last_was_blit would not
653              * be set
654              */
655         }
656         TRACE("Context is already set up for blitting, nothing to do\n");
657         return;
658     }
659     context->last_was_blit = TRUE;
660
661     /* TODO: Use a display list */
662
663     /* Disable shaders */
664     This->shader_backend->shader_cleanup((IWineD3DDevice *) This);
665     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
666     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
667
668     /* Disable all textures. The caller can then bind a texture it wants to blit
669      * from
670      */
671     if(GL_SUPPORT(NV_REGISTER_COMBINERS)) {
672         glDisable(GL_REGISTER_COMBINERS_NV);
673         checkGLcall("glDisable(GL_REGISTER_COMBINERS_NV)");
674     }
675     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
676         /* The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
677          * function texture unit. No need to care for higher samplers
678          */
679         for(i = GL_LIMITS(textures) - 1; i > 0 ; i--) {
680             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
681             checkGLcall("glActiveTextureARB");
682
683             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
684                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
685                 checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
686             }
687             glDisable(GL_TEXTURE_3D);
688             checkGLcall("glDisable GL_TEXTURE_3D");
689             glDisable(GL_TEXTURE_2D);
690             checkGLcall("glDisable GL_TEXTURE_2D");
691
692             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
693             checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
694
695             Context_MarkStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), StateTable);
696             Context_MarkStateDirty(context, STATE_SAMPLER(i), StateTable);
697         }
698         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
699         checkGLcall("glActiveTextureARB");
700     }
701     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
702         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
703         checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
704     }
705     glDisable(GL_TEXTURE_3D);
706     checkGLcall("glDisable GL_TEXTURE_3D");
707     glDisable(GL_TEXTURE_2D);
708     checkGLcall("glDisable GL_TEXTURE_2D");
709
710     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
711
712     glMatrixMode(GL_TEXTURE);
713     checkGLcall("glMatrixMode(GL_TEXTURE)");
714     glLoadIdentity();
715     checkGLcall("glLoadIdentity()");
716     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0), StateTable);
717
718     if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
719         glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
720                   GL_TEXTURE_LOD_BIAS_EXT,
721                   0.0);
722         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
723     }
724     Context_MarkStateDirty(context, STATE_SAMPLER(0), StateTable);
725     Context_MarkStateDirty(context, STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), StateTable);
726
727     /* Other misc states */
728     glDisable(GL_ALPHA_TEST);
729     checkGLcall("glDisable(GL_ALPHA_TEST)");
730     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHATESTENABLE), StateTable);
731     glDisable(GL_LIGHTING);
732     checkGLcall("glDisable GL_LIGHTING");
733     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING), StateTable);
734     glDisable(GL_DEPTH_TEST);
735     checkGLcall("glDisable GL_DEPTH_TEST");
736     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE), StateTable);
737     glDisable(GL_FOG);
738     checkGLcall("glDisable GL_FOG");
739     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE), StateTable);
740     glDisable(GL_BLEND);
741     checkGLcall("glDisable GL_BLEND");
742     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
743     glDisable(GL_CULL_FACE);
744     checkGLcall("glDisable GL_CULL_FACE");
745     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CULLMODE), StateTable);
746     glDisable(GL_STENCIL_TEST);
747     checkGLcall("glDisable GL_STENCIL_TEST");
748     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_STENCILENABLE), StateTable);
749     glDisable(GL_SCISSOR_TEST);
750     checkGLcall("glDisable GL_SCISSOR_TEST");
751     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable);
752     if(GL_SUPPORT(ARB_POINT_SPRITE)) {
753         glDisable(GL_POINT_SPRITE_ARB);
754         checkGLcall("glDisable GL_POINT_SPRITE_ARB");
755         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), StateTable);
756     }
757     glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
758     checkGLcall("glColorMask");
759     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
760     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
761         glDisable(GL_COLOR_SUM_EXT);
762         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable);
763         checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
764     }
765     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
766         GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
767         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable);
768         checkGLcall("glFinalCombinerInputNV");
769     }
770
771     /* Setup transforms */
772     glMatrixMode(GL_MODELVIEW);
773     checkGLcall("glMatrixMode(GL_MODELVIEW)");
774     glLoadIdentity();
775     checkGLcall("glLoadIdentity()");
776     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), StateTable);
777
778     context->last_was_rhw = TRUE;
779     Context_MarkStateDirty(context, STATE_VDECL, StateTable); /* because of last_was_rhw = TRUE */
780
781     glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)");
782     glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)");
783     glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)");
784     glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)");
785     glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
786     glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
787     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
788
789     set_blit_dimension(width, height);
790     context->blit_w = width; context->blit_h = height;
791     Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
792     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
793
794
795     This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
796 }
797
798 /*****************************************************************************
799  * findThreadContextForSwapChain
800  *
801  * Searches a swapchain for all contexts and picks one for the thread tid.
802  * If none can be found the swapchain is requested to create a new context
803  *
804  *****************************************************************************/
805 static WineD3DContext *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid) {
806     int i;
807
808     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
809         if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
810             return ((IWineD3DSwapChainImpl *) swapchain)->context[i];
811         }
812
813     }
814
815     /* Create a new context for the thread */
816     return IWineD3DSwapChainImpl_CreateContextForThread(swapchain);
817 }
818
819 /*****************************************************************************
820  * FindContext
821  *
822  * Finds a context for the current render target and thread
823  *
824  * Parameters:
825  *  target: Render target to find the context for
826  *  tid: Thread to activate the context for
827  *
828  * Returns: The needed context
829  *
830  *****************************************************************************/
831 static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, DWORD tid, GLint *buffer) {
832     IWineD3DSwapChain *swapchain = NULL;
833     HRESULT hr;
834     BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
835     WineD3DContext *context = This->activeContext;
836     BOOL oldRenderOffscreen = This->render_offscreen;
837     const WINED3DFORMAT oldFmt = ((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->resource.format;
838     const WINED3DFORMAT newFmt = ((IWineD3DSurfaceImpl *) target)->resource.format;
839     const struct StateEntry *StateTable = This->StateTable;
840
841     /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
842      * the alpha blend state changes with different render target formats
843      */
844     if(oldFmt != newFmt) {
845         const GlPixelFormatDesc *glDesc;
846         const StaticPixelFormatDesc *old = getFormatDescEntry(oldFmt, NULL, NULL);
847         const StaticPixelFormatDesc *new = getFormatDescEntry(newFmt, &GLINFO_LOCATION, &glDesc);
848
849         /* Disable blending when the alphaMask has changed and when a format doesn't support blending */
850         if((old->alphaMask && !new->alphaMask) || (!old->alphaMask && new->alphaMask) || !(glDesc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)) {
851             Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
852         }
853     }
854
855     hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
856     if(hr == WINED3D_OK && swapchain) {
857         TRACE("Rendering onscreen\n");
858
859         context = findThreadContextForSwapChain(swapchain, tid);
860
861         This->render_offscreen = FALSE;
862         /* The context != This->activeContext will catch a NOP context change. This can occur
863          * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
864          * rendering. No context change is needed in that case
865          */
866
867         if(((IWineD3DSwapChainImpl *) swapchain)->frontBuffer == target) {
868             *buffer = GL_FRONT;
869         } else {
870             *buffer = GL_BACK;
871         }
872         if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
873             if(This->pbufferContext && tid == This->pbufferContext->tid) {
874                 This->pbufferContext->tid = 0;
875             }
876         }
877         IWineD3DSwapChain_Release(swapchain);
878
879         if(oldRenderOffscreen) {
880             Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable);
881             Context_MarkStateDirty(context, STATE_VDECL, StateTable);
882             Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
883             Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
884             Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
885         }
886
887     } else {
888         TRACE("Rendering offscreen\n");
889         This->render_offscreen = TRUE;
890         *buffer = This->offscreenBuffer;
891
892         switch(wined3d_settings.offscreen_rendering_mode) {
893             case ORM_FBO:
894                 /* FBOs do not need a different context. Stay with whatever context is active at the moment */
895                 if(This->activeContext && tid == This->lastThread) {
896                     context = This->activeContext;
897                 } else {
898                     /* This may happen if the app jumps straight into offscreen rendering
899                      * Start using the context of the primary swapchain. tid == 0 is no problem
900                      * for findThreadContextForSwapChain.
901                      *
902                      * Can also happen on thread switches - in that case findThreadContextForSwapChain
903                      * is perfect to call.
904                      */
905                     context = findThreadContextForSwapChain(This->swapchains[0], tid);
906                 }
907                 break;
908
909             case ORM_PBUFFER:
910             {
911                 IWineD3DSurfaceImpl *targetimpl = (IWineD3DSurfaceImpl *) target;
912                 if(This->pbufferContext == NULL ||
913                    This->pbufferWidth < targetimpl->currentDesc.Width ||
914                    This->pbufferHeight < targetimpl->currentDesc.Height) {
915                     if(This->pbufferContext) {
916                         DestroyContext(This, This->pbufferContext);
917                     }
918
919                     /* The display is irrelevant here, the window is 0. But CreateContext needs a valid X connection.
920                      * Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
921                      */
922                     This->pbufferContext = CreateContext(This, targetimpl,
923                             ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0]->win_handle,
924                             TRUE /* pbuffer */, &((IWineD3DSwapChainImpl *)This->swapchains[0])->presentParms);
925                     This->pbufferWidth = targetimpl->currentDesc.Width;
926                     This->pbufferHeight = targetimpl->currentDesc.Height;
927                    }
928
929                    if(This->pbufferContext) {
930                        if(This->pbufferContext->tid != 0 && This->pbufferContext->tid != tid) {
931                            FIXME("The PBuffr context is only supported for one thread for now!\n");
932                        }
933                        This->pbufferContext->tid = tid;
934                        context = This->pbufferContext;
935                        break;
936                    } else {
937                        ERR("Failed to create a buffer context and drawable, falling back to back buffer offscreen rendering\n");
938                        wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
939                    }
940             }
941
942             case ORM_BACKBUFFER:
943                 /* Stay with the currently active context for back buffer rendering */
944                 if(This->activeContext && tid == This->lastThread) {
945                     context = This->activeContext;
946                 } else {
947                     /* This may happen if the app jumps straight into offscreen rendering
948                      * Start using the context of the primary swapchain. tid == 0 is no problem
949                      * for findThreadContextForSwapChain.
950                      *
951                      * Can also happen on thread switches - in that case findThreadContextForSwapChain
952                      * is perfect to call.
953                      */
954                     context = findThreadContextForSwapChain(This->swapchains[0], tid);
955                 }
956                 break;
957         }
958
959         if(!oldRenderOffscreen) {
960             Context_MarkStateDirty(context, WINED3DTS_PROJECTION, StateTable);
961             Context_MarkStateDirty(context, STATE_VDECL, StateTable);
962             Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
963             Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
964             Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
965         }
966     }
967
968     /* When switching away from an offscreen render target, and we're not using FBOs,
969      * we have to read the drawable into the texture. This is done via PreLoad(and
970      * SFLAG_INDRAWABLE set on the surface). There are some things that need care though.
971      * PreLoad needs a GL context, and FindContext is called before the context is activated.
972      * It also has to be called with the old rendertarget active, otherwise a wrong drawable
973      * is read. This leads to these possible situations:
974      *
975      * 0) lastActiveRenderTarget == target && oldTid == newTid:
976      *    Nothing to do, we don't even reach this code in this case...
977      *
978      * 1) lastActiveRenderTarget != target && oldTid == newTid:
979      *    The currently active context is OK for readback. Call PreLoad, and it
980      *    performs the read
981      *
982      * 2) lastActiveRenderTarget == target && oldTid != newTid:
983      *    Nothing to do - the drawable is unchanged
984      *
985      * 3) lastActiveRenderTarget != target && oldTid != newTid:
986      *    This is tricky. We have to get a context with the old drawable from somewhere
987      *    before we can switch to the new context. In this case, PreLoad calls
988      *    ActivateContext(lastActiveRenderTarget) from the new(current) thread. This
989      *    is case (2) then. The old drawable is activated for the new thread, and the
990      *    readback can be done. The recursed ActivateContext does *not* call PreLoad again.
991      *    After that, the outer ActivateContext(which calls PreLoad) can activate the new
992      *    target for the new thread
993      */
994     if (readTexture && This->lastActiveRenderTarget != target) {
995         BOOL oldInDraw = This->isInDraw;
996
997         /* PreLoad requires a context to load the texture, thus it will call ActivateContext.
998          * Set the isInDraw to true to signal PreLoad that it has a context. Will be tricky
999          * when using offscreen rendering with multithreading
1000          */
1001         This->isInDraw = TRUE;
1002
1003         /* Do that before switching the context:
1004          * Read the back buffer of the old drawable into the destination texture
1005          */
1006         IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
1007
1008         /* Assume that the drawable will be modified by some other things now */
1009         IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE);
1010
1011         This->isInDraw = oldInDraw;
1012     }
1013
1014     return context;
1015 }
1016
1017 /*****************************************************************************
1018  * ActivateContext
1019  *
1020  * Finds a rendering context and drawable matching the device and render
1021  * target for the current thread, activates them and puts them into the
1022  * requested state.
1023  *
1024  * Params:
1025  *  This: Device to activate the context for
1026  *  target: Requested render target
1027  *  usage: Prepares the context for blitting, drawing or other actions
1028  *
1029  *****************************************************************************/
1030 void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
1031     DWORD                         tid = GetCurrentThreadId();
1032     int                           i;
1033     DWORD                         dirtyState, idx;
1034     BYTE                          shift;
1035     WineD3DContext                *context;
1036     GLint                         drawBuffer=0;
1037     const struct StateEntry       *StateTable = This->StateTable;
1038
1039     TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
1040     if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
1041         context = FindContext(This, target, tid, &drawBuffer);
1042         This->lastActiveRenderTarget = target;
1043         This->lastThread = tid;
1044     } else {
1045         /* Stick to the old context */
1046         context = This->activeContext;
1047     }
1048
1049     /* Activate the opengl context */
1050     if(context != This->activeContext) {
1051         BOOL ret;
1052
1053         /* Prevent an unneeded context switch as those are expensive */
1054         if(context->glCtx && (context->glCtx == pwglGetCurrentContext())) {
1055             TRACE("Already using gl context %p\n", context->glCtx);
1056         }
1057         else {
1058             TRACE("Switching gl ctx to %p, hdc=%p ctx=%p\n", context, context->hdc, context->glCtx);
1059
1060             This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, FALSE);
1061             ret = pwglMakeCurrent(context->hdc, context->glCtx);
1062             if(ret == FALSE) {
1063                 ERR("Failed to activate the new context\n");
1064             } else if(!context->last_was_blit) {
1065                 This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
1066             }
1067         }
1068         if(This->activeContext->vshader_const_dirty) {
1069             memset(This->activeContext->vshader_const_dirty, 1,
1070                    sizeof(*This->activeContext->vshader_const_dirty) * GL_LIMITS(vshader_constantsF));
1071         }
1072         if(This->activeContext->pshader_const_dirty) {
1073             memset(This->activeContext->pshader_const_dirty, 1,
1074                    sizeof(*This->activeContext->pshader_const_dirty) * GL_LIMITS(pshader_constantsF));
1075         }
1076         This->activeContext = context;
1077     }
1078
1079     /* We only need ENTER_GL for the gl calls made below and for the helper functions which make GL calls */
1080     ENTER_GL();
1081     /* Select the right draw buffer. It is selected in FindContext. */
1082     if(drawBuffer && context->last_draw_buffer != drawBuffer) {
1083         TRACE("Drawing to buffer: %#x\n", drawBuffer);
1084         context->last_draw_buffer = drawBuffer;
1085
1086         glDrawBuffer(drawBuffer);
1087         checkGLcall("glDrawBuffer");
1088     }
1089
1090     switch(usage) {
1091         case CTXUSAGE_RESOURCELOAD:
1092             /* This does not require any special states to be set up */
1093             break;
1094
1095         case CTXUSAGE_CLEAR:
1096             if(context->last_was_blit) {
1097                 This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
1098             }
1099
1100             /* Blending and clearing should be orthogonal, but tests on the nvidia driver show that disabling
1101              * blending when clearing improves the clearing performance incredibly.
1102              */
1103             glDisable(GL_BLEND);
1104             Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
1105
1106             glEnable(GL_SCISSOR_TEST);
1107             checkGLcall("glEnable GL_SCISSOR_TEST");
1108             context->last_was_blit = FALSE;
1109             Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable);
1110             Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
1111             break;
1112
1113         case CTXUSAGE_DRAWPRIM:
1114             /* This needs all dirty states applied */
1115             if(context->last_was_blit) {
1116                 This->shader_backend->shader_fragment_enable((IWineD3DDevice *) This, TRUE);
1117             }
1118
1119             IWineD3DDeviceImpl_FindTexUnitMap(This);
1120
1121             for(i=0; i < context->numDirtyEntries; i++) {
1122                 dirtyState = context->dirtyArray[i];
1123                 idx = dirtyState >> 5;
1124                 shift = dirtyState & 0x1f;
1125                 context->isStateDirty[idx] &= ~(1 << shift);
1126                 StateTable[dirtyState].apply(dirtyState, This->stateBlock, context);
1127             }
1128             context->numDirtyEntries = 0; /* This makes the whole list clean */
1129             context->last_was_blit = FALSE;
1130             break;
1131
1132         case CTXUSAGE_BLIT:
1133             SetupForBlit(This, context,
1134                          ((IWineD3DSurfaceImpl *)target)->currentDesc.Width,
1135                          ((IWineD3DSurfaceImpl *)target)->currentDesc.Height);
1136             break;
1137
1138         default:
1139             FIXME("Unexpected context usage requested\n");
1140     }
1141     LEAVE_GL();
1142 }