wined3d: Get rid of GLINFO_LOCATION.
[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  * Copyright 2009 Henri Verbeet for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include <stdio.h>
24 #ifdef HAVE_FLOAT_H
25 # include <float.h>
26 #endif
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30
31 static DWORD wined3d_context_tls_idx;
32
33 /* FBO helper functions */
34
35 /* GL locking is done by the caller */
36 void context_bind_fbo(struct wined3d_context *context, GLenum target, GLuint *fbo)
37 {
38     const struct wined3d_gl_info *gl_info = context->gl_info;
39     GLuint f;
40
41     if (!fbo)
42     {
43         f = 0;
44     }
45     else
46     {
47         if (!*fbo)
48         {
49             gl_info->fbo_ops.glGenFramebuffers(1, fbo);
50             checkGLcall("glGenFramebuffers()");
51             TRACE("Created FBO %u.\n", *fbo);
52         }
53         f = *fbo;
54     }
55
56     switch (target)
57     {
58         case GL_READ_FRAMEBUFFER:
59             if (context->fbo_read_binding == f) return;
60             context->fbo_read_binding = f;
61             break;
62
63         case GL_DRAW_FRAMEBUFFER:
64             if (context->fbo_draw_binding == f) return;
65             context->fbo_draw_binding = f;
66             break;
67
68         case GL_FRAMEBUFFER:
69             if (context->fbo_read_binding == f
70                     && context->fbo_draw_binding == f) return;
71             context->fbo_read_binding = f;
72             context->fbo_draw_binding = f;
73             break;
74
75         default:
76             FIXME("Unhandled target %#x.\n", target);
77             break;
78     }
79
80     gl_info->fbo_ops.glBindFramebuffer(target, f);
81     checkGLcall("glBindFramebuffer()");
82 }
83
84 /* GL locking is done by the caller */
85 static void context_clean_fbo_attachments(const struct wined3d_gl_info *gl_info, GLenum target)
86 {
87     unsigned int i;
88
89     for (i = 0; i < gl_info->limits.buffers; ++i)
90     {
91         gl_info->fbo_ops.glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
92         checkGLcall("glFramebufferTexture2D()");
93     }
94     gl_info->fbo_ops.glFramebufferTexture2D(target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
95     checkGLcall("glFramebufferTexture2D()");
96
97     gl_info->fbo_ops.glFramebufferTexture2D(target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
98     checkGLcall("glFramebufferTexture2D()");
99 }
100
101 /* GL locking is done by the caller */
102 static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
103 {
104     const struct wined3d_gl_info *gl_info = context->gl_info;
105
106     context_bind_fbo(context, GL_FRAMEBUFFER, fbo);
107     context_clean_fbo_attachments(gl_info, GL_FRAMEBUFFER);
108     context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
109
110     gl_info->fbo_ops.glDeleteFramebuffers(1, fbo);
111     checkGLcall("glDeleteFramebuffers()");
112 }
113
114 /* GL locking is done by the caller */
115 static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface)
116 {
117     IWineD3DBaseTextureImpl *texture_impl;
118
119     /* Update base texture states array */
120     if (SUCCEEDED(IWineD3DSurface_GetContainer((IWineD3DSurface *)surface,
121             &IID_IWineD3DBaseTexture, (void **)&texture_impl)))
122     {
123         IWineD3DDeviceImpl *device = surface->resource.device;
124         BOOL update_minfilter = FALSE;
125         BOOL update_magfilter = FALSE;
126
127         if (texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] != WINED3DTEXF_POINT
128             || texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] != WINED3DTEXF_NONE)
129         {
130             texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT;
131             texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE;
132             update_minfilter = TRUE;
133         }
134
135         if (texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] != WINED3DTEXF_POINT)
136         {
137             texture_impl->baseTexture.texture_rgb.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT;
138             update_magfilter = TRUE;
139         }
140
141         if (texture_impl->baseTexture.bindCount)
142         {
143             WARN("Render targets should not be bound to a sampler\n");
144             IWineD3DDeviceImpl_MarkStateDirty(device, STATE_SAMPLER(texture_impl->baseTexture.sampler));
145         }
146
147         IWineD3DBaseTexture_Release((IWineD3DBaseTexture *)texture_impl);
148
149         if (update_minfilter || update_magfilter)
150         {
151             GLenum target, bind_target;
152             GLint old_binding;
153
154             target = surface->texture_target;
155             if (target == GL_TEXTURE_2D)
156             {
157                 bind_target = GL_TEXTURE_2D;
158                 glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_binding);
159             }
160             else if (target == GL_TEXTURE_RECTANGLE_ARB)
161             {
162                 bind_target = GL_TEXTURE_RECTANGLE_ARB;
163                 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
164             }
165             else
166             {
167                 bind_target = GL_TEXTURE_CUBE_MAP_ARB;
168                 glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
169             }
170
171             glBindTexture(bind_target, surface->texture_name);
172             if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
173             if (update_magfilter) glTexParameteri(bind_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
174             glBindTexture(bind_target, old_binding);
175         }
176
177         checkGLcall("apply_attachment_filter_states()");
178     }
179 }
180
181 /* GL locking is done by the caller */
182 void context_attach_depth_stencil_fbo(struct wined3d_context *context,
183         GLenum fbo_target, IWineD3DSurfaceImpl *depth_stencil, BOOL use_render_buffer)
184 {
185     const struct wined3d_gl_info *gl_info = context->gl_info;
186
187     TRACE("Attach depth stencil %p\n", depth_stencil);
188
189     if (depth_stencil)
190     {
191         DWORD format_flags = depth_stencil->resource.format_desc->Flags;
192
193         if (use_render_buffer && depth_stencil->current_renderbuffer)
194         {
195             if (format_flags & WINED3DFMT_FLAG_DEPTH)
196             {
197                 gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_DEPTH_ATTACHMENT,
198                         GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id);
199                 checkGLcall("glFramebufferRenderbuffer()");
200             }
201
202             if (format_flags & WINED3DFMT_FLAG_STENCIL)
203             {
204                 gl_info->fbo_ops.glFramebufferRenderbuffer(fbo_target, GL_STENCIL_ATTACHMENT,
205                         GL_RENDERBUFFER, depth_stencil->current_renderbuffer->id);
206                 checkGLcall("glFramebufferRenderbuffer()");
207             }
208         }
209         else
210         {
211             surface_prepare_texture(depth_stencil, gl_info, FALSE);
212             context_apply_attachment_filter_states(depth_stencil);
213
214             if (format_flags & WINED3DFMT_FLAG_DEPTH)
215             {
216                 gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT,
217                         depth_stencil->texture_target, depth_stencil->texture_name,
218                         depth_stencil->texture_level);
219                 checkGLcall("glFramebufferTexture2D()");
220             }
221
222             if (format_flags & WINED3DFMT_FLAG_STENCIL)
223             {
224                 gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT,
225                         depth_stencil->texture_target, depth_stencil->texture_name,
226                         depth_stencil->texture_level);
227                 checkGLcall("glFramebufferTexture2D()");
228             }
229         }
230
231         if (!(format_flags & WINED3DFMT_FLAG_DEPTH))
232         {
233             gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
234             checkGLcall("glFramebufferTexture2D()");
235         }
236
237         if (!(format_flags & WINED3DFMT_FLAG_STENCIL))
238         {
239             gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
240             checkGLcall("glFramebufferTexture2D()");
241         }
242     }
243     else
244     {
245         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
246         checkGLcall("glFramebufferTexture2D()");
247
248         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
249         checkGLcall("glFramebufferTexture2D()");
250     }
251 }
252
253 /* GL locking is done by the caller */
254 static void context_attach_surface_fbo(const struct wined3d_context *context,
255         GLenum fbo_target, DWORD idx, IWineD3DSurfaceImpl *surface)
256 {
257     const struct wined3d_gl_info *gl_info = context->gl_info;
258
259     TRACE("Attach surface %p to %u\n", surface, idx);
260
261     if (surface)
262     {
263         surface_prepare_texture(surface, gl_info, FALSE);
264         context_apply_attachment_filter_states(surface);
265
266         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, surface->texture_target,
267                 surface->texture_name, surface->texture_level);
268         checkGLcall("glFramebufferTexture2D()");
269     }
270     else
271     {
272         gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, GL_TEXTURE_2D, 0, 0);
273         checkGLcall("glFramebufferTexture2D()");
274     }
275 }
276
277 /* GL locking is done by the caller */
278 static void context_check_fbo_status(struct wined3d_context *context, GLenum target)
279 {
280     const struct wined3d_gl_info *gl_info = context->gl_info;
281     GLenum status;
282
283     status = gl_info->fbo_ops.glCheckFramebufferStatus(target);
284     if (status == GL_FRAMEBUFFER_COMPLETE)
285     {
286         TRACE("FBO complete\n");
287     } else {
288         IWineD3DSurfaceImpl *attachment;
289         unsigned int i;
290         FIXME("FBO status %s (%#x)\n", debug_fbostatus(status), status);
291
292         if (!context->current_fbo)
293         {
294             ERR("FBO 0 is incomplete, driver bug?\n");
295             return;
296         }
297
298         /* Dump the FBO attachments */
299         for (i = 0; i < gl_info->limits.buffers; ++i)
300         {
301             attachment = context->current_fbo->render_targets[i];
302             if (attachment)
303             {
304                 FIXME("\tColor attachment %d: (%p) %s %ux%u\n",
305                         i, attachment, debug_d3dformat(attachment->resource.format_desc->format),
306                         attachment->pow2Width, attachment->pow2Height);
307             }
308         }
309         attachment = context->current_fbo->depth_stencil;
310         if (attachment)
311         {
312             FIXME("\tDepth attachment: (%p) %s %ux%u\n",
313                     attachment, debug_d3dformat(attachment->resource.format_desc->format),
314                     attachment->pow2Width, attachment->pow2Height);
315         }
316     }
317 }
318
319 static struct fbo_entry *context_create_fbo_entry(struct wined3d_context *context,
320         IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
321 {
322     const struct wined3d_gl_info *gl_info = context->gl_info;
323     struct fbo_entry *entry;
324
325     entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
326     entry->render_targets = HeapAlloc(GetProcessHeap(), 0, gl_info->limits.buffers * sizeof(*entry->render_targets));
327     memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
328     entry->depth_stencil = depth_stencil;
329     entry->attached = FALSE;
330     entry->id = 0;
331
332     return entry;
333 }
334
335 /* GL locking is done by the caller */
336 static void context_reuse_fbo_entry(struct wined3d_context *context, GLenum target,
337         IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil,
338         struct fbo_entry *entry)
339 {
340     const struct wined3d_gl_info *gl_info = context->gl_info;
341
342     context_bind_fbo(context, target, &entry->id);
343     context_clean_fbo_attachments(gl_info, target);
344
345     memcpy(entry->render_targets, render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets));
346     entry->depth_stencil = depth_stencil;
347     entry->attached = FALSE;
348 }
349
350 /* GL locking is done by the caller */
351 static void context_destroy_fbo_entry(struct wined3d_context *context, struct fbo_entry *entry)
352 {
353     if (entry->id)
354     {
355         TRACE("Destroy FBO %d\n", entry->id);
356         context_destroy_fbo(context, &entry->id);
357     }
358     --context->fbo_entry_count;
359     list_remove(&entry->entry);
360     HeapFree(GetProcessHeap(), 0, entry->render_targets);
361     HeapFree(GetProcessHeap(), 0, entry);
362 }
363
364
365 /* GL locking is done by the caller */
366 static struct fbo_entry *context_find_fbo_entry(struct wined3d_context *context, GLenum target,
367         IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
368 {
369     const struct wined3d_gl_info *gl_info = context->gl_info;
370     struct fbo_entry *entry;
371
372     LIST_FOR_EACH_ENTRY(entry, &context->fbo_list, struct fbo_entry, entry)
373     {
374         if (!memcmp(entry->render_targets,
375                 render_targets, gl_info->limits.buffers * sizeof(*entry->render_targets))
376                 && entry->depth_stencil == depth_stencil)
377         {
378             list_remove(&entry->entry);
379             list_add_head(&context->fbo_list, &entry->entry);
380             return entry;
381         }
382     }
383
384     if (context->fbo_entry_count < WINED3D_MAX_FBO_ENTRIES)
385     {
386         entry = context_create_fbo_entry(context, render_targets, depth_stencil);
387         list_add_head(&context->fbo_list, &entry->entry);
388         ++context->fbo_entry_count;
389     }
390     else
391     {
392         entry = LIST_ENTRY(list_tail(&context->fbo_list), struct fbo_entry, entry);
393         context_reuse_fbo_entry(context, target, render_targets, depth_stencil, entry);
394         list_remove(&entry->entry);
395         list_add_head(&context->fbo_list, &entry->entry);
396     }
397
398     return entry;
399 }
400
401 /* GL locking is done by the caller */
402 static void context_apply_fbo_entry(struct wined3d_context *context, GLenum target, struct fbo_entry *entry)
403 {
404     const struct wined3d_gl_info *gl_info = context->gl_info;
405     unsigned int i;
406
407     context_bind_fbo(context, target, &entry->id);
408
409     if (!entry->attached)
410     {
411         /* Apply render targets */
412         for (i = 0; i < gl_info->limits.buffers; ++i)
413         {
414             context_attach_surface_fbo(context, target, i, entry->render_targets[i]);
415         }
416
417         /* Apply depth targets */
418         if (entry->depth_stencil)
419         {
420             surface_set_compatible_renderbuffer(entry->depth_stencil,
421                     entry->render_targets[0]->pow2Width, entry->render_targets[0]->pow2Height);
422         }
423         context_attach_depth_stencil_fbo(context, target, entry->depth_stencil, TRUE);
424
425         entry->attached = TRUE;
426     }
427     else
428     {
429         for (i = 0; i < gl_info->limits.buffers; ++i)
430         {
431             if (entry->render_targets[i])
432                 context_apply_attachment_filter_states(entry->render_targets[i]);
433         }
434         if (entry->depth_stencil)
435             context_apply_attachment_filter_states(entry->depth_stencil);
436     }
437 }
438
439 /* GL locking is done by the caller */
440 static void context_apply_fbo_state(struct wined3d_context *context, GLenum target,
441         IWineD3DSurfaceImpl **render_targets, IWineD3DSurfaceImpl *depth_stencil)
442 {
443     struct fbo_entry *entry, *entry2;
444
445     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
446     {
447         context_destroy_fbo_entry(context, entry);
448     }
449
450     if (context->rebind_fbo)
451     {
452         context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
453         context->rebind_fbo = FALSE;
454     }
455
456     if (render_targets)
457     {
458         context->current_fbo = context_find_fbo_entry(context, target, render_targets, depth_stencil);
459         context_apply_fbo_entry(context, target, context->current_fbo);
460     }
461     else
462     {
463         context->current_fbo = NULL;
464         context_bind_fbo(context, target, NULL);
465     }
466
467     context_check_fbo_status(context, target);
468 }
469
470 /* GL locking is done by the caller */
471 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
472         IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil)
473 {
474     if (surface_is_offscreen(render_target))
475     {
476         context->blit_targets[0] = render_target;
477         context_apply_fbo_state(context, target, context->blit_targets, depth_stencil);
478     }
479     else
480     {
481         context_apply_fbo_state(context, target, NULL, NULL);
482     }
483 }
484
485 /* Context activation is done by the caller. */
486 void context_alloc_occlusion_query(struct wined3d_context *context, struct wined3d_occlusion_query *query)
487 {
488     const struct wined3d_gl_info *gl_info = context->gl_info;
489
490     if (context->free_occlusion_query_count)
491     {
492         query->id = context->free_occlusion_queries[--context->free_occlusion_query_count];
493     }
494     else
495     {
496         if (gl_info->supported[ARB_OCCLUSION_QUERY])
497         {
498             ENTER_GL();
499             GL_EXTCALL(glGenQueriesARB(1, &query->id));
500             checkGLcall("glGenQueriesARB");
501             LEAVE_GL();
502
503             TRACE("Allocated occlusion query %u in context %p.\n", query->id, context);
504         }
505         else
506         {
507             WARN("Occlusion queries not supported, not allocating query id.\n");
508             query->id = 0;
509         }
510     }
511
512     query->context = context;
513     list_add_head(&context->occlusion_queries, &query->entry);
514 }
515
516 void context_free_occlusion_query(struct wined3d_occlusion_query *query)
517 {
518     struct wined3d_context *context = query->context;
519
520     list_remove(&query->entry);
521     query->context = NULL;
522
523     if (context->free_occlusion_query_count >= context->free_occlusion_query_size - 1)
524     {
525         UINT new_size = context->free_occlusion_query_size << 1;
526         GLuint *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_occlusion_queries,
527                 new_size * sizeof(*context->free_occlusion_queries));
528
529         if (!new_data)
530         {
531             ERR("Failed to grow free list, leaking query %u in context %p.\n", query->id, context);
532             return;
533         }
534
535         context->free_occlusion_query_size = new_size;
536         context->free_occlusion_queries = new_data;
537     }
538
539     context->free_occlusion_queries[context->free_occlusion_query_count++] = query->id;
540 }
541
542 /* Context activation is done by the caller. */
543 void context_alloc_event_query(struct wined3d_context *context, struct wined3d_event_query *query)
544 {
545     const struct wined3d_gl_info *gl_info = context->gl_info;
546
547     if (context->free_event_query_count)
548     {
549         query->object = context->free_event_queries[--context->free_event_query_count];
550     }
551     else
552     {
553         if (gl_info->supported[ARB_SYNC])
554         {
555             /* Using ARB_sync, not much to do here. */
556             query->object.sync = NULL;
557             TRACE("Allocated event query %p in context %p.\n", query->object.sync, context);
558         }
559         else if (gl_info->supported[APPLE_FENCE])
560         {
561             ENTER_GL();
562             GL_EXTCALL(glGenFencesAPPLE(1, &query->object.id));
563             checkGLcall("glGenFencesAPPLE");
564             LEAVE_GL();
565
566             TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
567         }
568         else if(gl_info->supported[NV_FENCE])
569         {
570             ENTER_GL();
571             GL_EXTCALL(glGenFencesNV(1, &query->object.id));
572             checkGLcall("glGenFencesNV");
573             LEAVE_GL();
574
575             TRACE("Allocated event query %u in context %p.\n", query->object.id, context);
576         }
577         else
578         {
579             WARN("Event queries not supported, not allocating query id.\n");
580             query->object.id = 0;
581         }
582     }
583
584     query->context = context;
585     list_add_head(&context->event_queries, &query->entry);
586 }
587
588 void context_free_event_query(struct wined3d_event_query *query)
589 {
590     struct wined3d_context *context = query->context;
591
592     list_remove(&query->entry);
593     query->context = NULL;
594
595     if (context->free_event_query_count >= context->free_event_query_size - 1)
596     {
597         UINT new_size = context->free_event_query_size << 1;
598         union wined3d_gl_query_object *new_data = HeapReAlloc(GetProcessHeap(), 0, context->free_event_queries,
599                 new_size * sizeof(*context->free_event_queries));
600
601         if (!new_data)
602         {
603             ERR("Failed to grow free list, leaking query %u in context %p.\n", query->object.id, context);
604             return;
605         }
606
607         context->free_event_query_size = new_size;
608         context->free_event_queries = new_data;
609     }
610
611     context->free_event_queries[context->free_event_query_count++] = query->object;
612 }
613
614 void context_resource_released(IWineD3DDevice *iface, IWineD3DResource *resource, WINED3DRESOURCETYPE type)
615 {
616     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
617     UINT i;
618
619     if (!This->d3d_initialized) return;
620
621     switch(type)
622     {
623         case WINED3DRTYPE_SURFACE:
624         {
625             for (i = 0; i < This->numContexts; ++i)
626             {
627                 struct wined3d_context *context = This->contexts[i];
628                 const struct wined3d_gl_info *gl_info = context->gl_info;
629                 struct fbo_entry *entry, *entry2;
630
631                 if (context->current_rt == (IWineD3DSurfaceImpl *)resource) context->current_rt = NULL;
632
633                 LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
634                 {
635                     UINT j;
636
637                     if (entry->depth_stencil == (IWineD3DSurfaceImpl *)resource)
638                     {
639                         list_remove(&entry->entry);
640                         list_add_head(&context->fbo_destroy_list, &entry->entry);
641                         continue;
642                     }
643
644                     for (j = 0; j < gl_info->limits.buffers; ++j)
645                     {
646                         if (entry->render_targets[j] == (IWineD3DSurfaceImpl *)resource)
647                         {
648                             list_remove(&entry->entry);
649                             list_add_head(&context->fbo_destroy_list, &entry->entry);
650                             break;
651                         }
652                     }
653                 }
654             }
655
656             break;
657         }
658
659         default:
660             break;
661     }
662 }
663
664 void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface)
665 {
666     const struct wined3d_gl_info *gl_info = context->gl_info;
667     struct fbo_entry *entry = context->current_fbo;
668     unsigned int i;
669
670     if (!entry || context->rebind_fbo) return;
671
672     for (i = 0; i < gl_info->limits.buffers; ++i)
673     {
674         if (surface == entry->render_targets[i])
675         {
676             TRACE("Updated surface %p is bound as color attachment %u to the current FBO.\n", surface, i);
677             context->rebind_fbo = TRUE;
678             return;
679         }
680     }
681
682     if (surface == entry->depth_stencil)
683     {
684         TRACE("Updated surface %p is bound as depth attachment to the current FBO.\n", surface);
685         context->rebind_fbo = TRUE;
686     }
687 }
688
689 static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC dc, int format)
690 {
691     int current = GetPixelFormat(dc);
692
693     if (current == format) return TRUE;
694
695     if (!current)
696     {
697         if (!SetPixelFormat(dc, format, NULL))
698         {
699             ERR("Failed to set pixel format %d on device context %p, last error %#x.\n",
700                     format, dc, GetLastError());
701             return FALSE;
702         }
703         return TRUE;
704     }
705
706     /* By default WGL doesn't allow pixel format adjustments but we need it
707      * here. For this reason there's a Wine specific wglSetPixelFormat()
708      * which allows us to set the pixel format multiple times. Only use it
709      * when really needed. */
710     if (gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH])
711     {
712         if (!GL_EXTCALL(wglSetPixelFormatWINE(dc, format, NULL)))
713         {
714             ERR("wglSetPixelFormatWINE failed to set pixel format %d on device context %p.\n",
715                     format, dc);
716             return FALSE;
717         }
718         return TRUE;
719     }
720
721     /* OpenGL doesn't allow pixel format adjustments. Print an error and
722      * continue using the old format. There's a big chance that the old
723      * format works although with a performance hit and perhaps rendering
724      * errors. */
725     ERR("Unable to set pixel format %d on device context %p. Already using format %d.\n",
726             format, dc, current);
727     return TRUE;
728 }
729
730 static void context_update_window(struct wined3d_context *context)
731 {
732     TRACE("Updating context %p window from %p to %p.\n",
733             context, context->win_handle, context->swapchain->win_handle);
734
735     if (context->valid)
736     {
737         if (!ReleaseDC(context->win_handle, context->hdc))
738         {
739             ERR("Failed to release device context %p, last error %#x.\n",
740                     context->hdc, GetLastError());
741         }
742     }
743     else context->valid = 1;
744
745     context->win_handle = context->swapchain->win_handle;
746
747     if (!(context->hdc = GetDC(context->win_handle)))
748     {
749         ERR("Failed to get a device context for window %p.\n", context->win_handle);
750         goto err;
751     }
752
753     if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format))
754     {
755         ERR("Failed to set pixel format %d on device context %p.\n",
756                 context->pixel_format, context->hdc);
757         goto err;
758     }
759
760     if (!pwglMakeCurrent(context->hdc, context->glCtx))
761     {
762         ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
763                 context->glCtx, context->hdc, GetLastError());
764         goto err;
765     }
766
767     return;
768
769 err:
770     context->valid = 0;
771 }
772
773 static void context_validate(struct wined3d_context *context)
774 {
775     HWND wnd = WindowFromDC(context->hdc);
776
777     if (wnd != context->win_handle)
778     {
779         WARN("DC %p belongs to window %p instead of %p.\n",
780                 context->hdc, wnd, context->win_handle);
781         context->valid = 0;
782     }
783
784     if (context->win_handle != context->swapchain->win_handle)
785         context_update_window(context);
786 }
787
788 static void context_destroy_gl_resources(struct wined3d_context *context)
789 {
790     const struct wined3d_gl_info *gl_info = context->gl_info;
791     struct wined3d_occlusion_query *occlusion_query;
792     struct wined3d_event_query *event_query;
793     struct fbo_entry *entry, *entry2;
794     HGLRC restore_ctx;
795     HDC restore_dc;
796     unsigned int i;
797
798     restore_ctx = pwglGetCurrentContext();
799     restore_dc = pwglGetCurrentDC();
800
801     context_validate(context);
802     if (context->valid && restore_ctx != context->glCtx) pwglMakeCurrent(context->hdc, context->glCtx);
803     else restore_ctx = NULL;
804
805     ENTER_GL();
806
807     LIST_FOR_EACH_ENTRY(occlusion_query, &context->occlusion_queries, struct wined3d_occlusion_query, entry)
808     {
809         if (context->valid && gl_info->supported[ARB_OCCLUSION_QUERY])
810             GL_EXTCALL(glDeleteQueriesARB(1, &occlusion_query->id));
811         occlusion_query->context = NULL;
812     }
813
814     LIST_FOR_EACH_ENTRY(event_query, &context->event_queries, struct wined3d_event_query, entry)
815     {
816         if (context->valid)
817         {
818             if (gl_info->supported[ARB_SYNC])
819             {
820                 if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
821             }
822             else if (gl_info->supported[APPLE_FENCE]) GL_EXTCALL(glDeleteFencesAPPLE(1, &event_query->object.id));
823             else if (gl_info->supported[NV_FENCE]) GL_EXTCALL(glDeleteFencesNV(1, &event_query->object.id));
824         }
825         event_query->context = NULL;
826     }
827
828     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_destroy_list, struct fbo_entry, entry)
829     {
830         if (!context->valid) entry->id = 0;
831         context_destroy_fbo_entry(context, entry);
832     }
833
834     LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &context->fbo_list, struct fbo_entry, entry)
835     {
836         if (!context->valid) entry->id = 0;
837         context_destroy_fbo_entry(context, entry);
838     }
839
840     if (context->valid)
841     {
842         if (context->dst_fbo)
843         {
844             TRACE("Destroy dst FBO %d\n", context->dst_fbo);
845             context_destroy_fbo(context, &context->dst_fbo);
846         }
847         if (context->dummy_arbfp_prog)
848         {
849             GL_EXTCALL(glDeleteProgramsARB(1, &context->dummy_arbfp_prog));
850         }
851
852         if (gl_info->supported[ARB_OCCLUSION_QUERY])
853             GL_EXTCALL(glDeleteQueriesARB(context->free_occlusion_query_count, context->free_occlusion_queries));
854
855         if (gl_info->supported[ARB_SYNC])
856         {
857             if (event_query->object.sync) GL_EXTCALL(glDeleteSync(event_query->object.sync));
858         }
859         else if (gl_info->supported[APPLE_FENCE])
860         {
861             for (i = 0; i < context->free_event_query_count; ++i)
862             {
863                 GL_EXTCALL(glDeleteFencesAPPLE(1, &context->free_event_queries[i].id));
864             }
865         }
866         else if (gl_info->supported[NV_FENCE])
867         {
868             for (i = 0; i < context->free_event_query_count; ++i)
869             {
870                 GL_EXTCALL(glDeleteFencesNV(1, &context->free_event_queries[i].id));
871             }
872         }
873
874         checkGLcall("context cleanup");
875     }
876
877     LEAVE_GL();
878
879     HeapFree(GetProcessHeap(), 0, context->free_occlusion_queries);
880     HeapFree(GetProcessHeap(), 0, context->free_event_queries);
881
882     if (restore_ctx)
883     {
884         if (!pwglMakeCurrent(restore_dc, restore_ctx))
885         {
886             DWORD err = GetLastError();
887             ERR("Failed to restore GL context %p on device context %p, last error %#x.\n",
888                     restore_ctx, restore_dc, err);
889         }
890     }
891     else if (pwglGetCurrentContext() && !pwglMakeCurrent(NULL, NULL))
892     {
893         ERR("Failed to disable GL context.\n");
894     }
895
896     ReleaseDC(context->win_handle, context->hdc);
897
898     if (!pwglDeleteContext(context->glCtx))
899     {
900         DWORD err = GetLastError();
901         ERR("wglDeleteContext(%p) failed, last error %#x.\n", context->glCtx, err);
902     }
903 }
904
905 DWORD context_get_tls_idx(void)
906 {
907     return wined3d_context_tls_idx;
908 }
909
910 void context_set_tls_idx(DWORD idx)
911 {
912     wined3d_context_tls_idx = idx;
913 }
914
915 struct wined3d_context *context_get_current(void)
916 {
917     return TlsGetValue(wined3d_context_tls_idx);
918 }
919
920 BOOL context_set_current(struct wined3d_context *ctx)
921 {
922     struct wined3d_context *old = context_get_current();
923
924     if (old == ctx)
925     {
926         TRACE("Already using D3D context %p.\n", ctx);
927         return TRUE;
928     }
929
930     if (old)
931     {
932         if (old->destroyed)
933         {
934             TRACE("Switching away from destroyed context %p.\n", old);
935             context_destroy_gl_resources(old);
936             HeapFree(GetProcessHeap(), 0, old);
937         }
938         else
939         {
940             old->current = 0;
941         }
942     }
943
944     if (ctx)
945     {
946         TRACE("Switching to D3D context %p, GL context %p, device context %p.\n", ctx, ctx->glCtx, ctx->hdc);
947         if (!pwglMakeCurrent(ctx->hdc, ctx->glCtx))
948         {
949             DWORD err = GetLastError();
950             ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
951                     ctx->glCtx, ctx->hdc, err);
952             TlsSetValue(wined3d_context_tls_idx, NULL);
953             return FALSE;
954         }
955         ctx->current = 1;
956     }
957     else if(pwglGetCurrentContext())
958     {
959         TRACE("Clearing current D3D context.\n");
960         if (!pwglMakeCurrent(NULL, NULL))
961         {
962             DWORD err = GetLastError();
963             ERR("Failed to clear current GL context, last error %#x.\n", err);
964             TlsSetValue(wined3d_context_tls_idx, NULL);
965             return FALSE;
966         }
967     }
968
969     return TlsSetValue(wined3d_context_tls_idx, ctx);
970 }
971
972 void context_release(struct wined3d_context *context)
973 {
974     TRACE("Releasing context %p, level %u.\n", context, context->level);
975
976     if (WARN_ON(d3d))
977     {
978         if (!context->level)
979             WARN("Context %p is not active.\n", context);
980         else if (context != context_get_current())
981             WARN("Context %p is not the current context.\n", context);
982     }
983
984     if (!--context->level && context->restore_ctx)
985     {
986         TRACE("Restoring GL context %p on device context %p.\n", context->restore_ctx, context->restore_dc);
987         if (!pwglMakeCurrent(context->restore_dc, context->restore_ctx))
988         {
989             DWORD err = GetLastError();
990             ERR("Failed to restore GL context %p on device context %p, last error %#x.\n",
991                     context->restore_ctx, context->restore_dc, err);
992         }
993         context->restore_ctx = NULL;
994         context->restore_dc = NULL;
995     }
996 }
997
998 static void context_enter(struct wined3d_context *context)
999 {
1000     TRACE("Entering context %p, level %u.\n", context, context->level + 1);
1001
1002     if (!context->level++)
1003     {
1004         const struct wined3d_context *current_context = context_get_current();
1005         HGLRC current_gl = pwglGetCurrentContext();
1006
1007         if (current_gl && (!current_context || current_context->glCtx != current_gl))
1008         {
1009             TRACE("Another GL context (%p on device context %p) is already current.\n",
1010                     current_gl, pwglGetCurrentDC());
1011             context->restore_ctx = current_gl;
1012             context->restore_dc = pwglGetCurrentDC();
1013         }
1014     }
1015 }
1016
1017 /*****************************************************************************
1018  * Context_MarkStateDirty
1019  *
1020  * Marks a state in a context dirty. Only one context, opposed to
1021  * IWineD3DDeviceImpl_MarkStateDirty, which marks the state dirty in all
1022  * contexts
1023  *
1024  * Params:
1025  *  context: Context to mark the state dirty in
1026  *  state: State to mark dirty
1027  *  StateTable: Pointer to the state table in use(for state grouping)
1028  *
1029  *****************************************************************************/
1030 static void Context_MarkStateDirty(struct wined3d_context *context, DWORD state, const struct StateEntry *StateTable)
1031 {
1032     DWORD rep = StateTable[state].representative;
1033     DWORD idx;
1034     BYTE shift;
1035
1036     if (isStateDirty(context, rep)) return;
1037
1038     context->dirtyArray[context->numDirtyEntries++] = rep;
1039     idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
1040     shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
1041     context->isStateDirty[idx] |= (1 << shift);
1042 }
1043
1044 /* This function takes care of WineD3D pixel format selection. */
1045 static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc,
1046         const struct wined3d_format_desc *color_format_desc, const struct wined3d_format_desc *ds_format_desc,
1047         BOOL auxBuffers, int numSamples, BOOL findCompatible)
1048 {
1049     int iPixelFormat=0;
1050     unsigned int matchtry;
1051     short redBits, greenBits, blueBits, alphaBits, colorBits;
1052     short depthBits=0, stencilBits=0;
1053
1054     struct match_type {
1055         BOOL require_aux;
1056         BOOL exact_alpha;
1057         BOOL exact_color;
1058     } matches[] = {
1059         /* First, try without alpha match buffers. MacOS supports aux buffers only
1060          * on A8R8G8B8, and we prefer better offscreen rendering over an alpha match.
1061          * Then try without aux buffers - this is the most common cause for not
1062          * finding a pixel format. Also some drivers(the open source ones)
1063          * only offer 32 bit ARB pixel formats. First try without an exact alpha
1064          * match, then try without an exact alpha and color match.
1065          */
1066         { TRUE,  TRUE,  TRUE  },
1067         { TRUE,  FALSE, TRUE  },
1068         { FALSE, TRUE,  TRUE  },
1069         { FALSE, FALSE, TRUE  },
1070         { TRUE,  FALSE, FALSE },
1071         { FALSE, FALSE, FALSE },
1072     };
1073
1074     int i = 0;
1075     int nCfgs = This->adapter->nCfgs;
1076
1077     TRACE("ColorFormat=%s, DepthStencilFormat=%s, auxBuffers=%d, numSamples=%d, findCompatible=%d\n",
1078           debug_d3dformat(color_format_desc->format), debug_d3dformat(ds_format_desc->format),
1079           auxBuffers, numSamples, findCompatible);
1080
1081     if (!getColorBits(color_format_desc, &redBits, &greenBits, &blueBits, &alphaBits, &colorBits))
1082     {
1083         ERR("Unable to get color bits for format %s (%#x)!\n",
1084                 debug_d3dformat(color_format_desc->format), color_format_desc->format);
1085         return 0;
1086     }
1087
1088     getDepthStencilBits(ds_format_desc, &depthBits, &stencilBits);
1089
1090     for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])) && !iPixelFormat; matchtry++) {
1091         for(i=0; i<nCfgs; i++) {
1092             BOOL exactDepthMatch = TRUE;
1093             WineD3D_PixelFormat *cfg = &This->adapter->cfgs[i];
1094
1095             /* For now only accept RGBA formats. Perhaps some day we will
1096              * allow floating point formats for pbuffers. */
1097             if(cfg->iPixelType != WGL_TYPE_RGBA_ARB)
1098                 continue;
1099
1100             /* In window mode we need a window drawable format and double buffering. */
1101             if(!(cfg->windowDrawable && cfg->doubleBuffer))
1102                 continue;
1103
1104             /* We like to have aux buffers in backbuffer mode */
1105             if(auxBuffers && !cfg->auxBuffers && matches[matchtry].require_aux)
1106                 continue;
1107
1108             if(matches[matchtry].exact_color) {
1109                 if(cfg->redSize != redBits)
1110                     continue;
1111                 if(cfg->greenSize != greenBits)
1112                     continue;
1113                 if(cfg->blueSize != blueBits)
1114                     continue;
1115             } else {
1116                 if(cfg->redSize < redBits)
1117                     continue;
1118                 if(cfg->greenSize < greenBits)
1119                     continue;
1120                 if(cfg->blueSize < blueBits)
1121                     continue;
1122             }
1123             if(matches[matchtry].exact_alpha) {
1124                 if(cfg->alphaSize != alphaBits)
1125                     continue;
1126             } else {
1127                 if(cfg->alphaSize < alphaBits)
1128                     continue;
1129             }
1130
1131             /* We try to locate a format which matches our requirements exactly. In case of
1132              * depth it is no problem to emulate 16-bit using e.g. 24-bit, so accept that. */
1133             if(cfg->depthSize < depthBits)
1134                 continue;
1135             else if(cfg->depthSize > depthBits)
1136                 exactDepthMatch = FALSE;
1137
1138             /* In all cases make sure the number of stencil bits matches our requirements
1139              * even when we don't need stencil because it could affect performance EXCEPT
1140              * on cards which don't offer depth formats without stencil like the i915 drivers
1141              * on Linux. */
1142             if(stencilBits != cfg->stencilSize && !(This->adapter->brokenStencil && stencilBits <= cfg->stencilSize))
1143                 continue;
1144
1145             /* Check multisampling support */
1146             if(cfg->numSamples != numSamples)
1147                 continue;
1148
1149             /* When we have passed all the checks then we have found a format which matches our
1150              * requirements. Note that we only check for a limit number of capabilities right now,
1151              * so there can easily be a dozen of pixel formats which appear to be the 'same' but
1152              * can still differ in things like multisampling, stereo, SRGB and other flags.
1153              */
1154
1155             /* Exit the loop as we have found a format :) */
1156             if(exactDepthMatch) {
1157                 iPixelFormat = cfg->iPixelFormat;
1158                 break;
1159             } else if(!iPixelFormat) {
1160                 /* In the end we might end up with a format which doesn't exactly match our depth
1161                  * requirements. Accept the first format we found because formats with higher iPixelFormat
1162                  * values tend to have more extended capabilities (e.g. multisampling) which we don't need. */
1163                 iPixelFormat = cfg->iPixelFormat;
1164             }
1165         }
1166     }
1167
1168     /* When findCompatible is set and no suitable format was found, let ChoosePixelFormat choose a pixel format in order not to crash. */
1169     if(!iPixelFormat && !findCompatible) {
1170         ERR("Can't find a suitable iPixelFormat\n");
1171         return FALSE;
1172     } else if(!iPixelFormat) {
1173         PIXELFORMATDESCRIPTOR pfd;
1174
1175         TRACE("Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel format\n");
1176         /* PixelFormat selection */
1177         ZeroMemory(&pfd, sizeof(pfd));
1178         pfd.nSize      = sizeof(pfd);
1179         pfd.nVersion   = 1;
1180         pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
1181         pfd.iPixelType = PFD_TYPE_RGBA;
1182         pfd.cAlphaBits = alphaBits;
1183         pfd.cColorBits = colorBits;
1184         pfd.cDepthBits = depthBits;
1185         pfd.cStencilBits = stencilBits;
1186         pfd.iLayerType = PFD_MAIN_PLANE;
1187
1188         iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1189         if(!iPixelFormat) {
1190             /* If this happens something is very wrong as ChoosePixelFormat barely fails */
1191             ERR("Can't find a suitable iPixelFormat\n");
1192             return FALSE;
1193         }
1194     }
1195
1196     TRACE("Found iPixelFormat=%d for ColorFormat=%s, DepthStencilFormat=%s\n",
1197             iPixelFormat, debug_d3dformat(color_format_desc->format), debug_d3dformat(ds_format_desc->format));
1198     return iPixelFormat;
1199 }
1200
1201 /*****************************************************************************
1202  * context_create
1203  *
1204  * Creates a new context.
1205  *
1206  * * Params:
1207  *  This: Device to activate the context for
1208  *  target: Surface this context will render to
1209  *  win_handle: handle to the window which we are drawing to
1210  *  pPresentParameters: contains the pixelformats to use for onscreen rendering
1211  *
1212  *****************************************************************************/
1213 struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
1214         const struct wined3d_format_desc *ds_format_desc)
1215 {
1216     IWineD3DDeviceImpl *device = swapchain->device;
1217     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1218     const struct wined3d_format_desc *color_format_desc;
1219     struct wined3d_context *ret;
1220     PIXELFORMATDESCRIPTOR pfd;
1221     BOOL auxBuffers = FALSE;
1222     int numSamples = 0;
1223     int pixel_format;
1224     unsigned int s;
1225     DWORD state;
1226     HGLRC ctx;
1227     HDC hdc;
1228
1229     TRACE("swapchain %p, target %p, window %p.\n", swapchain, target, swapchain->win_handle);
1230
1231     ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
1232     if (!ret)
1233     {
1234         ERR("Failed to allocate context memory.\n");
1235         return NULL;
1236     }
1237
1238     if (!(hdc = GetDC(swapchain->win_handle)))
1239     {
1240         ERR("Failed to retrieve a device context.\n");
1241         goto out;
1242     }
1243
1244     color_format_desc = target->resource.format_desc;
1245
1246     /* In case of ORM_BACKBUFFER, make sure to request an alpha component for
1247      * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */
1248     if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
1249     {
1250         auxBuffers = TRUE;
1251
1252         if (color_format_desc->format == WINED3DFMT_B4G4R4X4_UNORM)
1253             color_format_desc = getFormatDescEntry(WINED3DFMT_B4G4R4A4_UNORM, gl_info);
1254         else if (color_format_desc->format == WINED3DFMT_B8G8R8X8_UNORM)
1255             color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
1256     }
1257
1258     /* DirectDraw supports 8bit paletted render targets and these are used by
1259      * old games like Starcraft and C&C. Most modern hardware doesn't support
1260      * 8bit natively so we perform some form of 8bit -> 32bit conversion. The
1261      * conversion (ab)uses the alpha component for storing the palette index.
1262      * For this reason we require a format with 8bit alpha, so request
1263      * A8R8G8B8. */
1264     if (color_format_desc->format == WINED3DFMT_P8_UINT)
1265         color_format_desc = getFormatDescEntry(WINED3DFMT_B8G8R8A8_UNORM, gl_info);
1266
1267     /* D3D only allows multisampling when SwapEffect is set to WINED3DSWAPEFFECT_DISCARD. */
1268     if (swapchain->presentParms.MultiSampleType && (swapchain->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD))
1269     {
1270         if (!gl_info->supported[ARB_MULTISAMPLE])
1271             WARN("The application is requesting multisampling without support.\n");
1272         else
1273         {
1274             TRACE("Requesting multisample type %#x.\n", swapchain->presentParms.MultiSampleType);
1275             numSamples = swapchain->presentParms.MultiSampleType;
1276         }
1277     }
1278
1279     /* Try to find a pixel format which matches our requirements. */
1280     pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc,
1281             auxBuffers, numSamples, FALSE /* findCompatible */);
1282
1283     /* Try to locate a compatible format if we weren't able to find anything. */
1284     if (!pixel_format)
1285     {
1286         TRACE("Trying to locate a compatible pixel format because an exact match failed.\n");
1287         pixel_format = WineD3D_ChoosePixelFormat(device, hdc, color_format_desc, ds_format_desc,
1288                 auxBuffers, 0 /* numSamples */, TRUE /* findCompatible */);
1289     }
1290
1291     /* If we still don't have a pixel format, something is very wrong as ChoosePixelFormat barely fails */
1292     if (!pixel_format)
1293     {
1294         ERR("Can't find a suitable pixel format.\n");
1295         goto out;
1296     }
1297
1298     DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd);
1299     if (!context_set_pixel_format(gl_info, hdc, pixel_format))
1300     {
1301         ERR("Failed to set pixel format %d on device context %p.\n", pixel_format, hdc);
1302         goto out;
1303     }
1304
1305     ctx = pwglCreateContext(hdc);
1306     if (device->numContexts)
1307     {
1308         if (!pwglShareLists(device->contexts[0]->glCtx, ctx))
1309         {
1310             DWORD err = GetLastError();
1311             ERR("wglShareLists(%p, %p) failed, last error %#x.\n",
1312                     device->contexts[0]->glCtx, ctx, err);
1313         }
1314     }
1315
1316     if(!ctx) {
1317         ERR("Failed to create a WGL context\n");
1318         goto out;
1319     }
1320
1321     if (!device_context_add(device, ret))
1322     {
1323         ERR("Failed to add the newly created context to the context list\n");
1324         if (!pwglDeleteContext(ctx))
1325         {
1326             DWORD err = GetLastError();
1327             ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, err);
1328         }
1329         goto out;
1330     }
1331
1332     ret->gl_info = gl_info;
1333
1334     /* Mark all states dirty to force a proper initialization of the states
1335      * on the first use of the context. */
1336     for (state = 0; state <= STATE_HIGHEST; ++state)
1337     {
1338         if (device->StateTable[state].representative)
1339             Context_MarkStateDirty(ret, state, device->StateTable);
1340     }
1341
1342     ret->swapchain = swapchain;
1343     ret->current_rt = target;
1344     ret->tid = GetCurrentThreadId();
1345
1346     ret->render_offscreen = surface_is_offscreen(target);
1347     ret->draw_buffer_dirty = TRUE;
1348     ret->valid = 1;
1349
1350     ret->glCtx = ctx;
1351     ret->win_handle = swapchain->win_handle;
1352     ret->hdc = hdc;
1353     ret->pixel_format = pixel_format;
1354
1355     if (device->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *)device))
1356     {
1357         /* Create the dirty constants array and initialize them to dirty */
1358         ret->vshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
1359                 sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
1360         ret->pshader_const_dirty = HeapAlloc(GetProcessHeap(), 0,
1361                 sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
1362         memset(ret->vshader_const_dirty, 1,
1363                sizeof(*ret->vshader_const_dirty) * device->d3d_vshader_constantF);
1364         memset(ret->pshader_const_dirty, 1,
1365                 sizeof(*ret->pshader_const_dirty) * device->d3d_pshader_constantF);
1366     }
1367
1368     ret->blit_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1369             gl_info->limits.buffers * sizeof(*ret->blit_targets));
1370     if (!ret->blit_targets) goto out;
1371
1372     ret->free_occlusion_query_size = 4;
1373     ret->free_occlusion_queries = HeapAlloc(GetProcessHeap(), 0,
1374             ret->free_occlusion_query_size * sizeof(*ret->free_occlusion_queries));
1375     if (!ret->free_occlusion_queries) goto out;
1376
1377     list_init(&ret->occlusion_queries);
1378
1379     ret->free_event_query_size = 4;
1380     ret->free_event_queries = HeapAlloc(GetProcessHeap(), 0,
1381             ret->free_event_query_size * sizeof(*ret->free_event_queries));
1382     if (!ret->free_event_queries) goto out;
1383
1384     list_init(&ret->event_queries);
1385
1386     TRACE("Successfully created new context %p\n", ret);
1387
1388     list_init(&ret->fbo_list);
1389     list_init(&ret->fbo_destroy_list);
1390
1391     context_enter(ret);
1392
1393     /* Set up the context defaults */
1394     if (!context_set_current(ret))
1395     {
1396         ERR("Cannot activate context to set up defaults\n");
1397         context_release(ret);
1398         goto out;
1399     }
1400
1401     ENTER_GL();
1402
1403     glGetIntegerv(GL_AUX_BUFFERS, &ret->aux_buffers);
1404
1405     TRACE("Setting up the screen\n");
1406     /* Clear the screen */
1407     glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
1408     checkGLcall("glClearColor");
1409     glClearIndex(0);
1410     glClearDepth(1);
1411     glClearStencil(0xffff);
1412
1413     checkGLcall("glClear");
1414
1415     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1416     checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
1417
1418     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
1419     checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
1420
1421     glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1422     checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
1423
1424     glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);
1425     checkGLcall("glPixelStorei(GL_PACK_ALIGNMENT, device->surface_alignment);");
1426     glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);
1427     checkGLcall("glPixelStorei(GL_UNPACK_ALIGNMENT, device->surface_alignment);");
1428
1429     if (gl_info->supported[APPLE_CLIENT_STORAGE])
1430     {
1431         /* Most textures will use client storage if supported. Exceptions are non-native power of 2 textures
1432          * and textures in DIB sections(due to the memory protection).
1433          */
1434         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
1435         checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
1436     }
1437     if (gl_info->supported[ARB_VERTEX_BLEND])
1438     {
1439         /* Direct3D always uses n-1 weights for n world matrices and uses 1 - sum for the last one
1440          * this is equal to GL_WEIGHT_SUM_UNITY_ARB. Enabling it doesn't do anything unless
1441          * GL_VERTEX_BLEND_ARB isn't enabled too
1442          */
1443         glEnable(GL_WEIGHT_SUM_UNITY_ARB);
1444         checkGLcall("glEnable(GL_WEIGHT_SUM_UNITY_ARB)");
1445     }
1446     if (gl_info->supported[NV_TEXTURE_SHADER2])
1447     {
1448         /* Set up the previous texture input for all shader units. This applies to bump mapping, and in d3d
1449          * the previous texture where to source the offset from is always unit - 1.
1450          */
1451         for (s = 1; s < gl_info->limits.textures; ++s)
1452         {
1453             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
1454             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + s - 1);
1455             checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, ...");
1456         }
1457     }
1458     if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
1459     {
1460         /* MacOS(radeon X1600 at least, but most likely others too) refuses to draw if GLSL and ARBFP are
1461          * enabled, but the currently bound arbfp program is 0. Enabling ARBFP with prog 0 is invalid, but
1462          * GLSL should bypass this. This causes problems in programs that never use the fixed function pipeline,
1463          * because the ARBFP extension is enabled by the ARBFP pipeline at context creation, but no program
1464          * is ever assigned.
1465          *
1466          * So make sure a program is assigned to each context. The first real ARBFP use will set a different
1467          * program and the dummy program is destroyed when the context is destroyed.
1468          */
1469         const char *dummy_program =
1470                 "!!ARBfp1.0\n"
1471                 "MOV result.color, fragment.color.primary;\n"
1472                 "END\n";
1473         GL_EXTCALL(glGenProgramsARB(1, &ret->dummy_arbfp_prog));
1474         GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, ret->dummy_arbfp_prog));
1475         GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(dummy_program), dummy_program));
1476     }
1477
1478     for (s = 0; s < gl_info->limits.point_sprite_units; ++s)
1479     {
1480         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + s));
1481         glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
1482         checkGLcall("glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE)");
1483     }
1484
1485     if (gl_info->supported[ARB_PROVOKING_VERTEX])
1486     {
1487         GL_EXTCALL(glProvokingVertex(GL_FIRST_VERTEX_CONVENTION));
1488     }
1489     else if (gl_info->supported[EXT_PROVOKING_VERTEX])
1490     {
1491         GL_EXTCALL(glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT));
1492     }
1493
1494     LEAVE_GL();
1495
1496     device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
1497
1498     TRACE("Created context %p.\n", ret);
1499
1500     return ret;
1501
1502 out:
1503     HeapFree(GetProcessHeap(), 0, ret->free_event_queries);
1504     HeapFree(GetProcessHeap(), 0, ret->free_occlusion_queries);
1505     HeapFree(GetProcessHeap(), 0, ret->blit_targets);
1506     HeapFree(GetProcessHeap(), 0, ret->pshader_const_dirty);
1507     HeapFree(GetProcessHeap(), 0, ret->vshader_const_dirty);
1508     HeapFree(GetProcessHeap(), 0, ret);
1509     return NULL;
1510 }
1511
1512 /*****************************************************************************
1513  * context_destroy
1514  *
1515  * Destroys a wined3d context
1516  *
1517  * Params:
1518  *  This: Device to activate the context for
1519  *  context: Context to destroy
1520  *
1521  *****************************************************************************/
1522 void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context)
1523 {
1524     BOOL destroy;
1525
1526     TRACE("Destroying ctx %p\n", context);
1527
1528     if (context->tid == GetCurrentThreadId() || !context->current)
1529     {
1530         context_destroy_gl_resources(context);
1531         TlsSetValue(wined3d_context_tls_idx, NULL);
1532         destroy = TRUE;
1533     }
1534     else
1535     {
1536         context->destroyed = 1;
1537         destroy = FALSE;
1538     }
1539
1540     HeapFree(GetProcessHeap(), 0, context->blit_targets);
1541     HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
1542     HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
1543     device_context_remove(This, context);
1544     if (destroy) HeapFree(GetProcessHeap(), 0, context);
1545 }
1546
1547 /* GL locking is done by the caller */
1548 static inline void set_blit_dimension(UINT width, UINT height) {
1549     glMatrixMode(GL_PROJECTION);
1550     checkGLcall("glMatrixMode(GL_PROJECTION)");
1551     glLoadIdentity();
1552     checkGLcall("glLoadIdentity()");
1553     glOrtho(0, width, height, 0, 0.0, -1.0);
1554     checkGLcall("glOrtho");
1555     glViewport(0, 0, width, height);
1556     checkGLcall("glViewport");
1557 }
1558
1559 /*****************************************************************************
1560  * SetupForBlit
1561  *
1562  * Sets up a context for DirectDraw blitting.
1563  * All texture units are disabled, texture unit 0 is set as current unit
1564  * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
1565  * color writing enabled for all channels
1566  * register combiners disabled, shaders disabled
1567  * world matrix is set to identity, texture matrix 0 too
1568  * projection matrix is setup for drawing screen coordinates
1569  *
1570  * Params:
1571  *  This: Device to activate the context for
1572  *  context: Context to setup
1573  *
1574  *****************************************************************************/
1575 /* Context activation is done by the caller. */
1576 static void SetupForBlit(IWineD3DDeviceImpl *This, struct wined3d_context *context)
1577 {
1578     int i;
1579     const struct StateEntry *StateTable = This->StateTable;
1580     const struct wined3d_gl_info *gl_info = context->gl_info;
1581     UINT width = context->current_rt->currentDesc.Width;
1582     UINT height = context->current_rt->currentDesc.Height;
1583     DWORD sampler;
1584
1585     TRACE("Setting up context %p for blitting\n", context);
1586     if(context->last_was_blit) {
1587         if(context->blit_w != width || context->blit_h != height) {
1588             ENTER_GL();
1589             set_blit_dimension(width, height);
1590             LEAVE_GL();
1591             context->blit_w = width; context->blit_h = height;
1592             /* No need to dirtify here, the states are still dirtified because they weren't
1593              * applied since the last SetupForBlit call. Otherwise last_was_blit would not
1594              * be set
1595              */
1596         }
1597         TRACE("Context is already set up for blitting, nothing to do\n");
1598         return;
1599     }
1600     context->last_was_blit = TRUE;
1601
1602     /* TODO: Use a display list */
1603
1604     /* Disable shaders */
1605     ENTER_GL();
1606     This->shader_backend->shader_select(context, FALSE, FALSE);
1607     LEAVE_GL();
1608
1609     Context_MarkStateDirty(context, STATE_VSHADER, StateTable);
1610     Context_MarkStateDirty(context, STATE_PIXELSHADER, StateTable);
1611
1612     /* Call ENTER_GL() once for all gl calls below. In theory we should not call
1613      * helper functions in between gl calls. This function is full of Context_MarkStateDirty
1614      * which can safely be called from here, we only lock once instead locking/unlocking
1615      * after each GL call.
1616      */
1617     ENTER_GL();
1618
1619     /* Disable all textures. The caller can then bind a texture it wants to blit
1620      * from
1621      *
1622      * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
1623      * function texture unit. No need to care for higher samplers
1624      */
1625     for (i = gl_info->limits.textures - 1; i > 0 ; --i)
1626     {
1627         sampler = This->rev_tex_unit_map[i];
1628         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1629         checkGLcall("glActiveTextureARB");
1630
1631         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
1632         {
1633             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1634             checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
1635         }
1636         glDisable(GL_TEXTURE_3D);
1637         checkGLcall("glDisable GL_TEXTURE_3D");
1638         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
1639         {
1640             glDisable(GL_TEXTURE_RECTANGLE_ARB);
1641             checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
1642         }
1643         glDisable(GL_TEXTURE_2D);
1644         checkGLcall("glDisable GL_TEXTURE_2D");
1645
1646         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1647         checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
1648
1649         if (sampler != WINED3D_UNMAPPED_STAGE)
1650         {
1651             if (sampler < MAX_TEXTURES) {
1652                 Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
1653             }
1654             Context_MarkStateDirty(context, STATE_SAMPLER(sampler), StateTable);
1655         }
1656     }
1657     GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
1658     checkGLcall("glActiveTextureARB");
1659
1660     sampler = This->rev_tex_unit_map[0];
1661
1662     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
1663     {
1664         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1665         checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
1666     }
1667     glDisable(GL_TEXTURE_3D);
1668     checkGLcall("glDisable GL_TEXTURE_3D");
1669     if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
1670     {
1671         glDisable(GL_TEXTURE_RECTANGLE_ARB);
1672         checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
1673     }
1674     glDisable(GL_TEXTURE_2D);
1675     checkGLcall("glDisable GL_TEXTURE_2D");
1676
1677     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1678
1679     glMatrixMode(GL_TEXTURE);
1680     checkGLcall("glMatrixMode(GL_TEXTURE)");
1681     glLoadIdentity();
1682     checkGLcall("glLoadIdentity()");
1683
1684     if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
1685     {
1686         glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1687                   GL_TEXTURE_LOD_BIAS_EXT,
1688                   0.0f);
1689         checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1690     }
1691
1692     if (sampler != WINED3D_UNMAPPED_STAGE)
1693     {
1694         if (sampler < MAX_TEXTURES) {
1695             Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + sampler), StateTable);
1696             Context_MarkStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP), StateTable);
1697         }
1698         Context_MarkStateDirty(context, STATE_SAMPLER(sampler), StateTable);
1699     }
1700
1701     /* Other misc states */
1702     glDisable(GL_ALPHA_TEST);
1703     checkGLcall("glDisable(GL_ALPHA_TEST)");
1704     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHATESTENABLE), StateTable);
1705     glDisable(GL_LIGHTING);
1706     checkGLcall("glDisable GL_LIGHTING");
1707     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING), StateTable);
1708     glDisable(GL_DEPTH_TEST);
1709     checkGLcall("glDisable GL_DEPTH_TEST");
1710     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ZENABLE), StateTable);
1711     glDisableWINE(GL_FOG);
1712     checkGLcall("glDisable GL_FOG");
1713     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_FOGENABLE), StateTable);
1714     glDisable(GL_BLEND);
1715     checkGLcall("glDisable GL_BLEND");
1716     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
1717     glDisable(GL_CULL_FACE);
1718     checkGLcall("glDisable GL_CULL_FACE");
1719     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CULLMODE), StateTable);
1720     glDisable(GL_STENCIL_TEST);
1721     checkGLcall("glDisable GL_STENCIL_TEST");
1722     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_STENCILENABLE), StateTable);
1723     glDisable(GL_SCISSOR_TEST);
1724     checkGLcall("glDisable GL_SCISSOR_TEST");
1725     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), StateTable);
1726     if (gl_info->supported[ARB_POINT_SPRITE])
1727     {
1728         glDisable(GL_POINT_SPRITE_ARB);
1729         checkGLcall("glDisable GL_POINT_SPRITE_ARB");
1730         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), StateTable);
1731     }
1732     glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
1733     checkGLcall("glColorMask");
1734     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE), StateTable);
1735     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), StateTable);
1736     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), StateTable);
1737     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), StateTable);
1738     if (gl_info->supported[EXT_SECONDARY_COLOR])
1739     {
1740         glDisable(GL_COLOR_SUM_EXT);
1741         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SPECULARENABLE), StateTable);
1742         checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
1743     }
1744
1745     /* Setup transforms */
1746     glMatrixMode(GL_MODELVIEW);
1747     checkGLcall("glMatrixMode(GL_MODELVIEW)");
1748     glLoadIdentity();
1749     checkGLcall("glLoadIdentity()");
1750     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), StateTable);
1751
1752     context->last_was_rhw = TRUE;
1753     Context_MarkStateDirty(context, STATE_VDECL, StateTable); /* because of last_was_rhw = TRUE */
1754
1755     glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)");
1756     glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)");
1757     glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)");
1758     glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)");
1759     glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)");
1760     glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)");
1761     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPING), StateTable);
1762
1763     set_blit_dimension(width, height);
1764
1765     LEAVE_GL();
1766
1767     context->blit_w = width; context->blit_h = height;
1768     Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
1769     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
1770
1771
1772     This->frag_pipe->enable_extension((IWineD3DDevice *) This, FALSE);
1773 }
1774
1775 /*****************************************************************************
1776  * findThreadContextForSwapChain
1777  *
1778  * Searches a swapchain for all contexts and picks one for the thread tid.
1779  * If none can be found the swapchain is requested to create a new context
1780  *
1781  *****************************************************************************/
1782 static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain, DWORD tid)
1783 {
1784     unsigned int i;
1785
1786     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
1787         if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
1788             return ((IWineD3DSwapChainImpl *) swapchain)->context[i];
1789         }
1790
1791     }
1792
1793     /* Create a new context for the thread */
1794     return swapchain_create_context_for_thread(swapchain);
1795 }
1796
1797 /*****************************************************************************
1798  * FindContext
1799  *
1800  * Finds a context for the current render target and thread
1801  *
1802  * Parameters:
1803  *  target: Render target to find the context for
1804  *  tid: Thread to activate the context for
1805  *
1806  * Returns: The needed context
1807  *
1808  *****************************************************************************/
1809 static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target)
1810 {
1811     IWineD3DSwapChain *swapchain = NULL;
1812     struct wined3d_context *current_context = context_get_current();
1813     DWORD tid = GetCurrentThreadId();
1814     struct wined3d_context *context;
1815
1816     if (current_context && current_context->destroyed) current_context = NULL;
1817
1818     if (!target)
1819     {
1820         if (current_context
1821                 && current_context->current_rt
1822                 && current_context->swapchain->device == This)
1823         {
1824             target = current_context->current_rt;
1825         }
1826         else
1827         {
1828             IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
1829             if (swapchain->back_buffers) target = swapchain->back_buffers[0];
1830             else target = swapchain->front_buffer;
1831         }
1832     }
1833
1834     if (current_context && current_context->current_rt == target)
1835     {
1836         context_validate(current_context);
1837         return current_context;
1838     }
1839
1840     if (target->Flags & SFLAG_SWAPCHAIN)
1841     {
1842         TRACE("Rendering onscreen\n");
1843
1844         swapchain = (IWineD3DSwapChain *)target->container;
1845         context = findThreadContextForSwapChain(swapchain, tid);
1846     }
1847     else
1848     {
1849         TRACE("Rendering offscreen\n");
1850
1851         /* Stay with the currently active context. */
1852         if (current_context && current_context->swapchain->device == This)
1853         {
1854             context = current_context;
1855         }
1856         else
1857         {
1858             /* This may happen if the app jumps straight into offscreen rendering
1859              * Start using the context of the primary swapchain. tid == 0 is no problem
1860              * for findThreadContextForSwapChain.
1861              *
1862              * Can also happen on thread switches - in that case findThreadContextForSwapChain
1863              * is perfect to call. */
1864             context = findThreadContextForSwapChain(This->swapchains[0], tid);
1865         }
1866     }
1867
1868     context_validate(context);
1869
1870     return context;
1871 }
1872
1873 /* Context activation is done by the caller. */
1874 static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit)
1875 {
1876     const struct wined3d_gl_info *gl_info = context->gl_info;
1877     IWineD3DSurfaceImpl *rt = context->current_rt;
1878     IWineD3DDeviceImpl *device;
1879
1880     device = rt->resource.device;
1881     if (!surface_is_offscreen(rt))
1882     {
1883         ENTER_GL();
1884         glDrawBuffer(surface_get_gl_buffer(rt));
1885         checkGLcall("glDrawBuffers()");
1886         LEAVE_GL();
1887     }
1888     else
1889     {
1890         ENTER_GL();
1891         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1892         {
1893             if (!blit)
1894             {
1895                 unsigned int i;
1896
1897                 for (i = 0; i < gl_info->limits.buffers; ++i)
1898                 {
1899                     if (device->render_targets[i])
1900                         device->draw_buffers[i] = GL_COLOR_ATTACHMENT0 + i;
1901                     else
1902                         device->draw_buffers[i] = GL_NONE;
1903                 }
1904
1905                 if (gl_info->supported[ARB_DRAW_BUFFERS])
1906                 {
1907                     GL_EXTCALL(glDrawBuffersARB(gl_info->limits.buffers, device->draw_buffers));
1908                     checkGLcall("glDrawBuffers()");
1909                 }
1910                 else
1911                 {
1912                     glDrawBuffer(device->draw_buffers[0]);
1913                     checkGLcall("glDrawBuffer()");
1914                 }
1915             } else {
1916                 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1917                 checkGLcall("glDrawBuffer()");
1918             }
1919         }
1920         else
1921         {
1922             glDrawBuffer(device->offscreenBuffer);
1923             checkGLcall("glDrawBuffer()");
1924         }
1925         LEAVE_GL();
1926     }
1927 }
1928
1929 /* GL locking is done by the caller. */
1930 void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer)
1931 {
1932     glDrawBuffer(buffer);
1933     checkGLcall("glDrawBuffer()");
1934     context->draw_buffer_dirty = TRUE;
1935 }
1936
1937 static inline void context_set_render_offscreen(struct wined3d_context *context, const struct StateEntry *StateTable,
1938         BOOL offscreen)
1939 {
1940     if (context->render_offscreen == offscreen) return;
1941
1942     Context_MarkStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION), StateTable);
1943     Context_MarkStateDirty(context, STATE_VDECL, StateTable);
1944     Context_MarkStateDirty(context, STATE_VIEWPORT, StateTable);
1945     Context_MarkStateDirty(context, STATE_SCISSORRECT, StateTable);
1946     Context_MarkStateDirty(context, STATE_FRONTFACE, StateTable);
1947     context->render_offscreen = offscreen;
1948 }
1949
1950 static BOOL match_depth_stencil_format(const struct wined3d_format_desc *existing,
1951         const struct wined3d_format_desc *required)
1952 {
1953     short existing_depth, existing_stencil, required_depth, required_stencil;
1954
1955     if(existing == required) return TRUE;
1956     if((existing->Flags & WINED3DFMT_FLAG_FLOAT) != (required->Flags & WINED3DFMT_FLAG_FLOAT)) return FALSE;
1957
1958     getDepthStencilBits(existing, &existing_depth, &existing_stencil);
1959     getDepthStencilBits(required, &required_depth, &required_stencil);
1960
1961     if(existing_depth < required_depth) return FALSE;
1962     /* If stencil bits are used the exact amount is required - otherwise wrapping
1963      * won't work correctly */
1964     if(required_stencil && required_stencil != existing_stencil) return FALSE;
1965     return TRUE;
1966 }
1967 /* The caller provides a context */
1968 static void context_validate_onscreen_formats(IWineD3DDeviceImpl *device,
1969         struct wined3d_context *context, IWineD3DSurfaceImpl *depth_stencil)
1970 {
1971     /* Onscreen surfaces are always in a swapchain */
1972     IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)context->current_rt->container;
1973
1974     if (context->render_offscreen || !depth_stencil) return;
1975     if (match_depth_stencil_format(swapchain->ds_format, depth_stencil->resource.format_desc)) return;
1976
1977     /* TODO: If the requested format would satisfy the needs of the existing one(reverse match),
1978      * or no onscreen depth buffer was created, the OpenGL drawable could be changed to the new
1979      * format. */
1980     WARN("Depth stencil format is not supported by WGL, rendering the backbuffer in an FBO\n");
1981
1982     /* The currently active context is the necessary context to access the swapchain's onscreen buffers */
1983     IWineD3DSurface_LoadLocation((IWineD3DSurface *)context->current_rt, SFLAG_INTEXTURE, NULL);
1984     swapchain->render_to_fbo = TRUE;
1985     context_set_render_offscreen(context, device->StateTable, TRUE);
1986 }
1987
1988 /* Context activation is done by the caller. */
1989 void context_apply_blit_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
1990 {
1991     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
1992     {
1993         context_validate_onscreen_formats(device, context, NULL);
1994
1995         if (context->render_offscreen)
1996         {
1997             FIXME("Applying blit state for an offscreen target with ORM_FBO. This should be avoided.\n");
1998             surface_internal_preload(context->current_rt, SRGB_RGB);
1999
2000             ENTER_GL();
2001             context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, context->current_rt, NULL);
2002             LEAVE_GL();
2003         }
2004         else
2005         {
2006             ENTER_GL();
2007             context_bind_fbo(context, GL_FRAMEBUFFER, NULL);
2008             LEAVE_GL();
2009         }
2010
2011         context->draw_buffer_dirty = TRUE;
2012     }
2013
2014     if (context->draw_buffer_dirty)
2015     {
2016         context_apply_draw_buffer(context, TRUE);
2017         if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
2018             context->draw_buffer_dirty = FALSE;
2019     }
2020
2021     SetupForBlit(device, context);
2022 }
2023
2024 /* Context activation is done by the caller. */
2025 void context_apply_clear_state(struct wined3d_context *context, IWineD3DDeviceImpl *device,
2026         IWineD3DSurfaceImpl *render_target, IWineD3DSurfaceImpl *depth_stencil)
2027 {
2028     const struct StateEntry *state_table = device->StateTable;
2029     GLenum buffer;
2030
2031     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2032     {
2033         context_validate_onscreen_formats(device, context, depth_stencil);
2034
2035         ENTER_GL();
2036         context_apply_fbo_state_blit(context, GL_FRAMEBUFFER, render_target, depth_stencil);
2037         LEAVE_GL();
2038     }
2039
2040     if (!surface_is_offscreen(render_target))
2041         buffer = surface_get_gl_buffer(render_target);
2042     else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2043         buffer = GL_COLOR_ATTACHMENT0;
2044     else
2045         buffer = device->offscreenBuffer;
2046
2047     ENTER_GL();
2048     context_set_draw_buffer(context, buffer);
2049     LEAVE_GL();
2050
2051     if (context->last_was_blit)
2052     {
2053         device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
2054     }
2055
2056     /* Blending and clearing should be orthogonal, but tests on the nvidia
2057      * driver show that disabling blending when clearing improves the clearing
2058      * performance incredibly. */
2059     ENTER_GL();
2060     glDisable(GL_BLEND);
2061     glEnable(GL_SCISSOR_TEST);
2062     checkGLcall("glEnable GL_SCISSOR_TEST");
2063     LEAVE_GL();
2064
2065     context->last_was_blit = FALSE;
2066     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_table);
2067     Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_table);
2068     Context_MarkStateDirty(context, STATE_SCISSORRECT, state_table);
2069 }
2070
2071 /* Context activation is done by the caller. */
2072 void context_apply_draw_state(struct wined3d_context *context, IWineD3DDeviceImpl *device)
2073 {
2074     const struct StateEntry *state_table = device->StateTable;
2075     unsigned int i;
2076
2077     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
2078     {
2079         context_validate_onscreen_formats(device, context, device->depth_stencil);
2080
2081         if (!context->render_offscreen)
2082         {
2083             ENTER_GL();
2084             context_apply_fbo_state(context, GL_FRAMEBUFFER, NULL, NULL);
2085             LEAVE_GL();
2086         }
2087         else
2088         {
2089             ENTER_GL();
2090             context_apply_fbo_state(context, GL_FRAMEBUFFER, device->render_targets, device->depth_stencil);
2091             LEAVE_GL();
2092         }
2093     }
2094
2095     if (context->draw_buffer_dirty)
2096     {
2097         context_apply_draw_buffer(context, FALSE);
2098         context->draw_buffer_dirty = FALSE;
2099     }
2100
2101     if (context->last_was_blit)
2102     {
2103         device->frag_pipe->enable_extension((IWineD3DDevice *)device, TRUE);
2104     }
2105
2106     IWineD3DDeviceImpl_FindTexUnitMap(device);
2107     device_preload_textures(device);
2108     if (isStateDirty(context, STATE_VDECL))
2109         device_update_stream_info(device, context->gl_info);
2110
2111     ENTER_GL();
2112     for (i = 0; i < context->numDirtyEntries; ++i)
2113     {
2114         DWORD rep = context->dirtyArray[i];
2115         DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
2116         BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
2117         context->isStateDirty[idx] &= ~(1 << shift);
2118         state_table[rep].apply(rep, device->stateBlock, context);
2119     }
2120     LEAVE_GL();
2121     context->numDirtyEntries = 0; /* This makes the whole list clean */
2122     context->last_was_blit = FALSE;
2123 }
2124
2125 static void context_setup_target(IWineD3DDeviceImpl *device,
2126         struct wined3d_context *context, IWineD3DSurfaceImpl *target)
2127 {
2128     BOOL old_render_offscreen = context->render_offscreen, render_offscreen;
2129     const struct StateEntry *StateTable = device->StateTable;
2130
2131     if (!target) return;
2132     else if (context->current_rt == target) return;
2133     render_offscreen = surface_is_offscreen(target);
2134
2135     context_set_render_offscreen(context, StateTable, render_offscreen);
2136
2137     /* To compensate the lack of format switching with some offscreen rendering methods and on onscreen buffers
2138      * the alpha blend state changes with different render target formats. */
2139     if (!context->current_rt)
2140     {
2141         Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
2142     }
2143     else
2144     {
2145         const struct wined3d_format_desc *old = context->current_rt->resource.format_desc;
2146         const struct wined3d_format_desc *new = target->resource.format_desc;
2147
2148         if (old->format != new->format)
2149         {
2150             /* Disable blending when the alpha mask has changed and when a format doesn't support blending. */
2151             if ((old->alpha_mask && !new->alpha_mask) || (!old->alpha_mask && new->alpha_mask)
2152                     || !(new->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
2153             {
2154                 Context_MarkStateDirty(context, STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), StateTable);
2155             }
2156         }
2157
2158         /* When switching away from an offscreen render target, and we're not
2159          * using FBOs, we have to read the drawable into the texture. This is
2160          * done via PreLoad (and SFLAG_INDRAWABLE set on the surface). There
2161          * are some things that need care though. PreLoad needs a GL context,
2162          * and FindContext is called before the context is activated. It also
2163          * has to be called with the old rendertarget active, otherwise a
2164          * wrong drawable is read. */
2165         if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
2166                 && old_render_offscreen && context->current_rt != target)
2167         {
2168             BOOL oldInDraw = device->isInDraw;
2169
2170             /* surface_internal_preload() requires a context to load the
2171              * texture, so it will call context_acquire(). Set isInDraw to true
2172              * to signal surface_internal_preload() that it has a context. */
2173
2174             /* FIXME: This is just broken. There's no guarantee whatsoever
2175              * that the currently active context, if any, is appropriate for
2176              * reading back the render target. We should probably call
2177              * context_set_current(context) here and then rely on
2178              * context_acquire() doing the right thing. */
2179             device->isInDraw = TRUE;
2180
2181             /* Read the back buffer of the old drawable into the destination texture. */
2182             if (context->current_rt->texture_name_srgb)
2183             {
2184                 surface_internal_preload(context->current_rt, SRGB_BOTH);
2185             }
2186             else
2187             {
2188                 surface_internal_preload(context->current_rt, SRGB_RGB);
2189             }
2190
2191             IWineD3DSurface_ModifyLocation((IWineD3DSurface *)context->current_rt, SFLAG_INDRAWABLE, FALSE);
2192
2193             device->isInDraw = oldInDraw;
2194         }
2195     }
2196
2197     context->draw_buffer_dirty = TRUE;
2198     context->current_rt = target;
2199 }
2200
2201 /*****************************************************************************
2202  * context_acquire
2203  *
2204  * Finds a rendering context and drawable matching the device and render
2205  * target for the current thread, activates them and puts them into the
2206  * requested state.
2207  *
2208  * Params:
2209  *  This: Device to activate the context for
2210  *  target: Requested render target
2211  *  usage: Prepares the context for blitting, drawing or other actions
2212  *
2213  *****************************************************************************/
2214 struct wined3d_context *context_acquire(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *target)
2215 {
2216     struct wined3d_context *current_context = context_get_current();
2217     struct wined3d_context *context;
2218
2219     TRACE("device %p, target %p.\n", device, target);
2220
2221     context = FindContext(device, target);
2222     context_setup_target(device, context, target);
2223     context_enter(context);
2224     if (!context->valid) return context;
2225
2226     if (context != current_context)
2227     {
2228         if (!context_set_current(context)) ERR("Failed to activate the new context.\n");
2229         else device->frag_pipe->enable_extension((IWineD3DDevice *)device, !context->last_was_blit);
2230
2231         if (context->vshader_const_dirty)
2232         {
2233             memset(context->vshader_const_dirty, 1,
2234                     sizeof(*context->vshader_const_dirty) * device->d3d_vshader_constantF);
2235             device->highest_dirty_vs_const = device->d3d_vshader_constantF;
2236         }
2237         if (context->pshader_const_dirty)
2238         {
2239             memset(context->pshader_const_dirty, 1,
2240                    sizeof(*context->pshader_const_dirty) * device->d3d_pshader_constantF);
2241             device->highest_dirty_ps_const = device->d3d_pshader_constantF;
2242         }
2243     }
2244     else if (context->restore_ctx)
2245     {
2246         if (!pwglMakeCurrent(context->hdc, context->glCtx))
2247         {
2248             DWORD err = GetLastError();
2249             ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
2250                     context->hdc, context->glCtx, err);
2251         }
2252     }
2253
2254     return context;
2255 }