177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**************************************************************************
277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * All Rights Reserved.
577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * copy of this software and associated documentation files (the
877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * "Software"), to deal in the Software without restriction, including
977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * without limitation the rights to use, copy, modify, merge, publish,
1077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * distribute, sub license, and/or sell copies of the Software, and to
1177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * permit persons to whom the Software is furnished to do so, subject to
1277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * the following conditions:
1377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
1477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * The above copyright notice and this permission notice (including the
1577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * next paragraph) shall be included in all copies or substantial portions
1677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * of the Software.
1777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
1877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
2677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt **************************************************************************/
2777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
2877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
296b341662b3bbde7e86b3b9184266412da1b27977Eric Anholt#include "main/enums.h"
30ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/imports.h"
316d2e1f6a2cd25107ad9bd88b1decd05fc8000f78Brian Paul#include "main/macros.h"
3245a56e4730a74a012ad712fd9b6013d900b04742Vinson Lee#include "main/mfeatures.h"
33ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/mtypes.h"
34ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/fbobject.h"
35ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/framebuffer.h"
36ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/renderbuffer.h"
37ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/context.h"
38c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts#include "main/teximage.h"
393eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace#include "main/image.h"
403eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace
414fa01d705f0b795a5df30127925ced8e0522631fBrian Paul#include "swrast/swrast.h"
428cb389ce354944a69418ca1d402791eef8fbf239Brian Paul#include "drivers/common/meta.h"
4377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
4477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_context.h"
45539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt#include "intel_batchbuffer.h"
4677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_buffers.h"
47eab201bad4d4f250ca9318a228d1c71561daee1aEric Anholt#include "intel_blit.h"
4877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_fbo.h"
4977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_mipmap_tree.h"
5077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_regions.h"
51e339b669a14f37698b842c0c51c1f5e4001ef12fEric Anholt#include "intel_tex.h"
52e339b669a14f37698b842c0c51c1f5e4001ef12fEric Anholt#include "intel_span.h"
53c0cdae03685056e170c25da7d46aed959176d652Eric Anholt#ifndef I915
54c0cdae03685056e170c25da7d46aed959176d652Eric Anholt#include "brw_context.h"
55c0cdae03685056e170c25da7d46aed959176d652Eric Anholt#endif
5677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
5777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#define FILE_DEBUG_FLAG DEBUG_FBO
5877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
59a91c31668fce46545570571468fefca216fcf881Eric Anholtstatic struct gl_renderbuffer *
60a91c31668fce46545570571468fefca216fcf881Eric Anholtintel_new_renderbuffer(struct gl_context * ctx, GLuint name);
61a91c31668fce46545570571468fefca216fcf881Eric Anholt
62c3c7cbd15418293208034e8970d626b5998abd4bChad Versacestruct intel_region*
63c3c7cbd15418293208034e8970d626b5998abd4bChad Versaceintel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
64c3c7cbd15418293208034e8970d626b5998abd4bChad Versace{
65c3c7cbd15418293208034e8970d626b5998abd4bChad Versace   struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
660b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt   if (irb && irb->mt) {
670b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt      if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
680b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt	 return irb->mt->stencil_mt->region;
690b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt      else
700b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt	 return irb->mt->region;
710b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt   } else
72c3c7cbd15418293208034e8970d626b5998abd4bChad Versace      return NULL;
73c3c7cbd15418293208034e8970d626b5998abd4bChad Versace}
74c3c7cbd15418293208034e8970d626b5998abd4bChad Versace
7577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
7677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Create a new framebuffer object.
7777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
7877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic struct gl_framebuffer *
79f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_new_framebuffer(struct gl_context * ctx, GLuint name)
8077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
8177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
8277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt    * class
8377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt    */
8477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   return _mesa_new_framebuffer(ctx, name);
8577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
8677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
8777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
885c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul/** Called by gl_renderbuffer::Delete() */
8977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
909d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paulintel_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
9177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
9277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
9377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
9477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   ASSERT(irb);
9577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
96da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   intel_miptree_release(&irb->mt);
97007c2d6cd2f6b206564689ac12a3e51aaae242bcEric Anholt
989d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul   _mesa_delete_renderbuffer(ctx, rb);
9977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
10077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
101f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace/**
102f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace * \see dd_function_table::MapRenderbuffer
103f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace */
104f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versacestatic void
105f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versaceintel_map_renderbuffer(struct gl_context *ctx,
106f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace		       struct gl_renderbuffer *rb,
107f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace		       GLuint x, GLuint y, GLuint w, GLuint h,
108f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace		       GLbitfield mode,
109f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace		       GLubyte **out_map,
110f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace		       GLint *out_stride)
111f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace{
112f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   struct intel_context *intel = intel_context(ctx);
11342e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
114f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
11596159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   void *map;
11696159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   int stride;
117f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace
11842e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt   if (srb->Buffer) {
11942e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt      /* this is a malloc'd renderbuffer (accum buffer), not an irb */
1206dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      GLint bpp = _mesa_get_format_bytes(rb->Format);
12142e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt      GLint rowStride = srb->RowStride;
12242e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt      *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
1236dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      *out_stride = rowStride;
1246dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      return;
1256dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul   }
1266dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul
127f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   /* We sometimes get called with this by our intel_span.c usage. */
1288967f750953ca94aa36e3a8ed703a61f1b434f64Eric Anholt   if (!irb->mt) {
129f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace      *out_map = NULL;
130f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace      *out_stride = 0;
131f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace      return;
132f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   }
133f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace
13496159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   /* For a window-system renderbuffer, we need to flip the mapping we receive
13596159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt    * upside-down.  So we need to ask for a rectangle on flipped vertically, and
13696159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt    * we then return a pointer to the bottom of it with a negative stride.
13796159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt    */
13896159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   if (rb->Name == 0) {
13996159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt      y = rb->Height - y - h;
14096159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   }
141b48c3bca87b30003f9e117d299011380e743aec9Eric Anholt
14296159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
14396159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt		     x, y, w, h, mode, &map, &stride);
144b48c3bca87b30003f9e117d299011380e743aec9Eric Anholt
14596159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   if (rb->Name == 0) {
14696159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt      map += (h - 1) * stride;
14796159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt      stride = -stride;
14896159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   }
149b48c3bca87b30003f9e117d299011380e743aec9Eric Anholt
15096159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
15196159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
152faa44bc2f64eb2dfa36b553c06c9bf5fe53ed502Eric Anholt       x, y, w, h, map, stride);
153b48c3bca87b30003f9e117d299011380e743aec9Eric Anholt
15496159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   *out_map = map;
15596159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   *out_stride = stride;
156f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace}
157f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace
158f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace/**
159f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace * \see dd_function_table::UnmapRenderbuffer
160f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace */
161f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versacestatic void
162f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versaceintel_unmap_renderbuffer(struct gl_context *ctx,
163f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace			 struct gl_renderbuffer *rb)
164f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace{
165b48c3bca87b30003f9e117d299011380e743aec9Eric Anholt   struct intel_context *intel = intel_context(ctx);
16642e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
167f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
168f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace
169f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace   DBG("%s: rb %d (%s)\n", __FUNCTION__,
170f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace       rb->Name, _mesa_get_format_name(rb->Format));
171f911cac7a7a8ebcad711587200c7f66ab61d1ccfChad Versace
17242e9936ce6bcac9f863b2f85978489e4f804e927Eric Anholt   if (srb->Buffer) {
1736dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      /* this is a malloc'd renderbuffer (accum buffer) */
1746dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      /* nothing to do */
1756dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul      return;
1766dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul   }
1776dbdc0395698de929e23b4ec1ab399e64ecfd264Brian Paul
17896159c37e3e8c966dba7cf7fe70875372dd12293Eric Anholt   intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
17992054cd94e2188c9f4d56ddf9377c5aeb8a4e64eEric Anholt}
18077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
18177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
18277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
18319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry * Round up the requested multisample count to the next supported sample size.
18419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry */
18553fa28f7b1f21251a3807abf1f234f52beff0256Chad Versaceunsigned
18653fa28f7b1f21251a3807abf1f234f52beff0256Chad Versaceintel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples)
18719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry{
18819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry   switch (intel->gen) {
18919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry   case 6:
19019e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      /* Gen6 supports only 4x multisampling. */
19119e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      if (num_samples > 0)
19219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry         return 4;
19319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      else
19419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry         return 0;
19519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry   case 7:
196497bf5dd2b36c7d0c8ae23d2bf039c91b97140fcPaul Berry      /* Gen7 supports 4x and 8x multisampling. */
197497bf5dd2b36c7d0c8ae23d2bf039c91b97140fcPaul Berry      if (num_samples > 4)
198497bf5dd2b36c7d0c8ae23d2bf039c91b97140fcPaul Berry         return 8;
199497bf5dd2b36c7d0c8ae23d2bf039c91b97140fcPaul Berry      else if (num_samples > 0)
200ab014adaed14a9ca213447dc913d0dce7906be56Paul Berry         return 4;
201ab014adaed14a9ca213447dc913d0dce7906be56Paul Berry      else
202ab014adaed14a9ca213447dc913d0dce7906be56Paul Berry         return 0;
20319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      return 0;
20419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry   default:
205c18806cebf107d03751b11cc8866062c3822a56fPaul Berry      /* MSAA unsupported.  However, a careful reading of
206c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       * EXT_framebuffer_multisample reveals that we need to permit
207c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       * num_samples to be 1 (since num_samples is permitted to be as high as
208c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       * GL_MAX_SAMPLES, and GL_MAX_SAMPLES must be at least 1).  Since
209c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       * platforms before Gen6 don't support MSAA, this is safe, because
210c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       * multisampling won't happen anyhow.
211c18806cebf107d03751b11cc8866062c3822a56fPaul Berry       */
212c18806cebf107d03751b11cc8866062c3822a56fPaul Berry      if (num_samples > 0)
213c18806cebf107d03751b11cc8866062c3822a56fPaul Berry         return 1;
21419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      return 0;
21519e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry   }
21619e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry}
21719e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry
21819e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry
21919e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry/**
22077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called via glRenderbufferStorageEXT() to set the format and allocate
22177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * storage for a user-created renderbuffer.
22277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
2235cd4d8551778e1b371397ad4a1144a1c0b9f436fChad VersaceGLboolean
224f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
22577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                                 GLenum internalFormat,
22677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                                 GLuint width, GLuint height)
22777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
22877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_context *intel = intel_context(ctx);
22953fa28f7b1f21251a3807abf1f234f52beff0256Chad Versace   struct intel_screen *screen = intel->intelScreen;
23077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
23153fa28f7b1f21251a3807abf1f234f52beff0256Chad Versace   rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples);
23277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
23377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   switch (internalFormat) {
234be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt   default:
235be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt      /* Use the same format-choice logic as for textures.
236be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt       * Renderbuffers aren't any different from textures for us,
237be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt       * except they're less useful because you can't texture with
238be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt       * them.
239be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt       */
240d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paul      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D,
241d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paul							 internalFormat,
2425dbb856e960f9448ec4e322f936f5f6763ee77e2Eric Anholt							 GL_NONE, GL_NONE);
243bda941e1b895547d680b68eaf28ae2db11e6149fNick Bowler      break;
24477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   case GL_STENCIL_INDEX:
24577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   case GL_STENCIL_INDEX1_EXT:
24677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   case GL_STENCIL_INDEX4_EXT:
24777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   case GL_STENCIL_INDEX8_EXT:
24877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   case GL_STENCIL_INDEX16_EXT:
249be72efb4f29180fdaf0935f8739f230fe5ea6317Eric Anholt      /* These aren't actual texture formats, so force them here. */
2501a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace      if (intel->has_separate_stencil) {
2511a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace	 rb->Format = MESA_FORMAT_S8;
2521a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace      } else {
2531a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace	 assert(!intel->must_use_separate_stencil);
2541a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace	 rb->Format = MESA_FORMAT_S8_Z24;
2551a1411e09b23fce9977f7926dba4f1f0c8f3c5ecChad Versace      }
25677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      break;
25777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
25877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
2593db27d4a4aee9f311a447778ce94007415f2637fChad Versace   rb->Width = width;
2603db27d4a4aee9f311a447778ce94007415f2637fChad Versace   rb->Height = height;
26145e76d2665b38ba3787548310efc59e969124c01Brian Paul   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
26245e76d2665b38ba3787548310efc59e969124c01Brian Paul
263da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   intel_miptree_release(&irb->mt);
26477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
2656b341662b3bbde7e86b3b9184266412da1b27977Eric Anholt   DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
2666b341662b3bbde7e86b3b9184266412da1b27977Eric Anholt       _mesa_lookup_enum_by_nr(internalFormat),
2676b341662b3bbde7e86b3b9184266412da1b27977Eric Anholt       _mesa_get_format_name(rb->Format), width, height);
26877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
269b7406404aba1817d5a87714f97a108a755943452Eric Anholt   if (width == 0 || height == 0)
270b7406404aba1817d5a87714f97a108a755943452Eric Anholt      return true;
271b7406404aba1817d5a87714f97a108a755943452Eric Anholt
272a91c31668fce46545570571468fefca216fcf881Eric Anholt   irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
27319e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry						   width, height,
27419e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry                                                   rb->NumSamples);
275a91c31668fce46545570571468fefca216fcf881Eric Anholt   if (!irb->mt)
276a91c31668fce46545570571468fefca216fcf881Eric Anholt      return false;
2773db27d4a4aee9f311a447778ce94007415f2637fChad Versace
2782e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return true;
27977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
28077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
28177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
28210e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg#if FEATURE_OES_EGL_image
28310e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsbergstatic void
284f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_image_target_renderbuffer_storage(struct gl_context *ctx,
28510e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg					struct gl_renderbuffer *rb,
28610e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg					void *image_handle)
28710e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg{
28810e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   struct intel_context *intel = intel_context(ctx);
28910e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   struct intel_renderbuffer *irb;
29010e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   __DRIscreen *screen;
29110e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   __DRIimage *image;
29210e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg
29310e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   screen = intel->intelScreen->driScrnPriv;
29417eace581d25a626a7d75d9d1205d012cbb14a6eKristian Høgsberg   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
29517eace581d25a626a7d75d9d1205d012cbb14a6eKristian Høgsberg					      screen->loaderPrivate);
29610e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   if (image == NULL)
29710e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg      return;
29810e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg
2999fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu   /* __DRIimage is opaque to the core so it has to be checked here */
3009fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu   switch (image->format) {
3019fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu   case MESA_FORMAT_RGBA8888_REV:
3029fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
3039fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu            "glEGLImageTargetRenderbufferStorage(unsupported image format");
3049fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu      return;
3059fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu      break;
3069fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu   default:
3079fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu      break;
3089fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu   }
3099fe197c62611815ebe74248033271ad9fd07ae06Chia-I Wu
31010e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   irb = intel_renderbuffer(rb);
311da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   intel_miptree_release(&irb->mt);
312da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   irb->mt = intel_miptree_create_for_region(intel,
313da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace                                             GL_TEXTURE_2D,
314da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace                                             image->format,
315da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace                                             image->region);
316da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   if (!irb->mt)
317da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace      return;
31810e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg
319af3f1bb26980537522a1586fef3fc3c208b44ebcKristian Høgsberg   rb->InternalFormat = image->internal_format;
32010e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   rb->Width = image->region->width;
32110e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   rb->Height = image->region->height;
32210e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   rb->Format = image->format;
32310e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
32410e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg					   image->internal_format);
32510e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg}
32610e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg#endif
32710e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg
32877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
32977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called for each hardware renderbuffer when a _window_ is resized.
33077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Just update fields.
33177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Not used for user-created renderbuffers!
33277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
33377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic GLboolean
334f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
33577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                           GLenum internalFormat, GLuint width, GLuint height)
33677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
33777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   ASSERT(rb->Name == 0);
33877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   rb->Width = width;
33977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   rb->Height = height;
34045e76d2665b38ba3787548310efc59e969124c01Brian Paul   rb->InternalFormat = internalFormat;
34177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3422e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return true;
34377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
34477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3455c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul
34677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
347f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb,
34877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt		     GLuint width, GLuint height)
34977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
35077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   int i;
35177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
35277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   _mesa_resize_framebuffer(ctx, fb, width, height);
35377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3542e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   fb->Initialized = true; /* XXX remove someday */
35577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
356c738ea1191cd1b5a0dc60b0e6d05fd918083e961Paul Berry   if (_mesa_is_user_fbo(fb)) {
35777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      return;
35877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
35977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
360d282128ff68cc58bc3f5b808031c5fe7325bd69bKristian Høgsberg
36177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* Make sure all window system renderbuffers are up to date */
362d282128ff68cc58bc3f5b808031c5fe7325bd69bKristian Høgsberg   for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) {
363d282128ff68cc58bc3f5b808031c5fe7325bd69bKristian Høgsberg      struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
36477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
36577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      /* only resize if size is changing */
36677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      if (rb && (rb->Width != width || rb->Height != height)) {
36777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt	 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height);
36877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      }
36977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
37077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
37177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3725c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul
3735c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul/** Dummy function for gl_renderbuffer::AllocStorage() */
37477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic GLboolean
375f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
37677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                        GLenum internalFormat, GLuint width, GLuint height)
37777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
37877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
3792e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return false;
38077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
38177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
38277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
38377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Create a new intel_renderbuffer which corresponds to an on-screen window,
38477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * not a user-created renderbuffer.
385e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace *
386e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace * \param num_samples must be quantized.
38777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
38877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstruct intel_renderbuffer *
389e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versaceintel_create_renderbuffer(gl_format format, unsigned num_samples)
39077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
39177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_renderbuffer *irb;
3929f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   struct gl_renderbuffer *rb;
3939f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul
3949f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   GET_CURRENT_CONTEXT(ctx);
39577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
39677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   irb = CALLOC_STRUCT(intel_renderbuffer);
39777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (!irb) {
39877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
39977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      return NULL;
40077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
40177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
4029f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb = &irb->Base.Base;
4039f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul
4049f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   _mesa_init_renderbuffer(rb, 0);
4059f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->ClassID = INTEL_RB_CLASS;
4069f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->_BaseFormat = _mesa_get_format_base_format(format);
4079f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->Format = format;
4089f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->InternalFormat = rb->_BaseFormat;
409e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace   rb->NumSamples = num_samples;
41077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
41177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* intel-specific methods */
4129f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->Delete = intel_delete_renderbuffer;
4139f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->AllocStorage = intel_alloc_window_storage;
41477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
41577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   return irb;
41677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
41777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
41877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
419433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt * Private window-system buffers (as opposed to ones shared with the display
420433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt * server created with intel_create_renderbuffer()) are most similar in their
421433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt * handling to user-created renderbuffers, but they have a resize handler that
422433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt * may be called at intel_update_renderbuffers() time.
423e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace *
424e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace * \param num_samples must be quantized.
425433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt */
426433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholtstruct intel_renderbuffer *
427e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versaceintel_create_private_renderbuffer(gl_format format, unsigned num_samples)
428433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt{
429433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt   struct intel_renderbuffer *irb;
430433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt
431e2f2376e884225705e2369caee4a8c4e90e938f3Chad Versace   irb = intel_create_renderbuffer(format, num_samples);
432433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt   irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage;
433433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt
434433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt   return irb;
435433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt}
436433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt
437433ff3e16e8e090fd3a1bf427e61f3e5971a5740Eric Anholt/**
43877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Create a new renderbuffer object.
43977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Typically called via glBindRenderbufferEXT().
44077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
44177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic struct gl_renderbuffer *
442f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_new_renderbuffer(struct gl_context * ctx, GLuint name)
44377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
44477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /*struct intel_context *intel = intel_context(ctx); */
44577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_renderbuffer *irb;
4469f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   struct gl_renderbuffer *rb;
44777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
44877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   irb = CALLOC_STRUCT(intel_renderbuffer);
44977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (!irb) {
45077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
45177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      return NULL;
45277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
45377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
4549f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb = &irb->Base.Base;
4559f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul
4569f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   _mesa_init_renderbuffer(rb, name);
4579f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->ClassID = INTEL_RB_CLASS;
45877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
45977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* intel-specific methods */
4609f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->Delete = intel_delete_renderbuffer;
4619f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->AllocStorage = intel_alloc_renderbuffer_storage;
46277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* span routines set in alloc_storage function */
46377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
4649f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   return rb;
46577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
46677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
46777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
46877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
46977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called via glBindFramebufferEXT().
47077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
47177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
472f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_bind_framebuffer(struct gl_context * ctx, GLenum target,
47377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
47477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
47577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
47617fa6772d7e223f940dd8ec4e4f6cf8cab9a03c7Ian Romanick      intel_draw_buffer(ctx);
47777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
47877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   else {
47977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
48077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
48177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
48277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
48377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
48477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
48577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called via glFramebufferRenderbufferEXT().
48677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
48777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
488f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_framebuffer_renderbuffer(struct gl_context * ctx,
48977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                               struct gl_framebuffer *fb,
49077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                               GLenum attachment, struct gl_renderbuffer *rb)
49177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
49277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
49377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
49477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
49517fa6772d7e223f940dd8ec4e4f6cf8cab9a03c7Ian Romanick   intel_draw_buffer(ctx);
49677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
49777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
498c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace/**
4993eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace * \par Special case for separate stencil
5003eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *
5013eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     When wrapping a depthstencil texture that uses separate stencil, this
5023eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     function is recursively called twice: once to create \c
5033eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     irb->wrapped_depth and again to create \c irb->wrapped_stencil.  On the
5043eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     call to create \c irb->wrapped_depth, the \c format and \c
5053eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     internal_format parameters do not match \c mt->format. In that case, \c
5063eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     mt->format is MESA_FORMAT_S8_Z24 and \c format is \c
5073eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *     MESA_FORMAT_X8_Z24.
5083eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace *
5093eb12dfaeed03f77e31943eea164acb03e86bbc9Chad Versace * @return true on success
510c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace */
511b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt
512bffae4c9cd7df044cdbeeed1de257d720f1e76acChad Versacestatic bool
513c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versaceintel_renderbuffer_update_wrapper(struct intel_context *intel,
514c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace                                  struct intel_renderbuffer *irb,
515b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt				  struct gl_texture_image *image,
516b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt                                  uint32_t layer)
51777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
5189f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   struct gl_renderbuffer *rb = &irb->Base.Base;
519b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   struct intel_texture_image *intel_image = intel_texture_image(image);
520b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   struct intel_mipmap_tree *mt = intel_image->mt;
521b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   int level = image->Level;
522c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace
523b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   rb->Format = image->TexFormat;
524b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   rb->InternalFormat = image->InternalFormat;
5257cac88679bb600f35694e91859c4682c04c32f7aEric Anholt   rb->_BaseFormat = image->_BaseFormat;
526c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   rb->Width = mt->level[level].width;
527c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   rb->Height = mt->level[level].height;
52877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
5299f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->Delete = intel_delete_renderbuffer;
5309f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul   rb->AllocStorage = intel_nop_alloc_storage;
53177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
532c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   intel_miptree_check_level_layer(mt, level, layer);
533c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   irb->mt_level = level;
534c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   irb->mt_layer = layer;
53524da7335b22432ef4c2d57cab86e4b8fbe8733d5Chad Versace
5360b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt   intel_miptree_reference(&irb->mt, mt);
537293e9a7ccfeb64efd54464658518e4ded054a13cChad Versace
5380c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt   intel_renderbuffer_set_draw_offset(irb);
5390c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt
5400c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt   if (mt->hiz_mt == NULL &&
5410c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt       intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
54219e9b24626c2b9d7abef054d57bb2a52106c545bPaul Berry      intel_miptree_alloc_hiz(intel, mt, 0 /* num_samples */);
5430c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt      if (!mt->hiz_mt)
5440c498467104e361e50bbb95adf2b2c0e799591dcEric Anholt	 return false;
5456ed829fe5063f61f1ab2fcb39a441e17d89e622cChad Versace   }
546c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace
5472e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return true;
548f94d317d7aea8043b179a0ba64308606375500d7Xiang, Haihao}
549f94d317d7aea8043b179a0ba64308606375500d7Xiang, Haihao
5505cd4d8551778e1b371397ad4a1144a1c0b9f436fChad Versacevoid
5513b38b33c1648b07e75dc4d8340758171e109c598Chad Versaceintel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
552c0cdae03685056e170c25da7d46aed959176d652Eric Anholt{
553c0cdae03685056e170c25da7d46aed959176d652Eric Anholt   unsigned int dst_x, dst_y;
554c0cdae03685056e170c25da7d46aed959176d652Eric Anholt
555c0cdae03685056e170c25da7d46aed959176d652Eric Anholt   /* compute offset of the particular 2D image within the texture region */
5563b38b33c1648b07e75dc4d8340758171e109c598Chad Versace   intel_miptree_get_image_offset(irb->mt,
5573b38b33c1648b07e75dc4d8340758171e109c598Chad Versace				  irb->mt_level,
5583b38b33c1648b07e75dc4d8340758171e109c598Chad Versace				  0, /* face, which we ignore */
5593b38b33c1648b07e75dc4d8340758171e109c598Chad Versace				  irb->mt_layer,
560c0cdae03685056e170c25da7d46aed959176d652Eric Anholt				  &dst_x, &dst_y);
561c0cdae03685056e170c25da7d46aed959176d652Eric Anholt
562b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt   irb->draw_x = dst_x;
563b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt   irb->draw_y = dst_y;
564b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt}
565b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt
566b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt/**
567b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * Rendering to tiled buffers requires that the base address of the
568b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * buffer be aligned to a page boundary.  We generally render to
569b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * textures by pointing the surface at the mipmap image level, which
570b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * may not be aligned to a tile boundary.
571b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt *
572b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * This function returns an appropriately-aligned base offset
573b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * according to the tiling restrictions, plus any required x/y offset
574b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt * from there.
575b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt */
576b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholtuint32_t
577b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholtintel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
578b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt				uint32_t *tile_x,
579b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt				uint32_t *tile_y)
580b17aab5753a6d14c9e757bedb186963b2dae8823Eric Anholt{
581da2816a45e6e3a33246a341fee72e6f893f315d9Chad Versace   struct intel_region *region = irb->mt->region;
5823ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   uint32_t mask_x, mask_y;
5833ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
58496fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry   intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
5853ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
5863ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   *tile_x = irb->draw_x & mask_x;
5873ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   *tile_y = irb->draw_y & mask_y;
5883ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   return intel_region_get_aligned_offset(region, irb->draw_x & ~mask_x,
58968da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry                                          irb->draw_y & ~mask_y, false);
590c0cdae03685056e170c25da7d46aed959176d652Eric Anholt}
59177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
59277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
59377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called by glFramebufferTexture[123]DEXT() (and other places) to
59477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * prepare for rendering into texture memory.  This might be called
59577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * many times to choose different texture levels, cube faces, etc
59677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * before intel_finish_render_texture() is ever called.
59777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
59877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
599f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_render_texture(struct gl_context * ctx,
60077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                     struct gl_framebuffer *fb,
60177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                     struct gl_renderbuffer_attachment *att)
60277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
603c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   struct intel_context *intel = intel_context(ctx);
604d29117752f10d9bcb61e7b26064a872017a64ebeEric Anholt   struct gl_texture_image *image = _mesa_get_attachment_teximage(att);
60577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
606d29117752f10d9bcb61e7b26064a872017a64ebeEric Anholt   struct intel_texture_image *intel_image = intel_texture_image(image);
607c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   struct intel_mipmap_tree *mt = intel_image->mt;
608062a4b601edaaea193397bd5d86fea11ceec04f4Brian Paul   int layer;
60977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
61077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   (void) fb;
61177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
612c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   if (att->CubeMapFace > 0) {
613c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace      assert(att->Zoffset == 0);
614c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace      layer = att->CubeMapFace;
615c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   } else {
616c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace      layer = att->Zoffset;
617c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace   }
618c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace
619e78a6aa2b94683faa8d43a39aa68d806b14f8833Eric Anholt   if (!intel_image->mt) {
620e78a6aa2b94683faa8d43a39aa68d806b14f8833Eric Anholt      /* Fallback on drawing to a texture that doesn't have a miptree
621e78a6aa2b94683faa8d43a39aa68d806b14f8833Eric Anholt       * (has a border, width/height 0, etc.)
6228b661a5d33604fd3706cb1825236d72ae2949598Eric Anholt       */
6235c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
624755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul      _swrast_render_texture(ctx, fb, att);
6255c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul      return;
6265c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul   }
6275c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul   else if (!irb) {
62874484c5d411788c855cf91a2017d763d6a8fb4f2Eric Anholt      intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
62974484c5d411788c855cf91a2017d763d6a8fb4f2Eric Anholt
63074484c5d411788c855cf91a2017d763d6a8fb4f2Eric Anholt      irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0);
631c80b31fdee1fa96b8d45ad2537ecdb5b9151973eChad Versace
63277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      if (irb) {
63377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         /* bind the wrapper to the attachment point */
6349f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul         _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base);
63577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      }
63677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      else {
63777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         /* fallback to software rendering */
638755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul         _swrast_render_texture(ctx, fb, att);
63977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         return;
64077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      }
6415c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul   }
6425c38801f8e36fdb4a16ed33c26454b98f3519465Brian Paul
643b73f5df6483b2e37235b258f705944321ee617f5Eric Anholt   if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
644f94d317d7aea8043b179a0ba64308606375500d7Xiang, Haihao       _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
645755f2e2ae597df9208523b0996bbdabf3db463b0Brian Paul       _swrast_render_texture(ctx, fb, att);
646f94d317d7aea8043b179a0ba64308606375500d7Xiang, Haihao       return;
64777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
64877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
649e2dce7f7ee3e7da9cbb0bb33307ecd79e824426dEric Anholt   irb->tex_image = image;
650e2dce7f7ee3e7da9cbb0bb33307ecd79e824426dEric Anholt
6513d798abc818326a377bbbdaac29058ac7b41e1a0Eric Anholt   DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n",
6523d798abc818326a377bbbdaac29058ac7b41e1a0Eric Anholt       _mesa_get_format_name(image->TexFormat),
653d29117752f10d9bcb61e7b26064a872017a64ebeEric Anholt       att->Texture->Name, image->Width, image->Height,
6549f8ed9d66298e2dc5dff508e3ea723469fe06d93Brian Paul       irb->Base.Base.RefCount);
65577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
65677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   /* update drawing region, etc */
65717fa6772d7e223f940dd8ec4e4f6cf8cab9a03c7Ian Romanick   intel_draw_buffer(ctx);
65877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
65977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
66077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
66177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
66277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Called by Mesa when rendering to a texture is done.
66377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
66477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtstatic void
665f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_finish_render_texture(struct gl_context * ctx,
66677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                            struct gl_renderbuffer_attachment *att)
66777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
668539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt   struct intel_context *intel = intel_context(ctx);
66975bdbdd90b15c8704d87ca195a364ff6a42edbb1Eric Anholt   struct gl_texture_object *tex_obj = att->Texture;
67075bdbdd90b15c8704d87ca195a364ff6a42edbb1Eric Anholt   struct gl_texture_image *image =
67175bdbdd90b15c8704d87ca195a364ff6a42edbb1Eric Anholt      tex_obj->Image[att->CubeMapFace][att->TextureLevel];
672e2dce7f7ee3e7da9cbb0bb33307ecd79e824426dEric Anholt   struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer);
673836803df794be7a2ae3be0fc047e882d49ab22bbEric Anholt
6743d798abc818326a377bbbdaac29058ac7b41e1a0Eric Anholt   DBG("Finish render %s texture tex=%u\n",
6753d798abc818326a377bbbdaac29058ac7b41e1a0Eric Anholt       _mesa_get_format_name(image->TexFormat), att->Texture->Name);
67675bdbdd90b15c8704d87ca195a364ff6a42edbb1Eric Anholt
677e2dce7f7ee3e7da9cbb0bb33307ecd79e824426dEric Anholt   if (irb)
678e2dce7f7ee3e7da9cbb0bb33307ecd79e824426dEric Anholt      irb->tex_image = NULL;
67977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
680539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt   /* Since we've (probably) rendered to the texture and will (likely) use
681539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt    * it in the texture domain later on in this batchbuffer, flush the
682539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt    * batch.  Once again, we wish for a domain tracker in libdrm to cover
683539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt    * usage inside of a batchbuffer like GEM does in the kernel.
684539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt    */
6858d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel_batchbuffer_emit_mi_flush(intel);
686539a14a1dd5a0d277b193d9cd2d06423ed98dc8aEric Anholt}
68777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
68877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**
6893c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul * Do additional "completeness" testing of a framebuffer object.
6903c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul */
6913c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paulstatic void
692f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergintel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
6933c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul{
694a7bf7230564ac282cc957207224d16f322fa73d8Eric Anholt   struct intel_context *intel = intel_context(ctx);
69571b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul   const struct intel_renderbuffer *depthRb =
69671b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul      intel_get_renderbuffer(fb, BUFFER_DEPTH);
69771b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul   const struct intel_renderbuffer *stencilRb =
69871b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul      intel_get_renderbuffer(fb, BUFFER_STENCIL);
6997eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt   struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
7002c30fd84dfa052949a117c78d932b58c1f88b446Eric Anholt   int i;
70171b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul
702308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt   DBG("%s() on fb %p (%s)\n", __FUNCTION__,
703308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt       fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
704308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	    (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer")));
705308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt
7067eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt   if (depthRb)
7077eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt      depth_mt = depthRb->mt;
7080b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt   if (stencilRb) {
7097eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt      stencil_mt = stencilRb->mt;
7100b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt      if (stencil_mt->stencil_mt)
7110b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt	 stencil_mt = stencil_mt->stencil_mt;
7120b8b6c7e974930daf12e97fb8f0b2a2cc29396d9Eric Anholt   }
7137eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt
7147eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt   if (depth_mt && stencil_mt) {
7157eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt      if (depth_mt == stencil_mt) {
7167eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	 /* For true packed depth/stencil (not faked on prefers-separate-stencil
7177eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	  * hardware) we need to be sure they're the same level/layer, since
7187eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	  * we'll be emitting a single packet describing the packed setup.
7197eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	  */
7207eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	 if (depthRb->mt_level != stencilRb->mt_level ||
7217eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	     depthRb->mt_layer != stencilRb->mt_layer) {
722308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	    DBG("depth image level/layer %d/%d != stencil image %d/%d\n",
723308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt		depthRb->mt_level,
724308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt		depthRb->mt_layer,
725308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt		stencilRb->mt_level,
726308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt		stencilRb->mt_layer);
7277eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
7287eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	 }
7297eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt      } else {
730308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	 if (!intel->has_separate_stencil) {
731308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	    DBG("separate stencil unsupported\n");
7327eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
733308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	 }
734308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	 if (stencil_mt->format != MESA_FORMAT_S8) {
735308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	    DBG("separate stencil is %s instead of S8\n",
736308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt		_mesa_get_format_name(stencil_mt->format));
7377eb0aa398b9c0f7d8a224f2a4952f7875067e917Eric Anholt	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
738308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	 }
739ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	 if (intel->gen < 7 && depth_mt->hiz_mt == NULL) {
740ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	    /* Before Gen7, separate depth and stencil buffers can be used
741ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	     * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
742ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	     * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
743ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	     *     [DevSNB]: This field must be set to the same value (enabled
744ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	     *     or disabled) as Hierarchical Depth Buffer Enable.
745ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	     */
746308c6be802fc8d7cd470316ace717aa7bb6b2a08Eric Anholt	    DBG("separate stencil without HiZ\n");
747ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;
748ba5252e590782a77b8a46d9c0ec4691cf8da6298Chad Versace	 }
7498cf2741d2b05fd9f41eca35f0f43e6e0684d57f2Eric Anholt      }
75071b78149bdb3d0d92b004aed29edcf9ea1a440a8Brian Paul   }
751f77b720cde981d441e482bbbd68115634b3041ceBrian Paul
7520ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt   for (i = 0; i < Elements(fb->Attachment); i++) {
7530ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      struct gl_renderbuffer *rb;
7540ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      struct intel_renderbuffer *irb;
7552c30fd84dfa052949a117c78d932b58c1f88b446Eric Anholt
7560ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      if (fb->Attachment[i].Type == GL_NONE)
7572c30fd84dfa052949a117c78d932b58c1f88b446Eric Anholt	 continue;
7582c30fd84dfa052949a117c78d932b58c1f88b446Eric Anholt
7590ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      /* A supported attachment will have a Renderbuffer set either
7600ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt       * from being a Renderbuffer or being a texture that got the
7610ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt       * intel_wrap_texture() treatment.
7620ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt       */
7630ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      rb = fb->Attachment[i].Renderbuffer;
7640ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      if (rb == NULL) {
7650ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt	 DBG("attachment without renderbuffer\n");
7660ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
7670ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt	 continue;
7680ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      }
7690ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt
77087b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick      if (fb->Attachment[i].Type == GL_TEXTURE) {
77187b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	 const struct gl_texture_image *img =
77287b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	    _mesa_get_attachment_teximage_const(&fb->Attachment[i]);
77387b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick
77487b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	 if (img->Border) {
77587b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	    DBG("texture with border\n");
77687b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	    fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
77787b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	    continue;
77887b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick	 }
77987b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick      }
78087b4c9b322dabeba7c9a9d02e9efefd2c89e6625Ian Romanick
7810ea49380e20bdf76cd0e434d3d431ca9f526f1f1Eric Anholt      irb = intel_renderbuffer(rb);
7828bba183b9eeb162661a287bf2e118c6dd419dd24Eric Anholt      if (irb == NULL) {
783e4df8d32b510a3f00c12477985818c9d42a0b178Eric Anholt	 DBG("software rendering renderbuffer\n");
7848bba183b9eeb162661a287bf2e118c6dd419dd24Eric Anholt	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
7858bba183b9eeb162661a287bf2e118c6dd419dd24Eric Anholt	 continue;
7868bba183b9eeb162661a287bf2e118c6dd419dd24Eric Anholt      }
7878bba183b9eeb162661a287bf2e118c6dd419dd24Eric Anholt
788796f44d77906342e5912e7da6bdba1ba86bab9f0Eric Anholt      if (!intel->vtbl.render_target_supported(intel, rb)) {
789925356c8c0b21998a1f53f042269818c19163385Eric Anholt	 DBG("Unsupported HW texture/renderbuffer format attached: %s\n",
790924de7dc96f4607cb3d833637b5f69f4b9e2a6d0Brian Paul	     _mesa_get_format_name(intel_rb_format(irb)));
7912c30fd84dfa052949a117c78d932b58c1f88b446Eric Anholt	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
792f77b720cde981d441e482bbbd68115634b3041ceBrian Paul      }
793f77b720cde981d441e482bbbd68115634b3041ceBrian Paul   }
7943c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul}
7953c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul
796c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts/**
797c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
798c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts * We can do this when the dst renderbuffer is actually a texture and
799c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts * there is no scaling, mirroring or scissoring.
800c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts *
801c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts * \return new buffer mask indicating the buffers left to blit using the
802c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts *         normal path.
803c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts */
804c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Robertsstatic GLbitfield
805c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Robertsintel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
806c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                          GLint srcX0, GLint srcY0,
807c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                          GLint srcX1, GLint srcY1,
808c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                          GLint dstX0, GLint dstY0,
809c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                          GLint dstX1, GLint dstY1,
810c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                          GLbitfield mask, GLenum filter)
811c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts{
812c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   if (mask & GL_COLOR_BUFFER_BIT) {
813c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
814c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
815c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      const struct gl_renderbuffer_attachment *drawAtt =
816c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
81756b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul      struct intel_renderbuffer *srcRb =
81856b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul         intel_renderbuffer(readFb->_ColorReadBuffer);
819c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
820c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      /* If the source and destination are the same size with no
821c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         mirroring, the rectangles are within the size of the
822c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         texture and there is no scissor then we can use
823c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         glCopyTexSubimage2D to implement the blit. This will end
824c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         up as a fast hardware blit on some drivers */
82556b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul      if (srcRb && drawAtt && drawAtt->Texture &&
826c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcX0 - srcX1 == dstX0 - dstX1 &&
827c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcY0 - srcY1 == dstY0 - dstY1 &&
828c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcX1 >= srcX0 &&
829c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcY1 >= srcY0 &&
830c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcX0 >= 0 && srcX1 <= readFb->Width &&
831c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          srcY0 >= 0 && srcY1 <= readFb->Height &&
832c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          dstX0 >= 0 && dstX1 <= drawFb->Width &&
833c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          dstY0 >= 0 && dstY1 <= drawFb->Height &&
834c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts          !ctx->Scissor.Enabled) {
835c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         const struct gl_texture_object *texObj = drawAtt->Texture;
836c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         const GLuint dstLevel = drawAtt->TextureLevel;
837c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         const GLenum target = texObj->Target;
838c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
839c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts         struct gl_texture_image *texImage =
840c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts            _mesa_select_tex_image(ctx, texObj, target, dstLevel);
841c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
842bd817215c893cda4f23cb0ad207478ad3935e65cIan Romanick         if (intel_copy_texsubimage(intel_context(ctx),
843c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                    intel_texture_image(texImage),
844c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                    dstX0, dstY0,
84556b57aa360a8bad0c4b68fbdf7c64ac33f9e7661Brian Paul                                    srcRb,
846c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                    srcX0, srcY0,
847c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                    srcX1 - srcX0, /* width */
848c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                    srcY1 - srcY0))
849c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts            mask &= ~GL_COLOR_BUFFER_BIT;
850c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      }
851c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   }
852c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
853c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   return mask;
854c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts}
855c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
856c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Robertsstatic void
857c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Robertsintel_blit_framebuffer(struct gl_context *ctx,
858c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
859c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
860c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                       GLbitfield mask, GLenum filter)
861c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts{
862c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */
863c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   mask = intel_blit_framebuffer_copy_tex_sub_image(ctx,
864c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                                    srcX0, srcY0, srcX1, srcY1,
865c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                                    dstX0, dstY0, dstX1, dstY1,
866c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                                                    mask, filter);
867c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   if (mask == 0x0)
868c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts      return;
869c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts
870506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#ifndef I915
871506d70be21cd3469118de89297cba0c0f709c1aePaul Berry   mask = brw_blorp_framebuffer(intel_context(ctx),
872506d70be21cd3469118de89297cba0c0f709c1aePaul Berry                                srcX0, srcY0, srcX1, srcY1,
873506d70be21cd3469118de89297cba0c0f709c1aePaul Berry                                dstX0, dstY0, dstX1, dstY1,
874506d70be21cd3469118de89297cba0c0f709c1aePaul Berry                                mask, filter);
875506d70be21cd3469118de89297cba0c0f709c1aePaul Berry   if (mask == 0x0)
876506d70be21cd3469118de89297cba0c0f709c1aePaul Berry      return;
877506d70be21cd3469118de89297cba0c0f709c1aePaul Berry#endif
878506d70be21cd3469118de89297cba0c0f709c1aePaul Berry
879c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   _mesa_meta_BlitFramebuffer(ctx,
880c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                              srcX0, srcY0, srcX1, srcY1,
881c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                              dstX0, dstY0, dstX1, dstY1,
882c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts                              mask, filter);
883c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts}
8843c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul
8856b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace/**
8866b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace * This is a no-op except on multisample buffers shared with DRI2.
8876b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace */
8886b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versacevoid
8896b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versaceintel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb)
8906b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace{
8916b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace   if (irb->mt && irb->mt->singlesample_mt)
8926b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace      irb->mt->need_downsample = true;
8936b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace}
8946b56140b4bafcef8bea5ca67cb31023a533c3bd4Chad Versace
8951383e56bd916f9fc4357a6224aac4e8c691303cbChad Versacevoid
8961383e56bd916f9fc4357a6224aac4e8c691303cbChad Versaceintel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
8971383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace{
8981383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   if (irb->mt) {
8991383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace      intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
9001383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                                irb->mt_level,
9011383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                                irb->mt_layer);
9021383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   }
9031383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace}
9041383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9051383e56bd916f9fc4357a6224aac4e8c691303cbChad Versacevoid
9061383e56bd916f9fc4357a6224aac4e8c691303cbChad Versaceintel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
9071383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace{
9081383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   if (irb->mt) {
9091383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace      intel_miptree_slice_set_needs_depth_resolve(irb->mt,
9101383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                                  irb->mt_level,
9111383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                                  irb->mt_layer);
9121383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   }
9131383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace}
9141383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9151383e56bd916f9fc4357a6224aac4e8c691303cbChad Versacebool
9161383e56bd916f9fc4357a6224aac4e8c691303cbChad Versaceintel_renderbuffer_resolve_hiz(struct intel_context *intel,
9171383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace			       struct intel_renderbuffer *irb)
9181383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace{
9191383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   if (irb->mt)
9201383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace      return intel_miptree_slice_resolve_hiz(intel,
9211383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                             irb->mt,
9221383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                             irb->mt_level,
9231383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                             irb->mt_layer);
9241383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9251383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   return false;
9261383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace}
9271383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9281383e56bd916f9fc4357a6224aac4e8c691303cbChad Versacebool
9291383e56bd916f9fc4357a6224aac4e8c691303cbChad Versaceintel_renderbuffer_resolve_depth(struct intel_context *intel,
9301383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace				 struct intel_renderbuffer *irb)
9311383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace{
9321383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   if (irb->mt)
9331383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace      return intel_miptree_slice_resolve_depth(intel,
9341383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                               irb->mt,
9351383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                               irb->mt_level,
9361383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace                                               irb->mt_layer);
9371383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9381383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace   return false;
9391383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace}
9401383e56bd916f9fc4357a6224aac4e8c691303cbChad Versace
9413c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul/**
94277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Do one-time context initializations related to GL_EXT_framebuffer_object.
94377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Hook in device driver functions.
94477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
94577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtvoid
94677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtintel_fbo_init(struct intel_context *intel)
94777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
94877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
94977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
95092054cd94e2188c9f4d56ddf9377c5aeb8a4e64eEric Anholt   intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
95192054cd94e2188c9f4d56ddf9377c5aeb8a4e64eEric Anholt   intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
95277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
95377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
95477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.RenderTexture = intel_render_texture;
95577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
95677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
9573c98d3cf32e1828b116173f97dc6d4d4a609951cBrian Paul   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
958c0ad70ae31ee5501281b434d56e389fc92b13a3aNeil Roberts   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
95910e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg
96010e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg#if FEATURE_OES_EGL_image
96110e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
96210e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg      intel_image_target_renderbuffer_storage;
96310e79627414bc2bbc72d68ed25fb9999948a294fKristian Høgsberg#endif
96477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
965