rename st_cb_teximage.h st_format.h
[mesa.git] / src / mesa / state_tracker / st_cb_fbo.c
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 /**
30 * Framebuffer/renderbuffer functions.
31 *
32 * \author Brian Paul
33 */
34
35
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"
41
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_format.h"
47
48
49
50 /**
51 * gl_renderbuffer::AllocStorage()
52 */
53 static GLboolean
54 st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
55 GLenum internalFormat,
56 GLuint width, GLuint height)
57 {
58 struct pipe_context *pipe = ctx->st->pipe;
59 struct st_renderbuffer *strb = st_renderbuffer(rb);
60 const GLuint pipeFormat
61 = st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE);
62 const struct pipe_format_info *info = st_get_format_info(pipeFormat);
63 GLuint cpp, pitch;
64
65 assert(info);
66 if (!info)
67 return GL_FALSE;
68
69 switch (pipeFormat) {
70 case PIPE_FORMAT_S8_Z24:
71 strb->Base.DataType = GL_UNSIGNED_INT;
72 break;
73 default:
74 strb->Base.DataType = GL_UNSIGNED_BYTE; /* XXX fix */
75 }
76
77 strb->Base._ActualFormat = info->base_format;
78 strb->Base.RedBits = info->red_bits;
79 strb->Base.GreenBits = info->green_bits;
80 strb->Base.BlueBits = info->blue_bits;
81 strb->Base.AlphaBits = info->alpha_bits;
82 strb->Base.DepthBits = info->depth_bits;
83 strb->Base.StencilBits = info->stencil_bits;
84
85 cpp = info->size;
86
87 if (!strb->surface) {
88 strb->surface = pipe->surface_alloc(pipe, pipeFormat);
89 assert(strb->surface);
90 if (!strb->surface)
91 return GL_FALSE;
92 }
93
94 /* free old region */
95 if (strb->surface->region) {
96 pipe->region_release(pipe, &strb->surface->region);
97 }
98
99 /* Choose a pitch to match hardware requirements:
100 */
101 pitch = ((cpp * width + 63) & ~63) / cpp; /* XXX fix: device-specific */
102
103 strb->surface->region = pipe->region_alloc(pipe, cpp, pitch, height);
104 if (!strb->surface->region)
105 return GL_FALSE; /* out of memory, try s/w buffer? */
106
107 ASSERT(strb->surface->region->buffer);
108
109 strb->Base.Width = strb->surface->width = width;
110 strb->Base.Height = strb->surface->height = height;
111
112 return GL_TRUE;
113 }
114
115
116 /**
117 * gl_renderbuffer::Delete()
118 */
119 static void
120 st_renderbuffer_delete(struct gl_renderbuffer *rb)
121 {
122 GET_CURRENT_CONTEXT(ctx);
123 struct pipe_context *pipe = ctx->st->pipe;
124 struct st_renderbuffer *strb = st_renderbuffer(rb);
125 ASSERT(strb);
126 if (strb && strb->surface) {
127 if (strb->surface->region) {
128 pipe->region_release(pipe, &strb->surface->region);
129 }
130 free(strb->surface);
131 }
132 free(strb);
133 }
134
135
136 /**
137 * gl_renderbuffer::GetPointer()
138 */
139 static void *
140 null_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb,
141 GLint x, GLint y)
142 {
143 /* By returning NULL we force all software rendering to go through
144 * the span routines.
145 */
146 #if 0
147 assert(0); /* Should never get called with softpipe */
148 #endif
149 return NULL;
150 }
151
152
153 /**
154 * Called via ctx->Driver.NewFramebuffer()
155 */
156 static struct gl_framebuffer *
157 st_new_framebuffer(GLcontext *ctx, GLuint name)
158 {
159 /* XXX not sure we need to subclass gl_framebuffer for pipe */
160 return _mesa_new_framebuffer(ctx, name);
161 }
162
163
164 /**
165 * Called via ctx->Driver.NewRenderbuffer()
166 */
167 static struct gl_renderbuffer *
168 st_new_renderbuffer(GLcontext *ctx, GLuint name)
169 {
170 struct st_renderbuffer *strb = CALLOC_STRUCT(st_renderbuffer);
171 if (strb) {
172 _mesa_init_renderbuffer(&strb->Base, name);
173 strb->Base.Delete = st_renderbuffer_delete;
174 strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
175 strb->Base.GetPointer = null_get_pointer;
176 return &strb->Base;
177 }
178 return NULL;
179 }
180
181
182 #if 000
183 struct gl_renderbuffer *
184 st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height)
185 {
186 struct st_renderbuffer *strb = CALLOC_STRUCT(st_renderbuffer);
187 if (!strb)
188 return;
189
190 _mesa_init_renderbuffer(&strb->Base, name);
191 strb->Base.Delete = st_renderbuffer_delete;
192 strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
193 strb->Base.GetPointer = null_get_pointer;
194 strb->Base.Width = width;
195 strb->Base.Heigth = height;
196
197 strb->region = region;
198
199 return &strb->Base;
200 }
201
202 #else
203
204 struct gl_renderbuffer *
205 st_new_renderbuffer_fb(GLenum intFormat)
206 {
207 struct st_renderbuffer *strb;
208
209 strb = CALLOC_STRUCT(st_renderbuffer);
210 if (!strb) {
211 _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer");
212 return NULL;
213 }
214
215 _mesa_init_renderbuffer(&strb->Base, 0);
216 strb->Base.ClassID = 0x42; /* XXX temp */
217 strb->Base.InternalFormat = intFormat;
218
219 switch (intFormat) {
220 case GL_RGB5:
221 case GL_RGBA8:
222 strb->Base._BaseFormat = GL_RGBA;
223 break;
224 case GL_DEPTH_COMPONENT16:
225 case GL_DEPTH_COMPONENT32:
226 strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
227 break;
228 case GL_DEPTH24_STENCIL8_EXT:
229 strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
230 break;
231 default:
232 _mesa_problem(NULL,
233 "Unexpected intFormat in st_new_renderbuffer");
234 return NULL;
235 }
236
237 /* st-specific methods */
238 strb->Base.Delete = st_renderbuffer_delete;
239 strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
240 strb->Base.GetPointer = null_get_pointer;
241
242 /* surface is allocate in alloc_renderbuffer_storage() */
243 strb->surface = NULL;
244
245 return &strb->Base;
246 }
247 #endif
248
249
250
251 /**
252 * Called via ctx->Driver.BindFramebufferEXT().
253 */
254 static void
255 st_bind_framebuffer(GLcontext *ctx, GLenum target,
256 struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
257 {
258
259 }
260
261 /**
262 * Called by ctx->Driver.FramebufferRenderbuffer
263 */
264 static void
265 st_framebuffer_renderbuffer(GLcontext *ctx,
266 struct gl_framebuffer *fb,
267 GLenum attachment,
268 struct gl_renderbuffer *rb)
269 {
270 /* XXX no need for derivation? */
271 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
272 }
273
274
275 /**
276 * Called by ctx->Driver.RenderTexture
277 */
278 static void
279 st_render_texture(GLcontext *ctx,
280 struct gl_framebuffer *fb,
281 struct gl_renderbuffer_attachment *att)
282 {
283 struct st_context *st = ctx->st;
284 struct pipe_framebuffer_state framebuffer;
285 struct pipe_surface *texsurface;
286
287 texsurface = NULL; /* find the mipmap level, cube face, etc */
288
289 /*
290 * XXX basically like this... set the current color (or depth)
291 * drawing surface to be the given texture renderbuffer.
292 */
293 memset(&framebuffer, 0, sizeof(framebuffer));
294 framebuffer.num_cbufs = 1;
295 framebuffer.cbufs[0] = texsurface;
296
297 if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) {
298 st->state.framebuffer = framebuffer;
299 st->pipe->set_framebuffer_state( st->pipe, &framebuffer );
300 }
301 }
302
303
304 /**
305 * Called via ctx->Driver.FinishRenderTexture.
306 */
307 static void
308 st_finish_render_texture(GLcontext *ctx,
309 struct gl_renderbuffer_attachment *att)
310 {
311 /* restore drawing to normal framebuffer. may be a no-op */
312 }
313
314
315
316 void st_init_fbo_functions(struct dd_function_table *functions)
317 {
318 functions->NewFramebuffer = st_new_framebuffer;
319 functions->NewRenderbuffer = st_new_renderbuffer;
320 functions->BindFramebuffer = st_bind_framebuffer;
321 functions->FramebufferRenderbuffer = st_framebuffer_renderbuffer;
322 functions->RenderTexture = st_render_texture;
323 functions->FinishRenderTexture = st_finish_render_texture;
324 /* no longer needed by core Mesa, drivers handle resizes...
325 functions->ResizeBuffers = st_resize_buffers;
326 */
327 }