Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  /*
  29.   * Authors:
  30.   *   Keith Whitwell <keith@tungstengraphics.com>
  31.   *   Brian Paul
  32.   */
  33.  
  34. #include "st_context.h"
  35. #include "st_atom.h"
  36. #include "st_cb_bitmap.h"
  37. #include "st_cb_fbo.h"
  38. #include "st_texture.h"
  39. #include "pipe/p_context.h"
  40. #include "cso_cache/cso_context.h"
  41. #include "util/u_math.h"
  42. #include "util/u_inlines.h"
  43. #include "util/u_format.h"
  44.  
  45.  
  46. /**
  47.  * When doing GL render to texture, we have to be sure that finalize_texture()
  48.  * didn't yank out the pipe_resource that we earlier created a surface for.
  49.  * Check for that here and create a new surface if needed.
  50.  */
  51. static void
  52. update_renderbuffer_surface(struct st_context *st,
  53.                             struct st_renderbuffer *strb)
  54. {
  55.    struct pipe_context *pipe = st->pipe;
  56.    struct pipe_resource *resource = strb->rtt ? strb->rtt->pt : strb->texture;
  57.    int rtt_width = strb->Base.Width;
  58.    int rtt_height = strb->Base.Height;
  59.    enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format);
  60.  
  61.    if (!strb->surface ||
  62.        strb->surface->texture->nr_samples != strb->Base.NumSamples ||
  63.        strb->surface->format != format ||
  64.        strb->surface->texture != resource ||
  65.        strb->surface->width != rtt_width ||
  66.        strb->surface->height != rtt_height) {
  67.       GLuint level;
  68.       /* find matching mipmap level size */
  69.       for (level = 0; level <= resource->last_level; level++) {
  70.          if (u_minify(resource->width0, level) == rtt_width &&
  71.              u_minify(resource->height0, level) == rtt_height) {
  72.             struct pipe_surface surf_tmpl;
  73.             memset(&surf_tmpl, 0, sizeof(surf_tmpl));
  74.             surf_tmpl.format = format;
  75.             surf_tmpl.u.tex.level = level;
  76.             surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
  77.             surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
  78.  
  79.             pipe_surface_reference(&strb->surface, NULL);
  80.  
  81.             strb->surface = pipe->create_surface(pipe,
  82.                                                  resource,
  83.                                                  &surf_tmpl);
  84. #if 0
  85.             printf("-- alloc new surface %d x %d into tex %p\n",
  86.                    strb->surface->width, strb->surface->height,
  87.                    texture);
  88. #endif
  89.             break;
  90.          }
  91.       }
  92.    }
  93. }
  94.  
  95.  
  96. /**
  97.  * Update framebuffer state (color, depth, stencil, etc. buffers)
  98.  */
  99. static void
  100. update_framebuffer_state( struct st_context *st )
  101. {
  102.    struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer;
  103.    struct gl_framebuffer *fb = st->ctx->DrawBuffer;
  104.    struct st_renderbuffer *strb;
  105.    GLuint i;
  106.  
  107.    st_flush_bitmap_cache(st);
  108.  
  109.    st->state.fb_orientation = st_fb_orientation(fb);
  110.    framebuffer->width = fb->Width;
  111.    framebuffer->height = fb->Height;
  112.  
  113.    /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/
  114.  
  115.    /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
  116.     * to determine which surfaces to draw to
  117.     */
  118.    framebuffer->nr_cbufs = 0;
  119.    for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
  120.       strb = st_renderbuffer(fb->_ColorDrawBuffers[i]);
  121.  
  122.       if (strb) {
  123.          /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
  124.          if (strb->rtt ||
  125.              (strb->texture && util_format_is_srgb(strb->texture->format))) {
  126.             /* rendering to a GL texture, may have to update surface */
  127.             update_renderbuffer_surface(st, strb);
  128.          }
  129.  
  130.          if (strb->surface) {
  131.             pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs],
  132.                                    strb->surface);
  133.             framebuffer->nr_cbufs++;
  134.          }
  135.          strb->defined = GL_TRUE; /* we'll be drawing something */
  136.       }
  137.    }
  138.    for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
  139.       pipe_surface_reference(&framebuffer->cbufs[i], NULL);
  140.    }
  141.  
  142.    /*
  143.     * Depth/Stencil renderbuffer/surface.
  144.     */
  145.    strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
  146.    if (strb) {
  147.       if (strb->rtt) {
  148.          /* rendering to a GL texture, may have to update surface */
  149.          update_renderbuffer_surface(st, strb);
  150.       }
  151.       pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
  152.    }
  153.    else {
  154.       strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
  155.       if (strb) {
  156.          assert(strb->surface);
  157.          pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
  158.       }
  159.       else
  160.          pipe_surface_reference(&framebuffer->zsbuf, NULL);
  161.    }
  162.  
  163. #ifdef DEBUG
  164.    /* Make sure the resource binding flags were set properly */
  165.    for (i = 0; i < framebuffer->nr_cbufs; i++) {
  166.       assert(framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET);
  167.    }
  168.    if (framebuffer->zsbuf) {
  169.       assert(framebuffer->zsbuf->texture->bind & PIPE_BIND_DEPTH_STENCIL);
  170.    }
  171. #endif
  172.  
  173.    cso_set_framebuffer(st->cso_context, framebuffer);
  174. }
  175.  
  176.  
  177. const struct st_tracked_state st_update_framebuffer = {
  178.    "st_update_framebuffer",                             /* name */
  179.    {                                                    /* dirty */
  180.       _NEW_BUFFERS,                                     /* mesa */
  181.       ST_NEW_FRAMEBUFFER,                               /* st */
  182.    },
  183.    update_framebuffer_state                             /* update */
  184. };
  185.  
  186.