14b87d37e90b6d2d9562a192540833b599bda5a35Brian/**************************************************************************
24b87d37e90b6d2d9562a192540833b599bda5a35Brian *
34b87d37e90b6d2d9562a192540833b599bda5a35Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
44b87d37e90b6d2d9562a192540833b599bda5a35Brian * All Rights Reserved.
54b87d37e90b6d2d9562a192540833b599bda5a35Brian *
64b87d37e90b6d2d9562a192540833b599bda5a35Brian * Permission is hereby granted, free of charge, to any person obtaining a
74b87d37e90b6d2d9562a192540833b599bda5a35Brian * copy of this software and associated documentation files (the
84b87d37e90b6d2d9562a192540833b599bda5a35Brian * "Software"), to deal in the Software without restriction, including
94b87d37e90b6d2d9562a192540833b599bda5a35Brian * without limitation the rights to use, copy, modify, merge, publish,
104b87d37e90b6d2d9562a192540833b599bda5a35Brian * distribute, sub license, and/or sell copies of the Software, and to
114b87d37e90b6d2d9562a192540833b599bda5a35Brian * permit persons to whom the Software is furnished to do so, subject to
124b87d37e90b6d2d9562a192540833b599bda5a35Brian * the following conditions:
134b87d37e90b6d2d9562a192540833b599bda5a35Brian *
144b87d37e90b6d2d9562a192540833b599bda5a35Brian * The above copyright notice and this permission notice (including the
154b87d37e90b6d2d9562a192540833b599bda5a35Brian * next paragraph) shall be included in all copies or substantial portions
164b87d37e90b6d2d9562a192540833b599bda5a35Brian * of the Software.
174b87d37e90b6d2d9562a192540833b599bda5a35Brian *
184b87d37e90b6d2d9562a192540833b599bda5a35Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194b87d37e90b6d2d9562a192540833b599bda5a35Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204b87d37e90b6d2d9562a192540833b599bda5a35Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
214b87d37e90b6d2d9562a192540833b599bda5a35Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
224b87d37e90b6d2d9562a192540833b599bda5a35Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234b87d37e90b6d2d9562a192540833b599bda5a35Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244b87d37e90b6d2d9562a192540833b599bda5a35Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254b87d37e90b6d2d9562a192540833b599bda5a35Brian *
264b87d37e90b6d2d9562a192540833b599bda5a35Brian **************************************************************************/
274b87d37e90b6d2d9562a192540833b599bda5a35Brian
284b87d37e90b6d2d9562a192540833b599bda5a35Brian
294b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
304b87d37e90b6d2d9562a192540833b599bda5a35Brian * Framebuffer/renderbuffer functions.
314b87d37e90b6d2d9562a192540833b599bda5a35Brian *
324b87d37e90b6d2d9562a192540833b599bda5a35Brian * \author Brian Paul
334b87d37e90b6d2d9562a192540833b599bda5a35Brian */
344b87d37e90b6d2d9562a192540833b599bda5a35Brian
354b87d37e90b6d2d9562a192540833b599bda5a35Brian
364b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "main/imports.h"
374b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "main/context.h"
384b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "main/fbobject.h"
394b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "main/framebuffer.h"
406352f4c854e9ec39c440054109ccb92caa5ff0bbBrian Paul#include "main/macros.h"
41edc09358f72cd48cb2315daf23c82e7646aeaea3Vinson Lee#include "main/mfeatures.h"
424b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "main/renderbuffer.h"
434b87d37e90b6d2d9562a192540833b599bda5a35Brian
444b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "pipe/p_context.h"
454b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "pipe/p_defines.h"
46adfbba476db1fc55006efb748656ebb1a481d143Zack Rusin#include "pipe/p_screen.h"
474b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "st_context.h"
484b87d37e90b6d2d9562a192540833b599bda5a35Brian#include "st_cb_fbo.h"
49da8412ec19ad00627ae9139dc02f46f344bbb6acChia-I Wu#include "st_cb_flush.h"
50de414f491526610bb260c73805c81ba413388e20Michel Dänzer#include "st_cb_texture.h"
51f8ab24760d0d3f07e9ee81c98207ddf92dfe74daBrian#include "st_format.h"
5258edb0683db45c449b219988a8715cf8fd69e42dBrian#include "st_texture.h"
53de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu#include "st_manager.h"
544b87d37e90b6d2d9562a192540833b599bda5a35Brian
55d28740c298968303500a8c43047ded2679e727acMichal Krol#include "util/u_format.h"
5628486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#include "util/u_surface.h"
584b87d37e90b6d2d9562a192540833b599bda5a35Brian
594b87d37e90b6d2d9562a192540833b599bda5a35Brian
60e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšákstatic GLboolean
61e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšákst_renderbuffer_alloc_sw_storage(struct gl_context * ctx,
62e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                 struct gl_renderbuffer *rb,
63e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                 GLenum internalFormat,
64e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                 GLuint width, GLuint height)
65e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák{
66e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   struct pipe_screen *screen = st_context(ctx)->pipe->screen;
67e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   struct st_renderbuffer *strb = st_renderbuffer(rb);
68e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   enum pipe_format format;
69e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   size_t size;
70e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
71e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   free(strb->data);
72e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->data = NULL;
73e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
74e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (internalFormat == GL_RGBA16_SNORM) {
75e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      /* Special case for software accum buffers.  Otherwise, if the
76e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák       * call to st_choose_renderbuffer_format() fails (because the
77e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák       * driver doesn't support signed 16-bit/channel colors) we'd
78e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák       * just return without allocating the software accum buffer.
79e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák       */
80e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      format = PIPE_FORMAT_R16G16B16A16_SNORM;
81e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   }
82e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   else {
83e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      format = st_choose_renderbuffer_format(screen, internalFormat, 0);
84e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
85c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák      /* Not setting gl_renderbuffer::Format here will cause
86c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák       * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called.
87c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák       */
88c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák      if (format == PIPE_FORMAT_NONE) {
89c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák         return GL_TRUE;
90c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák      }
91e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   }
92e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
93e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->Base.Format = st_pipe_format_to_mesa_format(format);
94e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
95e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   size = _mesa_format_image_size(strb->Base.Format, width, height, 1);
96e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->data = malloc(size);
97e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   return strb->data != NULL;
98e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák}
99e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
100e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
1014b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
10202f7f46fa15c7d31d774c638684d4f5b81e360ecBrian * gl_renderbuffer::AllocStorage()
1032b2d0e05842691e715782a64845aeca12a428427Brian Paul * This is called to allocate the original drawing surface, and
1042b2d0e05842691e715782a64845aeca12a428427Brian Paul * during window resize.
10502f7f46fa15c7d31d774c638684d4f5b81e360ecBrian */
10602f7f46fa15c7d31d774c638684d4f5b81e360ecBrianstatic GLboolean
10735266fbe4f2d11093e71ef41083d9d733aac5869Brian Paulst_renderbuffer_alloc_storage(struct gl_context * ctx,
10835266fbe4f2d11093e71ef41083d9d733aac5869Brian Paul                              struct gl_renderbuffer *rb,
10902f7f46fa15c7d31d774c638684d4f5b81e360ecBrian                              GLenum internalFormat,
11002f7f46fa15c7d31d774c638684d4f5b81e360ecBrian                              GLuint width, GLuint height)
11102f7f46fa15c7d31d774c638684d4f5b81e360ecBrian{
11276c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
1134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_context *pipe = st->pipe;
11476c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct pipe_screen *screen = st->pipe->screen;
11502f7f46fa15c7d31d774c638684d4f5b81e360ecBrian   struct st_renderbuffer *strb = st_renderbuffer(rb);
1167c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák   enum pipe_format format = PIPE_FORMAT_NONE;
1174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_surface surf_tmpl;
118e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   struct pipe_resource templ;
119b2021e7c06a9ec13b82eeeb352ad2408fe060518Keith Whitwell
120e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   /* init renderbuffer fields */
121e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->Base.Width  = width;
122e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->Base.Height = height;
123e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
124e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->defined = GL_FALSE;  /* undefined contents now */
125e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
126e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (strb->software) {
127e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      return st_renderbuffer_alloc_sw_storage(ctx, rb, internalFormat,
128e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                              width, height);
129c87d1a3c3d24924f8af082e47c18a6d535419089Brian Paul   }
130fb5d9e1199cabe653ae1bb822bb66ce9f0ce7f55Marek Olšák
131e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   /* Free the old surface and texture
132e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák    */
133e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   pipe_surface_reference( &strb->surface, NULL );
134e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   pipe_resource_reference( &strb->texture, NULL );
135e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
1367c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák   /* Handle multisample renderbuffers first.
1377c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *
1387c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    * From ARB_framebuffer_object:
1397c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero.
1407c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   Otherwise <samples> represents a request for a desired minimum
1417c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   number of samples. Since different implementations may support
1427c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   different sample counts for multisampled rendering, the actual
1437c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   number of samples allocated for the renderbuffer image is
1447c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   implementation dependent.  However, the resulting value for
1457c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal
1467c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   to <samples> and no more than the next larger sample count supported
1477c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *   by the implementation.
1487c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    *
1497c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    * So let's find the supported number of samples closest to NumSamples.
1507c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    * (NumSamples == 1) is treated the same as (NumSamples == 0).
1517c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák    */
1527c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák   if (rb->NumSamples > 1) {
1537c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák      unsigned i;
1547c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák
1557c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák      for (i = rb->NumSamples; i <= ctx->Const.MaxSamples; i++) {
1567c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák         format = st_choose_renderbuffer_format(screen, internalFormat, i);
1577c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák
1587c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák         if (format != PIPE_FORMAT_NONE) {
1597c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák            rb->NumSamples = i;
1607c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák            break;
1617c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák         }
1627c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák      }
1637c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák   } else {
1647c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák      format = st_choose_renderbuffer_format(screen, internalFormat, 0);
1657c3786d780e1c475b219c3f2ddbe33554177be02Marek Olšák   }
166e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
167c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák   /* Not setting gl_renderbuffer::Format here will cause
168c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák    * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called.
169c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák    */
170fb5d9e1199cabe653ae1bb822bb66ce9f0ce7f55Marek Olšák   if (format == PIPE_FORMAT_NONE) {
171c760283159dbf3607b0f072b0d1ff50859feb3f4Marek Olšák      return GL_TRUE;
172fb5d9e1199cabe653ae1bb822bb66ce9f0ce7f55Marek Olšák   }
173fb5d9e1199cabe653ae1bb822bb66ce9f0ce7f55Marek Olšák
174d7de632de39888dbc955055ba0eb3623e5335992Brian Paul   strb->Base.Format = st_pipe_format_to_mesa_format(format);
175a73ae3d5eb8419feab5aea26573aa41b72f941ebKeith Whitwell
176e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (width == 0 || height == 0) {
177e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      /* if size is zero, nothing to allocate */
178e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      return GL_TRUE;
179e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   }
180b85b315ebbe25efbd118887bdc87a562d4334fccBrian Paul
181e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   /* Setup new texture template.
182e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák    */
183e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   memset(&templ, 0, sizeof(templ));
184e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.target = st->internal_target;
185e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.format = format;
186e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.width0 = width;
187e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.height0 = height;
188e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.depth0 = 1;
189e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.array_size = 1;
190e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   templ.nr_samples = rb->NumSamples;
191e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (util_format_is_depth_or_stencil(format)) {
192e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      templ.bind = PIPE_BIND_DEPTH_STENCIL;
193e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   }
194e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   else if (strb->Base.Name != 0) {
195e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      /* this is a user-created renderbuffer */
196e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      templ.bind = PIPE_BIND_RENDER_TARGET;
19752411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca   }
19852411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca   else {
199e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      /* this is a window-system buffer */
200e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      templ.bind = (PIPE_BIND_DISPLAY_TARGET |
201e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                    PIPE_BIND_RENDER_TARGET);
202e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   }
2034a159132082429d5492f5298c2ccb0df551c9f65Keith Whitwell
204e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->texture = screen->resource_create(screen, &templ);
20568564726898308c9fd7ac63169bfc2e2012d6fe3Brian Paul
206e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (!strb->texture)
207e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      return FALSE;
208e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
209e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   u_surface_default_template(&surf_tmpl, strb->texture, templ.bind);
210e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   strb->surface = pipe->create_surface(pipe,
211e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                        strb->texture,
212e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák                                        &surf_tmpl);
213e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   if (strb->surface) {
214e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      assert(strb->surface->texture);
215e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      assert(strb->surface->format);
216e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      assert(strb->surface->width == width);
217e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák      assert(strb->surface->height == height);
21852411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca   }
219e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák
220e4b2e6b5270644c267892fae07d919b494cc4397Marek Olšák   return strb->surface != NULL;
2214b87d37e90b6d2d9562a192540833b599bda5a35Brian}
2224b87d37e90b6d2d9562a192540833b599bda5a35Brian
2234b87d37e90b6d2d9562a192540833b599bda5a35Brian
2244b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
2254b87d37e90b6d2d9562a192540833b599bda5a35Brian * gl_renderbuffer::Delete()
2264b87d37e90b6d2d9562a192540833b599bda5a35Brian */
2274b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic void
2289d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paulst_renderbuffer_delete(struct gl_context *ctx, struct gl_renderbuffer *rb)
2294b87d37e90b6d2d9562a192540833b599bda5a35Brian{
2304b87d37e90b6d2d9562a192540833b599bda5a35Brian   struct st_renderbuffer *strb = st_renderbuffer(rb);
231d32aff91c1c42b3f8bfb6c4109a8ea79c1f46d8dBrian Paul   if (ctx) {
232d32aff91c1c42b3f8bfb6c4109a8ea79c1f46d8dBrian Paul      struct st_context *st = st_context(ctx);
233d32aff91c1c42b3f8bfb6c4109a8ea79c1f46d8dBrian Paul      pipe_surface_release(st->pipe, &strb->surface);
234d32aff91c1c42b3f8bfb6c4109a8ea79c1f46d8dBrian Paul   }
235287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&strb->texture, NULL);
23632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(strb->data);
2379d4ab9a663d4088ec553edaae0eeafb746d2490dBrian Paul   _mesa_delete_renderbuffer(ctx, rb);
2384b87d37e90b6d2d9562a192540833b599bda5a35Brian}
2394b87d37e90b6d2d9562a192540833b599bda5a35Brian
2404b87d37e90b6d2d9562a192540833b599bda5a35Brian
2414b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
2424b87d37e90b6d2d9562a192540833b599bda5a35Brian * Called via ctx->Driver.NewFramebuffer()
2434b87d37e90b6d2d9562a192540833b599bda5a35Brian */
2444b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic struct gl_framebuffer *
245f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_new_framebuffer(struct gl_context *ctx, GLuint name)
2464b87d37e90b6d2d9562a192540833b599bda5a35Brian{
2474b87d37e90b6d2d9562a192540833b599bda5a35Brian   /* XXX not sure we need to subclass gl_framebuffer for pipe */
2484b87d37e90b6d2d9562a192540833b599bda5a35Brian   return _mesa_new_framebuffer(ctx, name);
2494b87d37e90b6d2d9562a192540833b599bda5a35Brian}
2504b87d37e90b6d2d9562a192540833b599bda5a35Brian
2514b87d37e90b6d2d9562a192540833b599bda5a35Brian
2524b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
2534b87d37e90b6d2d9562a192540833b599bda5a35Brian * Called via ctx->Driver.NewRenderbuffer()
2544b87d37e90b6d2d9562a192540833b599bda5a35Brian */
2554b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic struct gl_renderbuffer *
256f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_new_renderbuffer(struct gl_context *ctx, GLuint name)
2574b87d37e90b6d2d9562a192540833b599bda5a35Brian{
258f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul   struct st_renderbuffer *strb = ST_CALLOC_STRUCT(st_renderbuffer);
2594b87d37e90b6d2d9562a192540833b599bda5a35Brian   if (strb) {
2605a70e12fc0897a3178c73b20d99fc0f11b180374Brian Paul      assert(name != 0);
2614b87d37e90b6d2d9562a192540833b599bda5a35Brian      _mesa_init_renderbuffer(&strb->Base, name);
2624b87d37e90b6d2d9562a192540833b599bda5a35Brian      strb->Base.Delete = st_renderbuffer_delete;
2634b87d37e90b6d2d9562a192540833b599bda5a35Brian      strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
2644b87d37e90b6d2d9562a192540833b599bda5a35Brian      return &strb->Base;
2654b87d37e90b6d2d9562a192540833b599bda5a35Brian   }
2664b87d37e90b6d2d9562a192540833b599bda5a35Brian   return NULL;
2674b87d37e90b6d2d9562a192540833b599bda5a35Brian}
2684b87d37e90b6d2d9562a192540833b599bda5a35Brian
26964da7515009f3551796c90acc74eb0a2ffdb68a0Brian
2703470d819fd7e3d3dd259d6fb2d4b963a514f0520Brian/**
2713470d819fd7e3d3dd259d6fb2d4b963a514f0520Brian * Allocate a renderbuffer for a an on-screen window (not a user-created
27220eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian * renderbuffer).  The window system code determines the format.
2733470d819fd7e3d3dd259d6fb2d4b963a514f0520Brian */
27464da7515009f3551796c90acc74eb0a2ffdb68a0Brianstruct gl_renderbuffer *
27552411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonsecast_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
27664da7515009f3551796c90acc74eb0a2ffdb68a0Brian{
277f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   struct st_renderbuffer *strb;
27864da7515009f3551796c90acc74eb0a2ffdb68a0Brian
279f1a59a6dd7b7b0523db191d82b3af1a841c6475dBrian Paul   strb = ST_CALLOC_STRUCT(st_renderbuffer);
280f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   if (!strb) {
28164da7515009f3551796c90acc74eb0a2ffdb68a0Brian      _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer");
28264da7515009f3551796c90acc74eb0a2ffdb68a0Brian      return NULL;
28364da7515009f3551796c90acc74eb0a2ffdb68a0Brian   }
28464da7515009f3551796c90acc74eb0a2ffdb68a0Brian
285f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   _mesa_init_renderbuffer(&strb->Base, 0);
2863470d819fd7e3d3dd259d6fb2d4b963a514f0520Brian   strb->Base.ClassID = 0x4242; /* just a unique value */
287e97681c7f551a2a2a6bd5eff0f4192a870c816c0Brian Paul   strb->Base.NumSamples = samples;
288d7de632de39888dbc955055ba0eb3623e5335992Brian Paul   strb->Base.Format = st_pipe_format_to_mesa_format(format);
289633c9fcf781d4cc23d69d4d839cf2143ac9df1fdBrian Paul   strb->Base._BaseFormat = _mesa_get_format_base_format(strb->Base.Format);
29052411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca   strb->software = sw;
29152411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca
29220eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian   switch (format) {
29386d2383e771a4e53bbee2ce0b6f924f0438249b5José Fonseca   case PIPE_FORMAT_R8G8B8A8_UNORM:
29420eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian   case PIPE_FORMAT_B8G8R8A8_UNORM:
2957d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_A8R8G8B8_UNORM:
29607b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      strb->Base.InternalFormat = GL_RGBA8;
29707b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      break;
29886d2383e771a4e53bbee2ce0b6f924f0438249b5José Fonseca   case PIPE_FORMAT_R8G8B8X8_UNORM:
2997333578d2a5fa18f7f0101fc3fd3b03cf2f356bcMichel Dänzer   case PIPE_FORMAT_B8G8R8X8_UNORM:
3007d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_X8R8G8B8_UNORM:
30107b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      strb->Base.InternalFormat = GL_RGB8;
30207b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      break;
3037d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_B5G5R5A1_UNORM:
30407b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      strb->Base.InternalFormat = GL_RGB5_A1;
30507b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      break;
3067d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_B4G4R4A4_UNORM:
30707b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      strb->Base.InternalFormat = GL_RGBA4;
30807b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      break;
3097d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_B5G6R5_UNORM:
31007b9b3c37b33e4994ff71930aed77821e758f0c9Marek Olšák      strb->Base.InternalFormat = GL_RGB565;
31164da7515009f3551796c90acc74eb0a2ffdb68a0Brian      break;
31220eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian   case PIPE_FORMAT_Z16_UNORM:
31320eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian      strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
31464da7515009f3551796c90acc74eb0a2ffdb68a0Brian      break;
31520eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian   case PIPE_FORMAT_Z32_UNORM:
31620eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian      strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
31720eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian      break;
318866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
319866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
3207333578d2a5fa18f7f0101fc3fd3b03cf2f356bcMichel Dänzer   case PIPE_FORMAT_Z24X8_UNORM:
3217d1a79a04eb1266649956f6924f25071d85e20feJosé Fonseca   case PIPE_FORMAT_X8Z24_UNORM:
32220eae595faa20dba8a59d8a4bfd01aa6b458cecdBrian      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
32364da7515009f3551796c90acc74eb0a2ffdb68a0Brian      break;
324866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie   case PIPE_FORMAT_S8_UINT:
325a2b4d4a8db77443b834daf811802a909768fa926Brian      strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
326a2b4d4a8db77443b834daf811802a909768fa926Brian      break;
32752411a1951da10bebc439a30c02c7ca99bc27c9cJosé Fonseca   case PIPE_FORMAT_R16G16B16A16_SNORM:
328b438005d961bc7fcc8cbedc34b8b15dfd09365b1Brian Paul      /* accum buffer */
329b438005d961bc7fcc8cbedc34b8b15dfd09365b1Brian Paul      strb->Base.InternalFormat = GL_RGBA16_SNORM;
3307fe09341489ff61dc1a3a771fd3e75b3f866d6a9Brian      break;
33171a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie   case PIPE_FORMAT_R8_UNORM:
33271a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      strb->Base.InternalFormat = GL_R8;
33371a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      break;
33471a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie   case PIPE_FORMAT_R8G8_UNORM:
33571a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      strb->Base.InternalFormat = GL_RG8;
33671a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      break;
33771a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie   case PIPE_FORMAT_R16_UNORM:
33871a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      strb->Base.InternalFormat = GL_R16;
33971a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      break;
34071a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie   case PIPE_FORMAT_R16G16_UNORM:
34171a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      strb->Base.InternalFormat = GL_RG16;
34271a079fb4ecbd17703ac9b5e6d5ef622fd7bc50fDave Airlie      break;
343c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul   case PIPE_FORMAT_R32G32B32A32_FLOAT:
344c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul      strb->Base.InternalFormat = GL_RGBA32F;
345c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul      break;
346c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul   case PIPE_FORMAT_R16G16B16A16_FLOAT:
347c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul      strb->Base.InternalFormat = GL_RGBA16F;
348c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul      break;
34964da7515009f3551796c90acc74eb0a2ffdb68a0Brian   default:
35064da7515009f3551796c90acc74eb0a2ffdb68a0Brian      _mesa_problem(NULL,
351c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul		    "Unexpected format %s in st_new_renderbuffer_fb",
352c68334ffc0a97406eedf11a6b8f4d846b236fb45Brian Paul                    util_format_name(format));
35332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(strb);
35464da7515009f3551796c90acc74eb0a2ffdb68a0Brian      return NULL;
35564da7515009f3551796c90acc74eb0a2ffdb68a0Brian   }
35664da7515009f3551796c90acc74eb0a2ffdb68a0Brian
35764da7515009f3551796c90acc74eb0a2ffdb68a0Brian   /* st-specific methods */
358f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   strb->Base.Delete = st_renderbuffer_delete;
359f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
36064da7515009f3551796c90acc74eb0a2ffdb68a0Brian
3613470d819fd7e3d3dd259d6fb2d4b963a514f0520Brian   /* surface is allocated in st_renderbuffer_alloc_storage() */
362f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   strb->surface = NULL;
36364da7515009f3551796c90acc74eb0a2ffdb68a0Brian
364f5713c7d2e7ba8e1170fd9b1dd95379662ab6117Brian   return &strb->Base;
36564da7515009f3551796c90acc74eb0a2ffdb68a0Brian}
36664da7515009f3551796c90acc74eb0a2ffdb68a0Brian
36764da7515009f3551796c90acc74eb0a2ffdb68a0Brian
3684b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
3694b87d37e90b6d2d9562a192540833b599bda5a35Brian * Called via ctx->Driver.BindFramebufferEXT().
3704b87d37e90b6d2d9562a192540833b599bda5a35Brian */
3714b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic void
372f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_bind_framebuffer(struct gl_context *ctx, GLenum target,
3734b87d37e90b6d2d9562a192540833b599bda5a35Brian                    struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
3744b87d37e90b6d2d9562a192540833b599bda5a35Brian{
375dba7ad0ca92f1ff4012db4ffdf102d7bb8ee3c10Brian Paul   /* no-op */
3764b87d37e90b6d2d9562a192540833b599bda5a35Brian}
3774b87d37e90b6d2d9562a192540833b599bda5a35Brian
3784b87d37e90b6d2d9562a192540833b599bda5a35Brian
3794b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
3804b87d37e90b6d2d9562a192540833b599bda5a35Brian * Called by ctx->Driver.RenderTexture
3814b87d37e90b6d2d9562a192540833b599bda5a35Brian */
3824b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic void
383f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_render_texture(struct gl_context *ctx,
3844b87d37e90b6d2d9562a192540833b599bda5a35Brian                  struct gl_framebuffer *fb,
3854b87d37e90b6d2d9562a192540833b599bda5a35Brian                  struct gl_renderbuffer_attachment *att)
3864b87d37e90b6d2d9562a192540833b599bda5a35Brian{
38776c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
3885d3d63d45a037fdf603ddcff88da635c3ce8075eBrian Paul   struct pipe_context *pipe = st->pipe;
3895e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   struct st_renderbuffer *strb;
3905e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   struct gl_renderbuffer *rb;
391de414f491526610bb260c73805c81ba413388e20Michel Dänzer   struct pipe_resource *pt;
3921a82d9648b3db780e58e4966924157542d148c58Brian Paul   struct st_texture_object *stObj;
3936352f4c854e9ec39c440054109ccb92caa5ff0bbBrian Paul   const struct gl_texture_image *texImage;
3944c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_surface surf_tmpl;
3951a82d9648b3db780e58e4966924157542d148c58Brian Paul
396de414f491526610bb260c73805c81ba413388e20Michel Dänzer   if (!st_finalize_texture(ctx, pipe, att->Texture))
397abd280ab0b72979bf709b2d029e11c8f4bc4d5f8Alan Hourihane      return;
398bfbb57790a06bb03e9bf3237b7f8756a67702192Alan Hourihane
399de414f491526610bb260c73805c81ba413388e20Michel Dänzer   pt = st_get_texobj_resource(att->Texture);
400de414f491526610bb260c73805c81ba413388e20Michel Dänzer   assert(pt);
401de414f491526610bb260c73805c81ba413388e20Michel Dänzer
402e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul   /* get pointer to texture image we're rendeing to */
403db0f9e701d59dcfcd3b50f4d245897692f27fec9Brian Paul   texImage = _mesa_get_attachment_teximage(att);
4046352f4c854e9ec39c440054109ccb92caa5ff0bbBrian Paul
405e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   /* create new renderbuffer which wraps the texture image.
406e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    * Use the texture's name as the renderbuffer's name so that we have
407e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    * something that's non-zero (to determine vertical orientation) and
408e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    * possibly helpful for debugging.
409e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    */
410e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   rb = st_new_renderbuffer(ctx, att->Texture->Name);
4115e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   if (!rb) {
4125e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
4135e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian      return;
4145e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   }
4155e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian
4165e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
4175e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   assert(rb->RefCount == 1);
4185e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   rb->AllocStorage = NULL; /* should not get called */
4195e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   strb = st_renderbuffer(rb);
4205e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian
4210a56a4968786bd93d9117af2a0a3bda13ea71c4dBrian Paul   assert(strb->Base.RefCount > 0);
4220a56a4968786bd93d9117af2a0a3bda13ea71c4dBrian Paul
423753db0d8407147393a7b0622ae3fa28f68d0353dMichel Dänzer   /* get the texture for the texture object */
4241a82d9648b3db780e58e4966924157542d148c58Brian Paul   stObj = st_texture_object(att->Texture);
4251a82d9648b3db780e58e4966924157542d148c58Brian Paul
4261a82d9648b3db780e58e4966924157542d148c58Brian Paul   /* point renderbuffer at texobject */
4271a82d9648b3db780e58e4966924157542d148c58Brian Paul   strb->rtt = stObj;
428e648d4a1d1c0c5f70916e38366b863f0bec79a62Brian Paul   strb->rtt_level = att->TextureLevel;
4291a82d9648b3db780e58e4966924157542d148c58Brian Paul   strb->rtt_face = att->CubeMapFace;
4301a82d9648b3db780e58e4966924157542d148c58Brian Paul   strb->rtt_slice = att->Zoffset;
4311a82d9648b3db780e58e4966924157542d148c58Brian Paul
4321a82d9648b3db780e58e4966924157542d148c58Brian Paul   rb->Width = texImage->Width2;
4331a82d9648b3db780e58e4966924157542d148c58Brian Paul   rb->Height = texImage->Height2;
43475e0a376cd32b127f3168c0af12992b5c8576e92José Fonseca   rb->_BaseFormat = texImage->_BaseFormat;
435c6f9d80ad2d11b44c38098cd0ae2eb91d31b86d9Simon Farnsworth   rb->InternalFormat = texImage->InternalFormat;
4362f605fd457ccd8763ce5b0acc8d2906a59ea22bcBrian
437287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference( &strb->texture, pt );
438296378b6c8b205048244746e260739448c4ee590Brian Paul
439527b3b8555f695d5b349d00eb1e63208b797bf2cBrian Paul   pipe_surface_release(pipe, &strb->surface);
4401a82d9648b3db780e58e4966924157542d148c58Brian Paul
4416352f4c854e9ec39c440054109ccb92caa5ff0bbBrian Paul   assert(strb->rtt_level <= strb->texture->last_level);
4426352f4c854e9ec39c440054109ccb92caa5ff0bbBrian Paul
4430a56a4968786bd93d9117af2a0a3bda13ea71c4dBrian Paul   /* new surface for rendering into the texture */
4444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
445dba7ad0ca92f1ff4012db4ffdf102d7bb8ee3c10Brian Paul   surf_tmpl.format = ctx->Color.sRGBEnabled
446dba7ad0ca92f1ff4012db4ffdf102d7bb8ee3c10Brian Paul      ? strb->texture->format : util_format_linear(strb->texture->format);
4474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
4484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   surf_tmpl.u.tex.level = strb->rtt_level;
4494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
4504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
4514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   strb->surface = pipe->create_surface(pipe,
4524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                        strb->texture,
4534c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                        &surf_tmpl);
4544b87d37e90b6d2d9562a192540833b599bda5a35Brian
455d7de632de39888dbc955055ba0eb3623e5335992Brian Paul   strb->Base.Format = st_pipe_format_to_mesa_format(pt->format);
45602f7f46fa15c7d31d774c638684d4f5b81e360ecBrian
4575e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   /* Invalidate buffer state so that the pipe's framebuffer state
4585e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian    * gets updated.
4595e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian    * That's where the new renderbuffer (which we just created) gets
4605e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian    * passed to the pipe as a (color/depth) render target.
4615e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian    */
4625e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian   st_invalidate_state(ctx, _NEW_BUFFERS);
463cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul
464cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul
465cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul   /* Need to trigger a call to update_framebuffer() since we just
466cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul    * attached a new renderbuffer.
467cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul    */
468cf77c29e6015d177c046adee3c48589cc9fb5015Brian Paul   ctx->NewState |= _NEW_BUFFERS;
4694b87d37e90b6d2d9562a192540833b599bda5a35Brian}
4704b87d37e90b6d2d9562a192540833b599bda5a35Brian
4714b87d37e90b6d2d9562a192540833b599bda5a35Brian
4724b87d37e90b6d2d9562a192540833b599bda5a35Brian/**
4734b87d37e90b6d2d9562a192540833b599bda5a35Brian * Called via ctx->Driver.FinishRenderTexture.
4744b87d37e90b6d2d9562a192540833b599bda5a35Brian */
4754b87d37e90b6d2d9562a192540833b599bda5a35Brianstatic void
476f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_finish_render_texture(struct gl_context *ctx,
4774b87d37e90b6d2d9562a192540833b599bda5a35Brian                         struct gl_renderbuffer_attachment *att)
4784b87d37e90b6d2d9562a192540833b599bda5a35Brian{
479137ec509946bba39940d3a7932bf196450cb951eBrian   struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
480137ec509946bba39940d3a7932bf196450cb951eBrian
4819ca1c62a963ca7024c4bccf83af3f90955cd5068Brian Paul   if (!strb)
4829ca1c62a963ca7024c4bccf83af3f90955cd5068Brian Paul      return;
4835e1bfe426f3e2bc7a13b3814f1fa732141f15a9aBrian
4841a82d9648b3db780e58e4966924157542d148c58Brian Paul   strb->rtt = NULL;
485d7b523b46b833fd08c70850d7a6cc7b6fd714a8eMichel Dänzer
486137ec509946bba39940d3a7932bf196450cb951eBrian   /* restore previous framebuffer state */
487137ec509946bba39940d3a7932bf196450cb951eBrian   st_invalidate_state(ctx, _NEW_BUFFERS);
4884b87d37e90b6d2d9562a192540833b599bda5a35Brian}
4894b87d37e90b6d2d9562a192540833b599bda5a35Brian
4904b87d37e90b6d2d9562a192540833b599bda5a35Brian
4912a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul/** Debug helper */
4922a4af651e6997f2fb88efd07aad14542a1b08579Brian Paulstatic void
4932a4af651e6997f2fb88efd07aad14542a1b08579Brian Paulst_fbo_invalid(const char *reason)
4942a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul{
4959dfe92019a6f76943316d84f437ca323c75234bcBrian Paul   if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) {
4969dfe92019a6f76943316d84f437ca323c75234bcBrian Paul      _mesa_debug(NULL, "Invalid FBO: %s\n", reason);
4979dfe92019a6f76943316d84f437ca323c75234bcBrian Paul   }
4982a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul}
4992a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul
5002a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul
5015fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul/**
502eb2bd2158ed8c1983ef427ea792dc159a2144c08Brian Paul * Validate a renderbuffer attachment for a particular set of bindings.
503f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom */
504f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstromstatic GLboolean
505c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšákst_validate_attachment(struct gl_context *ctx,
506c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák		       struct pipe_screen *screen,
507f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom		       const struct gl_renderbuffer_attachment *att,
508eb2bd2158ed8c1983ef427ea792dc159a2144c08Brian Paul		       unsigned bindings)
509f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom{
510eb2bd2158ed8c1983ef427ea792dc159a2144c08Brian Paul   const struct st_texture_object *stObj = st_texture_object(att->Texture);
511c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   enum pipe_format format;
512c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   gl_format texFormat;
5132a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul   GLboolean valid;
514f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom
515eb2bd2158ed8c1983ef427ea792dc159a2144c08Brian Paul   /* Only validate texture attachments for now, since
516f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom    * st_renderbuffer_alloc_storage makes sure that
517f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom    * the format is supported.
518f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom    */
519f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   if (att->Type != GL_TEXTURE)
520f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      return GL_TRUE;
521f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom
522f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   if (!stObj)
523f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      return GL_FALSE;
524f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom
525c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   format = stObj->pt->format;
526db0f9e701d59dcfcd3b50f4d245897692f27fec9Brian Paul   texFormat = _mesa_get_attachment_teximage_const(att)->TexFormat;
527c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák
528c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   /* If the encoding is sRGB and sRGB rendering cannot be enabled,
529c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák    * check for linear format support instead.
530c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák    * Later when we create a surface, we change the format to a linear one. */
53169c8f468ba93dc2999d4fde8909f8051e910929aMarek Olšák   if (!ctx->Extensions.EXT_framebuffer_sRGB &&
532c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák       _mesa_get_format_color_encoding(texFormat) == GL_SRGB) {
533c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák      const gl_format linearFormat = _mesa_get_srgb_format_linear(texFormat);
534c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák      format = st_mesa_format_to_pipe_format(linearFormat);
535c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   }
536c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák
5372a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul   valid = screen->is_format_supported(screen, format,
5386f3721a8ecb3695344e9a878bb452342ee502764Roland Scheidegger                                      PIPE_TEXTURE_2D,
539e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák                                      stObj->pt->nr_samples, bindings);
5402a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul   if (!valid) {
5412a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul      st_fbo_invalid("Invalid format");
5422a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul   }
5432a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul
5442a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul   return valid;
545f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom}
546f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom
547eb2bd2158ed8c1983ef427ea792dc159a2144c08Brian Paul
548f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom/**
54924bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul * Check if two renderbuffer attachments name a combined depth/stencil
55024bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul * renderbuffer.
55124bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul */
55224bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian PaulGLboolean
55324bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paulst_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
55424bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul                             const struct gl_renderbuffer_attachment *stencil)
55524bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul{
55624bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul   assert(depth && stencil);
55724bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul
55824bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul   if (depth->Type == stencil->Type) {
55924bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul      if (depth->Type == GL_RENDERBUFFER_EXT &&
56024bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul          depth->Renderbuffer == stencil->Renderbuffer)
56124bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul         return GL_TRUE;
56224bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul
56324bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul      if (depth->Type == GL_TEXTURE &&
56424bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul          depth->Texture == stencil->Texture)
56524bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul         return GL_TRUE;
56624bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul   }
56724bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul
56824bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul   return GL_FALSE;
56924bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul}
57024bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul
57124bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul
57224bd9780bcf400a00f6fc5a89b1648c7e3b7df07Brian Paul/**
5735fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul * Check that the framebuffer configuration is valid in terms of what
5745fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul * the driver can support.
5755fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul *
5765fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul * For Gallium we only supports combined Z+stencil, not separate buffers.
5775fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul */
5785fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paulstatic void
579f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
5805fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul{
58176c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
58276c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct pipe_screen *screen = st->pipe->screen;
5834fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   const struct gl_renderbuffer_attachment *depth =
5844fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák         &fb->Attachment[BUFFER_DEPTH];
5854fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   const struct gl_renderbuffer_attachment *stencil =
5864fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák         &fb->Attachment[BUFFER_STENCIL];
587f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   GLuint i;
58825f26997670302b07d48207b28f385f85f6af9bbMarek Olšák   enum pipe_format first_format = PIPE_FORMAT_NONE;
58925f26997670302b07d48207b28f385f85f6af9bbMarek Olšák   boolean mixed_formats =
59025f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0;
5915fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul
5924fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
5932a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul      st_fbo_invalid("Different Depth/Stencil buffer formats");
5944fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
5954fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák      return;
5964fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   }
5974fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   if (depth->Type == GL_RENDERBUFFER_EXT &&
5984fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák       stencil->Type == GL_RENDERBUFFER_EXT &&
5994fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák       depth->Renderbuffer != stencil->Renderbuffer) {
6002a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul      st_fbo_invalid("Separate Depth/Stencil buffers");
6014fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
6024fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák      return;
6034fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   }
6044fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák   if (depth->Type == GL_TEXTURE &&
6054fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák       stencil->Type == GL_TEXTURE &&
6064fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák       depth->Texture != stencil->Texture) {
6075fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
6082a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul      st_fbo_invalid("Different Depth/Stencil textures");
609f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      return;
610f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   }
611f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom
612c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   if (!st_validate_attachment(ctx,
613c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák                               screen,
6144fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák                               depth,
615287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			       PIPE_BIND_DEPTH_STENCIL)) {
616f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
617f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      return;
618f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   }
619c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák   if (!st_validate_attachment(ctx,
620c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák                               screen,
6214fd39a8d69cade6db5c4a0295a5f5f3014110b1cMarek Olšák                               stencil,
622287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			       PIPE_BIND_DEPTH_STENCIL)) {
623f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
624f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      return;
625f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   }
626f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom   for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
62725f26997670302b07d48207b28f385f85f6af9bbMarek Olšák      struct gl_renderbuffer_attachment *att =
62825f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            &fb->Attachment[BUFFER_COLOR0 + i];
62925f26997670302b07d48207b28f385f85f6af9bbMarek Olšák      enum pipe_format format;
63025f26997670302b07d48207b28f385f85f6af9bbMarek Olšák
631c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák      if (!st_validate_attachment(ctx,
632c0beaf6e6d5764531a4cb21d0d0a9a1fd09affeeMarek Olšák                                  screen,
63325f26997670302b07d48207b28f385f85f6af9bbMarek Olšák				  att,
634287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  PIPE_BIND_RENDER_TARGET)) {
635f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom	 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
636f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom	 return;
637f583745519b2b99ca637cdfa6201fd653c848fd6Thomas Hellstrom      }
63825f26997670302b07d48207b28f385f85f6af9bbMarek Olšák
63925f26997670302b07d48207b28f385f85f6af9bbMarek Olšák      if (!mixed_formats) {
64025f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         /* Disallow mixed formats. */
64125f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         if (att->Type != GL_NONE) {
64225f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            format = st_renderbuffer(att->Renderbuffer)->surface->format;
64325f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         } else {
64425f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            continue;
64525f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         }
64625f26997670302b07d48207b28f385f85f6af9bbMarek Olšák
64725f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         if (first_format == PIPE_FORMAT_NONE) {
64825f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            first_format = format;
64925f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         } else if (format != first_format) {
65025f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
6512a4af651e6997f2fb88efd07aad14542a1b08579Brian Paul            st_fbo_invalid("Mixed color formats");
65225f26997670302b07d48207b28f385f85f6af9bbMarek Olšák            return;
65325f26997670302b07d48207b28f385f85f6af9bbMarek Olšák         }
65425f26997670302b07d48207b28f385f85f6af9bbMarek Olšák      }
6555fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul   }
6565fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul}
6575fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul
6584b87d37e90b6d2d9562a192540833b599bda5a35Brian
659cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul/**
660cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul * Called via glDrawBuffer.
661cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul */
662cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paulstatic void
663f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_DrawBuffers(struct gl_context *ctx, GLsizei count, const GLenum *buffers)
664cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul{
66576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
66631aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg   struct gl_framebuffer *fb = ctx->DrawBuffer;
667de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu   GLuint i;
668de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu
669cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul   (void) count;
670cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul   (void) buffers;
671de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu
672de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu   /* add the renderbuffers on demand */
673de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu   for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
674de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu      gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i];
67576c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul      st_manager_add_color_renderbuffer(st, fb, idx);
676de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu   }
677cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul}
678cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul
679cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul
680cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul/**
681cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul * Called via glReadBuffer.
682cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul */
683cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paulstatic void
684f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_ReadBuffer(struct gl_context *ctx, GLenum buffer)
685cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul{
68676c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   struct st_context *st = st_context(ctx);
68731aca27c08d6a385c595d34fe4ee06390bf5b0e8Kristian Høgsberg   struct gl_framebuffer *fb = ctx->ReadBuffer;
688de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu
689cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul   (void) buffer;
690de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu
691de8a879f5c77dbf5c31251e07b2f1b8d2635716cChia-I Wu   /* add the renderbuffer on demand */
69276c7ad2e7d387feefe58dc2116b613fe11a8b273Brian Paul   st_manager_add_color_renderbuffer(st, fb, fb->_ColorReadBufferIndex);
693cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul}
694cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul
695cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul
696377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
697377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul/**
698377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul * Called via ctx->Driver.MapRenderbuffer.
699377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul */
700377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paulstatic void
701377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paulst_MapRenderbuffer(struct gl_context *ctx,
702377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                   struct gl_renderbuffer *rb,
703377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                   GLuint x, GLuint y, GLuint w, GLuint h,
704377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                   GLbitfield mode,
705377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                   GLubyte **mapOut, GLint *rowStrideOut)
706377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul{
707377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct st_context *st = st_context(ctx);
708377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct st_renderbuffer *strb = st_renderbuffer(rb);
709377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct pipe_context *pipe = st->pipe;
710e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   const GLboolean invert = rb->Name == 0;
711377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   unsigned usage;
712e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   GLuint y2;
713377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
714122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul   if (strb->software) {
715122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      /* software-allocated renderbuffer (probably an accum buffer) */
716122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      if (strb->data) {
7172e12b4cfef79b81a68597ec1320754989b1c1fa4Brian Paul         GLint bpp = _mesa_get_format_bytes(strb->Base.Format);
7182e12b4cfef79b81a68597ec1320754989b1c1fa4Brian Paul         GLint stride = _mesa_format_row_stride(strb->Base.Format,
7192e12b4cfef79b81a68597ec1320754989b1c1fa4Brian Paul                                                strb->Base.Width);
7202e12b4cfef79b81a68597ec1320754989b1c1fa4Brian Paul         *mapOut = (GLubyte *) strb->data + y * stride + x * bpp;
7212e12b4cfef79b81a68597ec1320754989b1c1fa4Brian Paul         *rowStrideOut = stride;
722122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      }
723122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      else {
724122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul         *mapOut = NULL;
725122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul         *rowStrideOut = 0;
726122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      }
727122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      return;
728122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul   }
729122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul
730377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   usage = 0x0;
731377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   if (mode & GL_MAP_READ_BIT)
732377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul      usage |= PIPE_TRANSFER_READ;
733377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   if (mode & GL_MAP_WRITE_BIT)
734377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul      usage |= PIPE_TRANSFER_WRITE;
73584c7c14697c82fe25586f8186b4f47d80a6f05f9Brian Paul   if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
73684c7c14697c82fe25586f8186b4f47d80a6f05f9Brian Paul      usage |= PIPE_TRANSFER_DISCARD_RANGE;
737377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
738e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   /* Note: y=0=bottom of buffer while y2=0=top of buffer.
739e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    * 'invert' will be true for window-system buffers and false for
740e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    * user-allocated renderbuffers and textures.
741e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul    */
742e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   if (invert)
743e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      y2 = strb->Base.Height - y - h;
744e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul   else
745e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      y2 = y;
746e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul
747377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   strb->transfer = pipe_get_transfer(pipe,
748377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                                      strb->texture,
749377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                                      strb->rtt_level,
750377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                                      strb->rtt_face + strb->rtt_slice,
751e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul                                      usage, x, y2, w, h);
752377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   if (strb->transfer) {
753e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      GLubyte *map = pipe_transfer_map(pipe, strb->transfer);
754e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      if (invert) {
755e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul         *rowStrideOut = -strb->transfer->stride;
756e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul         map += (h - 1) * strb->transfer->stride;
757e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      }
758e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      else {
759e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul         *rowStrideOut = strb->transfer->stride;
760e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      }
761e0e454943cf40730b6ba311310d9878f704a4f95Brian Paul      *mapOut = map;
762377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   }
763377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   else {
764377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul      *mapOut = NULL;
765377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul      *rowStrideOut = 0;
766377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   }
767377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul}
768377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
769377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
770377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul/**
771377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul * Called via ctx->Driver.UnmapRenderbuffer.
772377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul */
773377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paulstatic void
774377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paulst_UnmapRenderbuffer(struct gl_context *ctx,
775377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul                     struct gl_renderbuffer *rb)
776377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul{
777377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct st_context *st = st_context(ctx);
778377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct st_renderbuffer *strb = st_renderbuffer(rb);
779377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   struct pipe_context *pipe = st->pipe;
780377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
781122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul   if (strb->software) {
782122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      /* software-allocated renderbuffer (probably an accum buffer) */
783122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul      return;
784122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul   }
785122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul
786377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   pipe_transfer_unmap(pipe, strb->transfer);
787377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   pipe->transfer_destroy(pipe, strb->transfer);
788377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   strb->transfer = NULL;
789377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul}
790377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
791377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
792377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
7936da9234fd437f97267e7831f034c78b31156d939Brianvoid st_init_fbo_functions(struct dd_function_table *functions)
7944b87d37e90b6d2d9562a192540833b599bda5a35Brian{
7959d4a0d7d4df3934cdefe4fe1118603e618d59831nobled#if FEATURE_EXT_framebuffer_object
7964b87d37e90b6d2d9562a192540833b599bda5a35Brian   functions->NewFramebuffer = st_new_framebuffer;
7974b87d37e90b6d2d9562a192540833b599bda5a35Brian   functions->NewRenderbuffer = st_new_renderbuffer;
7984b87d37e90b6d2d9562a192540833b599bda5a35Brian   functions->BindFramebuffer = st_bind_framebuffer;
799418306397fa7f71e070b285919460e9914af8739Brian Paul   functions->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
8004b87d37e90b6d2d9562a192540833b599bda5a35Brian   functions->RenderTexture = st_render_texture;
8014b87d37e90b6d2d9562a192540833b599bda5a35Brian   functions->FinishRenderTexture = st_finish_render_texture;
8025fc74734d92f7e7ff3df693254986ba5d2b5e653Brian Paul   functions->ValidateFramebuffer = st_validate_framebuffer;
8039d4a0d7d4df3934cdefe4fe1118603e618d59831nobled#endif
804cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul
805cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul   functions->DrawBuffers = st_DrawBuffers;
806cd6734288ddc15a778def9578e128184b3f6bdeaBrian Paul   functions->ReadBuffer = st_ReadBuffer;
807377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul
808377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   functions->MapRenderbuffer = st_MapRenderbuffer;
809377eb5c30cfe94723cad214f12ca4ff9e5aee35eBrian Paul   functions->UnmapRenderbuffer = st_UnmapRenderbuffer;
8104b87d37e90b6d2d9562a192540833b599bda5a35Brian}
811dbf20a1f0fa7965254aa8a0e2ea35a6b8576fd7dMichal Krol
812dbf20a1f0fa7965254aa8a0e2ea35a6b8576fd7dMichal Krol
813