Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
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