st/mesa: add support for ARB_sample_locations
[mesa.git] / src / mesa / state_tracker / st_manager.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2010 LunarG Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #include "main/mtypes.h"
29 #include "main/extensions.h"
30 #include "main/context.h"
31 #include "main/debug_output.h"
32 #include "main/glthread.h"
33 #include "main/texobj.h"
34 #include "main/teximage.h"
35 #include "main/texstate.h"
36 #include "main/errors.h"
37 #include "main/framebuffer.h"
38 #include "main/fbobject.h"
39 #include "main/renderbuffer.h"
40 #include "main/version.h"
41 #include "util/hash_table.h"
42 #include "st_texture.h"
43
44 #include "st_context.h"
45 #include "st_debug.h"
46 #include "st_extensions.h"
47 #include "st_format.h"
48 #include "st_cb_bitmap.h"
49 #include "st_cb_fbo.h"
50 #include "st_cb_flush.h"
51 #include "st_manager.h"
52 #include "st_sampler_view.h"
53
54 #include "state_tracker/st_gl_api.h"
55
56 #include "pipe/p_context.h"
57 #include "pipe/p_screen.h"
58 #include "util/u_format.h"
59 #include "util/u_pointer.h"
60 #include "util/u_inlines.h"
61 #include "util/u_atomic.h"
62 #include "util/u_surface.h"
63 #include "util/list.h"
64
65 struct hash_table;
66 struct st_manager_private
67 {
68 struct hash_table *stfbi_ht; /* framebuffer iface objects hash table */
69 mtx_t st_mutex;
70 };
71
72
73 /**
74 * Map an attachment to a buffer index.
75 */
76 static inline gl_buffer_index
77 attachment_to_buffer_index(enum st_attachment_type statt)
78 {
79 gl_buffer_index index;
80
81 switch (statt) {
82 case ST_ATTACHMENT_FRONT_LEFT:
83 index = BUFFER_FRONT_LEFT;
84 break;
85 case ST_ATTACHMENT_BACK_LEFT:
86 index = BUFFER_BACK_LEFT;
87 break;
88 case ST_ATTACHMENT_FRONT_RIGHT:
89 index = BUFFER_FRONT_RIGHT;
90 break;
91 case ST_ATTACHMENT_BACK_RIGHT:
92 index = BUFFER_BACK_RIGHT;
93 break;
94 case ST_ATTACHMENT_DEPTH_STENCIL:
95 index = BUFFER_DEPTH;
96 break;
97 case ST_ATTACHMENT_ACCUM:
98 index = BUFFER_ACCUM;
99 break;
100 case ST_ATTACHMENT_SAMPLE:
101 default:
102 index = BUFFER_COUNT;
103 break;
104 }
105
106 return index;
107 }
108
109
110 /**
111 * Map a buffer index to an attachment.
112 */
113 static inline enum st_attachment_type
114 buffer_index_to_attachment(gl_buffer_index index)
115 {
116 enum st_attachment_type statt;
117
118 switch (index) {
119 case BUFFER_FRONT_LEFT:
120 statt = ST_ATTACHMENT_FRONT_LEFT;
121 break;
122 case BUFFER_BACK_LEFT:
123 statt = ST_ATTACHMENT_BACK_LEFT;
124 break;
125 case BUFFER_FRONT_RIGHT:
126 statt = ST_ATTACHMENT_FRONT_RIGHT;
127 break;
128 case BUFFER_BACK_RIGHT:
129 statt = ST_ATTACHMENT_BACK_RIGHT;
130 break;
131 case BUFFER_DEPTH:
132 statt = ST_ATTACHMENT_DEPTH_STENCIL;
133 break;
134 case BUFFER_ACCUM:
135 statt = ST_ATTACHMENT_ACCUM;
136 break;
137 default:
138 statt = ST_ATTACHMENT_INVALID;
139 break;
140 }
141
142 return statt;
143 }
144
145
146 /**
147 * Make sure a context picks up the latest cached state of the
148 * drawables it binds to.
149 */
150 static void
151 st_context_validate(struct st_context *st,
152 struct st_framebuffer *stdraw,
153 struct st_framebuffer *stread)
154 {
155 if (stdraw && stdraw->stamp != st->draw_stamp) {
156 st->dirty |= ST_NEW_FRAMEBUFFER;
157 _mesa_resize_framebuffer(st->ctx, &stdraw->Base,
158 stdraw->Base.Width,
159 stdraw->Base.Height);
160 st->draw_stamp = stdraw->stamp;
161 }
162
163 if (stread && stread->stamp != st->read_stamp) {
164 if (stread != stdraw) {
165 st->dirty |= ST_NEW_FRAMEBUFFER;
166 _mesa_resize_framebuffer(st->ctx, &stread->Base,
167 stread->Base.Width,
168 stread->Base.Height);
169 }
170 st->read_stamp = stread->stamp;
171 }
172 }
173
174
175 /**
176 * Validate a framebuffer to make sure up-to-date pipe_textures are used.
177 * The context is only used for creating pipe surfaces and for calling
178 * _mesa_resize_framebuffer().
179 * (That should probably be rethought, since those surfaces become
180 * drawable state, not context state, and can be freed by another pipe
181 * context).
182 */
183 static void
184 st_framebuffer_validate(struct st_framebuffer *stfb,
185 struct st_context *st)
186 {
187 struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
188 uint width, height;
189 unsigned i;
190 boolean changed = FALSE;
191 int32_t new_stamp;
192
193 new_stamp = p_atomic_read(&stfb->iface->stamp);
194 if (stfb->iface_stamp == new_stamp)
195 return;
196
197 memset(textures, 0, stfb->num_statts * sizeof(textures[0]));
198
199 /* validate the fb */
200 do {
201 if (!stfb->iface->validate(&st->iface, stfb->iface, stfb->statts,
202 stfb->num_statts, textures))
203 return;
204
205 stfb->iface_stamp = new_stamp;
206 new_stamp = p_atomic_read(&stfb->iface->stamp);
207 } while(stfb->iface_stamp != new_stamp);
208
209 width = stfb->Base.Width;
210 height = stfb->Base.Height;
211
212 for (i = 0; i < stfb->num_statts; i++) {
213 struct st_renderbuffer *strb;
214 struct pipe_surface *ps, surf_tmpl;
215 gl_buffer_index idx;
216
217 if (!textures[i])
218 continue;
219
220 idx = attachment_to_buffer_index(stfb->statts[i]);
221 if (idx >= BUFFER_COUNT) {
222 pipe_resource_reference(&textures[i], NULL);
223 continue;
224 }
225
226 strb = st_renderbuffer(stfb->Base.Attachment[idx].Renderbuffer);
227 assert(strb);
228 if (strb->texture == textures[i]) {
229 pipe_resource_reference(&textures[i], NULL);
230 continue;
231 }
232
233 u_surface_default_template(&surf_tmpl, textures[i]);
234 ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
235 if (ps) {
236 struct pipe_surface **psurf =
237 util_format_is_srgb(ps->format) ? &strb->surface_srgb :
238 &strb->surface_linear;
239
240 pipe_surface_reference(psurf, ps);
241 strb->surface = *psurf;
242 pipe_resource_reference(&strb->texture, ps->texture);
243 /* ownership transfered */
244 pipe_surface_reference(&ps, NULL);
245
246 changed = TRUE;
247
248 strb->Base.Width = strb->surface->width;
249 strb->Base.Height = strb->surface->height;
250
251 width = strb->Base.Width;
252 height = strb->Base.Height;
253 }
254
255 pipe_resource_reference(&textures[i], NULL);
256 }
257
258 if (changed) {
259 ++stfb->stamp;
260 _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height);
261 }
262 }
263
264
265 /**
266 * Update the attachments to validate by looping the existing renderbuffers.
267 */
268 static void
269 st_framebuffer_update_attachments(struct st_framebuffer *stfb)
270 {
271 gl_buffer_index idx;
272
273 stfb->num_statts = 0;
274 for (idx = 0; idx < BUFFER_COUNT; idx++) {
275 struct st_renderbuffer *strb;
276 enum st_attachment_type statt;
277
278 strb = st_renderbuffer(stfb->Base.Attachment[idx].Renderbuffer);
279 if (!strb || strb->software)
280 continue;
281
282 statt = buffer_index_to_attachment(idx);
283 if (statt != ST_ATTACHMENT_INVALID &&
284 st_visual_have_buffers(stfb->iface->visual, 1 << statt))
285 stfb->statts[stfb->num_statts++] = statt;
286 }
287 stfb->stamp++;
288 }
289
290
291 /**
292 * Add a renderbuffer to the framebuffer. The framebuffer is one that
293 * corresponds to a window and is not a user-created FBO.
294 */
295 static boolean
296 st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb,
297 gl_buffer_index idx)
298 {
299 struct gl_renderbuffer *rb;
300 enum pipe_format format;
301 boolean sw;
302
303 assert(_mesa_is_winsys_fbo(&stfb->Base));
304
305 /* do not distinguish depth/stencil buffers */
306 if (idx == BUFFER_STENCIL)
307 idx = BUFFER_DEPTH;
308
309 switch (idx) {
310 case BUFFER_DEPTH:
311 format = stfb->iface->visual->depth_stencil_format;
312 sw = FALSE;
313 break;
314 case BUFFER_ACCUM:
315 format = stfb->iface->visual->accum_format;
316 sw = TRUE;
317 break;
318 default:
319 format = stfb->iface->visual->color_format;
320 if (stfb->Base.Visual.sRGBCapable)
321 format = util_format_srgb(format);
322 sw = FALSE;
323 break;
324 }
325
326 if (format == PIPE_FORMAT_NONE)
327 return FALSE;
328
329 rb = st_new_renderbuffer_fb(format, stfb->iface->visual->samples, sw);
330 if (!rb)
331 return FALSE;
332
333 if (idx != BUFFER_DEPTH) {
334 _mesa_attach_and_own_rb(&stfb->Base, idx, rb);
335 return TRUE;
336 }
337
338 bool rb_ownership_taken = false;
339 if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
340 _mesa_attach_and_own_rb(&stfb->Base, BUFFER_DEPTH, rb);
341 rb_ownership_taken = true;
342 }
343
344 if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
345 if (rb_ownership_taken)
346 _mesa_attach_and_reference_rb(&stfb->Base, BUFFER_STENCIL, rb);
347 else
348 _mesa_attach_and_own_rb(&stfb->Base, BUFFER_STENCIL, rb);
349 }
350
351 return TRUE;
352 }
353
354
355 /**
356 * Intialize a struct gl_config from a visual.
357 */
358 static void
359 st_visual_to_context_mode(const struct st_visual *visual,
360 struct gl_config *mode)
361 {
362 memset(mode, 0, sizeof(*mode));
363
364 if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
365 mode->doubleBufferMode = GL_TRUE;
366
367 if (st_visual_have_buffers(visual,
368 ST_ATTACHMENT_FRONT_RIGHT_MASK | ST_ATTACHMENT_BACK_RIGHT_MASK))
369 mode->stereoMode = GL_TRUE;
370
371 if (visual->color_format != PIPE_FORMAT_NONE) {
372 mode->rgbMode = GL_TRUE;
373
374 mode->redBits =
375 util_format_get_component_bits(visual->color_format,
376 UTIL_FORMAT_COLORSPACE_RGB, 0);
377 mode->greenBits =
378 util_format_get_component_bits(visual->color_format,
379 UTIL_FORMAT_COLORSPACE_RGB, 1);
380 mode->blueBits =
381 util_format_get_component_bits(visual->color_format,
382 UTIL_FORMAT_COLORSPACE_RGB, 2);
383 mode->alphaBits =
384 util_format_get_component_bits(visual->color_format,
385 UTIL_FORMAT_COLORSPACE_RGB, 3);
386
387 mode->rgbBits = mode->redBits +
388 mode->greenBits + mode->blueBits + mode->alphaBits;
389 mode->sRGBCapable = util_format_is_srgb(visual->color_format);
390 }
391
392 if (visual->depth_stencil_format != PIPE_FORMAT_NONE) {
393 mode->depthBits =
394 util_format_get_component_bits(visual->depth_stencil_format,
395 UTIL_FORMAT_COLORSPACE_ZS, 0);
396 mode->stencilBits =
397 util_format_get_component_bits(visual->depth_stencil_format,
398 UTIL_FORMAT_COLORSPACE_ZS, 1);
399
400 mode->haveDepthBuffer = mode->depthBits > 0;
401 mode->haveStencilBuffer = mode->stencilBits > 0;
402 }
403
404 if (visual->accum_format != PIPE_FORMAT_NONE) {
405 mode->haveAccumBuffer = GL_TRUE;
406
407 mode->accumRedBits =
408 util_format_get_component_bits(visual->accum_format,
409 UTIL_FORMAT_COLORSPACE_RGB, 0);
410 mode->accumGreenBits =
411 util_format_get_component_bits(visual->accum_format,
412 UTIL_FORMAT_COLORSPACE_RGB, 1);
413 mode->accumBlueBits =
414 util_format_get_component_bits(visual->accum_format,
415 UTIL_FORMAT_COLORSPACE_RGB, 2);
416 mode->accumAlphaBits =
417 util_format_get_component_bits(visual->accum_format,
418 UTIL_FORMAT_COLORSPACE_RGB, 3);
419 }
420
421 if (visual->samples > 1) {
422 mode->sampleBuffers = 1;
423 mode->samples = visual->samples;
424 }
425 }
426
427
428 /**
429 * Create a framebuffer from a manager interface.
430 */
431 static struct st_framebuffer *
432 st_framebuffer_create(struct st_context *st,
433 struct st_framebuffer_iface *stfbi)
434 {
435 struct st_framebuffer *stfb;
436 struct gl_config mode;
437 gl_buffer_index idx;
438
439 if (!stfbi)
440 return NULL;
441
442 stfb = CALLOC_STRUCT(st_framebuffer);
443 if (!stfb)
444 return NULL;
445
446 st_visual_to_context_mode(stfbi->visual, &mode);
447
448 /*
449 * For desktop GL, sRGB framebuffer write is controlled by both the
450 * capability of the framebuffer and GL_FRAMEBUFFER_SRGB. We should
451 * advertise the capability when the pipe driver (and core Mesa) supports
452 * it so that applications can enable sRGB write when they want to.
453 *
454 * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB. When
455 * the attribute is GLX_TRUE, it tells the st manager to pick a color
456 * format such that util_format_srgb(visual->color_format) can be supported
457 * by the pipe driver. We still need to advertise the capability here.
458 *
459 * For GLES, however, sRGB framebuffer write is controlled only by the
460 * capability of the framebuffer. There is GL_EXT_sRGB_write_control to
461 * give applications the control back, but sRGB write is still enabled by
462 * default. To avoid unexpected results, we should not advertise the
463 * capability. This could change when we add support for
464 * EGL_KHR_gl_colorspace.
465 */
466 if (_mesa_is_desktop_gl(st->ctx)) {
467 struct pipe_screen *screen = st->pipe->screen;
468 const enum pipe_format srgb_format =
469 util_format_srgb(stfbi->visual->color_format);
470
471 if (srgb_format != PIPE_FORMAT_NONE &&
472 st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE &&
473 screen->is_format_supported(screen, srgb_format,
474 PIPE_TEXTURE_2D, stfbi->visual->samples,
475 (PIPE_BIND_DISPLAY_TARGET |
476 PIPE_BIND_RENDER_TARGET)))
477 mode.sRGBCapable = GL_TRUE;
478 }
479
480 _mesa_initialize_window_framebuffer(&stfb->Base, &mode);
481
482 stfb->iface = stfbi;
483 stfb->iface_ID = stfbi->ID;
484 stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1;
485
486 /* add the color buffer */
487 idx = stfb->Base._ColorDrawBufferIndexes[0];
488 if (!st_framebuffer_add_renderbuffer(stfb, idx)) {
489 free(stfb);
490 return NULL;
491 }
492
493 st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH);
494 st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM);
495
496 stfb->stamp = 0;
497 st_framebuffer_update_attachments(stfb);
498
499 return stfb;
500 }
501
502
503 /**
504 * Reference a framebuffer.
505 */
506 void
507 st_framebuffer_reference(struct st_framebuffer **ptr,
508 struct st_framebuffer *stfb)
509 {
510 struct gl_framebuffer *fb = &stfb->Base;
511 _mesa_reference_framebuffer((struct gl_framebuffer **) ptr, fb);
512 }
513
514
515 static uint32_t
516 st_framebuffer_iface_hash(const void *key)
517 {
518 return (uintptr_t)key;
519 }
520
521
522 static bool
523 st_framebuffer_iface_equal(const void *a, const void *b)
524 {
525 return (struct st_framebuffer_iface *)a == (struct st_framebuffer_iface *)b;
526 }
527
528
529 static boolean
530 st_framebuffer_iface_lookup(struct st_manager *smapi,
531 const struct st_framebuffer_iface *stfbi)
532 {
533 struct st_manager_private *smPriv =
534 (struct st_manager_private *)smapi->st_manager_private;
535 struct hash_entry *entry;
536
537 assert(smPriv);
538 assert(smPriv->stfbi_ht);
539
540 mtx_lock(&smPriv->st_mutex);
541 entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi);
542 mtx_unlock(&smPriv->st_mutex);
543
544 return entry != NULL;
545 }
546
547
548 static boolean
549 st_framebuffer_iface_insert(struct st_manager *smapi,
550 struct st_framebuffer_iface *stfbi)
551 {
552 struct st_manager_private *smPriv =
553 (struct st_manager_private *)smapi->st_manager_private;
554 struct hash_entry *entry;
555
556 assert(smPriv);
557 assert(smPriv->stfbi_ht);
558
559 mtx_lock(&smPriv->st_mutex);
560 entry = _mesa_hash_table_insert(smPriv->stfbi_ht, stfbi, stfbi);
561 mtx_unlock(&smPriv->st_mutex);
562
563 return entry != NULL;
564 }
565
566
567 static void
568 st_framebuffer_iface_remove(struct st_manager *smapi,
569 struct st_framebuffer_iface *stfbi)
570 {
571 struct st_manager_private *smPriv =
572 (struct st_manager_private *)smapi->st_manager_private;
573 struct hash_entry *entry;
574
575 if (!smPriv || !smPriv->stfbi_ht)
576 return;
577
578 mtx_lock(&smPriv->st_mutex);
579 entry = _mesa_hash_table_search(smPriv->stfbi_ht, stfbi);
580 if (!entry)
581 goto unlock;
582
583 _mesa_hash_table_remove(smPriv->stfbi_ht, entry);
584
585 unlock:
586 mtx_unlock(&smPriv->st_mutex);
587 }
588
589
590 /**
591 * The framebuffer interface object is no longer valid.
592 * Remove the object from the framebuffer interface hash table.
593 */
594 static void
595 st_api_destroy_drawable(struct st_api *stapi,
596 struct st_framebuffer_iface *stfbi)
597 {
598 if (!stfbi)
599 return;
600
601 st_framebuffer_iface_remove(stfbi->state_manager, stfbi);
602 }
603
604
605 /**
606 * Purge the winsys buffers list to remove any references to
607 * non-existing framebuffer interface objects.
608 */
609 static void
610 st_framebuffers_purge(struct st_context *st)
611 {
612 struct st_context_iface *st_iface = &st->iface;
613 struct st_manager *smapi = st_iface->state_manager;
614 struct st_framebuffer *stfb, *next;
615
616 assert(smapi);
617
618 LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) {
619 struct st_framebuffer_iface *stfbi = stfb->iface;
620
621 assert(stfbi);
622
623 /**
624 * If the corresponding framebuffer interface object no longer exists,
625 * remove the framebuffer object from the context's winsys buffers list,
626 * and unreference the framebuffer object, so its resources can be
627 * deleted.
628 */
629 if (!st_framebuffer_iface_lookup(smapi, stfbi)) {
630 LIST_DEL(&stfb->head);
631 st_framebuffer_reference(&stfb, NULL);
632 }
633 }
634 }
635
636
637 static void
638 st_context_flush(struct st_context_iface *stctxi, unsigned flags,
639 struct pipe_fence_handle **fence)
640 {
641 struct st_context *st = (struct st_context *) stctxi;
642 unsigned pipe_flags = 0;
643
644 if (flags & ST_FLUSH_END_OF_FRAME)
645 pipe_flags |= PIPE_FLUSH_END_OF_FRAME;
646 if (flags & ST_FLUSH_FENCE_FD)
647 pipe_flags |= PIPE_FLUSH_FENCE_FD;
648
649 FLUSH_VERTICES(st->ctx, 0);
650 FLUSH_CURRENT(st->ctx, 0);
651 st_flush(st, fence, pipe_flags);
652
653 if ((flags & ST_FLUSH_WAIT) && fence && *fence) {
654 st->pipe->screen->fence_finish(st->pipe->screen, NULL, *fence,
655 PIPE_TIMEOUT_INFINITE);
656 st->pipe->screen->fence_reference(st->pipe->screen, fence, NULL);
657 }
658
659 if (flags & ST_FLUSH_FRONT)
660 st_manager_flush_frontbuffer(st);
661
662 /* DRI3 changes the framebuffer after SwapBuffers, but we need to invoke
663 * st_manager_validate_framebuffers to notice that.
664 *
665 * Set gfx_shaders_may_be_dirty to invoke st_validate_state in the next
666 * draw call, which will invoke st_manager_validate_framebuffers, but it
667 * won't dirty states if there is no change.
668 */
669 if (flags & ST_FLUSH_END_OF_FRAME)
670 st->gfx_shaders_may_be_dirty = true;
671 }
672
673 static boolean
674 st_context_teximage(struct st_context_iface *stctxi,
675 enum st_texture_type tex_type,
676 int level, enum pipe_format pipe_format,
677 struct pipe_resource *tex, boolean mipmap)
678 {
679 struct st_context *st = (struct st_context *) stctxi;
680 struct gl_context *ctx = st->ctx;
681 struct gl_texture_object *texObj;
682 struct gl_texture_image *texImage;
683 struct st_texture_object *stObj;
684 struct st_texture_image *stImage;
685 GLenum internalFormat;
686 GLuint width, height, depth;
687 GLenum target;
688
689 switch (tex_type) {
690 case ST_TEXTURE_1D:
691 target = GL_TEXTURE_1D;
692 break;
693 case ST_TEXTURE_2D:
694 target = GL_TEXTURE_2D;
695 break;
696 case ST_TEXTURE_3D:
697 target = GL_TEXTURE_3D;
698 break;
699 case ST_TEXTURE_RECT:
700 target = GL_TEXTURE_RECTANGLE_ARB;
701 break;
702 default:
703 return FALSE;
704 }
705
706 texObj = _mesa_get_current_tex_object(ctx, target);
707
708 _mesa_lock_texture(ctx, texObj);
709
710 stObj = st_texture_object(texObj);
711 /* switch to surface based */
712 if (!stObj->surface_based) {
713 _mesa_clear_texture_object(ctx, texObj, NULL);
714 stObj->surface_based = GL_TRUE;
715 }
716
717 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
718 stImage = st_texture_image(texImage);
719 if (tex) {
720 mesa_format texFormat = st_pipe_format_to_mesa_format(pipe_format);
721
722 if (util_format_has_alpha(tex->format))
723 internalFormat = GL_RGBA;
724 else
725 internalFormat = GL_RGB;
726
727 _mesa_init_teximage_fields(ctx, texImage,
728 tex->width0, tex->height0, 1, 0,
729 internalFormat, texFormat);
730
731 width = tex->width0;
732 height = tex->height0;
733 depth = tex->depth0;
734
735 /* grow the image size until we hit level = 0 */
736 while (level > 0) {
737 if (width != 1)
738 width <<= 1;
739 if (height != 1)
740 height <<= 1;
741 if (depth != 1)
742 depth <<= 1;
743 level--;
744 }
745 }
746 else {
747 _mesa_clear_texture_image(ctx, texImage);
748 width = height = depth = 0;
749 }
750
751 pipe_resource_reference(&stObj->pt, tex);
752 st_texture_release_all_sampler_views(st, stObj);
753 pipe_resource_reference(&stImage->pt, tex);
754 stObj->surface_format = pipe_format;
755
756 stObj->needs_validation = true;
757
758 _mesa_dirty_texobj(ctx, texObj);
759 _mesa_unlock_texture(ctx, texObj);
760
761 return TRUE;
762 }
763
764
765 static void
766 st_context_copy(struct st_context_iface *stctxi,
767 struct st_context_iface *stsrci, unsigned mask)
768 {
769 struct st_context *st = (struct st_context *) stctxi;
770 struct st_context *src = (struct st_context *) stsrci;
771
772 _mesa_copy_context(src->ctx, st->ctx, mask);
773 }
774
775
776 static boolean
777 st_context_share(struct st_context_iface *stctxi,
778 struct st_context_iface *stsrci)
779 {
780 struct st_context *st = (struct st_context *) stctxi;
781 struct st_context *src = (struct st_context *) stsrci;
782
783 return _mesa_share_state(st->ctx, src->ctx);
784 }
785
786
787 static void
788 st_context_destroy(struct st_context_iface *stctxi)
789 {
790 struct st_context *st = (struct st_context *) stctxi;
791 st_destroy_context(st);
792 }
793
794
795 static void
796 st_start_thread(struct st_context_iface *stctxi)
797 {
798 struct st_context *st = (struct st_context *) stctxi;
799
800 _mesa_glthread_init(st->ctx);
801 }
802
803
804 static void
805 st_thread_finish(struct st_context_iface *stctxi)
806 {
807 struct st_context *st = (struct st_context *) stctxi;
808
809 _mesa_glthread_finish(st->ctx);
810 }
811
812
813 static void
814 st_manager_destroy(struct st_manager *smapi)
815 {
816 struct st_manager_private *smPriv = smapi->st_manager_private;
817
818 if (smPriv && smPriv->stfbi_ht) {
819 _mesa_hash_table_destroy(smPriv->stfbi_ht, NULL);
820 mtx_destroy(&smPriv->st_mutex);
821 free(smPriv);
822 smapi->st_manager_private = NULL;
823 }
824 }
825
826
827 static struct st_context_iface *
828 st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
829 const struct st_context_attribs *attribs,
830 enum st_context_error *error,
831 struct st_context_iface *shared_stctxi)
832 {
833 struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
834 struct st_context *st;
835 struct pipe_context *pipe;
836 struct gl_config mode;
837 gl_api api;
838 bool no_error = false;
839 unsigned ctx_flags = PIPE_CONTEXT_PREFER_THREADED;
840
841 if (!(stapi->profile_mask & (1 << attribs->profile)))
842 return NULL;
843
844 switch (attribs->profile) {
845 case ST_PROFILE_DEFAULT:
846 api = API_OPENGL_COMPAT;
847 break;
848 case ST_PROFILE_OPENGL_ES1:
849 api = API_OPENGLES;
850 break;
851 case ST_PROFILE_OPENGL_ES2:
852 api = API_OPENGLES2;
853 break;
854 case ST_PROFILE_OPENGL_CORE:
855 api = API_OPENGL_CORE;
856 break;
857 default:
858 *error = ST_CONTEXT_ERROR_BAD_API;
859 return NULL;
860 }
861
862 /* Create a hash table for the framebuffer interface objects
863 * if it has not been created for this st manager.
864 */
865 if (smapi->st_manager_private == NULL) {
866 struct st_manager_private *smPriv;
867
868 smPriv = CALLOC_STRUCT(st_manager_private);
869 mtx_init(&smPriv->st_mutex, mtx_plain);
870 smPriv->stfbi_ht = _mesa_hash_table_create(NULL,
871 st_framebuffer_iface_hash,
872 st_framebuffer_iface_equal);
873 smapi->st_manager_private = smPriv;
874 smapi->destroy = st_manager_destroy;
875 }
876
877 if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS)
878 ctx_flags |= PIPE_CONTEXT_ROBUST_BUFFER_ACCESS;
879
880 if (attribs->flags & ST_CONTEXT_FLAG_NO_ERROR)
881 no_error = true;
882
883 if (attribs->flags & ST_CONTEXT_FLAG_LOW_PRIORITY)
884 ctx_flags |= PIPE_CONTEXT_LOW_PRIORITY;
885 else if (attribs->flags & ST_CONTEXT_FLAG_HIGH_PRIORITY)
886 ctx_flags |= PIPE_CONTEXT_HIGH_PRIORITY;
887
888 pipe = smapi->screen->context_create(smapi->screen, NULL, ctx_flags);
889 if (!pipe) {
890 *error = ST_CONTEXT_ERROR_NO_MEMORY;
891 return NULL;
892 }
893
894 st_visual_to_context_mode(&attribs->visual, &mode);
895 st = st_create_context(api, pipe, &mode, shared_ctx,
896 &attribs->options, no_error);
897 if (!st) {
898 *error = ST_CONTEXT_ERROR_NO_MEMORY;
899 pipe->destroy(pipe);
900 return NULL;
901 }
902
903 if (attribs->flags & ST_CONTEXT_FLAG_DEBUG) {
904 if (!_mesa_set_debug_state_int(st->ctx, GL_DEBUG_OUTPUT, GL_TRUE)) {
905 *error = ST_CONTEXT_ERROR_NO_MEMORY;
906 return NULL;
907 }
908
909 st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
910 }
911
912 if (st->ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT) {
913 st_update_debug_callback(st);
914 }
915
916 if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE)
917 st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
918 if (attribs->flags & ST_CONTEXT_FLAG_ROBUST_ACCESS) {
919 st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB;
920 st->ctx->Const.RobustAccess = GL_TRUE;
921 }
922 if (attribs->flags & ST_CONTEXT_FLAG_RESET_NOTIFICATION_ENABLED) {
923 st->ctx->Const.ResetStrategy = GL_LOSE_CONTEXT_ON_RESET_ARB;
924 st_install_device_reset_callback(st);
925 }
926
927 if (attribs->flags & ST_CONTEXT_FLAG_RELEASE_NONE)
928 st->ctx->Const.ContextReleaseBehavior = GL_NONE;
929
930 /* need to perform version check */
931 if (attribs->major > 1 || attribs->minor > 0) {
932 /* Is the actual version less than the requested version?
933 */
934 if (st->ctx->Version < attribs->major * 10U + attribs->minor) {
935 *error = ST_CONTEXT_ERROR_BAD_VERSION;
936 st_destroy_context(st);
937 return NULL;
938 }
939 }
940
941 st->invalidate_on_gl_viewport =
942 smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
943
944 st->iface.destroy = st_context_destroy;
945 st->iface.flush = st_context_flush;
946 st->iface.teximage = st_context_teximage;
947 st->iface.copy = st_context_copy;
948 st->iface.share = st_context_share;
949 st->iface.start_thread = st_start_thread;
950 st->iface.thread_finish = st_thread_finish;
951 st->iface.st_context_private = (void *) smapi;
952 st->iface.cso_context = st->cso_context;
953 st->iface.pipe = st->pipe;
954 st->iface.state_manager = smapi;
955
956 *error = ST_CONTEXT_SUCCESS;
957 return &st->iface;
958 }
959
960
961 static struct st_context_iface *
962 st_api_get_current(struct st_api *stapi)
963 {
964 GET_CURRENT_CONTEXT(ctx);
965 struct st_context *st = ctx ? ctx->st : NULL;
966
967 return st ? &st->iface : NULL;
968 }
969
970
971 static struct st_framebuffer *
972 st_framebuffer_reuse_or_create(struct st_context *st,
973 struct gl_framebuffer *fb,
974 struct st_framebuffer_iface *stfbi)
975 {
976 struct st_framebuffer *cur = NULL, *stfb = NULL;
977
978 if (!stfbi)
979 return NULL;
980
981 /* Check if there is already a framebuffer object for the specified
982 * framebuffer interface in this context. If there is one, use it.
983 */
984 LIST_FOR_EACH_ENTRY(cur, &st->winsys_buffers, head) {
985 if (cur->iface_ID == stfbi->ID) {
986 st_framebuffer_reference(&stfb, cur);
987 break;
988 }
989 }
990
991 /* If there is not already a framebuffer object, create one */
992 if (stfb == NULL) {
993 cur = st_framebuffer_create(st, stfbi);
994
995 if (cur) {
996 /* add the referenced framebuffer interface object to
997 * the framebuffer interface object hash table.
998 */
999 if (!st_framebuffer_iface_insert(stfbi->state_manager, stfbi)) {
1000 st_framebuffer_reference(&cur, NULL);
1001 return NULL;
1002 }
1003
1004 /* add to the context's winsys buffers list */
1005 LIST_ADD(&cur->head, &st->winsys_buffers);
1006
1007 st_framebuffer_reference(&stfb, cur);
1008 }
1009 }
1010
1011 return stfb;
1012 }
1013
1014
1015 static boolean
1016 st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
1017 struct st_framebuffer_iface *stdrawi,
1018 struct st_framebuffer_iface *streadi)
1019 {
1020 struct st_context *st = (struct st_context *) stctxi;
1021 struct st_framebuffer *stdraw, *stread;
1022 boolean ret;
1023
1024 _glapi_check_multithread();
1025
1026 if (st) {
1027 /* reuse or create the draw fb */
1028 stdraw = st_framebuffer_reuse_or_create(st,
1029 st->ctx->WinSysDrawBuffer, stdrawi);
1030 if (streadi != stdrawi) {
1031 /* do the same for the read fb */
1032 stread = st_framebuffer_reuse_or_create(st,
1033 st->ctx->WinSysReadBuffer, streadi);
1034 }
1035 else {
1036 stread = NULL;
1037 /* reuse the draw fb for the read fb */
1038 if (stdraw)
1039 st_framebuffer_reference(&stread, stdraw);
1040 }
1041
1042 if (stdraw && stread) {
1043 st_framebuffer_validate(stdraw, st);
1044 if (stread != stdraw)
1045 st_framebuffer_validate(stread, st);
1046
1047 ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base);
1048
1049 st->draw_stamp = stdraw->stamp - 1;
1050 st->read_stamp = stread->stamp - 1;
1051 st_context_validate(st, stdraw, stread);
1052 }
1053 else {
1054 struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
1055 ret = _mesa_make_current(st->ctx, incomplete, incomplete);
1056 }
1057
1058 st_framebuffer_reference(&stdraw, NULL);
1059 st_framebuffer_reference(&stread, NULL);
1060
1061 /* Purge the context's winsys_buffers list in case any
1062 * of the referenced drawables no longer exist.
1063 */
1064 st_framebuffers_purge(st);
1065 }
1066 else {
1067 ret = _mesa_make_current(NULL, NULL, NULL);
1068 }
1069
1070 return ret;
1071 }
1072
1073
1074 static void
1075 st_api_destroy(struct st_api *stapi)
1076 {
1077 }
1078
1079
1080 /**
1081 * Flush the front buffer if the current context renders to the front buffer.
1082 */
1083 void
1084 st_manager_flush_frontbuffer(struct st_context *st)
1085 {
1086 struct st_framebuffer *stfb = st_ws_framebuffer(st->ctx->DrawBuffer);
1087 struct st_renderbuffer *strb = NULL;
1088
1089 if (stfb)
1090 strb = st_renderbuffer(stfb->Base.Attachment[BUFFER_FRONT_LEFT].
1091 Renderbuffer);
1092
1093 /* Do we have a front color buffer and has it been drawn to since last
1094 * frontbuffer flush?
1095 */
1096 if (strb && strb->defined) {
1097 stfb->iface->flush_front(&st->iface, stfb->iface,
1098 ST_ATTACHMENT_FRONT_LEFT);
1099 strb->defined = GL_FALSE;
1100
1101 /* Trigger an update of strb->defined on next draw */
1102 st->dirty |= ST_NEW_FB_STATE;
1103 }
1104 }
1105
1106
1107 /**
1108 * Re-validate the framebuffers.
1109 */
1110 void
1111 st_manager_validate_framebuffers(struct st_context *st)
1112 {
1113 struct st_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
1114 struct st_framebuffer *stread = st_ws_framebuffer(st->ctx->ReadBuffer);
1115
1116 if (stdraw)
1117 st_framebuffer_validate(stdraw, st);
1118 if (stread && stread != stdraw)
1119 st_framebuffer_validate(stread, st);
1120
1121 st_context_validate(st, stdraw, stread);
1122 }
1123
1124
1125 /**
1126 * Flush any outstanding swapbuffers on the current draw framebuffer.
1127 */
1128 void
1129 st_manager_flush_swapbuffers(void)
1130 {
1131 GET_CURRENT_CONTEXT(ctx);
1132 struct st_context *st = (ctx) ? ctx->st : NULL;
1133 struct st_framebuffer *stfb;
1134
1135 if (!st)
1136 return;
1137
1138 stfb = st_ws_framebuffer(ctx->DrawBuffer);
1139 if (!stfb || !stfb->iface->flush_swapbuffers)
1140 return;
1141
1142 stfb->iface->flush_swapbuffers(&st->iface, stfb->iface);
1143 }
1144
1145
1146 /**
1147 * Add a color renderbuffer on demand. The FBO must correspond to a window,
1148 * not a user-created FBO.
1149 */
1150 boolean
1151 st_manager_add_color_renderbuffer(struct st_context *st,
1152 struct gl_framebuffer *fb,
1153 gl_buffer_index idx)
1154 {
1155 struct st_framebuffer *stfb = st_ws_framebuffer(fb);
1156
1157 /* FBO */
1158 if (!stfb)
1159 return FALSE;
1160
1161 assert(_mesa_is_winsys_fbo(fb));
1162
1163 if (stfb->Base.Attachment[idx].Renderbuffer)
1164 return TRUE;
1165
1166 switch (idx) {
1167 case BUFFER_FRONT_LEFT:
1168 case BUFFER_BACK_LEFT:
1169 case BUFFER_FRONT_RIGHT:
1170 case BUFFER_BACK_RIGHT:
1171 break;
1172 default:
1173 return FALSE;
1174 }
1175
1176 if (!st_framebuffer_add_renderbuffer(stfb, idx))
1177 return FALSE;
1178
1179 st_framebuffer_update_attachments(stfb);
1180
1181 /*
1182 * Force a call to the state tracker manager to validate the
1183 * new renderbuffer. It might be that there is a window system
1184 * renderbuffer available.
1185 */
1186 if (stfb->iface)
1187 stfb->iface_stamp = p_atomic_read(&stfb->iface->stamp) - 1;
1188
1189 st_invalidate_buffers(st);
1190
1191 return TRUE;
1192 }
1193
1194
1195 static unsigned
1196 get_version(struct pipe_screen *screen,
1197 struct st_config_options *options, gl_api api)
1198 {
1199 struct gl_constants consts = {0};
1200 struct gl_extensions extensions = {0};
1201 GLuint version;
1202
1203 if (_mesa_override_gl_version_contextless(&consts, &api, &version)) {
1204 return version;
1205 }
1206
1207 _mesa_init_constants(&consts, api);
1208 _mesa_init_extensions(&extensions);
1209
1210 st_init_limits(screen, &consts, &extensions, api);
1211 st_init_extensions(screen, &consts, &extensions, options, api);
1212
1213 return _mesa_get_version(&extensions, &consts, api);
1214 }
1215
1216
1217 static void
1218 st_api_query_versions(struct st_api *stapi, struct st_manager *sm,
1219 struct st_config_options *options,
1220 int *gl_core_version,
1221 int *gl_compat_version,
1222 int *gl_es1_version,
1223 int *gl_es2_version)
1224 {
1225 *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE);
1226 *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT);
1227 *gl_es1_version = get_version(sm->screen, options, API_OPENGLES);
1228 *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2);
1229 }
1230
1231
1232 static const struct st_api st_gl_api = {
1233 .name = "Mesa " PACKAGE_VERSION,
1234 .api = ST_API_OPENGL,
1235 .profile_mask = ST_PROFILE_DEFAULT_MASK |
1236 ST_PROFILE_OPENGL_CORE_MASK |
1237 ST_PROFILE_OPENGL_ES1_MASK |
1238 ST_PROFILE_OPENGL_ES2_MASK |
1239 0,
1240 .feature_mask = ST_API_FEATURE_MS_VISUALS_MASK,
1241 .destroy = st_api_destroy,
1242 .query_versions = st_api_query_versions,
1243 .create_context = st_api_create_context,
1244 .make_current = st_api_make_current,
1245 .get_current = st_api_get_current,
1246 .destroy_drawable = st_api_destroy_drawable,
1247 };
1248
1249
1250 struct st_api *
1251 st_gl_api_create(void)
1252 {
1253 return (struct st_api *) &st_gl_api;
1254 }