i965: Fix emit of a MOV with bad destination channel on gen6 math in FPs.
[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
60 bool
61 intel_framebuffer_has_hiz(struct gl_framebuffer *fb)
62 {
63 struct intel_renderbuffer *rb = NULL;
64 if (fb)
65 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
66 return rb && rb->mt && rb->mt->hiz_mt;
67 }
68
69 struct intel_region*
70 intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
71 {
72 struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
73 if (irb && irb->mt)
74 return irb->mt->region;
75 else
76 return NULL;
77 }
78
79 /**
80 * Create a new framebuffer object.
81 */
82 static struct gl_framebuffer *
83 intel_new_framebuffer(struct gl_context * ctx, GLuint name)
84 {
85 /* Only drawable state in intel_framebuffer at this time, just use Mesa's
86 * class
87 */
88 return _mesa_new_framebuffer(ctx, name);
89 }
90
91
92 /** Called by gl_renderbuffer::Delete() */
93 static void
94 intel_delete_renderbuffer(struct gl_renderbuffer *rb)
95 {
96 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
97
98 ASSERT(irb);
99
100 intel_miptree_release(&irb->mt);
101
102 _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
103 _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
104
105 free(irb);
106 }
107
108 /**
109 * \brief Map a renderbuffer through the GTT.
110 *
111 * \see intel_map_renderbuffer()
112 */
113 static void
114 intel_map_renderbuffer_gtt(struct gl_context *ctx,
115 struct gl_renderbuffer *rb,
116 GLuint x, GLuint y, GLuint w, GLuint h,
117 GLbitfield mode,
118 GLubyte **out_map,
119 GLint *out_stride)
120 {
121 struct intel_context *intel = intel_context(ctx);
122 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
123 GLubyte *map;
124 int stride, flip_stride;
125
126 assert(irb->mt);
127
128 intel_renderbuffer_resolve_depth(intel, irb);
129 if (mode & GL_MAP_WRITE_BIT) {
130 intel_renderbuffer_set_needs_hiz_resolve(irb);
131 }
132
133 irb->map_mode = mode;
134 irb->map_x = x;
135 irb->map_y = y;
136 irb->map_w = w;
137 irb->map_h = h;
138
139 stride = irb->mt->region->pitch * irb->mt->region->cpp;
140
141 if (rb->Name == 0) {
142 y = irb->mt->region->height - 1 - y;
143 flip_stride = -stride;
144 } else {
145 x += irb->draw_x;
146 y += irb->draw_y;
147 flip_stride = stride;
148 }
149
150 if (drm_intel_bo_references(intel->batch.bo, irb->mt->region->bo)) {
151 intel_batchbuffer_flush(intel);
152 }
153
154 drm_intel_gem_bo_map_gtt(irb->mt->region->bo);
155
156 map = irb->mt->region->bo->virtual;
157 map += x * irb->mt->region->cpp;
158 map += (int)y * stride;
159
160 *out_map = map;
161 *out_stride = flip_stride;
162
163 DBG("%s: rb %d (%s) gtt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
164 __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
165 x, y, w, h, *out_map, *out_stride);
166 }
167
168 /**
169 * \brief Map a renderbuffer by blitting it to a temporary gem buffer.
170 *
171 * On gen6+, we have LLC sharing, which means we can get high-performance
172 * access to linear-mapped buffers.
173 *
174 * This function allocates a temporary gem buffer at
175 * intel_renderbuffer::map_bo, then blits the renderbuffer into it, and
176 * returns a map of that. (Note: Only X tiled buffers can be blitted).
177 *
178 * \see intel_renderbuffer::map_bo
179 * \see intel_map_renderbuffer()
180 */
181 static void
182 intel_map_renderbuffer_blit(struct gl_context *ctx,
183 struct gl_renderbuffer *rb,
184 GLuint x, GLuint y, GLuint w, GLuint h,
185 GLbitfield mode,
186 GLubyte **out_map,
187 GLint *out_stride)
188 {
189 struct intel_context *intel = intel_context(ctx);
190 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
191
192 int src_x, src_y;
193 int dst_stride;
194
195 assert(irb->mt->region);
196 assert(intel->gen >= 6);
197 assert(!(mode & GL_MAP_WRITE_BIT));
198 assert(irb->mt->region->tiling == I915_TILING_X);
199
200 irb->map_mode = mode;
201 irb->map_x = x;
202 irb->map_y = y;
203 irb->map_w = w;
204 irb->map_h = h;
205
206 dst_stride = ALIGN(w * irb->mt->region->cpp, 4);
207
208 if (rb->Name) {
209 src_x = x + irb->draw_x;
210 src_y = y + irb->draw_y;
211 } else {
212 src_x = x;
213 src_y = irb->mt->region->height - y - h;
214 }
215
216 irb->map_bo = drm_intel_bo_alloc(intel->bufmgr, "MapRenderbuffer() temp",
217 dst_stride * h, 4096);
218
219 /* We don't do the flip in the blit, because it's always so tricky to get
220 * right.
221 */
222 if (irb->map_bo &&
223 intelEmitCopyBlit(intel,
224 irb->mt->region->cpp,
225 irb->mt->region->pitch, irb->mt->region->bo,
226 0, irb->mt->region->tiling,
227 dst_stride / irb->mt->region->cpp, irb->map_bo,
228 0, I915_TILING_NONE,
229 src_x, src_y,
230 0, 0,
231 w, h,
232 GL_COPY)) {
233 intel_batchbuffer_flush(intel);
234 drm_intel_bo_map(irb->map_bo, false);
235
236 if (rb->Name) {
237 *out_map = irb->map_bo->virtual;
238 *out_stride = dst_stride;
239 } else {
240 *out_map = irb->map_bo->virtual + (h - 1) * dst_stride;
241 *out_stride = -dst_stride;
242 }
243
244 DBG("%s: rb %d (%s) blit mapped: (%d, %d) (%dx%d) -> %p/%d\n",
245 __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
246 src_x, src_y, w, h, *out_map, *out_stride);
247 } else {
248 /* Fallback to GTT mapping. */
249 drm_intel_bo_unreference(irb->map_bo);
250 irb->map_bo = NULL;
251 intel_map_renderbuffer_gtt(ctx, rb,
252 x, y, w, h,
253 mode,
254 out_map, out_stride);
255 }
256 }
257
258 /**
259 * \brief Map a stencil renderbuffer.
260 *
261 * Stencil buffers are W-tiled. Since the GTT has no W fence, we must detile
262 * the buffer in software.
263 *
264 * This function allocates a temporary malloc'd buffer at
265 * intel_renderbuffer::map_buffer, detiles the stencil buffer into it, then
266 * returns the temporary buffer as the map.
267 *
268 * \see intel_renderbuffer::map_buffer
269 * \see intel_map_renderbuffer()
270 * \see intel_unmap_renderbuffer_s8()
271 */
272 static void
273 intel_map_renderbuffer_s8(struct gl_context *ctx,
274 struct gl_renderbuffer *rb,
275 GLuint x, GLuint y, GLuint w, GLuint h,
276 GLbitfield mode,
277 GLubyte **out_map,
278 GLint *out_stride)
279 {
280 struct intel_context *intel = intel_context(ctx);
281 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
282 uint8_t *tiled_s8_map;
283 uint8_t *untiled_s8_map;
284
285 assert(rb->Format == MESA_FORMAT_S8);
286 assert(irb->mt);
287
288 irb->map_mode = mode;
289 irb->map_x = x;
290 irb->map_y = y;
291 irb->map_w = w;
292 irb->map_h = h;
293
294 /* Flip the Y axis for the default framebuffer. */
295 int y_flip = (rb->Name == 0) ? -1 : 1;
296 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
297
298 irb->map_buffer = malloc(w * h);
299 untiled_s8_map = irb->map_buffer;
300 tiled_s8_map = intel_region_map(intel, irb->mt->region, mode);
301
302 for (uint32_t pix_y = 0; pix_y < h; pix_y++) {
303 for (uint32_t pix_x = 0; pix_x < w; pix_x++) {
304 uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias;
305 ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
306 x + pix_x,
307 flipped_y);
308 untiled_s8_map[pix_y * w + pix_x] = tiled_s8_map[offset];
309 }
310 }
311
312 *out_map = untiled_s8_map;
313 *out_stride = w;
314
315 DBG("%s: rb %d (%s) s8 detiled mapped: (%d, %d) (%dx%d) -> %p/%d\n",
316 __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
317 x, y, w, h, *out_map, *out_stride);
318 }
319
320 /**
321 * \brief Map a depthstencil buffer with separate stencil.
322 *
323 * A depthstencil renderbuffer, if using separate stencil, consists of a depth
324 * renderbuffer and a hidden stencil renderbuffer. This function maps the
325 * depth buffer, whose format is MESA_FORMAT_X8_Z24, through the GTT and
326 * returns that as the mapped pointer. The caller need not be aware of the
327 * hidden stencil buffer and may safely assume that the mapped pointer points
328 * to a MESA_FORMAT_S8_Z24 buffer
329 *
330 * The consistency between the depth buffer's S8 bits and the hidden stencil
331 * buffer is managed within intel_map_renderbuffer() and
332 * intel_unmap_renderbuffer() by scattering or gathering the stencil bits
333 * according to the map mode.
334 *
335 * \see intel_map_renderbuffer()
336 * \see intel_unmap_renderbuffer_separate_s8z24()
337 */
338 static void
339 intel_map_renderbuffer_separate_s8z24(struct gl_context *ctx,
340 struct gl_renderbuffer *rb,
341 GLuint x, GLuint y, GLuint w, GLuint h,
342 GLbitfield mode,
343 GLubyte **out_map,
344 GLint *out_stride)
345 {
346 struct intel_context *intel = intel_context(ctx);
347 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
348
349 uint8_t *s8z24_map;
350 int32_t s8z24_stride;
351
352 struct intel_renderbuffer *s8_irb;
353 uint8_t *s8_map;
354
355 assert(rb->Name != 0);
356 assert(rb->Format == MESA_FORMAT_S8_Z24);
357 assert(irb->wrapped_depth != NULL);
358 assert(irb->wrapped_stencil != NULL);
359
360 irb->map_mode = mode;
361 irb->map_x = x;
362 irb->map_y = y;
363 irb->map_w = w;
364 irb->map_h = h;
365
366 /* Map with write mode for the gather below. */
367 intel_map_renderbuffer_gtt(ctx, irb->wrapped_depth,
368 x, y, w, h, mode | GL_MAP_WRITE_BIT,
369 &s8z24_map, &s8z24_stride);
370
371 s8_irb = intel_renderbuffer(irb->wrapped_stencil);
372 s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_READ_BIT);
373
374 /* Gather the stencil buffer into the depth buffer. */
375 for (uint32_t pix_y = 0; pix_y < h; ++pix_y) {
376 for (uint32_t pix_x = 0; pix_x < w; ++pix_x) {
377 ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch,
378 x + pix_x,
379 y + pix_y);
380 ptrdiff_t s8z24_offset = pix_y * s8z24_stride
381 + pix_x * 4
382 + 3;
383 s8z24_map[s8z24_offset] = s8_map[s8_offset];
384 }
385 }
386
387 intel_region_unmap(intel, s8_irb->mt->region);
388
389 *out_map = s8z24_map;
390 *out_stride = s8z24_stride;
391 }
392
393 /**
394 * \see dd_function_table::MapRenderbuffer
395 */
396 static void
397 intel_map_renderbuffer(struct gl_context *ctx,
398 struct gl_renderbuffer *rb,
399 GLuint x, GLuint y, GLuint w, GLuint h,
400 GLbitfield mode,
401 GLubyte **out_map,
402 GLint *out_stride)
403 {
404 struct intel_context *intel = intel_context(ctx);
405 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
406
407 /* We sometimes get called with this by our intel_span.c usage. */
408 if (!irb->mt && !irb->wrapped_depth) {
409 *out_map = NULL;
410 *out_stride = 0;
411 return;
412 }
413
414 if (rb->Format == MESA_FORMAT_S8) {
415 intel_map_renderbuffer_s8(ctx, rb, x, y, w, h, mode,
416 out_map, out_stride);
417 } else if (irb->wrapped_depth) {
418 intel_map_renderbuffer_separate_s8z24(ctx, rb, x, y, w, h, mode,
419 out_map, out_stride);
420 } else if (intel->gen >= 6 &&
421 !(mode & GL_MAP_WRITE_BIT) &&
422 irb->mt->region->tiling == I915_TILING_X) {
423 intel_map_renderbuffer_blit(ctx, rb, x, y, w, h, mode,
424 out_map, out_stride);
425 } else {
426 intel_map_renderbuffer_gtt(ctx, rb, x, y, w, h, mode,
427 out_map, out_stride);
428 }
429 }
430
431 /**
432 * \see intel_map_renderbuffer_s8()
433 */
434 static void
435 intel_unmap_renderbuffer_s8(struct gl_context *ctx,
436 struct gl_renderbuffer *rb)
437 {
438 struct intel_context *intel = intel_context(ctx);
439 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
440
441 DBG("%s: rb %d (%s)\n", __FUNCTION__,
442 rb->Name, _mesa_get_format_name(rb->Format));
443
444 assert(rb->Format == MESA_FORMAT_S8);
445
446 if (!irb->map_buffer)
447 return;
448
449 if (irb->map_mode & GL_MAP_WRITE_BIT) {
450 /* The temporary buffer was written to, so we must copy its pixels into
451 * the real buffer.
452 */
453 uint8_t *untiled_s8_map = irb->map_buffer;
454 uint8_t *tiled_s8_map = irb->mt->region->bo->virtual;
455
456 /* Flip the Y axis for the default framebuffer. */
457 int y_flip = (rb->Name == 0) ? -1 : 1;
458 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0;
459
460 for (uint32_t pix_y = 0; pix_y < irb->map_h; pix_y++) {
461 for (uint32_t pix_x = 0; pix_x < irb->map_w; pix_x++) {
462 uint32_t flipped_y = y_flip * (int32_t)(pix_y + irb->map_y) + y_bias;
463 ptrdiff_t offset = intel_offset_S8(irb->mt->region->pitch,
464 pix_x + irb->map_x,
465 flipped_y);
466 tiled_s8_map[offset] =
467 untiled_s8_map[pix_y * irb->map_w + pix_x];
468 }
469 }
470 }
471
472 intel_region_unmap(intel, irb->mt->region);
473 free(irb->map_buffer);
474 irb->map_buffer = NULL;
475 }
476
477 /**
478 * \brief Unmap a depthstencil renderbuffer with separate stencil.
479 *
480 * \see intel_map_renderbuffer_separate_s8z24()
481 * \see intel_unmap_renderbuffer()
482 */
483 static void
484 intel_unmap_renderbuffer_separate_s8z24(struct gl_context *ctx,
485 struct gl_renderbuffer *rb)
486 {
487 struct intel_context *intel = intel_context(ctx);
488 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
489 struct intel_renderbuffer *s8z24_irb;
490
491 assert(rb->Name != 0);
492 assert(rb->Format == MESA_FORMAT_S8_Z24);
493 assert(irb->wrapped_depth != NULL);
494 assert(irb->wrapped_stencil != NULL);
495
496 s8z24_irb = intel_renderbuffer(irb->wrapped_depth);
497
498 if (irb->map_mode & GL_MAP_WRITE_BIT) {
499 /* Copy the stencil bits from the depth buffer into the stencil buffer.
500 */
501 uint32_t map_x = irb->map_x;
502 uint32_t map_y = irb->map_y;
503 uint32_t map_w = irb->map_w;
504 uint32_t map_h = irb->map_h;
505
506 struct intel_renderbuffer *s8_irb;
507 uint8_t *s8_map;
508
509 s8_irb = intel_renderbuffer(irb->wrapped_stencil);
510 s8_map = intel_region_map(intel, s8_irb->mt->region, GL_MAP_WRITE_BIT);
511
512 int32_t s8z24_stride = 4 * s8z24_irb->mt->region->pitch;
513 uint8_t *s8z24_map = s8z24_irb->mt->region->bo->virtual
514 + map_y * s8z24_stride
515 + map_x * 4;
516
517 for (uint32_t pix_y = 0; pix_y < map_h; ++pix_y) {
518 for (uint32_t pix_x = 0; pix_x < map_w; ++pix_x) {
519 ptrdiff_t s8_offset = intel_offset_S8(s8_irb->mt->region->pitch,
520 map_x + pix_x,
521 map_y + pix_y);
522 ptrdiff_t s8z24_offset = pix_y * s8z24_stride
523 + pix_x * 4
524 + 3;
525 s8_map[s8_offset] = s8z24_map[s8z24_offset];
526 }
527 }
528
529 intel_region_unmap(intel, s8_irb->mt->region);
530 }
531
532 drm_intel_gem_bo_unmap_gtt(s8z24_irb->mt->region->bo);
533 }
534
535 /**
536 * \see dd_function_table::UnmapRenderbuffer
537 */
538 static void
539 intel_unmap_renderbuffer(struct gl_context *ctx,
540 struct gl_renderbuffer *rb)
541 {
542 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
543
544 DBG("%s: rb %d (%s)\n", __FUNCTION__,
545 rb->Name, _mesa_get_format_name(rb->Format));
546
547 if (rb->Format == MESA_FORMAT_S8) {
548 intel_unmap_renderbuffer_s8(ctx, rb);
549 } else if (irb->wrapped_depth) {
550 intel_unmap_renderbuffer_separate_s8z24(ctx, rb);
551 } else if (irb->map_bo) {
552 /* Paired with intel_map_renderbuffer_blit(). */
553 drm_intel_bo_unmap(irb->map_bo);
554 drm_intel_bo_unreference(irb->map_bo);
555 irb->map_bo = 0;
556 } else {
557 /* Paired with intel_map_renderbuffer_gtt(). */
558 if (irb->mt) {
559 /* The miptree may be null when intel_map_renderbuffer() is
560 * called from intel_span.c.
561 */
562 drm_intel_gem_bo_unmap_gtt(irb->mt->region->bo);
563 }
564 }
565 }
566
567 /**
568 * Return a pointer to a specific pixel in a renderbuffer.
569 */
570 static void *
571 intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb,
572 GLint x, GLint y)
573 {
574 /* By returning NULL we force all software rendering to go through
575 * the span routines.
576 */
577 return NULL;
578 }
579
580
581 /**
582 * Called via glRenderbufferStorageEXT() to set the format and allocate
583 * storage for a user-created renderbuffer.
584 */
585 GLboolean
586 intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
587 GLenum internalFormat,
588 GLuint width, GLuint height)
589 {
590 struct intel_context *intel = intel_context(ctx);
591 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
592 int cpp, tiling;
593
594 ASSERT(rb->Name != 0);
595
596 switch (internalFormat) {
597 default:
598 /* Use the same format-choice logic as for textures.
599 * Renderbuffers aren't any different from textures for us,
600 * except they're less useful because you can't texture with
601 * them.
602 */
603 rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat,
604 GL_NONE, GL_NONE);
605 break;
606 case GL_STENCIL_INDEX:
607 case GL_STENCIL_INDEX1_EXT:
608 case GL_STENCIL_INDEX4_EXT:
609 case GL_STENCIL_INDEX8_EXT:
610 case GL_STENCIL_INDEX16_EXT:
611 /* These aren't actual texture formats, so force them here. */
612 if (intel->has_separate_stencil) {
613 rb->Format = MESA_FORMAT_S8;
614 } else {
615 assert(!intel->must_use_separate_stencil);
616 rb->Format = MESA_FORMAT_S8_Z24;
617 }
618 break;
619 }
620
621 rb->Width = width;
622 rb->Height = height;
623 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
624 rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
625 cpp = _mesa_get_format_bytes(rb->Format);
626
627 intel_flush(ctx);
628
629 intel_miptree_release(&irb->mt);
630
631 DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
632 _mesa_lookup_enum_by_nr(internalFormat),
633 _mesa_get_format_name(rb->Format), width, height);
634
635 tiling = I915_TILING_NONE;
636 if (intel->use_texture_tiling) {
637 GLenum base_format = _mesa_get_format_base_format(rb->Format);
638
639 if (intel->gen >= 4 && (base_format == GL_DEPTH_COMPONENT ||
640 base_format == GL_STENCIL_INDEX ||
641 base_format == GL_DEPTH_STENCIL))
642 tiling = I915_TILING_Y;
643 else
644 tiling = I915_TILING_X;
645 }
646
647 if (irb->Base.Format == MESA_FORMAT_S8) {
648 /*
649 * The stencil buffer is W tiled. However, we request from the kernel a
650 * non-tiled buffer because the GTT is incapable of W fencing.
651 *
652 * The stencil buffer has quirky pitch requirements. From Vol 2a,
653 * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
654 * The pitch must be set to 2x the value computed based on width, as
655 * the stencil buffer is stored with two rows interleaved.
656 * To accomplish this, we resort to the nasty hack of doubling the drm
657 * region's cpp and halving its height.
658 *
659 * If we neglect to double the pitch, then render corruption occurs.
660 */
661 irb->mt = intel_miptree_create_for_renderbuffer(
662 intel,
663 rb->Format,
664 I915_TILING_NONE,
665 cpp * 2,
666 ALIGN(width, 64),
667 ALIGN((height + 1) / 2, 64));
668 if (!irb->mt)
669 return false;
670
671 } else if (irb->Base.Format == MESA_FORMAT_S8_Z24
672 && intel->has_separate_stencil) {
673
674 bool ok = true;
675 struct gl_renderbuffer *depth_rb;
676 struct gl_renderbuffer *stencil_rb;
677
678 depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
679 MESA_FORMAT_X8_Z24);
680 stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
681 MESA_FORMAT_S8);
682 ok = depth_rb && stencil_rb;
683 ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb,
684 depth_rb->InternalFormat,
685 width, height);
686 ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb,
687 stencil_rb->InternalFormat,
688 width, height);
689
690 if (!ok) {
691 if (depth_rb) {
692 intel_delete_renderbuffer(depth_rb);
693 }
694 if (stencil_rb) {
695 intel_delete_renderbuffer(stencil_rb);
696 }
697 return false;
698 }
699
700 depth_rb->Wrapped = rb;
701 stencil_rb->Wrapped = rb;
702 _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb);
703 _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb);
704
705 } else {
706 irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
707 tiling, cpp,
708 width, height);
709 if (!irb->mt)
710 return false;
711
712 if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
713 bool ok = intel_miptree_alloc_hiz(intel, irb->mt);
714 if (!ok) {
715 intel_miptree_release(&irb->mt);
716 return false;
717 }
718 }
719 }
720
721 return true;
722 }
723
724
725 #if FEATURE_OES_EGL_image
726 static void
727 intel_image_target_renderbuffer_storage(struct gl_context *ctx,
728 struct gl_renderbuffer *rb,
729 void *image_handle)
730 {
731 struct intel_context *intel = intel_context(ctx);
732 struct intel_renderbuffer *irb;
733 __DRIscreen *screen;
734 __DRIimage *image;
735
736 screen = intel->intelScreen->driScrnPriv;
737 image = screen->dri2.image->lookupEGLImage(screen, image_handle,
738 screen->loaderPrivate);
739 if (image == NULL)
740 return;
741
742 /* __DRIimage is opaque to the core so it has to be checked here */
743 switch (image->format) {
744 case MESA_FORMAT_RGBA8888_REV:
745 _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
746 "glEGLImageTargetRenderbufferStorage(unsupported image format");
747 return;
748 break;
749 default:
750 break;
751 }
752
753 irb = intel_renderbuffer(rb);
754 intel_miptree_release(&irb->mt);
755 irb->mt = intel_miptree_create_for_region(intel,
756 GL_TEXTURE_2D,
757 image->format,
758 image->region);
759 if (!irb->mt)
760 return;
761
762 rb->InternalFormat = image->internal_format;
763 rb->Width = image->region->width;
764 rb->Height = image->region->height;
765 rb->Format = image->format;
766 rb->DataType = image->data_type;
767 rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
768 image->internal_format);
769 }
770 #endif
771
772 /**
773 * Called for each hardware renderbuffer when a _window_ is resized.
774 * Just update fields.
775 * Not used for user-created renderbuffers!
776 */
777 static GLboolean
778 intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
779 GLenum internalFormat, GLuint width, GLuint height)
780 {
781 ASSERT(rb->Name == 0);
782 rb->Width = width;
783 rb->Height = height;
784 rb->InternalFormat = internalFormat;
785
786 return true;
787 }
788
789
790 static void
791 intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
792 GLuint width, GLuint height)
793 {
794 int i;
795
796 _mesa_resize_framebuffer(ctx, fb, width, height);
797
798 fb->Initialized = true; /* XXX remove someday */
799
800 if (fb->Name != 0) {
801 return;
802 }
803
804
805 /* Make sure all window system renderbuffers are up to date */
806 for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
807 struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
808
809 /* only resize if size is changing */
810 if (rb && (rb->Width != width || rb->Height != height)) {
811 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
812 }
813 }
814 }
815
816
817 /** Dummy function for gl_renderbuffer::AllocStorage() */
818 static GLboolean
819 intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
820 GLenum internalFormat, GLuint width, GLuint height)
821 {
822 _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
823 return false;
824 }
825
826 /**
827 * Create a new intel_renderbuffer which corresponds to an on-screen window,
828 * not a user-created renderbuffer.
829 */
830 struct intel_renderbuffer *
831 intel_create_renderbuffer(gl_format format)
832 {
833 GET_CURRENT_CONTEXT(ctx);
834
835 struct intel_renderbuffer *irb;
836
837 irb = CALLOC_STRUCT(intel_renderbuffer);
838 if (!irb) {
839 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
840 return NULL;
841 }
842
843 _mesa_init_renderbuffer(&irb->Base, 0);
844 irb->Base.ClassID = INTEL_RB_CLASS;
845 irb->Base._BaseFormat = _mesa_get_format_base_format(format);
846 irb->Base.Format = format;
847 irb->Base.InternalFormat = irb->Base._BaseFormat;
848 irb->Base.DataType = intel_mesa_format_to_rb_datatype(format);
849
850 /* intel-specific methods */
851 irb->Base.Delete = intel_delete_renderbuffer;
852 irb->Base.AllocStorage = intel_alloc_window_storage;
853 irb->Base.GetPointer = intel_get_pointer;
854
855 return irb;
856 }
857
858
859 struct gl_renderbuffer*
860 intel_create_wrapped_renderbuffer(struct gl_context * ctx,
861 int width, int height,
862 gl_format format)
863 {
864 /*
865 * The name here is irrelevant, as long as its nonzero, because the
866 * renderbuffer never gets entered into Mesa's renderbuffer hash table.
867 */
868 GLuint name = ~0;
869
870 struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
871 if (!irb) {
872 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
873 return NULL;
874 }
875
876 struct gl_renderbuffer *rb = &irb->Base;
877 _mesa_init_renderbuffer(rb, name);
878 rb->ClassID = INTEL_RB_CLASS;
879 rb->_BaseFormat = _mesa_get_format_base_format(format);
880 rb->Format = format;
881 rb->InternalFormat = rb->_BaseFormat;
882 rb->DataType = intel_mesa_format_to_rb_datatype(format);
883 rb->Width = width;
884 rb->Height = height;
885
886 return rb;
887 }
888
889
890 /**
891 * Create a new renderbuffer object.
892 * Typically called via glBindRenderbufferEXT().
893 */
894 static struct gl_renderbuffer *
895 intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
896 {
897 /*struct intel_context *intel = intel_context(ctx); */
898 struct intel_renderbuffer *irb;
899
900 irb = CALLOC_STRUCT(intel_renderbuffer);
901 if (!irb) {
902 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
903 return NULL;
904 }
905
906 _mesa_init_renderbuffer(&irb->Base, name);
907 irb->Base.ClassID = INTEL_RB_CLASS;
908
909 /* intel-specific methods */
910 irb->Base.Delete = intel_delete_renderbuffer;
911 irb->Base.AllocStorage = intel_alloc_renderbuffer_storage;
912 irb->Base.GetPointer = intel_get_pointer;
913 /* span routines set in alloc_storage function */
914
915 return &irb->Base;
916 }
917
918
919 /**
920 * Called via glBindFramebufferEXT().
921 */
922 static void
923 intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
924 struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
925 {
926 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
927 intel_draw_buffer(ctx);
928 }
929 else {
930 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
931 }
932 }
933
934
935 /**
936 * Called via glFramebufferRenderbufferEXT().
937 */
938 static void
939 intel_framebuffer_renderbuffer(struct gl_context * ctx,
940 struct gl_framebuffer *fb,
941 GLenum attachment, struct gl_renderbuffer *rb)
942 {
943 DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
944
945 intel_flush(ctx);
946
947 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
948 intel_draw_buffer(ctx);
949 }
950
951 static struct intel_renderbuffer*
952 intel_renderbuffer_wrap_miptree(struct intel_context *intel,
953 struct intel_mipmap_tree *mt,
954 uint32_t level,
955 uint32_t layer,
956 gl_format format,
957 GLenum internal_format);
958
959 /**
960 * \par Special case for separate stencil
961 *
962 * When wrapping a depthstencil texture that uses separate stencil, this
963 * function is recursively called twice: once to create \c
964 * irb->wrapped_depth and again to create \c irb->wrapped_stencil. On the
965 * call to create \c irb->wrapped_depth, the \c format and \c
966 * internal_format parameters do not match \c mt->format. In that case, \c
967 * mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
968 * MESA_FORMAT_X8_Z24.
969 *
970 * @return true on success
971 */
972 static bool
973 intel_renderbuffer_update_wrapper(struct intel_context *intel,
974 struct intel_renderbuffer *irb,
975 struct intel_mipmap_tree *mt,
976 uint32_t level,
977 uint32_t layer,
978 gl_format format,
979 GLenum internal_format)
980 {
981 struct gl_renderbuffer *rb = &irb->Base;
982
983 rb->Format = format;
984 rb->InternalFormat = internal_format;
985 rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
986 rb->_BaseFormat = _mesa_get_format_base_format(rb->Format);
987 rb->Width = mt->level[level].width;
988 rb->Height = mt->level[level].height;
989
990 irb->Base.Delete = intel_delete_renderbuffer;
991 irb->Base.AllocStorage = intel_nop_alloc_storage;
992
993 intel_miptree_check_level_layer(mt, level, layer);
994 irb->mt_level = level;
995 irb->mt_layer = layer;
996
997 if (mt->stencil_mt && _mesa_is_depthstencil_format(rb->InternalFormat)) {
998 assert((irb->wrapped_depth == NULL) == (irb->wrapped_stencil == NULL));
999
1000 struct intel_renderbuffer *depth_irb;
1001 struct intel_renderbuffer *stencil_irb;
1002
1003 if (!irb->wrapped_depth) {
1004 depth_irb = intel_renderbuffer_wrap_miptree(intel,
1005 mt, level, layer,
1006 MESA_FORMAT_X8_Z24,
1007 GL_DEPTH_COMPONENT24);
1008 stencil_irb = intel_renderbuffer_wrap_miptree(intel,
1009 mt->stencil_mt,
1010 level, layer,
1011 MESA_FORMAT_S8,
1012 GL_STENCIL_INDEX8);
1013 _mesa_reference_renderbuffer(&irb->wrapped_depth, &depth_irb->Base);
1014 _mesa_reference_renderbuffer(&irb->wrapped_stencil, &stencil_irb->Base);
1015
1016 if (!irb->wrapped_depth || !irb->wrapped_stencil)
1017 return false;
1018 } else {
1019 bool ok = true;
1020
1021 depth_irb = intel_renderbuffer(irb->wrapped_depth);
1022 stencil_irb = intel_renderbuffer(irb->wrapped_stencil);
1023
1024 ok &= intel_renderbuffer_update_wrapper(intel,
1025 depth_irb,
1026 mt,
1027 level, layer,
1028 MESA_FORMAT_X8_Z24,
1029 GL_DEPTH_COMPONENT24);
1030 ok &= intel_renderbuffer_update_wrapper(intel,
1031 stencil_irb,
1032 mt->stencil_mt,
1033 level, layer,
1034 MESA_FORMAT_S8,
1035 GL_STENCIL_INDEX8);
1036 if (!ok)
1037 return false;
1038 }
1039 } else {
1040 intel_miptree_reference(&irb->mt, mt);
1041 intel_renderbuffer_set_draw_offset(irb);
1042
1043 if (mt->hiz_mt == NULL &&
1044 intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
1045 intel_miptree_alloc_hiz(intel, mt);
1046 if (!mt->hiz_mt)
1047 return false;
1048 }
1049 }
1050
1051 return true;
1052 }
1053
1054 /**
1055 * \brief Wrap a renderbuffer around a single slice of a miptree.
1056 *
1057 * Called by glFramebufferTexture*(). This just allocates a
1058 * ``struct intel_renderbuffer`` then calls
1059 * intel_renderbuffer_update_wrapper() to do the real work.
1060 *
1061 * \see intel_renderbuffer_update_wrapper()
1062 */
1063 static struct intel_renderbuffer*
1064 intel_renderbuffer_wrap_miptree(struct intel_context *intel,
1065 struct intel_mipmap_tree *mt,
1066 uint32_t level,
1067 uint32_t layer,
1068 gl_format format,
1069 GLenum internal_format)
1070
1071 {
1072 const GLuint name = ~0; /* not significant, but distinct for debugging */
1073 struct gl_context *ctx = &intel->ctx;
1074 struct intel_renderbuffer *irb;
1075
1076 intel_miptree_check_level_layer(mt, level, layer);
1077
1078 irb = CALLOC_STRUCT(intel_renderbuffer);
1079 if (!irb) {
1080 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture");
1081 return NULL;
1082 }
1083
1084 _mesa_init_renderbuffer(&irb->Base, name);
1085 irb->Base.ClassID = INTEL_RB_CLASS;
1086
1087 if (!intel_renderbuffer_update_wrapper(intel, irb,
1088 mt, level, layer,
1089 format, internal_format)) {
1090 free(irb);
1091 return NULL;
1092 }
1093
1094 return irb;
1095 }
1096
1097 void
1098 intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
1099 {
1100 unsigned int dst_x, dst_y;
1101
1102 /* compute offset of the particular 2D image within the texture region */
1103 intel_miptree_get_image_offset(irb->mt,
1104 irb->mt_level,
1105 0, /* face, which we ignore */
1106 irb->mt_layer,
1107 &dst_x, &dst_y);
1108
1109 irb->draw_x = dst_x;
1110 irb->draw_y = dst_y;
1111 }
1112
1113 /**
1114 * Rendering to tiled buffers requires that the base address of the
1115 * buffer be aligned to a page boundary. We generally render to
1116 * textures by pointing the surface at the mipmap image level, which
1117 * may not be aligned to a tile boundary.
1118 *
1119 * This function returns an appropriately-aligned base offset
1120 * according to the tiling restrictions, plus any required x/y offset
1121 * from there.
1122 */
1123 uint32_t
1124 intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
1125 uint32_t *tile_x,
1126 uint32_t *tile_y)
1127 {
1128 struct intel_region *region = irb->mt->region;
1129 int cpp = region->cpp;
1130 uint32_t pitch = region->pitch * cpp;
1131
1132 if (region->tiling == I915_TILING_NONE) {
1133 *tile_x = 0;
1134 *tile_y = 0;
1135 return irb->draw_x * cpp + irb->draw_y * pitch;
1136 } else if (region->tiling == I915_TILING_X) {
1137 *tile_x = irb->draw_x % (512 / cpp);
1138 *tile_y = irb->draw_y % 8;
1139 return ((irb->draw_y / 8) * (8 * pitch) +
1140 (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
1141 } else {
1142 assert(region->tiling == I915_TILING_Y);
1143 *tile_x = irb->draw_x % (128 / cpp);
1144 *tile_y = irb->draw_y % 32;
1145 return ((irb->draw_y / 32) * (32 * pitch) +
1146 (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
1147 }
1148 }
1149
1150 #ifndef I915
1151 static bool
1152 need_tile_offset_workaround(struct brw_context *brw,
1153 struct intel_renderbuffer *irb)
1154 {
1155 uint32_t tile_x, tile_y;
1156
1157 if (brw->has_surface_tile_offset)
1158 return false;
1159
1160 intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
1161
1162 return tile_x != 0 || tile_y != 0;
1163 }
1164 #endif
1165
1166 /**
1167 * Called by glFramebufferTexture[123]DEXT() (and other places) to
1168 * prepare for rendering into texture memory. This might be called
1169 * many times to choose different texture levels, cube faces, etc
1170 * before intel_finish_render_texture() is ever called.
1171 */
1172 static void
1173 intel_render_texture(struct gl_context * ctx,
1174 struct gl_framebuffer *fb,
1175 struct gl_renderbuffer_attachment *att)
1176 {
1177 struct intel_context *intel = intel_context(ctx);
1178 struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
1179 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
1180 struct intel_texture_image *intel_image = intel_texture_image(image);
1181 struct intel_mipmap_tree *mt = intel_image->mt;
1182
1183 (void) fb;
1184
1185 int layer;
1186 if (att->CubeMapFace > 0) {
1187 assert(att->Zoffset == 0);
1188 layer = att->CubeMapFace;
1189 } else {
1190 layer = att->Zoffset;
1191 }
1192
1193 if (!intel_image->mt) {
1194 /* Fallback on drawing to a texture that doesn't have a miptree
1195 * (has a border, width/height 0, etc.)
1196 */
1197 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
1198 _swrast_render_texture(ctx, fb, att);
1199 return;
1200 }
1201 else if (!irb) {
1202 irb = intel_renderbuffer_wrap_miptree(intel,
1203 mt,
1204 att->TextureLevel,
1205 layer,
1206 image->TexFormat,
1207 image->InternalFormat);
1208
1209 if (irb) {
1210 /* bind the wrapper to the attachment point */
1211 _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base);
1212 }
1213 else {
1214 /* fallback to software rendering */
1215 _swrast_render_texture(ctx, fb, att);
1216 return;
1217 }
1218 }
1219
1220 if (!intel_renderbuffer_update_wrapper(intel, irb,
1221 mt, att->TextureLevel, layer,
1222 image->TexFormat,
1223 image->InternalFormat)) {
1224 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
1225 _swrast_render_texture(ctx, fb, att);
1226 return;
1227 }
1228
1229 DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
1230 _mesa_get_format_name(image->TexFormat),
1231 att->Texture->Name, image->Width, image->Height,
1232 irb->Base.RefCount);
1233
1234 intel_image->used_as_render_target = true;
1235
1236 #ifndef I915
1237 if (need_tile_offset_workaround(brw_context(ctx), irb)) {
1238 /* Original gen4 hardware couldn't draw to a non-tile-aligned
1239 * destination in a miptree unless you actually setup your
1240 * renderbuffer as a miptree and used the fragile
1241 * lod/array_index/etc. controls to select the image. So,
1242 * instead, we just make a new single-level miptree and render
1243 * into that.
1244 */
1245 struct intel_context *intel = intel_context(ctx);
1246 struct intel_mipmap_tree *new_mt;
1247 int width, height, depth;
1248
1249 intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
1250
1251 new_mt = intel_miptree_create(intel, image->TexObject->Target,
1252 intel_image->base.Base.TexFormat,
1253 intel_image->base.Base.Level,
1254 intel_image->base.Base.Level,
1255 width, height, depth,
1256 true);
1257
1258 intel_miptree_copy_teximage(intel, intel_image, new_mt);
1259 intel_renderbuffer_set_draw_offset(irb);
1260
1261 intel_miptree_reference(&irb->mt, intel_image->mt);
1262 intel_miptree_release(&new_mt);
1263 }
1264 #endif
1265 /* update drawing region, etc */
1266 intel_draw_buffer(ctx);
1267 }
1268
1269
1270 /**
1271 * Called by Mesa when rendering to a texture is done.
1272 */
1273 static void
1274 intel_finish_render_texture(struct gl_context * ctx,
1275 struct gl_renderbuffer_attachment *att)
1276 {
1277 struct intel_context *intel = intel_context(ctx);
1278 struct gl_texture_object *tex_obj = att->Texture;
1279 struct gl_texture_image *image =
1280 tex_obj->Image[att->CubeMapFace][att->TextureLevel];
1281 struct intel_texture_image *intel_image = intel_texture_image(image);
1282
1283 DBG("Finish render %s texture tex=%u\n",
1284 _mesa_get_format_name(image->TexFormat), att->Texture->Name);
1285
1286 /* Flag that this image may now be validated into the object's miptree. */
1287 if (intel_image)
1288 intel_image->used_as_render_target = false;
1289
1290 /* Since we've (probably) rendered to the texture and will (likely) use
1291 * it in the texture domain later on in this batchbuffer, flush the
1292 * batch. Once again, we wish for a domain tracker in libdrm to cover
1293 * usage inside of a batchbuffer like GEM does in the kernel.
1294 */
1295 intel_batchbuffer_emit_mi_flush(intel);
1296 }
1297
1298 /**
1299 * Do additional "completeness" testing of a framebuffer object.
1300 */
1301 static void
1302 intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
1303 {
1304 struct intel_context *intel = intel_context(ctx);
1305 const struct intel_renderbuffer *depthRb =
1306 intel_get_renderbuffer(fb, BUFFER_DEPTH);
1307 const struct intel_renderbuffer *stencilRb =
1308 intel_get_renderbuffer(fb, BUFFER_STENCIL);
1309 int i;
1310
1311 /*
1312 * The depth and stencil renderbuffers are the same renderbuffer or wrap
1313 * the same texture.
1314 */
1315 if (depthRb && stencilRb) {
1316 bool depth_stencil_are_same;
1317 if (depthRb == stencilRb)
1318 depth_stencil_are_same = true;
1319 else if ((fb->Attachment[BUFFER_DEPTH].Type == GL_TEXTURE) &&
1320 (fb->Attachment[BUFFER_STENCIL].Type == GL_TEXTURE) &&
1321 (fb->Attachment[BUFFER_DEPTH].Texture->Name ==
1322 fb->Attachment[BUFFER_STENCIL].Texture->Name))
1323 depth_stencil_are_same = true;
1324 else
1325 depth_stencil_are_same = false;
1326
1327 if (!intel->has_separate_stencil && !depth_stencil_are_same) {
1328 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1329 }
1330 }
1331
1332 for (i = 0; i < Elements(fb->Attachment); i++) {
1333 struct gl_renderbuffer *rb;
1334 struct intel_renderbuffer *irb;
1335
1336 if (fb->Attachment[i].Type == GL_NONE)
1337 continue;
1338
1339 /* A supported attachment will have a Renderbuffer set either
1340 * from being a Renderbuffer or being a texture that got the
1341 * intel_wrap_texture() treatment.
1342 */
1343 rb = fb->Attachment[i].Renderbuffer;
1344 if (rb == NULL) {
1345 DBG("attachment without renderbuffer\n");
1346 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1347 continue;
1348 }
1349
1350 irb = intel_renderbuffer(rb);
1351 if (irb == NULL) {
1352 DBG("software rendering renderbuffer\n");
1353 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1354 continue;
1355 }
1356
1357 if (!intel->vtbl.render_target_supported(intel, irb->Base.Format)) {
1358 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
1359 _mesa_get_format_name(irb->Base.Format));
1360 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1361 }
1362
1363 #ifdef I915
1364 if (!intel_span_supports_format(irb->Base.Format)) {
1365 DBG("Unsupported swrast texture/renderbuffer format attached: %s\n",
1366 _mesa_get_format_name(irb->Base.Format));
1367 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
1368 }
1369 #endif
1370 }
1371 }
1372
1373 /**
1374 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
1375 * We can do this when the dst renderbuffer is actually a texture and
1376 * there is no scaling, mirroring or scissoring.
1377 *
1378 * \return new buffer mask indicating the buffers left to blit using the
1379 * normal path.
1380 */
1381 static GLbitfield
1382 intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
1383 GLint srcX0, GLint srcY0,
1384 GLint srcX1, GLint srcY1,
1385 GLint dstX0, GLint dstY0,
1386 GLint dstX1, GLint dstY1,
1387 GLbitfield mask, GLenum filter)
1388 {
1389 if (mask & GL_COLOR_BUFFER_BIT) {
1390 const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
1391 const struct gl_framebuffer *readFb = ctx->ReadBuffer;
1392 const struct gl_renderbuffer_attachment *drawAtt =
1393 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
1394
1395 /* If the source and destination are the same size with no
1396 mirroring, the rectangles are within the size of the
1397 texture and there is no scissor then we can use
1398 glCopyTexSubimage2D to implement the blit. This will end
1399 up as a fast hardware blit on some drivers */
1400 if (drawAtt && drawAtt->Texture &&
1401 srcX0 - srcX1 == dstX0 - dstX1 &&
1402 srcY0 - srcY1 == dstY0 - dstY1 &&
1403 srcX1 >= srcX0 &&
1404 srcY1 >= srcY0 &&
1405 srcX0 >= 0 && srcX1 <= readFb->Width &&
1406 srcY0 >= 0 && srcY1 <= readFb->Height &&
1407 dstX0 >= 0 && dstX1 <= drawFb->Width &&
1408 dstY0 >= 0 && dstY1 <= drawFb->Height &&
1409 !ctx->Scissor.Enabled) {
1410 const struct gl_texture_object *texObj = drawAtt->Texture;
1411 const GLuint dstLevel = drawAtt->TextureLevel;
1412 const GLenum target = texObj->Target;
1413
1414 struct gl_texture_image *texImage =
1415 _mesa_select_tex_image(ctx, texObj, target, dstLevel);
1416
1417 if (intel_copy_texsubimage(intel_context(ctx),
1418 intel_texture_image(texImage),
1419 dstX0, dstY0,
1420 srcX0, srcY0,
1421 srcX1 - srcX0, /* width */
1422 srcY1 - srcY0))
1423 mask &= ~GL_COLOR_BUFFER_BIT;
1424 }
1425 }
1426
1427 return mask;
1428 }
1429
1430 static void
1431 intel_blit_framebuffer(struct gl_context *ctx,
1432 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1433 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1434 GLbitfield mask, GLenum filter)
1435 {
1436 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
1437 mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
1438 srcX0, srcY0, srcX1, srcY1,
1439 dstX0, dstY0, dstX1, dstY1,
1440 mask, filter);
1441 if (mask == 0x0)
1442 return;
1443
1444 _mesa_meta_BlitFramebuffer(ctx,
1445 srcX0, srcY0, srcX1, srcY1,
1446 dstX0, dstY0, dstX1, dstY1,
1447 mask, filter);
1448 }
1449
1450 void
1451 intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
1452 {
1453 if (irb->mt) {
1454 intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
1455 irb->mt_level,
1456 irb->mt_layer);
1457 } else if (irb->wrapped_depth) {
1458 intel_renderbuffer_set_needs_hiz_resolve(
1459 intel_renderbuffer(irb->wrapped_depth));
1460 } else {
1461 return;
1462 }
1463 }
1464
1465 void
1466 intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
1467 {
1468 if (irb->mt) {
1469 intel_miptree_slice_set_needs_depth_resolve(irb->mt,
1470 irb->mt_level,
1471 irb->mt_layer);
1472 } else if (irb->wrapped_depth) {
1473 intel_renderbuffer_set_needs_depth_resolve(
1474 intel_renderbuffer(irb->wrapped_depth));
1475 } else {
1476 return;
1477 }
1478 }
1479
1480 bool
1481 intel_renderbuffer_resolve_hiz(struct intel_context *intel,
1482 struct intel_renderbuffer *irb)
1483 {
1484 if (irb->mt)
1485 return intel_miptree_slice_resolve_hiz(intel,
1486 irb->mt,
1487 irb->mt_level,
1488 irb->mt_layer);
1489 if (irb->wrapped_depth)
1490 return intel_renderbuffer_resolve_hiz(intel,
1491 intel_renderbuffer(irb->wrapped_depth));
1492
1493 return false;
1494 }
1495
1496 bool
1497 intel_renderbuffer_resolve_depth(struct intel_context *intel,
1498 struct intel_renderbuffer *irb)
1499 {
1500 if (irb->mt)
1501 return intel_miptree_slice_resolve_depth(intel,
1502 irb->mt,
1503 irb->mt_level,
1504 irb->mt_layer);
1505
1506 if (irb->wrapped_depth)
1507 return intel_renderbuffer_resolve_depth(intel,
1508 intel_renderbuffer(irb->wrapped_depth));
1509
1510 return false;
1511 }
1512
1513 /**
1514 * Do one-time context initializations related to GL_EXT_framebuffer_object.
1515 * Hook in device driver functions.
1516 */
1517 void
1518 intel_fbo_init(struct intel_context *intel)
1519 {
1520 intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
1521 intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
1522 intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
1523 intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
1524 intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
1525 intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
1526 intel->ctx.Driver.RenderTexture = intel_render_texture;
1527 intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
1528 intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
1529 intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
1530 intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
1531
1532 #if FEATURE_OES_EGL_image
1533 intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
1534 intel_image_target_renderbuffer_storage;
1535 #endif
1536 }