st_atom_framebuffer.c revision 162b3ad94d52b28d83462202952987012387e12f
12cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner/**************************************************************************
2c140c4803dc3e10e08138670829bc0494986abe9David Goodwin *
3c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * All Rights Reserved.
5c140c4803dc3e10e08138670829bc0494986abe9David Goodwin *
6c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * Permission is hereby granted, free of charge, to any person obtaining a
7c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * copy of this software and associated documentation files (the
8c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * "Software"), to deal in the Software without restriction, including
9c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * without limitation the rights to use, copy, modify, merge, publish,
10c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * distribute, sub license, and/or sell copies of the Software, and to
11c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * permit persons to whom the Software is furnished to do so, subject to
12c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * the following conditions:
13c140c4803dc3e10e08138670829bc0494986abe9David Goodwin *
14c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * The above copyright notice and this permission notice (including the
15c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * next paragraph) shall be included in all copies or substantial portions
16db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin * of the Software.
17c140c4803dc3e10e08138670829bc0494986abe9David Goodwin *
18c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
239adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
249adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25c140c4803dc3e10e08138670829bc0494986abe9David Goodwin *
26c140c4803dc3e10e08138670829bc0494986abe9David Goodwin **************************************************************************/
27c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
28c140c4803dc3e10e08138670829bc0494986abe9David Goodwin /*
29c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  * Authors:
30c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  *   Keith Whitwell <keith@tungstengraphics.com>
31c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  *   Brian Paul
323dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  */
33ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin
34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "st_context.h"
35c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "st_atom.h"
36c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "st_cb_bitmap.h"
37c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "st_cb_fbo.h"
38c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "st_texture.h"
39c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "pipe/p_context.h"
4018ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach#include "cso_cache/cso_context.h"
41c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "util/u_math.h"
428c407d45964fbba19719be555324f247e4fb14e1Dan Gohman#include "util/u_inlines.h"
43a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach#include "util/u_format.h"
443197380143cdc18837722129ac888528b9fbfc2bJim Grosbach
45cd59dc5e81eb080cd9b61f5a7e7d9f3eec206d8cJim Grosbach
46a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach/**
47ae47c6d69e2e34bc558a302586cbc3f27a6d7334Jim Grosbach * When doing GL render to texture, we have to be sure that finalize_texture()
48a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach * didn't yank out the pipe_resource that we earlier created a surface for.
498c407d45964fbba19719be555324f247e4fb14e1Dan Gohman * Check for that here and create a new surface if needed.
508c407d45964fbba19719be555324f247e4fb14e1Dan Gohman */
518c407d45964fbba19719be555324f247e4fb14e1Dan Gohmanstatic void
5218ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbachupdate_renderbuffer_surface(struct st_context *st,
53c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                            struct st_renderbuffer *strb)
548295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng{
558295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   struct pipe_context *pipe = st->pipe;
568295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   struct pipe_resource *resource = strb->rtt->pt;
57c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   int rtt_width = strb->Base.Width;
58c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   int rtt_height = strb->Base.Height;
59c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format);
60c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
61c23197a26f34f559ea9797de51e187087c039c42Torok Edwin   if (!strb->surface ||
628295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng       strb->surface->format != format ||
638295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng       strb->surface->texture != resource ||
648295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng       strb->surface->width != rtt_width ||
658295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng       strb->surface->height != rtt_height) {
668295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      GLuint level;
678295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      /* find matching mipmap level size */
688295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      for (level = 0; level <= resource->last_level; level++) {
698295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng         if (u_minify(resource->width0, level) == rtt_width &&
708295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng             u_minify(resource->height0, level) == rtt_height) {
718295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            struct pipe_surface surf_tmpl;
728295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            memset(&surf_tmpl, 0, sizeof(surf_tmpl));
738295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            surf_tmpl.format = format;
748295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
758295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            surf_tmpl.u.tex.level = level;
768295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
778295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
788295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng
798295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            pipe_surface_reference(&strb->surface, NULL);
808295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng
818295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            strb->surface = pipe->create_surface(pipe,
828295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                                                 resource,
838295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                                                 &surf_tmpl);
848295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng#if 0
858295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng            printf("-- alloc new surface %d x %d into tex %p\n",
868295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                   strb->surface->width, strb->surface->height,
878295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                   texture);
888295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng#endif
8998330ff8e344d2e88c0a2166901d394e813e8162Bob Wilson            break;
908295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng         }
918295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      }
928295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   }
938295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng}
948295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng
95c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
96c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/**
97c140c4803dc3e10e08138670829bc0494986abe9David Goodwin * Update framebuffer state (color, depth, stencil, etc. buffers)
98c140c4803dc3e10e08138670829bc0494986abe9David Goodwin */
99c140c4803dc3e10e08138670829bc0494986abe9David Goodwinstatic void
100c140c4803dc3e10e08138670829bc0494986abe9David Goodwinupdate_framebuffer_state( struct st_context *st )
101c140c4803dc3e10e08138670829bc0494986abe9David Goodwin{
102c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer;
1038295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   struct gl_framebuffer *fb = st->ctx->DrawBuffer;
1048295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   struct st_renderbuffer *strb;
1058295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng   GLuint i;
106c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
107c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   st_flush_bitmap_cache(st);
108c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
109c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   st->state.fb_orientation = st_fb_orientation(fb);
110c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   framebuffer->width = fb->Width;
111c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   framebuffer->height = fb->Height;
112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
113c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/
114c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
115c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
116c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    * to determine which surfaces to draw to
117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    */
118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   framebuffer->nr_cbufs = 0;
119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      strb = st_renderbuffer(fb->_ColorDrawBuffers[i]);
121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
122c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (strb) {
123c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
124c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         if (strb->rtt) {
125c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            /* rendering to a GL texture, may have to update surface */
126c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            update_renderbuffer_surface(st, strb);
127c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         }
128c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
129c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         if (strb->surface) {
130c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs],
131c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                   strb->surface);
132c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            framebuffer->nr_cbufs++;
133c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         }
134c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         strb->defined = GL_TRUE; /* we'll be drawing something */
135c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
136c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
137c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
138c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      pipe_surface_reference(&framebuffer->cbufs[i], NULL);
139c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
140c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
141c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   /*
142c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    * Depth/Stencil renderbuffer/surface.
143c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    */
144c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
145db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin   if (strb) {
146c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (strb->rtt) {
147c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         /* rendering to a GL texture, may have to update surface */
148c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         update_renderbuffer_surface(st, strb);
149c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
150c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
151c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
152c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   else {
153c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
154c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (strb) {
155c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         assert(strb->surface);
156c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
157c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
158c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
159c140c4803dc3e10e08138670829bc0494986abe9David Goodwin         pipe_surface_reference(&framebuffer->zsbuf, NULL);
160c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
161c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
162c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#ifdef DEBUG
163c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   /* Make sure the resource binding flags were set properly */
164c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   for (i = 0; i < framebuffer->nr_cbufs; i++) {
165c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      assert(framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET);
166c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
167c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   if (framebuffer->zsbuf) {
168c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      assert(framebuffer->zsbuf->texture->bind & PIPE_BIND_DEPTH_STENCIL);
169c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   }
170c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#endif
171c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
172c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   cso_set_framebuffer(st->cso_context, framebuffer);
173c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
174c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
175c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1769631864688c593711f82bb8d21f8b724c628d786Jim Grosbachconst struct st_tracked_state st_update_framebuffer = {
1779631864688c593711f82bb8d21f8b724c628d786Jim Grosbach   "st_update_framebuffer",				/* name */
178c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   {							/* dirty */
179c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      _NEW_BUFFERS,					/* mesa */
180c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ST_NEW_FRAMEBUFFER,				/* st */
181c140c4803dc3e10e08138670829bc0494986abe9David Goodwin   },
182d1fb583128c6682bb8a7c74eafa810a9270cc8dfNate Begeman   update_framebuffer_state				/* update */
183ac096808a3accc516ae7c193c9a2c1392bf3301aEvan Cheng};
184c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
185c140c4803dc3e10e08138670829bc0494986abe9David Goodwin