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