st_cb_fbo.c File Reference

Include dependency graph for st_cb_fbo.c:

Go to the source code of this file.

Functions

static int init_renderbuffer_bits (struct st_renderbuffer *strb, enum pipe_format pipeFormat)
 Framebuffer/renderbuffer functions.
static GLboolean st_renderbuffer_alloc_storage (GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height)
 gl_renderbuffer::AllocStorage() This is called to allocate the original drawing surface, and during window resize.
static void st_renderbuffer_delete (struct gl_renderbuffer *rb)
 gl_renderbuffer::Delete()
static void * null_get_pointer (GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
 gl_renderbuffer::GetPointer()
static struct gl_framebuffer * st_new_framebuffer (GLcontext *ctx, GLuint name)
 Called via ctx->Driver.NewFramebuffer().
static struct gl_renderbuffer * st_new_renderbuffer (GLcontext *ctx, GLuint name)
 Called via ctx->Driver.NewRenderbuffer().
struct gl_renderbuffer * st_new_renderbuffer_fb (enum pipe_format format, int samples)
 Allocate a renderbuffer for a an on-screen window (not a user-created renderbuffer).
static void st_bind_framebuffer (GLcontext *ctx, GLenum target, struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
 Called via ctx->Driver.BindFramebufferEXT().
static void st_framebuffer_renderbuffer (GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment, struct gl_renderbuffer *rb)
 Called by ctx->Driver.FramebufferRenderbuffer.
static void st_render_texture (GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att)
 Called by ctx->Driver.RenderTexture.
static void st_finish_render_texture (GLcontext *ctx, struct gl_renderbuffer_attachment *att)
 Called via ctx->Driver.FinishRenderTexture.
void st_init_fbo_functions (struct dd_function_table *functions)


Function Documentation

static int init_renderbuffer_bits ( struct st_renderbuffer strb,
enum pipe_format  pipeFormat 
) [static]

Framebuffer/renderbuffer functions.

Author:
Brian Paul Compute the renderbuffer's Red/Green/EtcBit fields from the pipe format.

Definition at line 59 of file st_cb_fbo.c.

References pipe_format_info::alpha_bits, assert, st_renderbuffer::Base, pipe_format_info::base_format, pipe_format_info::blue_bits, pipe_format_info::depth_bits, pipe_format_info::green_bits, pipe_format_info::red_bits, pipe_format_info::size, st_format_datatype(), st_get_format_info(), and pipe_format_info::stencil_bits.

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 }

static void* null_get_pointer ( GLcontext *  ctx,
struct gl_renderbuffer *  rb,
GLint  x,
GLint  y 
) [static]

gl_renderbuffer::GetPointer()

Definition at line 206 of file st_cb_fbo.c.

References assert.

00208 {
00209    /* By returning NULL we force all software rendering to go through
00210     * the span routines.
00211     */
00212 #if 0
00213    assert(0);  /* Should never get called with softpipe */
00214 #endif
00215    return NULL;
00216 }

static void st_bind_framebuffer ( GLcontext *  ctx,
GLenum  target,
struct gl_framebuffer *  fb,
struct gl_framebuffer *  fbread 
) [static]

Called via ctx->Driver.BindFramebufferEXT().

Definition at line 327 of file st_cb_fbo.c.

00329 {
00330 
00331 }

static void st_finish_render_texture ( GLcontext *  ctx,
struct gl_renderbuffer_attachment *  att 
) [static]

Called via ctx->Driver.FinishRenderTexture.

Definition at line 420 of file st_cb_fbo.c.

References PIPE_FLUSH_RENDER_CACHE, st_renderbuffer::rtt, pipe_texture::screen, st_flush(), st_invalidate_state(), st_renderbuffer(), st_renderbuffer::surface, and pipe_screen::tex_surface_release.

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    printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface);
00438    */
00439 
00440    _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
00441 
00442    /* restore previous framebuffer state */
00443    st_invalidate_state(ctx, _NEW_BUFFERS);
00444 }

static void st_framebuffer_renderbuffer ( GLcontext *  ctx,
struct gl_framebuffer *  fb,
GLenum  attachment,
struct gl_renderbuffer *  rb 
) [static]

Called by ctx->Driver.FramebufferRenderbuffer.

Definition at line 337 of file st_cb_fbo.c.

00341 {
00342    /* XXX no need for derivation? */
00343    _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
00344 }

void st_init_fbo_functions ( struct dd_function_table *  functions  ) 

Definition at line 448 of file st_cb_fbo.c.

References st_bind_framebuffer(), st_finish_render_texture(), st_framebuffer_renderbuffer(), st_new_framebuffer(), st_new_renderbuffer(), and st_render_texture().

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    /* no longer needed by core Mesa, drivers handle resizes...
00457    functions->ResizeBuffers = st_resize_buffers;
00458    */
00459 }

static struct gl_framebuffer* st_new_framebuffer ( GLcontext *  ctx,
GLuint  name 
) [static, read]

Called via ctx->Driver.NewFramebuffer().

Definition at line 223 of file st_cb_fbo.c.

00224 {
00225    /* XXX not sure we need to subclass gl_framebuffer for pipe */
00226    return _mesa_new_framebuffer(ctx, name);
00227 }

static struct gl_renderbuffer* st_new_renderbuffer ( GLcontext *  ctx,
GLuint  name 
) [static, read]

Called via ctx->Driver.NewRenderbuffer().

Definition at line 234 of file st_cb_fbo.c.

References st_renderbuffer::Base, CALLOC_STRUCT, st_renderbuffer::format, null_get_pointer(), PIPE_FORMAT_NONE, st_renderbuffer_alloc_storage(), and st_renderbuffer_delete().

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 }

struct gl_renderbuffer* st_new_renderbuffer_fb ( enum pipe_format  format,
int  samples 
) [read]

Allocate a renderbuffer for a an on-screen window (not a user-created renderbuffer).

The window system code determines the format.

Definition at line 254 of file st_cb_fbo.c.

References st_renderbuffer::Base, CALLOC_STRUCT, DEFAULT_ACCUM_PIPE_FORMAT, st_renderbuffer::format, null_get_pointer(), PIPE_FORMAT_A1R5G5B5_UNORM, PIPE_FORMAT_A4R4G4B4_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_S8_UNORM, PIPE_FORMAT_S8Z24_UNORM, PIPE_FORMAT_X8R8G8B8_UNORM, PIPE_FORMAT_X8Z24_UNORM, PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24S8_UNORM, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z32_UNORM, st_renderbuffer_alloc_storage(), st_renderbuffer_delete(), and st_renderbuffer::surface.

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; /* just a unique value */
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: /*PIPE_FORMAT_R16G16B16A16_SNORM*/
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    /* st-specific methods */
00310    strb->Base.Delete = st_renderbuffer_delete;
00311    strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
00312    strb->Base.GetPointer = null_get_pointer;
00313 
00314    /* surface is allocated in st_renderbuffer_alloc_storage() */
00315    strb->surface = NULL;
00316 
00317    return &strb->Base;
00318 }

static void st_render_texture ( GLcontext *  ctx,
struct gl_framebuffer *  fb,
struct gl_renderbuffer_attachment *  att 
) [static]

Called by ctx->Driver.RenderTexture.

Definition at line 351 of file st_cb_fbo.c.

References assert, pipe_texture::format, init_renderbuffer_bits(), pipe_surface_reference(), pipe_texture_reference(), st_renderbuffer::rtt, st_renderbuffer::rtt_face, st_renderbuffer::rtt_level, st_renderbuffer::rtt_slice, st_get_texobj_texture(), st_invalidate_state(), st_new_renderbuffer(), st_renderbuffer(), st_texture_object(), st_renderbuffer::surface, and st_renderbuffer::texture.

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    /* create new renderbuffer which wraps the texture image */
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; /* should not get called */
00375    strb = st_renderbuffer(rb);
00376 
00377    /* get the texture for the texture object */
00378    stObj = st_texture_object(att->Texture);
00379 
00380    /* point renderbuffer at texobject */
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    /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
00389 
00390    pt = st_get_texobj_texture(att->Texture);
00391    assert(pt);
00392    /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
00393 
00394    pipe_texture_reference( &strb->texture, pt );
00395 
00396    pipe_surface_reference(&strb->surface, NULL);
00397 
00398    /* the new surface will be created during framebuffer validation */
00399 
00400    init_renderbuffer_bits(strb, pt->format);
00401 
00402    /*
00403    printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p  %d x %d\n",
00404           att->Texture, pt, strb->surface, rb->Width, rb->Height);
00405    */
00406 
00407    /* Invalidate buffer state so that the pipe's framebuffer state
00408     * gets updated.
00409     * That's where the new renderbuffer (which we just created) gets
00410     * passed to the pipe as a (color/depth) render target.
00411     */
00412    st_invalidate_state(ctx, _NEW_BUFFERS);
00413 }

static GLboolean st_renderbuffer_alloc_storage ( GLcontext *  ctx,
struct gl_renderbuffer *  rb,
GLenum  internalFormat,
GLuint  width,
GLuint  height 
) [static]

gl_renderbuffer::AllocStorage() This is called to allocate the original drawing surface, and during window resize.

Definition at line 86 of file st_cb_fbo.c.

References assert, st_renderbuffer::Base, pipe_surface::block, block(), pipe_surface::buffer, DEFAULT_ACCUM_PIPE_FORMAT, FALSE, pipe_surface::format, pipe_texture::format, st_renderbuffer::format, pipe_screen::get_tex_surface, pipe_surface::height, pipe_format_block::height, init_renderbuffer_bits(), pf_get_block(), pf_is_depth_stencil(), PIPE_BUFFER_USAGE_CPU_READ, PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_BUFFER_USAGE_GPU_READ, PIPE_BUFFER_USAGE_GPU_WRITE, PIPE_FORMAT_NONE, pipe_surface_reference(), PIPE_TEXTURE_2D, pipe_texture_reference(), PIPE_TEXTURE_USAGE_DEPTH_STENCIL, PIPE_TEXTURE_USAGE_DISPLAY_TARGET, PIPE_TEXTURE_USAGE_RENDER_TARGET, pipe_context::screen, pipe_format_block::size, st_choose_renderbuffer_format(), st_renderbuffer(), pipe_surface::stride, st_renderbuffer::surface, pipe_texture::tex_usage, pipe_surface::texture, st_renderbuffer::texture, pipe_screen::texture_create, pipe_surface::width, and pipe_format_block::width.

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    /* Free the old surface and texture
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    /* Probably need dedicated flags for surface usage too: 
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    /* Special path for accum buffers.  
00145     *
00146     * Try a different surface format.  Since accum buffers are s/w
00147     * only for now, the surface pixel format doesn't really matter,
00148     * only that the buffer is large enough.
00149     */
00150    if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) 
00151    {
00152       /* Actually, just setting this usage value should be sufficient
00153        * to tell the driver to go ahead and allocate the buffer, even
00154        * if HW doesn't support the format.
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 }

static void st_renderbuffer_delete ( struct gl_renderbuffer *  rb  )  [static]

gl_renderbuffer::Delete()

Definition at line 192 of file st_cb_fbo.c.

References ASSERT, pipe_surface_reference(), pipe_texture_reference(), st_renderbuffer(), st_renderbuffer::surface, and st_renderbuffer::texture.

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 }


Generated on Tue Sep 29 06:25:53 2009 for Gallium3D by  doxygen 1.5.4