1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
30 * Framebuffer/renderbuffer functions.
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/fbobject.h"
39 #include "main/framebuffer.h"
40 #include "main/renderbuffer.h"
42 #include "pipe/p_context.h"
43 #include "pipe/p_defines.h"
44 #include "st_context.h"
45 #include "st_cb_fbo.h"
46 #include "st_cb_teximage.h"
50 * Derived renderbuffer class. Just need to add a pointer to the
53 struct st_renderbuffer
55 struct gl_renderbuffer Base
;
56 struct pipe_surface
*surface
;
63 static INLINE
struct st_renderbuffer
*
64 st_renderbuffer(struct gl_renderbuffer
*rb
)
66 return (struct st_renderbuffer
*) rb
;
70 struct pipe_format_info
78 GLubyte luminance_bits
;
79 GLubyte intensity_bits
;
82 GLubyte size
; /**< in bytes */
89 static const struct pipe_format_info
*
90 pipe_get_format_info(GLuint format
)
92 static const struct pipe_format_info info
[] = {
94 PIPE_FORMAT_U_R8_G8_B8_A8
, /* format */
95 GL_RGBA
, /* base_format */
96 4, 4, 4, 4, 0, 0, /* color bits */
97 0, 0, /* depth, stencil */
101 PIPE_FORMAT_U_A8_R8_G8_B8
,
102 GL_RGBA
, /* base_format */
103 4, 4, 4, 4, 0, 0, /* color bits */
104 0, 0, /* depth, stencil */
105 4 /* size in bytes */
108 PIPE_FORMAT_U_A1_R5_G5_B5
,
109 GL_RGBA
, /* base_format */
110 5, 5, 5, 1, 0, 0, /* color bits */
111 0, 0, /* depth, stencil */
112 2 /* size in bytes */
115 PIPE_FORMAT_U_R5_G6_B5
,
116 GL_RGBA
, /* base_format */
117 5, 6, 5, 0, 0, 0, /* color bits */
118 0, 0, /* depth, stencil */
119 2 /* size in bytes */
124 GL_DEPTH_STENCIL_EXT
, /* base_format */
125 0, 0, 0, 0, 0, 0, /* color bits */
126 24, 8, /* depth, stencil */
127 4 /* size in bytes */
132 for (i
= 0; i
< sizeof(info
) / sizeof(info
[0]); i
++) {
133 if (info
[i
].format
== format
)
141 * gl_renderbuffer::AllocStorage()
144 st_renderbuffer_alloc_storage(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
145 GLenum internalFormat
,
146 GLuint width
, GLuint height
)
148 struct pipe_context
*pipe
= ctx
->st
->pipe
;
149 struct st_renderbuffer
*strb
= st_renderbuffer(rb
);
150 const GLuint pipeFormat
151 = st_choose_pipe_format(pipe
, internalFormat
, GL_NONE
, GL_NONE
);
152 const struct pipe_format_info
*info
= pipe_get_format_info(pipeFormat
);
158 strb
->Base
._ActualFormat
= info
->base_format
;
159 strb
->Base
.DataType
= GL_UNSIGNED_BYTE
; /* XXX fix */
160 strb
->Base
.RedBits
= info
->red_bits
;
161 strb
->Base
.GreenBits
= info
->green_bits
;
162 strb
->Base
.BlueBits
= info
->blue_bits
;
163 strb
->Base
.AlphaBits
= info
->alpha_bits
;
164 strb
->Base
.DepthBits
= info
->depth_bits
;
165 strb
->Base
.StencilBits
= info
->stencil_bits
;
169 if (!strb
->surface
) {
170 strb
->surface
= pipe
->surface_alloc(pipe
, pipeFormat
);
175 /* free old region */
176 if (strb
->surface
->region
) {
177 pipe
->region_release(pipe
, &strb
->surface
->region
);
180 /* Choose a pitch to match hardware requirements:
182 pitch
= ((cpp
* width
+ 63) & ~63) / cpp
; /* XXX fix: device-specific */
184 strb
->surface
->region
= pipe
->region_alloc(pipe
, cpp
, pitch
, height
);
185 if (!strb
->surface
->region
)
186 return GL_FALSE
; /* out of memory, try s/w buffer? */
188 ASSERT(strb
->surface
->region
->buffer
);
190 strb
->Base
.Width
= strb
->surface
->width
= width
;
191 strb
->Base
.Height
= strb
->surface
->height
= height
;
198 * gl_renderbuffer::Delete()
201 st_renderbuffer_delete(struct gl_renderbuffer
*rb
)
203 GET_CURRENT_CONTEXT(ctx
);
204 struct pipe_context
*pipe
= ctx
->st
->pipe
;
205 struct st_renderbuffer
*strb
= st_renderbuffer(rb
);
207 if (strb
&& strb
->surface
) {
208 if (rb
->surface
->region
) {
209 pipe
->region_release(pipe
, &strb
->surface
->region
);
218 * gl_renderbuffer::GetPointer()
221 null_get_pointer(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
224 /* By returning NULL we force all software rendering to go through
227 assert(0); /* Should never get called with softpipe */
233 * Called via ctx->Driver.NewFramebuffer()
235 static struct gl_framebuffer
*
236 st_new_framebuffer(GLcontext
*ctx
, GLuint name
)
238 /* XXX not sure we need to subclass gl_framebuffer for pipe */
239 return _mesa_new_framebuffer(ctx
, name
);
244 * Called via ctx->Driver.NewRenderbuffer()
246 static struct gl_renderbuffer
*
247 st_new_renderbuffer(GLcontext
*ctx
, GLuint name
)
249 struct st_renderbuffer
*strb
= CALLOC_STRUCT(st_renderbuffer
);
251 _mesa_init_renderbuffer(&strb
->Base
, name
);
252 strb
->Base
.Delete
= st_renderbuffer_delete
;
253 strb
->Base
.AllocStorage
= st_renderbuffer_alloc_storage
;
254 strb
->Base
.GetPointer
= null_get_pointer
;
261 * Called via ctx->Driver.BindFramebufferEXT().
264 st_bind_framebuffer(GLcontext
*ctx
, GLenum target
,
265 struct gl_framebuffer
*fb
, struct gl_framebuffer
*fbread
)
271 * Called by ctx->Driver.FramebufferRenderbuffer
274 st_framebuffer_renderbuffer(GLcontext
*ctx
,
275 struct gl_framebuffer
*fb
,
277 struct gl_renderbuffer
*rb
)
279 /* XXX no need for derivation? */
280 _mesa_framebuffer_renderbuffer(ctx
, fb
, attachment
, rb
);
285 * Called by ctx->Driver.RenderTexture
288 st_render_texture(GLcontext
*ctx
,
289 struct gl_framebuffer
*fb
,
290 struct gl_renderbuffer_attachment
*att
)
292 struct st_context
*st
= ctx
->st
;
293 struct pipe_framebuffer_state framebuffer
;
294 struct pipe_surface
*texsurface
;
296 texsurface
= NULL
; /* find the mipmap level, cube face, etc */
299 * XXX basically like this... set the current color (or depth)
300 * drawing surface to be the given texture renderbuffer.
302 memset(&framebuffer
, 0, sizeof(framebuffer
));
303 framebuffer
.num_cbufs
= 1;
304 framebuffer
.cbufs
[0] = texsurface
;
306 if (memcmp(&framebuffer
, &st
->state
.framebuffer
, sizeof(framebuffer
)) != 0) {
307 st
->state
.framebuffer
= framebuffer
;
308 st
->pipe
->set_framebuffer_state( st
->pipe
, &framebuffer
);
314 * Called via ctx->Driver.FinishRenderTexture.
317 st_finish_render_texture(GLcontext
*ctx
,
318 struct gl_renderbuffer_attachment
*att
)
320 /* restore drawing to normal framebuffer. may be a no-op */
325 void st_init_fbo_functions(struct dd_function_table
*functions
)
327 functions
->NewFramebuffer
= st_new_framebuffer
;
328 functions
->NewRenderbuffer
= st_new_renderbuffer
;
329 functions
->BindFramebuffer
= st_bind_framebuffer
;
330 functions
->FramebufferRenderbuffer
= st_framebuffer_renderbuffer
;
331 functions
->RenderTexture
= st_render_texture
;
332 functions
->FinishRenderTexture
= st_finish_render_texture
;
333 /* no longer needed by core Mesa, drivers handle resizes...
334 functions->ResizeBuffers = st_resize_buffers;