i965: use _mesa_readpixels() instead of _swrast_ReadPixels()
[mesa.git] / src / mesa / drivers / dri / intel / intel_context.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/extensions.h"
32 #include "main/fbobject.h"
33 #include "main/framebuffer.h"
34 #include "main/imports.h"
35 #include "main/points.h"
36 #include "main/renderbuffer.h"
37
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/tnl.h"
41 #include "drivers/common/driverfuncs.h"
42 #include "drivers/common/meta.h"
43
44 #include "intel_chipset.h"
45 #include "intel_buffers.h"
46 #include "intel_tex.h"
47 #include "intel_batchbuffer.h"
48 #include "intel_clear.h"
49 #include "intel_extensions.h"
50 #include "intel_pixel.h"
51 #include "intel_regions.h"
52 #include "intel_buffer_objects.h"
53 #include "intel_fbo.h"
54 #include "intel_bufmgr.h"
55 #include "intel_screen.h"
56
57 #include "utils.h"
58 #include "../glsl/ralloc.h"
59
60 #ifndef INTEL_DEBUG
61 int INTEL_DEBUG = (0);
62 #endif
63
64
65 static const GLubyte *
66 intelGetString(struct gl_context * ctx, GLenum name)
67 {
68 const struct intel_context *const intel = intel_context(ctx);
69 const char *chipset;
70 static char buffer[128];
71
72 switch (name) {
73 case GL_VENDOR:
74 return (GLubyte *) "Tungsten Graphics, Inc";
75 break;
76
77 case GL_RENDERER:
78 switch (intel->intelScreen->deviceID) {
79 case PCI_CHIP_845_G:
80 chipset = "Intel(R) 845G";
81 break;
82 case PCI_CHIP_I830_M:
83 chipset = "Intel(R) 830M";
84 break;
85 case PCI_CHIP_I855_GM:
86 chipset = "Intel(R) 852GM/855GM";
87 break;
88 case PCI_CHIP_I865_G:
89 chipset = "Intel(R) 865G";
90 break;
91 case PCI_CHIP_I915_G:
92 chipset = "Intel(R) 915G";
93 break;
94 case PCI_CHIP_E7221_G:
95 chipset = "Intel (R) E7221G (i915)";
96 break;
97 case PCI_CHIP_I915_GM:
98 chipset = "Intel(R) 915GM";
99 break;
100 case PCI_CHIP_I945_G:
101 chipset = "Intel(R) 945G";
102 break;
103 case PCI_CHIP_I945_GM:
104 chipset = "Intel(R) 945GM";
105 break;
106 case PCI_CHIP_I945_GME:
107 chipset = "Intel(R) 945GME";
108 break;
109 case PCI_CHIP_G33_G:
110 chipset = "Intel(R) G33";
111 break;
112 case PCI_CHIP_Q35_G:
113 chipset = "Intel(R) Q35";
114 break;
115 case PCI_CHIP_Q33_G:
116 chipset = "Intel(R) Q33";
117 break;
118 case PCI_CHIP_IGD_GM:
119 case PCI_CHIP_IGD_G:
120 chipset = "Intel(R) IGD";
121 break;
122 case PCI_CHIP_I965_Q:
123 chipset = "Intel(R) 965Q";
124 break;
125 case PCI_CHIP_I965_G:
126 case PCI_CHIP_I965_G_1:
127 chipset = "Intel(R) 965G";
128 break;
129 case PCI_CHIP_I946_GZ:
130 chipset = "Intel(R) 946GZ";
131 break;
132 case PCI_CHIP_I965_GM:
133 chipset = "Intel(R) 965GM";
134 break;
135 case PCI_CHIP_I965_GME:
136 chipset = "Intel(R) 965GME/GLE";
137 break;
138 case PCI_CHIP_GM45_GM:
139 chipset = "Mobile IntelĀ® GM45 Express Chipset";
140 break;
141 case PCI_CHIP_IGD_E_G:
142 chipset = "Intel(R) Integrated Graphics Device";
143 break;
144 case PCI_CHIP_G45_G:
145 chipset = "Intel(R) G45/G43";
146 break;
147 case PCI_CHIP_Q45_G:
148 chipset = "Intel(R) Q45/Q43";
149 break;
150 case PCI_CHIP_G41_G:
151 chipset = "Intel(R) G41";
152 break;
153 case PCI_CHIP_B43_G:
154 case PCI_CHIP_B43_G1:
155 chipset = "Intel(R) B43";
156 break;
157 case PCI_CHIP_ILD_G:
158 chipset = "Intel(R) Ironlake Desktop";
159 break;
160 case PCI_CHIP_ILM_G:
161 chipset = "Intel(R) Ironlake Mobile";
162 break;
163 case PCI_CHIP_SANDYBRIDGE_GT1:
164 case PCI_CHIP_SANDYBRIDGE_GT2:
165 case PCI_CHIP_SANDYBRIDGE_GT2_PLUS:
166 chipset = "Intel(R) Sandybridge Desktop";
167 break;
168 case PCI_CHIP_SANDYBRIDGE_M_GT1:
169 case PCI_CHIP_SANDYBRIDGE_M_GT2:
170 case PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS:
171 chipset = "Intel(R) Sandybridge Mobile";
172 break;
173 case PCI_CHIP_SANDYBRIDGE_S:
174 chipset = "Intel(R) Sandybridge Server";
175 break;
176 case PCI_CHIP_IVYBRIDGE_GT1:
177 case PCI_CHIP_IVYBRIDGE_GT2:
178 chipset = "Intel(R) Ivybridge Desktop";
179 break;
180 case PCI_CHIP_IVYBRIDGE_M_GT1:
181 case PCI_CHIP_IVYBRIDGE_M_GT2:
182 chipset = "Intel(R) Ivybridge Mobile";
183 break;
184 case PCI_CHIP_IVYBRIDGE_S_GT1:
185 chipset = "Intel(R) Ivybridge Server";
186 break;
187 default:
188 chipset = "Unknown Intel Chipset";
189 break;
190 }
191
192 (void) driGetRendererString(buffer, chipset, 0);
193 return (GLubyte *) buffer;
194
195 default:
196 return NULL;
197 }
198 }
199
200 static void
201 intel_flush_front(struct gl_context *ctx)
202 {
203 struct intel_context *intel = intel_context(ctx);
204 __DRIcontext *driContext = intel->driContext;
205 __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
206
207 if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
208 if (screen->dri2.loader &&
209 (screen->dri2.loader->base.version >= 2)
210 && (screen->dri2.loader->flushFrontBuffer != NULL) &&
211 driContext->driDrawablePriv &&
212 driContext->driDrawablePriv->loaderPrivate) {
213 (*screen->dri2.loader->flushFrontBuffer)(driContext->driDrawablePriv,
214 driContext->driDrawablePriv->loaderPrivate);
215
216 /* We set the dirty bit in intel_prepare_render() if we're
217 * front buffer rendering once we get there.
218 */
219 intel->front_buffer_dirty = false;
220 }
221 }
222 }
223
224 static unsigned
225 intel_bits_per_pixel(const struct intel_renderbuffer *rb)
226 {
227 return _mesa_get_format_bytes(rb->Base.Format) * 8;
228 }
229
230 static void
231 intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
232 __DRIdrawable *drawable,
233 __DRIbuffer **buffers,
234 int *count);
235
236 static void
237 intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
238 __DRIdrawable *drawable,
239 __DRIbuffer *buffer,
240 struct intel_renderbuffer *rb,
241 const char *buffer_name);
242
243 static void
244 intel_query_dri2_buffers_with_separate_stencil(struct intel_context *intel,
245 __DRIdrawable *drawable,
246 __DRIbuffer **buffers,
247 unsigned **attachments,
248 int *count);
249
250 static void
251 intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel,
252 __DRIdrawable *drawable,
253 __DRIbuffer *buffer,
254 struct intel_renderbuffer *rb,
255 const char *buffer_name);
256 static void
257 intel_verify_dri2_has_hiz(struct intel_context *intel,
258 __DRIdrawable *drawable,
259 __DRIbuffer **buffers,
260 unsigned **attachments,
261 int *count);
262
263 void
264 intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
265 {
266 struct gl_framebuffer *fb = drawable->driverPrivate;
267 struct intel_renderbuffer *rb;
268 struct intel_context *intel = context->driverPrivate;
269 __DRIbuffer *buffers = NULL;
270 unsigned *attachments = NULL;
271 int i, count;
272 const char *region_name;
273
274 bool try_separate_stencil =
275 intel->has_separate_stencil &&
276 intel->intelScreen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE &&
277 intel->intelScreen->driScrnPriv->dri2.loader != NULL &&
278 intel->intelScreen->driScrnPriv->dri2.loader->base.version > 2 &&
279 intel->intelScreen->driScrnPriv->dri2.loader->getBuffersWithFormat != NULL;
280
281 assert(!intel->must_use_separate_stencil || try_separate_stencil);
282
283 /* If we're rendering to the fake front buffer, make sure all the
284 * pending drawing has landed on the real front buffer. Otherwise
285 * when we eventually get to DRI2GetBuffersWithFormat the stale
286 * real front buffer contents will get copied to the new fake front
287 * buffer.
288 */
289 if (intel->is_front_buffer_rendering) {
290 intel_flush(&intel->ctx);
291 intel_flush_front(&intel->ctx);
292 }
293
294 /* Set this up front, so that in case our buffers get invalidated
295 * while we're getting new buffers, we don't clobber the stamp and
296 * thus ignore the invalidate. */
297 drawable->lastStamp = drawable->dri2.stamp;
298
299 if (unlikely(INTEL_DEBUG & DEBUG_DRI))
300 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
301
302 if (try_separate_stencil) {
303 intel_query_dri2_buffers_with_separate_stencil(intel, drawable, &buffers,
304 &attachments, &count);
305 } else {
306 intel_query_dri2_buffers_no_separate_stencil(intel, drawable, &buffers,
307 &count);
308 }
309
310 if (buffers == NULL)
311 return;
312
313 for (i = 0; i < count; i++) {
314 switch (buffers[i].attachment) {
315 case __DRI_BUFFER_FRONT_LEFT:
316 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
317 region_name = "dri2 front buffer";
318 break;
319
320 case __DRI_BUFFER_FAKE_FRONT_LEFT:
321 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
322 region_name = "dri2 fake front buffer";
323 break;
324
325 case __DRI_BUFFER_BACK_LEFT:
326 rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
327 region_name = "dri2 back buffer";
328 break;
329
330 case __DRI_BUFFER_DEPTH:
331 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
332 region_name = "dri2 depth buffer";
333 break;
334
335 case __DRI_BUFFER_HIZ:
336 /* The hiz region resides in the depth renderbuffer. */
337 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
338 region_name = "dri2 hiz buffer";
339 break;
340
341 case __DRI_BUFFER_DEPTH_STENCIL:
342 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
343 region_name = "dri2 depth / stencil buffer";
344 break;
345
346 case __DRI_BUFFER_STENCIL:
347 rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
348 region_name = "dri2 stencil buffer";
349 break;
350
351 case __DRI_BUFFER_ACCUM:
352 default:
353 fprintf(stderr,
354 "unhandled buffer attach event, attachment type %d\n",
355 buffers[i].attachment);
356 return;
357 }
358
359 if (try_separate_stencil) {
360 intel_process_dri2_buffer_with_separate_stencil(intel, drawable,
361 &buffers[i], rb,
362 region_name);
363 } else {
364 intel_process_dri2_buffer_no_separate_stencil(intel, drawable,
365 &buffers[i], rb,
366 region_name);
367 }
368 }
369
370 if (try_separate_stencil
371 && intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN) {
372 intel_verify_dri2_has_hiz(intel, drawable, &buffers, &attachments,
373 &count);
374 }
375
376 if (attachments)
377 free(attachments);
378
379 driUpdateFramebufferSize(&intel->ctx, drawable);
380 }
381
382 /**
383 * intel_prepare_render should be called anywhere that curent read/drawbuffer
384 * state is required.
385 */
386 void
387 intel_prepare_render(struct intel_context *intel)
388 {
389 __DRIcontext *driContext = intel->driContext;
390 __DRIdrawable *drawable;
391
392 drawable = driContext->driDrawablePriv;
393 if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
394 if (drawable->lastStamp != drawable->dri2.stamp)
395 intel_update_renderbuffers(driContext, drawable);
396 intel_draw_buffer(&intel->ctx);
397 driContext->dri2.draw_stamp = drawable->dri2.stamp;
398 }
399
400 drawable = driContext->driReadablePriv;
401 if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
402 if (drawable->lastStamp != drawable->dri2.stamp)
403 intel_update_renderbuffers(driContext, drawable);
404 driContext->dri2.read_stamp = drawable->dri2.stamp;
405 }
406
407 /* If we're currently rendering to the front buffer, the rendering
408 * that will happen next will probably dirty the front buffer. So
409 * mark it as dirty here.
410 */
411 if (intel->is_front_buffer_rendering)
412 intel->front_buffer_dirty = true;
413
414 /* Wait for the swapbuffers before the one we just emitted, so we
415 * don't get too many swaps outstanding for apps that are GPU-heavy
416 * but not CPU-heavy.
417 *
418 * We're using intelDRI2Flush (called from the loader before
419 * swapbuffer) and glFlush (for front buffer rendering) as the
420 * indicator that a frame is done and then throttle when we get
421 * here as we prepare to render the next frame. At this point for
422 * round trips for swap/copy and getting new buffers are done and
423 * we'll spend less time waiting on the GPU.
424 *
425 * Unfortunately, we don't have a handle to the batch containing
426 * the swap, and getting our hands on that doesn't seem worth it,
427 * so we just us the first batch we emitted after the last swap.
428 */
429 if (intel->need_throttle && intel->first_post_swapbuffers_batch) {
430 drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
431 drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
432 intel->first_post_swapbuffers_batch = NULL;
433 intel->need_throttle = false;
434 }
435 }
436
437 static void
438 intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
439 {
440 struct intel_context *intel = intel_context(ctx);
441 __DRIcontext *driContext = intel->driContext;
442
443 if (intel->saved_viewport)
444 intel->saved_viewport(ctx, x, y, w, h);
445
446 if (ctx->DrawBuffer->Name == 0) {
447 dri2InvalidateDrawable(driContext->driDrawablePriv);
448 dri2InvalidateDrawable(driContext->driReadablePriv);
449 }
450 }
451
452 static const struct dri_debug_control debug_control[] = {
453 { "tex", DEBUG_TEXTURE},
454 { "state", DEBUG_STATE},
455 { "ioctl", DEBUG_IOCTL},
456 { "blit", DEBUG_BLIT},
457 { "mip", DEBUG_MIPTREE},
458 { "fall", DEBUG_FALLBACKS},
459 { "verb", DEBUG_VERBOSE},
460 { "bat", DEBUG_BATCH},
461 { "pix", DEBUG_PIXEL},
462 { "buf", DEBUG_BUFMGR},
463 { "reg", DEBUG_REGION},
464 { "fbo", DEBUG_FBO},
465 { "gs", DEBUG_GS},
466 { "sync", DEBUG_SYNC},
467 { "prim", DEBUG_PRIMS },
468 { "vert", DEBUG_VERTS },
469 { "dri", DEBUG_DRI },
470 { "sf", DEBUG_SF },
471 { "san", DEBUG_SANITY },
472 { "sleep", DEBUG_SLEEP },
473 { "stats", DEBUG_STATS },
474 { "tile", DEBUG_TILE },
475 { "wm", DEBUG_WM },
476 { "urb", DEBUG_URB },
477 { "vs", DEBUG_VS },
478 { "clip", DEBUG_CLIP },
479 { NULL, 0 }
480 };
481
482
483 static void
484 intelInvalidateState(struct gl_context * ctx, GLuint new_state)
485 {
486 struct intel_context *intel = intel_context(ctx);
487
488 _swrast_InvalidateState(ctx, new_state);
489 _vbo_InvalidateState(ctx, new_state);
490
491 intel->NewGLState |= new_state;
492
493 if (intel->vtbl.invalidate_state)
494 intel->vtbl.invalidate_state( intel, new_state );
495 }
496
497 void
498 intel_flush_rendering_to_batch(struct gl_context *ctx)
499 {
500 struct intel_context *intel = intel_context(ctx);
501
502 if (intel->Fallback)
503 _swrast_flush(ctx);
504
505 if (intel->gen < 4)
506 INTEL_FIREVERTICES(intel);
507 }
508
509 void
510 intel_flush(struct gl_context *ctx)
511 {
512 struct intel_context *intel = intel_context(ctx);
513
514 intel_flush_rendering_to_batch(ctx);
515
516 if (intel->batch.used)
517 intel_batchbuffer_flush(intel);
518 }
519
520 static void
521 intel_glFlush(struct gl_context *ctx)
522 {
523 struct intel_context *intel = intel_context(ctx);
524
525 intel_flush(ctx);
526 intel_flush_front(ctx);
527 if (intel->is_front_buffer_rendering)
528 intel->need_throttle = true;
529 }
530
531 void
532 intelFinish(struct gl_context * ctx)
533 {
534 struct intel_context *intel = intel_context(ctx);
535
536 intel_flush(ctx);
537 intel_flush_front(ctx);
538
539 if (intel->batch.last_bo)
540 drm_intel_bo_wait_rendering(intel->batch.last_bo);
541 }
542
543 void
544 intelInitDriverFunctions(struct dd_function_table *functions)
545 {
546 _mesa_init_driver_functions(functions);
547
548 functions->Flush = intel_glFlush;
549 functions->Finish = intelFinish;
550 functions->GetString = intelGetString;
551 functions->UpdateState = intelInvalidateState;
552
553 intelInitTextureFuncs(functions);
554 intelInitTextureImageFuncs(functions);
555 intelInitTextureSubImageFuncs(functions);
556 intelInitTextureCopyImageFuncs(functions);
557 intelInitStateFuncs(functions);
558 intelInitClearFuncs(functions);
559 intelInitBufferFuncs(functions);
560 intelInitPixelFuncs(functions);
561 intelInitBufferObjectFuncs(functions);
562 intel_init_syncobj_functions(functions);
563 }
564
565 bool
566 intelInitContext(struct intel_context *intel,
567 int api,
568 const struct gl_config * mesaVis,
569 __DRIcontext * driContextPriv,
570 void *sharedContextPrivate,
571 struct dd_function_table *functions)
572 {
573 struct gl_context *ctx = &intel->ctx;
574 struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
575 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
576 struct intel_screen *intelScreen = sPriv->driverPrivate;
577 int bo_reuse_mode;
578 struct gl_config visual;
579
580 /* we can't do anything without a connection to the device */
581 if (intelScreen->bufmgr == NULL)
582 return false;
583
584 /* Can't rely on invalidate events, fall back to glViewport hack */
585 if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
586 intel->saved_viewport = functions->Viewport;
587 functions->Viewport = intel_viewport;
588 }
589
590 if (mesaVis == NULL) {
591 memset(&visual, 0, sizeof visual);
592 mesaVis = &visual;
593 }
594
595 if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
596 functions, (void *) intel)) {
597 printf("%s: failed to init mesa context\n", __FUNCTION__);
598 return false;
599 }
600
601 driContextPriv->driverPrivate = intel;
602 intel->intelScreen = intelScreen;
603 intel->driContext = driContextPriv;
604 intel->driFd = sPriv->fd;
605
606 intel->gen = intelScreen->gen;
607
608 const int devID = intelScreen->deviceID;
609
610 if (IS_SNB_GT1(devID) || IS_IVB_GT1(devID))
611 intel->gt = 1;
612 else if (IS_SNB_GT2(devID) || IS_IVB_GT2(devID))
613 intel->gt = 2;
614 else
615 intel->gt = 0;
616
617 if (IS_G4X(devID)) {
618 intel->is_g4x = true;
619 } else if (IS_945(devID)) {
620 intel->is_945 = true;
621 }
622
623 if (intel->gen >= 5) {
624 intel->needs_ff_sync = true;
625 }
626
627 intel->has_separate_stencil = intel->intelScreen->hw_has_separate_stencil;
628 intel->must_use_separate_stencil = intel->intelScreen->hw_must_use_separate_stencil;
629 intel->has_hiz = intel->intelScreen->hw_has_hiz;
630
631 memset(&ctx->TextureFormatSupported, 0,
632 sizeof(ctx->TextureFormatSupported));
633 ctx->TextureFormatSupported[MESA_FORMAT_ARGB8888] = true;
634 if (devID != PCI_CHIP_I830_M && devID != PCI_CHIP_845_G)
635 ctx->TextureFormatSupported[MESA_FORMAT_XRGB8888] = true;
636 ctx->TextureFormatSupported[MESA_FORMAT_ARGB4444] = true;
637 ctx->TextureFormatSupported[MESA_FORMAT_ARGB1555] = true;
638 ctx->TextureFormatSupported[MESA_FORMAT_RGB565] = true;
639 ctx->TextureFormatSupported[MESA_FORMAT_L8] = true;
640 ctx->TextureFormatSupported[MESA_FORMAT_A8] = true;
641 ctx->TextureFormatSupported[MESA_FORMAT_I8] = true;
642 ctx->TextureFormatSupported[MESA_FORMAT_AL88] = true;
643 if (intel->gen >= 4) {
644 ctx->TextureFormatSupported[MESA_FORMAT_L16] = true;
645 ctx->TextureFormatSupported[MESA_FORMAT_A16] = true;
646 ctx->TextureFormatSupported[MESA_FORMAT_I16] = true;
647 ctx->TextureFormatSupported[MESA_FORMAT_AL1616] = true;
648 }
649
650 /* Depth and stencil */
651 ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = true;
652 ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = true;
653 ctx->TextureFormatSupported[MESA_FORMAT_S8] = intel->has_separate_stencil;
654
655 /*
656 * This was disabled in initial FBO enabling to avoid combinations
657 * of depth+stencil that wouldn't work together. We since decided
658 * that it was OK, since it's up to the app to come up with the
659 * combo that actually works, so this can probably be re-enabled.
660 */
661 /*
662 ctx->TextureFormatSupported[MESA_FORMAT_Z16] = true;
663 ctx->TextureFormatSupported[MESA_FORMAT_Z24] = true;
664 */
665
666 /* ctx->Extensions.MESA_ycbcr_texture */
667 ctx->TextureFormatSupported[MESA_FORMAT_YCBCR] = true;
668 ctx->TextureFormatSupported[MESA_FORMAT_YCBCR_REV] = true;
669
670 /* GL_3DFX_texture_compression_FXT1 */
671 ctx->TextureFormatSupported[MESA_FORMAT_RGB_FXT1] = true;
672 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_FXT1] = true;
673
674 /* GL_EXT_texture_compression_s3tc */
675 ctx->TextureFormatSupported[MESA_FORMAT_RGB_DXT1] = true;
676 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_DXT1] = true;
677 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_DXT3] = true;
678 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_DXT5] = true;
679
680 #ifndef I915
681 /* GL_ARB_texture_compression_rgtc */
682 ctx->TextureFormatSupported[MESA_FORMAT_RED_RGTC1] = true;
683 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_RED_RGTC1] = true;
684 ctx->TextureFormatSupported[MESA_FORMAT_RG_RGTC2] = true;
685 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_RG_RGTC2] = true;
686
687 /* GL_ARB_texture_rg */
688 ctx->TextureFormatSupported[MESA_FORMAT_R8] = true;
689 ctx->TextureFormatSupported[MESA_FORMAT_R16] = true;
690 ctx->TextureFormatSupported[MESA_FORMAT_RG88] = true;
691 ctx->TextureFormatSupported[MESA_FORMAT_RG1616] = true;
692
693 /* GL_MESA_texture_signed_rgba / GL_EXT_texture_snorm */
694 ctx->TextureFormatSupported[MESA_FORMAT_DUDV8] = true;
695 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_RGBA8888_REV] = true;
696 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_R8] = true;
697 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_RG88_REV] = true;
698 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_R16] = true;
699 ctx->TextureFormatSupported[MESA_FORMAT_SIGNED_GR1616] = true;
700
701 /* GL_EXT_texture_sRGB */
702 ctx->TextureFormatSupported[MESA_FORMAT_SARGB8] = true;
703 if (intel->gen >= 5 || intel->is_g4x)
704 ctx->TextureFormatSupported[MESA_FORMAT_SRGB_DXT1] = true;
705 ctx->TextureFormatSupported[MESA_FORMAT_SRGBA_DXT1] = true;
706 ctx->TextureFormatSupported[MESA_FORMAT_SRGBA_DXT3] = true;
707 ctx->TextureFormatSupported[MESA_FORMAT_SRGBA_DXT5] = true;
708 if (intel->gen >= 5 || intel->is_g4x) {
709 ctx->TextureFormatSupported[MESA_FORMAT_SL8] = true;
710 ctx->TextureFormatSupported[MESA_FORMAT_SLA8] = true;
711 }
712
713 if (intel->gen >= 4) {
714 /* Each combination of 32-bit ints are supported, but the RGB 32-bit ints
715 * don't support use as a render target (GPU hangs).
716 */
717 ctx->TextureFormatSupported[MESA_FORMAT_R_INT32] = true;
718 ctx->TextureFormatSupported[MESA_FORMAT_RG_INT32] = true;
719 ctx->TextureFormatSupported[MESA_FORMAT_RGB_INT32] = true;
720 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_INT32] = true;
721
722 ctx->TextureFormatSupported[MESA_FORMAT_R_UINT32] = true;
723 ctx->TextureFormatSupported[MESA_FORMAT_RG_UINT32] = true;
724 ctx->TextureFormatSupported[MESA_FORMAT_RGB_UINT32] = true;
725 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_UINT32] = true;
726
727 /* For 16 and 8 bits, RGB is unsupported entirely. */
728 ctx->TextureFormatSupported[MESA_FORMAT_R_UINT16] = true;
729 ctx->TextureFormatSupported[MESA_FORMAT_RG_UINT16] = true;
730 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_UINT16] = true;
731 ctx->TextureFormatSupported[MESA_FORMAT_R_INT16] = true;
732 ctx->TextureFormatSupported[MESA_FORMAT_RG_INT16] = true;
733 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_INT16] = true;
734
735 ctx->TextureFormatSupported[MESA_FORMAT_R_UINT8] = true;
736 ctx->TextureFormatSupported[MESA_FORMAT_RG_UINT8] = true;
737 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_UINT8] = true;
738 ctx->TextureFormatSupported[MESA_FORMAT_R_INT8] = true;
739 ctx->TextureFormatSupported[MESA_FORMAT_RG_INT8] = true;
740 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_INT8] = true;
741 }
742
743 #ifdef TEXTURE_FLOAT_ENABLED
744 ctx->TextureFormatSupported[MESA_FORMAT_RGBA_FLOAT32] = true;
745 ctx->TextureFormatSupported[MESA_FORMAT_RG_FLOAT32] = true;
746 ctx->TextureFormatSupported[MESA_FORMAT_R_FLOAT32] = true;
747 ctx->TextureFormatSupported[MESA_FORMAT_INTENSITY_FLOAT32] = true;
748 ctx->TextureFormatSupported[MESA_FORMAT_LUMINANCE_FLOAT32] = true;
749 ctx->TextureFormatSupported[MESA_FORMAT_ALPHA_FLOAT32] = true;
750 ctx->TextureFormatSupported[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = true;
751
752 /* GL_EXT_texture_shared_exponent */
753 ctx->TextureFormatSupported[MESA_FORMAT_RGB9_E5_FLOAT] = true;
754
755 /* GL_EXT_packed_float */
756 ctx->TextureFormatSupported[MESA_FORMAT_R11_G11_B10_FLOAT] = true;
757 #endif
758
759 #endif /* !I915 */
760
761 driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
762 sPriv->myNum, (intel->gen >= 4) ? "i965" : "i915");
763 if (intel->gen < 4)
764 intel->maxBatchSize = 4096;
765 else
766 intel->maxBatchSize = sizeof(intel->batch.map);
767
768 intel->bufmgr = intelScreen->bufmgr;
769
770 bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
771 switch (bo_reuse_mode) {
772 case DRI_CONF_BO_REUSE_DISABLED:
773 break;
774 case DRI_CONF_BO_REUSE_ALL:
775 intel_bufmgr_gem_enable_reuse(intel->bufmgr);
776 break;
777 }
778
779 /* This doesn't yet catch all non-conformant rendering, but it's a
780 * start.
781 */
782 if (getenv("INTEL_STRICT_CONFORMANCE")) {
783 unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE"));
784 if (value > 0) {
785 intel->conformance_mode = value;
786 }
787 else {
788 intel->conformance_mode = 1;
789 }
790 }
791
792 if (intel->conformance_mode > 0) {
793 ctx->Const.MinLineWidth = 1.0;
794 ctx->Const.MinLineWidthAA = 1.0;
795 ctx->Const.MaxLineWidth = 1.0;
796 ctx->Const.MaxLineWidthAA = 1.0;
797 ctx->Const.LineWidthGranularity = 1.0;
798 }
799 else {
800 ctx->Const.MinLineWidth = 1.0;
801 ctx->Const.MinLineWidthAA = 1.0;
802 ctx->Const.MaxLineWidth = 5.0;
803 ctx->Const.MaxLineWidthAA = 5.0;
804 ctx->Const.LineWidthGranularity = 0.5;
805 }
806
807 ctx->Const.MinPointSize = 1.0;
808 ctx->Const.MinPointSizeAA = 1.0;
809 ctx->Const.MaxPointSize = 255.0;
810 ctx->Const.MaxPointSizeAA = 3.0;
811 ctx->Const.PointSizeGranularity = 1.0;
812
813 ctx->Const.MaxSamples = 1.0;
814
815 if (intel->gen >= 6)
816 ctx->Const.MaxClipPlanes = 8;
817
818 ctx->Const.StripTextureBorder = GL_TRUE;
819
820 /* reinitialize the context point state.
821 * It depend on constants in __struct gl_contextRec::Const
822 */
823 _mesa_init_point(ctx);
824
825 if (intel->gen >= 4) {
826 ctx->Const.sRGBCapable = true;
827 if (MAX_WIDTH > 8192)
828 ctx->Const.MaxRenderbufferSize = 8192;
829 } else {
830 if (MAX_WIDTH > 2048)
831 ctx->Const.MaxRenderbufferSize = 2048;
832 }
833
834 /* Initialize the software rasterizer and helper modules. */
835 _swrast_CreateContext(ctx);
836 _vbo_CreateContext(ctx);
837 _tnl_CreateContext(ctx);
838 _swsetup_CreateContext(ctx);
839
840 /* Configure swrast to match hardware characteristics: */
841 _swrast_allow_pixel_fog(ctx, false);
842 _swrast_allow_vertex_fog(ctx, true);
843
844 _mesa_meta_init(ctx);
845
846 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
847 intel->hw_stipple = 1;
848
849 /* XXX FBO: this doesn't seem to be used anywhere */
850 switch (mesaVis->depthBits) {
851 case 0: /* what to do in this case? */
852 case 16:
853 intel->polygon_offset_scale = 1.0;
854 break;
855 case 24:
856 intel->polygon_offset_scale = 2.0; /* req'd to pass glean */
857 break;
858 default:
859 assert(0);
860 break;
861 }
862
863 if (intel->gen >= 4)
864 intel->polygon_offset_scale /= 0xffff;
865
866 intel->RenderIndex = ~0;
867
868 switch (ctx->API) {
869 case API_OPENGL:
870 intelInitExtensions(ctx);
871 break;
872 case API_OPENGLES:
873 intelInitExtensionsES1(ctx);
874 break;
875 case API_OPENGLES2:
876 intelInitExtensionsES2(ctx);
877 break;
878 }
879
880 INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
881 if (INTEL_DEBUG & DEBUG_BUFMGR)
882 dri_bufmgr_set_debug(intel->bufmgr, true);
883
884 intel_batchbuffer_init(intel);
885
886 intel_fbo_init(intel);
887
888 intel->use_texture_tiling = driQueryOptionb(&intel->optionCache,
889 "texture_tiling");
890 intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
891
892 intel->prim.primitive = ~0;
893
894 /* Force all software fallbacks */
895 if (driQueryOptionb(&intel->optionCache, "no_rast")) {
896 fprintf(stderr, "disabling 3D rasterization\n");
897 intel->no_rast = 1;
898 }
899
900 if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
901 fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
902 intel->always_flush_batch = 1;
903 }
904
905 if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
906 fprintf(stderr, "flushing GPU caches before/after each draw call\n");
907 intel->always_flush_cache = 1;
908 }
909
910 return true;
911 }
912
913 void
914 intelDestroyContext(__DRIcontext * driContextPriv)
915 {
916 struct intel_context *intel =
917 (struct intel_context *) driContextPriv->driverPrivate;
918
919 assert(intel); /* should never be null */
920 if (intel) {
921 INTEL_FIREVERTICES(intel);
922
923 _mesa_meta_free(&intel->ctx);
924
925 intel->vtbl.destroy(intel);
926
927 _swsetup_DestroyContext(&intel->ctx);
928 _tnl_DestroyContext(&intel->ctx);
929 _vbo_DestroyContext(&intel->ctx);
930
931 _swrast_DestroyContext(&intel->ctx);
932 intel->Fallback = 0x0; /* don't call _swrast_Flush later */
933
934 intel_batchbuffer_free(intel);
935
936 free(intel->prim.vb);
937 intel->prim.vb = NULL;
938 drm_intel_bo_unreference(intel->prim.vb_bo);
939 intel->prim.vb_bo = NULL;
940 drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
941 intel->first_post_swapbuffers_batch = NULL;
942
943 driDestroyOptionCache(&intel->optionCache);
944
945 /* free the Mesa context */
946 _mesa_free_context_data(&intel->ctx);
947
948 _math_matrix_dtr(&intel->ViewportMatrix);
949
950 ralloc_free(intel);
951 driContextPriv->driverPrivate = NULL;
952 }
953 }
954
955 GLboolean
956 intelUnbindContext(__DRIcontext * driContextPriv)
957 {
958 /* Unset current context and dispath table */
959 _mesa_make_current(NULL, NULL, NULL);
960
961 return true;
962 }
963
964 GLboolean
965 intelMakeCurrent(__DRIcontext * driContextPriv,
966 __DRIdrawable * driDrawPriv,
967 __DRIdrawable * driReadPriv)
968 {
969 struct intel_context *intel;
970 GET_CURRENT_CONTEXT(curCtx);
971
972 if (driContextPriv)
973 intel = (struct intel_context *) driContextPriv->driverPrivate;
974 else
975 intel = NULL;
976
977 /* According to the glXMakeCurrent() man page: "Pending commands to
978 * the previous context, if any, are flushed before it is released."
979 * But only flush if we're actually changing contexts.
980 */
981 if (intel_context(curCtx) && intel_context(curCtx) != intel) {
982 _mesa_flush(curCtx);
983 }
984
985 if (driContextPriv) {
986 struct gl_framebuffer *fb, *readFb;
987
988 if (driDrawPriv == NULL && driReadPriv == NULL) {
989 fb = _mesa_get_incomplete_framebuffer();
990 readFb = _mesa_get_incomplete_framebuffer();
991 } else {
992 fb = driDrawPriv->driverPrivate;
993 readFb = driReadPriv->driverPrivate;
994 driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
995 driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
996 }
997
998 intel_prepare_render(intel);
999 _mesa_make_current(&intel->ctx, fb, readFb);
1000
1001 /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer
1002 * is NULL at that point. We can't call _mesa_makecurrent()
1003 * first, since we need the buffer size for the initial
1004 * viewport. So just call intel_draw_buffer() again here. */
1005 intel_draw_buffer(&intel->ctx);
1006 }
1007 else {
1008 _mesa_make_current(NULL, NULL, NULL);
1009 }
1010
1011 return true;
1012 }
1013
1014 /**
1015 * \brief Query DRI2 to obtain a DRIdrawable's buffers.
1016 *
1017 * To determine which DRI buffers to request, examine the renderbuffers
1018 * attached to the drawable's framebuffer. Then request the buffers with
1019 * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
1020 *
1021 * This is called from intel_update_renderbuffers(). It is used only if either
1022 * the hardware or the X driver lacks separate stencil support.
1023 *
1024 * \param drawable Drawable whose buffers are queried.
1025 * \param buffers [out] List of buffers returned by DRI2 query.
1026 * \param buffer_count [out] Number of buffers returned.
1027 *
1028 * \see intel_update_renderbuffers()
1029 * \see DRI2GetBuffers()
1030 * \see DRI2GetBuffersWithFormat()
1031 */
1032 static void
1033 intel_query_dri2_buffers_no_separate_stencil(struct intel_context *intel,
1034 __DRIdrawable *drawable,
1035 __DRIbuffer **buffers,
1036 int *buffer_count)
1037 {
1038 assert(!intel->must_use_separate_stencil);
1039
1040 __DRIscreen *screen = intel->intelScreen->driScrnPriv;
1041 struct gl_framebuffer *fb = drawable->driverPrivate;
1042
1043 if (screen->dri2.loader
1044 && screen->dri2.loader->base.version > 2
1045 && screen->dri2.loader->getBuffersWithFormat != NULL) {
1046
1047 int i = 0;
1048 const int max_attachments = 4;
1049 unsigned *attachments = calloc(2 * max_attachments, sizeof(unsigned));
1050
1051 struct intel_renderbuffer *front_rb;
1052 struct intel_renderbuffer *back_rb;
1053 struct intel_renderbuffer *depth_rb;
1054 struct intel_renderbuffer *stencil_rb;
1055
1056 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1057 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1058 depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
1059 stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
1060
1061 if ((intel->is_front_buffer_rendering ||
1062 intel->is_front_buffer_reading ||
1063 !back_rb) && front_rb) {
1064 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1065 attachments[i++] = intel_bits_per_pixel(front_rb);
1066 }
1067
1068 if (back_rb) {
1069 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1070 attachments[i++] = intel_bits_per_pixel(back_rb);
1071 }
1072
1073 if (depth_rb && stencil_rb) {
1074 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
1075 attachments[i++] = intel_bits_per_pixel(depth_rb);
1076 } else if (depth_rb) {
1077 attachments[i++] = __DRI_BUFFER_DEPTH;
1078 attachments[i++] = intel_bits_per_pixel(depth_rb);
1079 } else if (stencil_rb) {
1080 attachments[i++] = __DRI_BUFFER_STENCIL;
1081 attachments[i++] = intel_bits_per_pixel(stencil_rb);
1082 }
1083
1084 assert(i <= 2 * max_attachments);
1085
1086 *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
1087 &drawable->w,
1088 &drawable->h,
1089 attachments, i / 2,
1090 buffer_count,
1091 drawable->loaderPrivate);
1092 free(attachments);
1093
1094 } else if (screen->dri2.loader) {
1095
1096 int i = 0;
1097 const int max_attachments = 4;
1098 unsigned *attachments = calloc(max_attachments, sizeof(unsigned));
1099
1100 if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT))
1101 attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
1102 if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT))
1103 attachments[i++] = __DRI_BUFFER_BACK_LEFT;
1104 if (intel_get_renderbuffer(fb, BUFFER_DEPTH))
1105 attachments[i++] = __DRI_BUFFER_DEPTH;
1106 if (intel_get_renderbuffer(fb, BUFFER_STENCIL))
1107 attachments[i++] = __DRI_BUFFER_STENCIL;
1108
1109 assert(i <= max_attachments);
1110
1111 *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
1112 &drawable->w,
1113 &drawable->h,
1114 attachments, i,
1115 buffer_count,
1116 drawable->loaderPrivate);
1117 free(attachments);
1118
1119 } else {
1120 *buffers = NULL;
1121 *buffer_count = 0;
1122 }
1123 }
1124
1125 /**
1126 * \brief Assign a DRI buffer's DRM region to a renderbuffer.
1127 *
1128 * This is called from intel_update_renderbuffers(). It is used only if
1129 * either the hardware or the X driver lacks separate stencil support.
1130 *
1131 * \par Note:
1132 * DRI buffers whose attachment point is DRI2BufferStencil or
1133 * DRI2BufferDepthStencil are handled as special cases.
1134 *
1135 * \param buffer_name is a human readable name, such as "dri2 front buffer",
1136 * that is passed to intel_region_alloc_for_handle().
1137 *
1138 * \see intel_update_renderbuffers()
1139 * \see intel_region_alloc_for_handle()
1140 */
1141 static void
1142 intel_process_dri2_buffer_no_separate_stencil(struct intel_context *intel,
1143 __DRIdrawable *drawable,
1144 __DRIbuffer *buffer,
1145 struct intel_renderbuffer *rb,
1146 const char *buffer_name)
1147 {
1148 assert(!intel->must_use_separate_stencil);
1149
1150 struct gl_framebuffer *fb = drawable->driverPrivate;
1151 struct intel_renderbuffer *depth_rb = NULL;
1152
1153 if (!rb)
1154 return;
1155
1156 if (rb->region && rb->region->name == buffer->name)
1157 return;
1158
1159 if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
1160 fprintf(stderr,
1161 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
1162 buffer->name, buffer->attachment,
1163 buffer->cpp, buffer->pitch);
1164 }
1165
1166 bool identify_depth_and_stencil = false;
1167 if (buffer->attachment == __DRI_BUFFER_STENCIL) {
1168 struct intel_renderbuffer *depth_rb =
1169 intel_get_renderbuffer(fb, BUFFER_DEPTH);
1170 identify_depth_and_stencil = depth_rb && depth_rb->region;
1171 }
1172
1173 if (identify_depth_and_stencil) {
1174 if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
1175 fprintf(stderr, "(reusing depth buffer as stencil)\n");
1176 }
1177 intel_region_reference(&rb->region, depth_rb->region);
1178 } else {
1179 intel_region_release(&rb->region);
1180 rb->region = intel_region_alloc_for_handle(intel->intelScreen,
1181 buffer->cpp,
1182 drawable->w,
1183 drawable->h,
1184 buffer->pitch / buffer->cpp,
1185 buffer->name,
1186 buffer_name);
1187 }
1188
1189 if (buffer->attachment == __DRI_BUFFER_DEPTH_STENCIL) {
1190 struct intel_renderbuffer *stencil_rb =
1191 intel_get_renderbuffer(fb, BUFFER_STENCIL);
1192
1193 if (!stencil_rb)
1194 return;
1195
1196 /* The rb passed in is the BUFFER_DEPTH attachment, and we need
1197 * to associate this region to BUFFER_STENCIL as well.
1198 */
1199 intel_region_reference(&stencil_rb->region, rb->region);
1200 }
1201 }
1202
1203 /**
1204 * \brief Query DRI2 to obtain a DRIdrawable's buffers.
1205 *
1206 * To determine which DRI buffers to request, examine the renderbuffers
1207 * attached to the drawable's framebuffer. Then request the buffers with
1208 * DRI2GetBuffersWithFormat().
1209 *
1210 * This is called from intel_update_renderbuffers(). It is used when 1) the
1211 * hardware supports separate stencil and 2) the X driver's separate stencil
1212 * support has been verified to work or is still unknown.
1213 *
1214 * \param drawable Drawable whose buffers are queried.
1215 * \param buffers [out] List of buffers returned by DRI2 query.
1216 * \param buffer_count [out] Number of buffers returned.
1217 * \param attachments [out] List of pairs (attachment_point, bits_per_pixel)
1218 * that were submitted in the DRI2 query. Number of pairs
1219 * is same as buffer_count.
1220 *
1221 * \see intel_update_renderbuffers()
1222 * \see DRI2GetBuffersWithFormat()
1223 * \see enum intel_dri2_has_hiz
1224 */
1225 static void
1226 intel_query_dri2_buffers_with_separate_stencil(struct intel_context *intel,
1227 __DRIdrawable *drawable,
1228 __DRIbuffer **buffers,
1229 unsigned **attachments,
1230 int *count)
1231 {
1232 assert(intel->has_separate_stencil);
1233
1234 __DRIscreen *screen = intel->intelScreen->driScrnPriv;
1235 struct gl_framebuffer *fb = drawable->driverPrivate;
1236
1237 const int max_attachments = 5;
1238 int i = 0;
1239
1240 *attachments = calloc(2 * max_attachments, sizeof(unsigned));
1241 if (!*attachments) {
1242 *buffers = NULL;
1243 *count = 0;
1244 return;
1245 }
1246
1247 struct intel_renderbuffer *front_rb;
1248 struct intel_renderbuffer *back_rb;
1249 struct intel_renderbuffer *depth_rb;
1250 struct intel_renderbuffer *stencil_rb;
1251
1252 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
1253 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
1254 depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
1255 stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
1256
1257 if ((intel->is_front_buffer_rendering ||
1258 intel->is_front_buffer_reading ||
1259 !back_rb) && front_rb) {
1260 (*attachments)[i++] = __DRI_BUFFER_FRONT_LEFT;
1261 (*attachments)[i++] = intel_bits_per_pixel(front_rb);
1262 }
1263
1264 if (back_rb) {
1265 (*attachments)[i++] = __DRI_BUFFER_BACK_LEFT;
1266 (*attachments)[i++] = intel_bits_per_pixel(back_rb);
1267 }
1268
1269 /*
1270 * We request a separate stencil buffer, and perhaps a hiz buffer too, even
1271 * if we do not yet know if the X driver supports it. See the comments for
1272 * 'enum intel_dri2_has_hiz'.
1273 */
1274
1275 if (depth_rb) {
1276 (*attachments)[i++] = __DRI_BUFFER_DEPTH;
1277 (*attachments)[i++] = intel_bits_per_pixel(depth_rb);
1278
1279 if (intel->vtbl.is_hiz_depth_format(intel, depth_rb->Base.Format)) {
1280 /* Depth and hiz buffer have same bpp. */
1281 (*attachments)[i++] = __DRI_BUFFER_HIZ;
1282 (*attachments)[i++] = intel_bits_per_pixel(depth_rb);
1283 }
1284 }
1285
1286 if (stencil_rb) {
1287 assert(stencil_rb->Base.Format == MESA_FORMAT_S8);
1288 (*attachments)[i++] = __DRI_BUFFER_STENCIL;
1289 (*attachments)[i++] = intel_bits_per_pixel(stencil_rb);
1290 }
1291
1292 assert(i <= 2 * max_attachments);
1293
1294 *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
1295 &drawable->w,
1296 &drawable->h,
1297 *attachments, i / 2,
1298 count,
1299 drawable->loaderPrivate);
1300
1301 if (!*buffers) {
1302 free(*attachments);
1303 *attachments = NULL;
1304 *count = 0;
1305 }
1306 }
1307
1308 /**
1309 * \brief Assign a DRI buffer's DRM region to a renderbuffer.
1310 *
1311 * This is called from intel_update_renderbuffers(). It is used when 1) the
1312 * hardware supports separate stencil and 2) the X driver's separate stencil
1313 * support has been verified to work or is still unknown.
1314 *
1315 * \par Note:
1316 * DRI buffers whose attachment point is DRI2BufferStencil or DRI2BufferHiz
1317 * are handled as special cases.
1318 *
1319 * \param buffer_name is a human readable name, such as "dri2 front buffer",
1320 * that is passed to intel_region_alloc_for_handle().
1321 *
1322 * \see intel_update_renderbuffers()
1323 * \see intel_region_alloc_for_handle()
1324 * \see enum intel_dri2_has_hiz
1325 */
1326 static void
1327 intel_process_dri2_buffer_with_separate_stencil(struct intel_context *intel,
1328 __DRIdrawable *drawable,
1329 __DRIbuffer *buffer,
1330 struct intel_renderbuffer *rb,
1331 const char *buffer_name)
1332 {
1333 assert(intel->has_separate_stencil);
1334 assert(buffer->attachment != __DRI_BUFFER_DEPTH_STENCIL);
1335
1336 if (!rb)
1337 return;
1338
1339 /* If the renderbuffer's and DRIbuffer's regions match, then continue. */
1340 if ((buffer->attachment != __DRI_BUFFER_HIZ &&
1341 rb->region &&
1342 rb->region->name == buffer->name) ||
1343 (buffer->attachment == __DRI_BUFFER_HIZ &&
1344 rb->hiz_region &&
1345 rb->hiz_region->name == buffer->name)) {
1346 return;
1347 }
1348
1349 if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
1350 fprintf(stderr,
1351 "attaching buffer %d, at %d, cpp %d, pitch %d\n",
1352 buffer->name, buffer->attachment,
1353 buffer->cpp, buffer->pitch);
1354 }
1355
1356 /*
1357 * The stencil buffer has quirky pitch requirements. From Section
1358 * 2.11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
1359 * The pitch must be set to 2x the value computed based on width, as
1360 * the stencil buffer is stored with two rows interleaved.
1361 * If we neglect to double the pitch, then drm_intel_gem_bo_map_gtt()
1362 * maps the memory incorrectly.
1363 *
1364 * To satisfy the pitch requirement, the X driver hackishly allocated
1365 * the gem buffer with bpp doubled and height halved. So buffer->cpp is
1366 * correct, but drawable->height is not.
1367 */
1368 int buffer_height = drawable->h;
1369 if (buffer->attachment == __DRI_BUFFER_STENCIL) {
1370 buffer_height /= 2;
1371 }
1372
1373 struct intel_region *region =
1374 intel_region_alloc_for_handle(intel->intelScreen,
1375 buffer->cpp,
1376 drawable->w,
1377 buffer_height,
1378 buffer->pitch / buffer->cpp,
1379 buffer->name,
1380 buffer_name);
1381
1382 if (buffer->attachment == __DRI_BUFFER_HIZ) {
1383 intel_region_reference(&rb->hiz_region, region);
1384 } else {
1385 intel_region_reference(&rb->region, region);
1386 }
1387
1388 intel_region_release(&region);
1389 }
1390
1391 /**
1392 * \brief Verify that the X driver supports hiz and separate stencil.
1393 *
1394 * This implements the cleanup stage of the handshake described in the
1395 * comments for 'enum intel_dri2_has_hiz'.
1396 *
1397 * This should be called from intel_update_renderbuffers() after 1) the
1398 * DRIdrawable has been queried for its buffers via DRI2GetBuffersWithFormat()
1399 * and 2) the DRM region of each returned DRIbuffer has been assigned to the
1400 * appropriate intel_renderbuffer. Furthermore, this should be called *only*
1401 * when 1) intel_update_renderbuffers() tried to used the X driver's separate
1402 * stencil functionality and 2) it has not yet been determined if the X driver
1403 * supports separate stencil.
1404 *
1405 * If we determine that the X driver does have support, then we set
1406 * intel_screen.dri2_has_hiz to true and return.
1407 *
1408 * If we determine that the X driver lacks support, and we requested
1409 * a DRI2BufferDepth and DRI2BufferStencil, then we must remedy the mistake by
1410 * taking the following actions:
1411 * 1. Discard the framebuffer's stencil and depth renderbuffers.
1412 * 2. Create a combined depth/stencil renderbuffer and attach
1413 * it to the framebuffer's depth and stencil attachment points.
1414 * 3. Query the drawable for a new set of buffers, which consists of the
1415 * originally requested set plus DRI2BufferDepthStencil.
1416 * 4. Assign the DRI2BufferDepthStencil's DRM region to the new
1417 * depth/stencil renderbuffer.
1418 *
1419 * \pre intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN
1420 *
1421 * \param drawable Drawable whose buffers were queried.
1422 *
1423 * \param buffers [in/out] As input, the buffer list returned by the
1424 * original DRI2 query. As output, the current buffer
1425 * list, which may have been altered by a new DRI2 query.
1426 *
1427 * \param attachments [in/out] As input, the attachment list submitted
1428 * in the original DRI2 query. As output, the attachment
1429 * list that was submitted in the DRI2 query that
1430 * obtained the current buffer list, as returned in the
1431 * output parameter \c buffers. (Note: If no new query
1432 * was made, then the list remains unaltered).
1433 *
1434 * \param count [out] Number of buffers in the current buffer list, as
1435 * returned in the output parameter \c buffers.
1436 *
1437 * \see enum intel_dri2_has_hiz
1438 * \see struct intel_screen::dri2_has_hiz
1439 * \see intel_update_renderbuffers
1440 */
1441 static void
1442 intel_verify_dri2_has_hiz(struct intel_context *intel,
1443 __DRIdrawable *drawable,
1444 __DRIbuffer **buffers,
1445 unsigned **attachments,
1446 int *count)
1447 {
1448 assert(intel->intelScreen->dri2_has_hiz == INTEL_DRI2_HAS_HIZ_UNKNOWN);
1449
1450 struct gl_framebuffer *fb = drawable->driverPrivate;
1451 struct intel_renderbuffer *stencil_rb =
1452 intel_get_renderbuffer(fb, BUFFER_STENCIL);
1453
1454 if (stencil_rb) {
1455 /*
1456 * We requested a DRI2BufferStencil without knowing if the X driver
1457 * supports it. Now, check if X handled the request correctly and clean
1458 * up if it did not. (See comments for 'enum intel_dri2_has_hiz').
1459 */
1460 struct intel_renderbuffer *depth_rb =
1461 intel_get_renderbuffer(fb, BUFFER_DEPTH);
1462 assert(stencil_rb->Base.Format == MESA_FORMAT_S8);
1463 assert(depth_rb && depth_rb->Base.Format == MESA_FORMAT_X8_Z24);
1464
1465 if (stencil_rb->region->tiling == I915_TILING_NONE) {
1466 /*
1467 * The stencil buffer is actually W tiled. The region's tiling is
1468 * I915_TILING_NONE, however, because the GTT is incapable of W
1469 * fencing.
1470 */
1471 intel->intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_TRUE;
1472 return;
1473 } else {
1474 /*
1475 * Oops... the screen doesn't support separate stencil. Discard the
1476 * separate depth and stencil buffers and replace them with
1477 * a combined depth/stencil buffer. Discard the hiz buffer too.
1478 */
1479 intel->intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_FALSE;
1480 if (intel->must_use_separate_stencil) {
1481 _mesa_problem(&intel->ctx,
1482 "intel_context requires separate stencil, but the "
1483 "DRIscreen does not support it. You may need to "
1484 "upgrade the Intel X driver to 2.16.0");
1485 abort();
1486 }
1487
1488 /* 1. Discard depth and stencil renderbuffers. */
1489 _mesa_remove_renderbuffer(fb, BUFFER_DEPTH);
1490 depth_rb = NULL;
1491 _mesa_remove_renderbuffer(fb, BUFFER_STENCIL);
1492 stencil_rb = NULL;
1493
1494 /* 2. Create new depth/stencil renderbuffer. */
1495 struct intel_renderbuffer *depth_stencil_rb =
1496 intel_create_renderbuffer(MESA_FORMAT_S8_Z24);
1497 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth_stencil_rb->Base);
1498 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depth_stencil_rb->Base);
1499
1500 /* 3. Append DRI2BufferDepthStencil to attachment list. */
1501 int old_count = *count;
1502 unsigned int *old_attachments = *attachments;
1503 *count = old_count + 1;
1504 *attachments = malloc(2 * (*count) * sizeof(unsigned));
1505 memcpy(*attachments, old_attachments, 2 * old_count * sizeof(unsigned));
1506 free(old_attachments);
1507 (*attachments)[2 * old_count + 0] = __DRI_BUFFER_DEPTH_STENCIL;
1508 (*attachments)[2 * old_count + 1] = intel_bits_per_pixel(depth_stencil_rb);
1509
1510 /* 4. Request new set of DRI2 attachments. */
1511 __DRIscreen *screen = intel->intelScreen->driScrnPriv;
1512 *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
1513 &drawable->w,
1514 &drawable->h,
1515 *attachments,
1516 *count,
1517 count,
1518 drawable->loaderPrivate);
1519 if (!*buffers)
1520 return;
1521
1522 /*
1523 * I don't know how to recover from the failure assertion below.
1524 * Rather than fail gradually and unexpectedly, we should just die
1525 * now.
1526 */
1527 assert(*count == old_count + 1);
1528
1529 /* 5. Assign the DRI buffer's DRM region to the its renderbuffers. */
1530 __DRIbuffer *depth_stencil_buffer = NULL;
1531 for (int i = 0; i < *count; ++i) {
1532 if ((*buffers)[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
1533 depth_stencil_buffer = &(*buffers)[i];
1534 break;
1535 }
1536 }
1537 struct intel_region *region =
1538 intel_region_alloc_for_handle(intel->intelScreen,
1539 depth_stencil_buffer->cpp,
1540 drawable->w,
1541 drawable->h,
1542 depth_stencil_buffer->pitch
1543 / depth_stencil_buffer->cpp,
1544 depth_stencil_buffer->name,
1545 "dri2 depth / stencil buffer");
1546 intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_DEPTH)->region,
1547 region);
1548 intel_region_reference(&intel_get_renderbuffer(fb, BUFFER_STENCIL)->region,
1549 region);
1550 intel_region_release(&region);
1551 }
1552 }
1553
1554 if (intel_framebuffer_has_hiz(fb)) {
1555 /*
1556 * In the future, the driver may advertise a GL config with hiz
1557 * compatible depth bits and 0 stencil bits (for example, when the
1558 * driver gains support for float32 depth buffers). When that day comes,
1559 * here we need to verify that the X driver does in fact support hiz and
1560 * clean up if it doesn't.
1561 *
1562 * Presently, however, no verification or clean up is necessary, and
1563 * execution should not reach here. If the framebuffer still has a hiz
1564 * region, then we have already set dri2_has_hiz to true after
1565 * confirming above that the stencil buffer is W tiled.
1566 */
1567 assert(0);
1568 }
1569 }