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