i965/msaa: Allow GL_SAMPLES to be set to 1 prior to Gen6.
[mesa.git] / src / mesa / drivers / dri / intel / intel_fbo.c
1 /**************************************************************************
2 *
3 * Copyright 2006 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/enums.h"
30 #include "main/imports.h"
31 #include "main/macros.h"
32 #include "main/mfeatures.h"
33 #include "main/mtypes.h"
34 #include "main/fbobject.h"
35 #include "main/framebuffer.h"
36 #include "main/renderbuffer.h"
37 #include "main/context.h"
38 #include "main/teximage.h"
39 #include "main/image.h"
40
41 #include "swrast/swrast.h"
42 #include "drivers/common/meta.h"
43
44 #include "intel_context.h"
45 #include "intel_batchbuffer.h"
46 #include "intel_buffers.h"
47 #include "intel_blit.h"
48 #include "intel_fbo.h"
49 #include "intel_mipmap_tree.h"
50 #include "intel_regions.h"
51 #include "intel_tex.h"
52 #include "intel_span.h"
53 #ifndef I915
54 #include "brw_context.h"
55 #endif
56
57 #define FILE_DEBUG_FLAG DEBUG_FBO
58
59 static struct gl_renderbuffer *
60 intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
61
62 struct intel_region*
63 intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
64 {
65 struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
66 if (irb && irb->mt) {
67 if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
68 return irb->mt->stencil_mt->region;
69 else
70 return irb->mt->region;
71 } else
72 return NULL;
73 }
74
75 /**
76 * Create a new framebuffer object.
77 */
78 static struct gl_framebuffer *
79 intel_new_framebuffer(struct gl_context * ctx, GLuint name)
80 {
81 /* Only drawable state in intel_framebuffer at this time, just use Mesa's
82 * class
83 */
84 return _mesa_new_framebuffer(ctx, name);
85 }
86
87
88 /** Called by gl_renderbuffer::Delete() */
89 static void
90 intel_delete_renderbuffer(struct gl_renderbuffer *rb)
91 {
92 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
93
94 ASSERT(irb);
95
96 intel_miptree_release(&irb->mt);
97
98 free(irb);
99 }
100
101 /**
102 * \see dd_function_table::MapRenderbuffer
103 */
104 static void
105 intel_map_renderbuffer(struct gl_context *ctx,
106 struct gl_renderbuffer *rb,
107 GLuint x, GLuint y, GLuint w, GLuint h,
108 GLbitfield mode,
109 GLubyte **out_map,
110 GLint *out_stride)
111 {
112 struct intel_context *intel = intel_context(ctx);
113 struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
114 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
115 void *map;
116 int stride;
117
118 if (srb->Buffer) {
119 /* this is a malloc'd renderbuffer (accum buffer), not an irb */
120 GLint bpp = _mesa_get_format_bytes(rb->Format);
121 GLint rowStride = srb->RowStride;
122 *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
123 *out_stride = rowStride;
124 return;
125 }
126
127 /* We sometimes get called with this by our intel_span.c usage. */
128 if (!irb->mt) {
129 *out_map = NULL;
130 *out_stride = 0;
131 return;
132 }
133
134 /* For a window-system renderbuffer, we need to flip the mapping we receive
135 * upside-down. So we need to ask for a rectangle on flipped vertically, and
136 * we then return a pointer to the bottom of it with a negative stride.
137 */
138 if (rb->Name == 0) {
139 y = rb->Height - y - h;
140 }
141
142 intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
143 x, y, w, h, mode, &map, &stride);
144
145 if (rb->Name == 0) {
146 map += (h - 1) * stride;
147 stride = -stride;
148 }
149
150 DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
151 __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
152 x, y, w, h, map, stride);
153
154 *out_map = map;
155 *out_stride = stride;
156 }
157
158 /**
159 * \see dd_function_table::UnmapRenderbuffer
160 */
161 static void
162 intel_unmap_renderbuffer(struct gl_context *ctx,
163 struct gl_renderbuffer *rb)
164 {
165 struct intel_context *intel = intel_context(ctx);
166 struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
167 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
168
169 DBG("%s: rb %d (%s)\n", __FUNCTION__,
170 rb->Name, _mesa_get_format_name(rb->Format));
171
172 if (srb->Buffer) {
173 /* this is a malloc'd renderbuffer (accum buffer) */
174 /* nothing to do */
175 return;
176 }
177
178 intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
179 }
180
181
182 /**
183 * Round up the requested multisample count to the next supported sample size.
184 */
185 static unsigned
186 quantize_num_samples(struct intel_context *intel, unsigned num_samples)
187 {
188 switch (intel->gen) {
189 case 6:
190 /* Gen6 supports only 4x multisampling. */
191 if (num_samples > 0)
192 return 4;
193 else
194 return 0;
195 case 7:
196 /* Gen7 supports 4x and 8x multisampling. */
197 if (num_samples > 4)
198 return 8;
199 else if (num_samples > 0)
200 return 4;
201 else
202 return 0;
203 return 0;
204 default:
205 /* MSAA unsupported. However, a careful reading of
206 * EXT_framebuffer_multisample reveals that we need to permit
207 * num_samples to be 1 (since num_samples is permitted to be as high as
208 * GL_MAX_SAMPLES, and GL_MAX_SAMPLES must be at least 1). Since
209 * platforms before Gen6 don't support MSAA, this is safe, because
210 * multisampling won't happen anyhow.
211 */
212 if (num_samples > 0)
213 return 1;
214 return 0;
215 }
216 }
217
218
219 /**
220 * Called via glRenderbufferStorageEXT() to set the format and allocate
221 * storage for a user-created renderbuffer.
222 */
223 GLboolean
224 intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
225 GLenum internalFormat,
226 GLuint width, GLuint height)
227 {
228 struct intel_context *intel = intel_context(ctx);
229 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
230 rb->NumSamples = quantize_num_samples(intel, rb->NumSamples);
231
232 switch (internalFormat) {
233 default:
234 /* Use the same format-choice logic as for textures.
235 * Renderbuffers aren't any different from textures for us,
236 * except they're less useful because you can't texture with
237 * them.
238 */
239 rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
240 GL_NONE, GL_NONE);
241 break;
242 case GL_STENCIL_INDEX:
243 case GL_STENCIL_INDEX1_EXT:
244 case GL_STENCIL_INDEX4_EXT:
245 case GL_STENCIL_INDEX8_EXT:
246 case GL_STENCIL_INDEX16_EXT:
247 /* These aren't actual texture formats, so force them here. */
248 if (intel->has_separate_stencil) {
249 rb->Format = MESA_FORMAT_S8;
250 } else {
251 assert(!intel->must_use_separate_stencil);
252 rb->Format = MESA_FORMAT_S8_Z24;
253 }
254 break;
255 }
256
257 rb->Width = width;
258 rb->Height = height;
259 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
260
261 intel_miptree_release(&irb->mt);
262
263 DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
264 _mesa_lookup_enum_by_nr(internalFormat),
265 _mesa_get_format_name(rb->Format), width, height);
266
267 if (width == 0 || height == 0)
268 return true;
269
270 irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
271 width, height,
272 rb->NumSamples);
273 if (!irb->mt)
274 return false;
275
276 if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
277 bool ok = intel_miptree_alloc_hiz(intel, irb->mt, rb->NumSamples);
278 if (!ok) {
279 intel_miptree_release(&irb->mt);
280 return false;
281 }
282 }
283
284 if (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
285 bool ok = intel_miptree_alloc_mcs(intel, irb->mt, rb->NumSamples);
286 if (!ok) {
287 intel_miptree_release(&irb->mt);
288 return false;
289 }
290 }
291
292 return true;
293 }
294
295
296 #if FEATURE_OES_EGL_image
297 static void
298 intel_image_target_renderbuffer_storage(struct gl_context *ctx,
299 struct gl_renderbuffer *rb,
300 void *image_handle)
301 {
302 struct intel_context *intel = intel_context(ctx);
303 struct intel_renderbuffer *irb;
304 __DRIscreen *screen;
305 __DRIimage *image;
306
307 screen = intel->intelScreen->driScrnPriv;
308 image = screen->dri2.image->lookupEGLImage(screen, image_handle,
309 screen->loaderPrivate);
310 if (image == NULL)
311 return;
312
313 /* __DRIimage is opaque to the core so it has to be checked here */
314 switch (image->format) {
315 case MESA_FORMAT_RGBA8888_REV:
316 _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
317 "glEGLImageTargetRenderbufferStorage(unsupported image format");
318 return;
319 break;
320 default:
321 break;
322 }
323
324 irb = intel_renderbuffer(rb);
325 intel_miptree_release(&irb->mt);
326 irb->mt = intel_miptree_create_for_region(intel,
327 GL_TEXTURE_2D,
328 image->format,
329 image->region);
330 if (!irb->mt)
331 return;
332
333 rb->InternalFormat = image->internal_format;
334 rb->Width = image->region->width;
335 rb->Height = image->region->height;
336 rb->Format = image->format;
337 rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
338 image->internal_format);
339 }
340 #endif
341
342 /**
343 * Called for each hardware renderbuffer when a _window_ is resized.
344 * Just update fields.
345 * Not used for user-created renderbuffers!
346 */
347 static GLboolean
348 intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
349 GLenum internalFormat, GLuint width, GLuint height)
350 {
351 ASSERT(rb->Name == 0);
352 rb->Width = width;
353 rb->Height = height;
354 rb->InternalFormat = internalFormat;
355
356 return true;
357 }
358
359
360 static void
361 intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
362 GLuint width, GLuint height)
363 {
364 int i;
365
366 _mesa_resize_framebuffer(ctx, fb, width, height);
367
368 fb->Initialized = true; /* XXX remove someday */
369
370 if (_mesa_is_user_fbo(fb)) {
371 return;
372 }
373
374
375 /* Make sure all window system renderbuffers are up to date */
376 for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
377 struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
378
379 /* only resize if size is changing */
380 if (rb && (rb->Width != width || rb->Height != height)) {
381 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
382 }
383 }
384 }
385
386
387 /** Dummy function for gl_renderbuffer::AllocStorage() */
388 static GLboolean
389 intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
390 GLenum internalFormat, GLuint width, GLuint height)
391 {
392 _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
393 return false;
394 }
395
396 /**
397 * Create a new intel_renderbuffer which corresponds to an on-screen window,
398 * not a user-created renderbuffer.
399 */
400 struct intel_renderbuffer *
401 intel_create_renderbuffer(gl_format format)
402 {
403 struct intel_renderbuffer *irb;
404 struct gl_renderbuffer *rb;
405
406 GET_CURRENT_CONTEXT(ctx);
407
408 irb = CALLOC_STRUCT(intel_renderbuffer);
409 if (!irb) {
410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
411 return NULL;
412 }
413
414 rb = &irb->Base.Base;
415
416 _mesa_init_renderbuffer(rb, 0);
417 rb->ClassID = INTEL_RB_CLASS;
418 rb->_BaseFormat = _mesa_get_format_base_format(format);
419 rb->Format = format;
420 rb->InternalFormat = rb->_BaseFormat;
421
422 /* intel-specific methods */
423 rb->Delete = intel_delete_renderbuffer;
424 rb->AllocStorage = intel_alloc_window_storage;
425
426 return irb;
427 }
428
429 /**
430 * Private window-system buffers (as opposed to ones shared with the display
431 * server created with intel_create_renderbuffer()) are most similar in their
432 * handling to user-created renderbuffers, but they have a resize handler that
433 * may be called at intel_update_renderbuffers() time.
434 */
435 struct intel_renderbuffer *
436 intel_create_private_renderbuffer(gl_format format)
437 {
438 struct intel_renderbuffer *irb;
439
440 irb = intel_create_renderbuffer(format);
441 irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage;
442
443 return irb;
444 }
445
446 /**
447 * Create a new renderbuffer object.
448 * Typically called via glBindRenderbufferEXT().
449 */
450 static struct gl_renderbuffer *
451 intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
452 {
453 /*struct intel_context *intel = intel_context(ctx); */
454 struct intel_renderbuffer *irb;
455 struct gl_renderbuffer *rb;
456
457 irb = CALLOC_STRUCT(intel_renderbuffer);
458 if (!irb) {
459 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
460 return NULL;
461 }
462
463 rb = &irb->Base.Base;
464
465 _mesa_init_renderbuffer(rb, name);
466 rb->ClassID = INTEL_RB_CLASS;
467
468 /* intel-specific methods */
469 rb->Delete = intel_delete_renderbuffer;
470 rb->AllocStorage = intel_alloc_renderbuffer_storage;
471 /* span routines set in alloc_storage function */
472
473 return rb;
474 }
475
476
477 /**
478 * Called via glBindFramebufferEXT().
479 */
480 static void
481 intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
482 struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
483 {
484 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
485 intel_draw_buffer(ctx);
486 }
487 else {
488 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
489 }
490 }
491
492
493 /**
494 * Called via glFramebufferRenderbufferEXT().
495 */
496 static void
497 intel_framebuffer_renderbuffer(struct gl_context * ctx,
498 struct gl_framebuffer *fb,
499 GLenum attachment, struct gl_renderbuffer *rb)
500 {
501 DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
502
503 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
504 intel_draw_buffer(ctx);
505 }
506
507 /**
508 * \par Special case for separate stencil
509 *
510 * When wrapping a depthstencil texture that uses separate stencil, this
511 * function is recursively called twice: once to create \c
512 * irb->wrapped_depth and again to create \c irb->wrapped_stencil. On the
513 * call to create \c irb->wrapped_depth, the \c format and \c
514 * internal_format parameters do not match \c mt->format. In that case, \c
515 * mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
516 * MESA_FORMAT_X8_Z24.
517 *
518 * @return true on success
519 */
520
521 static bool
522 intel_renderbuffer_update_wrapper(struct intel_context *intel,
523 struct intel_renderbuffer *irb,
524 struct gl_texture_image *image,
525 uint32_t layer)
526 {
527 struct gl_renderbuffer *rb = &irb->Base.Base;
528 struct intel_texture_image *intel_image = intel_texture_image(image);
529 struct intel_mipmap_tree *mt = intel_image->mt;
530 int level = image->Level;
531
532 rb->Format = image->TexFormat;
533 rb->InternalFormat = image->InternalFormat;
534 rb->_BaseFormat = image->_BaseFormat;
535 rb->Width = mt->level[level].width;
536 rb->Height = mt->level[level].height;
537
538 rb->Delete = intel_delete_renderbuffer;
539 rb->AllocStorage = intel_nop_alloc_storage;
540
541 intel_miptree_check_level_layer(mt, level, layer);
542 irb->mt_level = level;
543 irb->mt_layer = layer;
544
545 intel_miptree_reference(&irb->mt, mt);
546
547 intel_renderbuffer_set_draw_offset(irb);
548
549 if (mt->hiz_mt == NULL &&
550 intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
551 intel_miptree_alloc_hiz(intel, mt, 0 /* num_samples */);
552 if (!mt->hiz_mt)
553 return false;
554 }
555
556 return true;
557 }
558
559 void
560 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
561 {
562 unsigned int dst_x, dst_y;
563
564 /* compute offset of the particular 2D image within the texture region */
565 intel_miptree_get_image_offset(irb->mt,
566 irb->mt_level,
567 0, /* face, which we ignore */
568 irb->mt_layer,
569 &dst_x, &dst_y);
570
571 irb->draw_x = dst_x;
572 irb->draw_y = dst_y;
573 }
574
575 /**
576 * Rendering to tiled buffers requires that the base address of the
577 * buffer be aligned to a page boundary. We generally render to
578 * textures by pointing the surface at the mipmap image level, which
579 * may not be aligned to a tile boundary.
580 *
581 * This function returns an appropriately-aligned base offset
582 * according to the tiling restrictions, plus any required x/y offset
583 * from there.
584 */
585 uint32_t
586 intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
587 uint32_t *tile_x,
588 uint32_t *tile_y)
589 {
590 struct intel_region *region = irb->mt->region;
591 uint32_t mask_x, mask_y;
592
593 intel_region_get_tile_masks(region, &mask_x, &mask_y);
594
595 *tile_x = irb->draw_x & mask_x;
596 *tile_y = irb->draw_y & mask_y;
597 return intel_region_get_aligned_offset(region, irb->draw_x & ~mask_x,
598 irb->draw_y & ~mask_y);
599 }
600
601 /**
602 * Called by glFramebufferTexture[123]DEXT() (and other places) to
603 * prepare for rendering into texture memory. This might be called
604 * many times to choose different texture levels, cube faces, etc
605 * before intel_finish_render_texture() is ever called.
606 */
607 static void
608 intel_render_texture(struct gl_context * ctx,
609 struct gl_framebuffer *fb,
610 struct gl_renderbuffer_attachment *att)
611 {
612 struct intel_context *intel = intel_context(ctx);
613 struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
614 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
615 struct intel_texture_image *intel_image = intel_texture_image(image);
616 struct intel_mipmap_tree *mt = intel_image->mt;
617 int layer;
618
619 (void) fb;
620
621 if (att->CubeMapFace > 0) {
622 assert(att->Zoffset == 0);
623 layer = att->CubeMapFace;
624 } else {
625 layer = att->Zoffset;
626 }
627
628 if (!intel_image->mt) {
629 /* Fallback on drawing to a texture that doesn't have a miptree
630 * (has a border, width/height 0, etc.)
631 */
632 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
633 _swrast_render_texture(ctx, fb, att);
634 return;
635 }
636 else if (!irb) {
637 intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
638
639 irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
640
641 if (irb) {
642 /* bind the wrapper to the attachment point */
643 _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
644 }
645 else {
646 /* fallback to software rendering */
647 _swrast_render_texture(ctx, fb, att);
648 return;
649 }
650 }
651
652 if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
653 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
654 _swrast_render_texture(ctx, fb, att);
655 return;
656 }
657
658 irb->tex_image = image;
659
660 DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
661 _mesa_get_format_name(image->TexFormat),
662 att->Texture->Name, image->Width, image->Height,
663 irb->Base.Base.RefCount);
664
665 /* update drawing region, etc */
666 intel_draw_buffer(ctx);
667 }
668
669
670 /**
671 * Called by Mesa when rendering to a texture is done.
672 */
673 static void
674 intel_finish_render_texture(struct gl_context * ctx,
675 struct gl_renderbuffer_attachment *att)
676 {
677 struct intel_context *intel = intel_context(ctx);
678 struct gl_texture_object *tex_obj = att->Texture;
679 struct gl_texture_image *image =
680 tex_obj->Image[att->CubeMapFace][att->TextureLevel];
681 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
682
683 DBG("Finish render %s texture tex=%u\n",
684 _mesa_get_format_name(image->TexFormat), att->Texture->Name);
685
686 if (irb)
687 irb->tex_image = NULL;
688
689 /* Since we've (probably) rendered to the texture and will (likely) use
690 * it in the texture domain later on in this batchbuffer, flush the
691 * batch. Once again, we wish for a domain tracker in libdrm to cover
692 * usage inside of a batchbuffer like GEM does in the kernel.
693 */
694 intel_batchbuffer_emit_mi_flush(intel);
695 }
696
697 /**
698 * Do additional "completeness" testing of a framebuffer object.
699 */
700 static void
701 intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
702 {
703 struct intel_context *intel = intel_context(ctx);
704 const struct intel_renderbuffer *depthRb =
705 intel_get_renderbuffer(fb, BUFFER_DEPTH);
706 const struct intel_renderbuffer *stencilRb =
707 intel_get_renderbuffer(fb, BUFFER_STENCIL);
708 struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
709 int i;
710
711 DBG("%s() on fb %p (%s)\n", __FUNCTION__,
712 fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
713 (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer")));
714
715 if (depthRb)
716 depth_mt = depthRb->mt;
717 if (stencilRb) {
718 stencil_mt = stencilRb->mt;
719 if (stencil_mt->stencil_mt)
720 stencil_mt = stencil_mt->stencil_mt;
721 }
722
723 if (depth_mt && stencil_mt) {
724 if (depth_mt == stencil_mt) {
725 /* For true packed depth/stencil (not faked on prefers-separate-stencil
726 * hardware) we need to be sure they're the same level/layer, since
727 * we'll be emitting a single packet describing the packed setup.
728 */
729 if (depthRb->mt_level != stencilRb->mt_level ||
730 depthRb->mt_layer != stencilRb->mt_layer) {
731 DBG("depth image level/layer %d/%d != stencil image %d/%d\n",
732 depthRb->mt_level,
733 depthRb->mt_layer,
734 stencilRb->mt_level,
735 stencilRb->mt_layer);
736 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
737 }
738 } else {
739 if (!intel->has_separate_stencil) {
740 DBG("separate stencil unsupported\n");
741 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
742 }
743 if (stencil_mt->format != MESA_FORMAT_S8) {
744 DBG("separate stencil is %s instead of S8\n",
745 _mesa_get_format_name(stencil_mt->format));
746 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
747 }
748 if (intel->gen < 7 && depth_mt->hiz_mt == NULL) {
749 /* Before Gen7, separate depth and stencil buffers can be used
750 * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
751 * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
752 * [DevSNB]: This field must be set to the same value (enabled
753 * or disabled) as Hierarchical Depth Buffer Enable.
754 */
755 DBG("separate stencil without HiZ\n");
756 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
757 }
758 }
759 }
760
761 for (i = 0; i < Elements(fb->Attachment); i++) {
762 struct gl_renderbuffer *rb;
763 struct intel_renderbuffer *irb;
764
765 if (fb->Attachment[i].Type == GL_NONE)
766 continue;
767
768 /* A supported attachment will have a Renderbuffer set either
769 * from being a Renderbuffer or being a texture that got the
770 * intel_wrap_texture() treatment.
771 */
772 rb = fb->Attachment[i].Renderbuffer;
773 if (rb == NULL) {
774 DBG("attachment without renderbuffer\n");
775 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
776 continue;
777 }
778
779 if (fb->Attachment[i].Type == GL_TEXTURE) {
780 const struct gl_texture_image *img =
781 _mesa_get_attachment_teximage_const(&fb->Attachment[i]);
782
783 if (img->Border) {
784 DBG("texture with border\n");
785 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
786 continue;
787 }
788 }
789
790 irb = intel_renderbuffer(rb);
791 if (irb == NULL) {
792 DBG("software rendering renderbuffer\n");
793 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
794 continue;
795 }
796
797 if (!intel->vtbl.render_target_supported(intel, rb)) {
798 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
799 _mesa_get_format_name(intel_rb_format(irb)));
800 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
801 }
802 }
803 }
804
805 /**
806 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
807 * We can do this when the dst renderbuffer is actually a texture and
808 * there is no scaling, mirroring or scissoring.
809 *
810 * \return new buffer mask indicating the buffers left to blit using the
811 * normal path.
812 */
813 static GLbitfield
814 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
815 GLint srcX0, GLint srcY0,
816 GLint srcX1, GLint srcY1,
817 GLint dstX0, GLint dstY0,
818 GLint dstX1, GLint dstY1,
819 GLbitfield mask, GLenum filter)
820 {
821 if (mask & GL_COLOR_BUFFER_BIT) {
822 const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
823 const struct gl_framebuffer *readFb = ctx->ReadBuffer;
824 const struct gl_renderbuffer_attachment *drawAtt =
825 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
826 struct intel_renderbuffer *srcRb =
827 intel_renderbuffer(readFb->_ColorReadBuffer);
828
829 /* If the source and destination are the same size with no
830 mirroring, the rectangles are within the size of the
831 texture and there is no scissor then we can use
832 glCopyTexSubimage2D to implement the blit. This will end
833 up as a fast hardware blit on some drivers */
834 if (srcRb && drawAtt && drawAtt->Texture &&
835 srcX0 - srcX1 == dstX0 - dstX1 &&
836 srcY0 - srcY1 == dstY0 - dstY1 &&
837 srcX1 >= srcX0 &&
838 srcY1 >= srcY0 &&
839 srcX0 >= 0 && srcX1 <= readFb->Width &&
840 srcY0 >= 0 && srcY1 <= readFb->Height &&
841 dstX0 >= 0 && dstX1 <= drawFb->Width &&
842 dstY0 >= 0 && dstY1 <= drawFb->Height &&
843 !ctx->Scissor.Enabled) {
844 const struct gl_texture_object *texObj = drawAtt->Texture;
845 const GLuint dstLevel = drawAtt->TextureLevel;
846 const GLenum target = texObj->Target;
847
848 struct gl_texture_image *texImage =
849 _mesa_select_tex_image(ctx, texObj, target, dstLevel);
850
851 if (intel_copy_texsubimage(intel_context(ctx),
852 intel_texture_image(texImage),
853 dstX0, dstY0,
854 srcRb,
855 srcX0, srcY0,
856 srcX1 - srcX0, /* width */
857 srcY1 - srcY0))
858 mask &= ~GL_COLOR_BUFFER_BIT;
859 }
860 }
861
862 return mask;
863 }
864
865 static void
866 intel_blit_framebuffer(struct gl_context *ctx,
867 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
868 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
869 GLbitfield mask, GLenum filter)
870 {
871 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
872 mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
873 srcX0, srcY0, srcX1, srcY1,
874 dstX0, dstY0, dstX1, dstY1,
875 mask, filter);
876 if (mask == 0x0)
877 return;
878
879 #ifndef I915
880 mask = brw_blorp_framebuffer(intel_context(ctx),
881 srcX0, srcY0, srcX1, srcY1,
882 dstX0, dstY0, dstX1, dstY1,
883 mask, filter);
884 if (mask == 0x0)
885 return;
886 #endif
887
888 _mesa_meta_BlitFramebuffer(ctx,
889 srcX0, srcY0, srcX1, srcY1,
890 dstX0, dstY0, dstX1, dstY1,
891 mask, filter);
892 }
893
894 void
895 intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
896 {
897 if (irb->mt) {
898 intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
899 irb->mt_level,
900 irb->mt_layer);
901 }
902 }
903
904 void
905 intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
906 {
907 if (irb->mt) {
908 intel_miptree_slice_set_needs_depth_resolve(irb->mt,
909 irb->mt_level,
910 irb->mt_layer);
911 }
912 }
913
914 bool
915 intel_renderbuffer_resolve_hiz(struct intel_context *intel,
916 struct intel_renderbuffer *irb)
917 {
918 if (irb->mt)
919 return intel_miptree_slice_resolve_hiz(intel,
920 irb->mt,
921 irb->mt_level,
922 irb->mt_layer);
923
924 return false;
925 }
926
927 bool
928 intel_renderbuffer_resolve_depth(struct intel_context *intel,
929 struct intel_renderbuffer *irb)
930 {
931 if (irb->mt)
932 return intel_miptree_slice_resolve_depth(intel,
933 irb->mt,
934 irb->mt_level,
935 irb->mt_layer);
936
937 return false;
938 }
939
940 /**
941 * Do one-time context initializations related to GL_EXT_framebuffer_object.
942 * Hook in device driver functions.
943 */
944 void
945 intel_fbo_init(struct intel_context *intel)
946 {
947 intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
948 intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
949 intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
950 intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
951 intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
952 intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
953 intel->ctx.Driver.RenderTexture = intel_render_texture;
954 intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
955 intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
956 intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
957 intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
958
959 #if FEATURE_OES_EGL_image
960 intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
961 intel_image_target_renderbuffer_storage;
962 #endif
963 }