00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #include "main/imports.h"
00037 #include "main/context.h"
00038 #include "main/fbobject.h"
00039 #include "main/framebuffer.h"
00040 #include "main/renderbuffer.h"
00041
00042 #include "pipe/p_context.h"
00043 #include "pipe/p_defines.h"
00044 #include "pipe/p_inlines.h"
00045 #include "pipe/p_winsys.h"
00046 #include "st_context.h"
00047 #include "st_cb_fbo.h"
00048 #include "st_cb_texture.h"
00049 #include "st_format.h"
00050 #include "st_public.h"
00051 #include "st_texture.h"
00052
00053
00054
00058 static int
00059 init_renderbuffer_bits(struct st_renderbuffer *strb,
00060 enum pipe_format pipeFormat)
00061 {
00062 struct pipe_format_info info;
00063
00064 if (!st_get_format_info( pipeFormat, &info )) {
00065 assert( 0 );
00066 }
00067
00068 strb->Base._ActualFormat = info.base_format;
00069 strb->Base.RedBits = info.red_bits;
00070 strb->Base.GreenBits = info.green_bits;
00071 strb->Base.BlueBits = info.blue_bits;
00072 strb->Base.AlphaBits = info.alpha_bits;
00073 strb->Base.DepthBits = info.depth_bits;
00074 strb->Base.StencilBits = info.stencil_bits;
00075 strb->Base.DataType = st_format_datatype(pipeFormat);
00076
00077 return info.size;
00078 }
00079
00085 static GLboolean
00086 st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
00087 GLenum internalFormat,
00088 GLuint width, GLuint height)
00089 {
00090 struct pipe_context *pipe = ctx->st->pipe;
00091 struct st_renderbuffer *strb = st_renderbuffer(rb);
00092 struct pipe_texture template;
00093 unsigned surface_usage;
00094
00095
00096
00097 pipe_surface_reference( &strb->surface, NULL );
00098 pipe_texture_reference( &strb->texture, NULL );
00099
00100
00101 memset(&template, 0, sizeof(template));
00102
00103 if (strb->format != PIPE_FORMAT_NONE) {
00104 template.format = strb->format;
00105 }
00106 else {
00107 template.format = st_choose_renderbuffer_format(pipe, internalFormat);
00108 }
00109
00110 strb->Base.Width = width;
00111 strb->Base.Height = height;
00112 init_renderbuffer_bits(strb, template.format);
00113
00114 template.target = PIPE_TEXTURE_2D;
00115 template.compressed = 0;
00116 pf_get_block(template.format, &template.block);
00117 template.width[0] = width;
00118 template.height[0] = height;
00119 template.depth[0] = 1;
00120 template.last_level = 0;
00121 template.nr_samples = rb->Samples;
00122
00123 if (pf_is_depth_stencil(template.format)) {
00124 template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
00125 }
00126 else {
00127 template.tex_usage = (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
00128 PIPE_TEXTURE_USAGE_RENDER_TARGET);
00129 }
00130
00131
00132
00133
00134 surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
00135 PIPE_BUFFER_USAGE_GPU_WRITE);
00136 #if 0
00137 PIPE_BUFFER_USAGE_CPU_READ |
00138 PIPE_BUFFER_USAGE_CPU_WRITE);
00139 #endif
00140
00141 strb->texture = pipe->screen->texture_create( pipe->screen,
00142 &template );
00143
00144
00145
00146
00147
00148
00149
00150 if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT)
00151 {
00152
00153
00154
00155
00156 template.tex_usage = 0;
00157 surface_usage = (PIPE_BUFFER_USAGE_CPU_READ |
00158 PIPE_BUFFER_USAGE_CPU_WRITE);
00159
00160 strb->texture = pipe->screen->texture_create( pipe->screen,
00161 &template );
00162
00163 }
00164
00165 if (!strb->texture)
00166 return FALSE;
00167
00168 strb->surface = pipe->screen->get_tex_surface( pipe->screen,
00169 strb->texture,
00170 0, 0, 0,
00171 surface_usage );
00172
00173 assert(strb->surface->texture);
00174 assert(strb->surface->buffer);
00175 assert(strb->surface->format);
00176 assert(strb->surface->block.size);
00177 assert(strb->surface->block.width);
00178 assert(strb->surface->block.height);
00179 assert(strb->surface->width == width);
00180 assert(strb->surface->height == height);
00181 assert(strb->surface->stride);
00182
00183
00184 return strb->surface != NULL;
00185 }
00186
00187
00191 static void
00192 st_renderbuffer_delete(struct gl_renderbuffer *rb)
00193 {
00194 struct st_renderbuffer *strb = st_renderbuffer(rb);
00195 ASSERT(strb);
00196 pipe_surface_reference(&strb->surface, NULL);
00197 pipe_texture_reference(&strb->texture, NULL);
00198 free(strb);
00199 }
00200
00201
00205 static void *
00206 null_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb,
00207 GLint x, GLint y)
00208 {
00209
00210
00211
00212 #if 0
00213 assert(0);
00214 #endif
00215 return NULL;
00216 }
00217
00218
00222 static struct gl_framebuffer *
00223 st_new_framebuffer(GLcontext *ctx, GLuint name)
00224 {
00225
00226 return _mesa_new_framebuffer(ctx, name);
00227 }
00228
00229
00233 static struct gl_renderbuffer *
00234 st_new_renderbuffer(GLcontext *ctx, GLuint name)
00235 {
00236 struct st_renderbuffer *strb = CALLOC_STRUCT(st_renderbuffer);
00237 if (strb) {
00238 _mesa_init_renderbuffer(&strb->Base, name);
00239 strb->Base.Delete = st_renderbuffer_delete;
00240 strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
00241 strb->Base.GetPointer = null_get_pointer;
00242 strb->format = PIPE_FORMAT_NONE;
00243 return &strb->Base;
00244 }
00245 return NULL;
00246 }
00247
00248
00253 struct gl_renderbuffer *
00254 st_new_renderbuffer_fb(enum pipe_format format, int samples)
00255 {
00256 struct st_renderbuffer *strb;
00257
00258 strb = CALLOC_STRUCT(st_renderbuffer);
00259 if (!strb) {
00260 _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer");
00261 return NULL;
00262 }
00263
00264 _mesa_init_renderbuffer(&strb->Base, 0);
00265 strb->Base.ClassID = 0x4242;
00266 strb->Base.Samples = samples;
00267 strb->format = format;
00268
00269 switch (format) {
00270 case PIPE_FORMAT_A8R8G8B8_UNORM:
00271 case PIPE_FORMAT_B8G8R8A8_UNORM:
00272 case PIPE_FORMAT_X8R8G8B8_UNORM:
00273 case PIPE_FORMAT_B8G8R8X8_UNORM:
00274 case PIPE_FORMAT_A1R5G5B5_UNORM:
00275 case PIPE_FORMAT_A4R4G4B4_UNORM:
00276 case PIPE_FORMAT_R5G6B5_UNORM:
00277 strb->Base.InternalFormat = GL_RGBA;
00278 strb->Base._BaseFormat = GL_RGBA;
00279 break;
00280 case PIPE_FORMAT_Z16_UNORM:
00281 strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
00282 strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
00283 break;
00284 case PIPE_FORMAT_Z32_UNORM:
00285 strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
00286 strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
00287 break;
00288 case PIPE_FORMAT_S8Z24_UNORM:
00289 case PIPE_FORMAT_Z24S8_UNORM:
00290 case PIPE_FORMAT_X8Z24_UNORM:
00291 case PIPE_FORMAT_Z24X8_UNORM:
00292 strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
00293 strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
00294 break;
00295 case PIPE_FORMAT_S8_UNORM:
00296 strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
00297 strb->Base._BaseFormat = GL_STENCIL_INDEX;
00298 break;
00299 case DEFAULT_ACCUM_PIPE_FORMAT:
00300 strb->Base.InternalFormat = GL_RGBA16;
00301 strb->Base._BaseFormat = GL_RGBA;
00302 break;
00303 default:
00304 _mesa_problem(NULL,
00305 "Unexpected format in st_new_renderbuffer_fb");
00306 return NULL;
00307 }
00308
00309
00310 strb->Base.Delete = st_renderbuffer_delete;
00311 strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
00312 strb->Base.GetPointer = null_get_pointer;
00313
00314
00315 strb->surface = NULL;
00316
00317 return &strb->Base;
00318 }
00319
00320
00321
00322
00326 static void
00327 st_bind_framebuffer(GLcontext *ctx, GLenum target,
00328 struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
00329 {
00330
00331 }
00332
00336 static void
00337 st_framebuffer_renderbuffer(GLcontext *ctx,
00338 struct gl_framebuffer *fb,
00339 GLenum attachment,
00340 struct gl_renderbuffer *rb)
00341 {
00342
00343 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
00344 }
00345
00346
00350 static void
00351 st_render_texture(GLcontext *ctx,
00352 struct gl_framebuffer *fb,
00353 struct gl_renderbuffer_attachment *att)
00354 {
00355 struct st_renderbuffer *strb;
00356 struct gl_renderbuffer *rb;
00357 struct pipe_texture *pt;
00358 struct st_texture_object *stObj;
00359 const struct gl_texture_image *texImage =
00360 att->Texture->Image[att->CubeMapFace][att->TextureLevel];
00361
00362
00363 assert(!att->Renderbuffer);
00364
00365
00366 rb = st_new_renderbuffer(ctx, 0);
00367 if (!rb) {
00368 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()");
00369 return;
00370 }
00371
00372 _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
00373 assert(rb->RefCount == 1);
00374 rb->AllocStorage = NULL;
00375 strb = st_renderbuffer(rb);
00376
00377
00378 stObj = st_texture_object(att->Texture);
00379
00380
00381 strb->rtt = stObj;
00382 strb->rtt_level = att->TextureLevel;
00383 strb->rtt_face = att->CubeMapFace;
00384 strb->rtt_slice = att->Zoffset;
00385
00386 rb->Width = texImage->Width2;
00387 rb->Height = texImage->Height2;
00388
00389
00390 pt = st_get_texobj_texture(att->Texture);
00391 assert(pt);
00392
00393
00394 pipe_texture_reference( &strb->texture, pt );
00395
00396 pipe_surface_reference(&strb->surface, NULL);
00397
00398
00399
00400 init_renderbuffer_bits(strb, pt->format);
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 st_invalidate_state(ctx, _NEW_BUFFERS);
00413 }
00414
00415
00419 static void
00420 st_finish_render_texture(GLcontext *ctx,
00421 struct gl_renderbuffer_attachment *att)
00422 {
00423 struct pipe_screen *screen = ctx->st->pipe->screen;
00424 struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
00425
00426 if (!strb)
00427 return;
00428
00429 st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL );
00430
00431 if (strb->surface)
00432 screen->tex_surface_release( screen, &strb->surface );
00433
00434 strb->rtt = NULL;
00435
00436
00437
00438
00439
00440 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
00441
00442
00443 st_invalidate_state(ctx, _NEW_BUFFERS);
00444 }
00445
00446
00447
00448 void st_init_fbo_functions(struct dd_function_table *functions)
00449 {
00450 functions->NewFramebuffer = st_new_framebuffer;
00451 functions->NewRenderbuffer = st_new_renderbuffer;
00452 functions->BindFramebuffer = st_bind_framebuffer;
00453 functions->FramebufferRenderbuffer = st_framebuffer_renderbuffer;
00454 functions->RenderTexture = st_render_texture;
00455 functions->FinishRenderTexture = st_finish_render_texture;
00456
00457
00458
00459 }