Home | History | Annotate | Download | only in swrast
      1 
      2 #include "main/context.h"
      3 #include "main/colormac.h"
      4 #include "main/fbobject.h"
      5 #include "main/macros.h"
      6 #include "main/teximage.h"
      7 #include "main/renderbuffer.h"
      8 #include "swrast/swrast.h"
      9 #include "swrast/s_context.h"
     10 #include "swrast/s_texfetch.h"
     11 
     12 
     13 /*
     14  * Render-to-texture code for GL_EXT_framebuffer_object
     15  */
     16 
     17 
     18 static void
     19 delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb)
     20 {
     21    ASSERT(rb->RefCount == 0);
     22    free(rb);
     23 }
     24 
     25 
     26 /**
     27  * This function creates a renderbuffer object which wraps a texture image.
     28  * The new renderbuffer is plugged into the given attachment point.
     29  * This allows rendering into the texture as if it were a renderbuffer.
     30  */
     31 static void
     32 wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
     33 {
     34    struct gl_renderbuffer *rb;
     35    const GLuint name = 0;
     36 
     37    ASSERT(att->Type == GL_TEXTURE);
     38    ASSERT(att->Renderbuffer == NULL);
     39 
     40    rb = ctx->Driver.NewRenderbuffer(ctx, name);
     41    if (!rb) {
     42       _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture");
     43       return;
     44    }
     45 
     46    /* init base gl_renderbuffer fields */
     47    _mesa_init_renderbuffer(rb, name);
     48    /* plug in our texture_renderbuffer-specific functions */
     49    rb->Delete = delete_texture_wrapper;
     50    rb->AllocStorage = NULL; /* illegal! */
     51 
     52    /* update attachment point */
     53    _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
     54 }
     55 
     56 /**
     57  * Update the renderbuffer wrapper for rendering to a texture.
     58  * For example, update the width, height of the RB based on the texture size,
     59  * update the internal format info, etc.
     60  */
     61 static void
     62 update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
     63 {
     64    struct gl_renderbuffer *rb = att->Renderbuffer;
     65    struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
     66    struct swrast_texture_image *swImage;
     67    gl_format format;
     68    GLuint zOffset;
     69 
     70    (void) ctx;
     71 
     72    swImage = swrast_texture_image(_mesa_get_attachment_teximage(att));
     73    assert(swImage);
     74 
     75    format = swImage->Base.TexFormat;
     76 
     77    if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
     78       zOffset = 0;
     79    }
     80    else {
     81       zOffset = att->Zoffset;
     82    }
     83 
     84    rb->Width = swImage->Base.Width;
     85    rb->Height = swImage->Base.Height;
     86    rb->InternalFormat = swImage->Base.InternalFormat;
     87    rb->_BaseFormat = _mesa_get_format_base_format(format);
     88 
     89    /* Want to store linear values, not sRGB */
     90    rb->Format = _mesa_get_srgb_format_linear(format);
     91 
     92    /* Set the gl_renderbuffer::Buffer field so that mapping the buffer
     93     * succeeds.
     94      */
     95    if (att->Texture->Target == GL_TEXTURE_3D ||
     96        att->Texture->Target == GL_TEXTURE_2D_ARRAY_EXT) {
     97       srb->Buffer = swImage->Buffer +
     98          swImage->ImageOffsets[zOffset] * _mesa_get_format_bytes(format);
     99    }
    100    else {
    101       srb->Buffer = swImage->Buffer;
    102    }
    103 }
    104 
    105 
    106 
    107 /**
    108  * Called when rendering to a texture image begins, or when changing
    109  * the dest mipmap level, cube face, etc.
    110  * This is a fallback routine for software render-to-texture.
    111  *
    112  * Called via the glRenderbufferTexture1D/2D/3D() functions
    113  * and elsewhere (such as glTexImage2D).
    114  *
    115  * The image we're rendering into is
    116  * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
    117  * It'll never be NULL.
    118  *
    119  * \param fb  the framebuffer object the texture is being bound to
    120  * \param att  the fb attachment point of the texture
    121  *
    122  * \sa _mesa_framebuffer_renderbuffer
    123  */
    124 void
    125 _swrast_render_texture(struct gl_context *ctx,
    126                        struct gl_framebuffer *fb,
    127                        struct gl_renderbuffer_attachment *att)
    128 {
    129    (void) fb;
    130 
    131    if (!att->Renderbuffer) {
    132       wrap_texture(ctx, att);
    133    }
    134    update_wrapper(ctx, att);
    135 }
    136 
    137 
    138 void
    139 _swrast_finish_render_texture(struct gl_context *ctx,
    140                               struct gl_renderbuffer_attachment *att)
    141 {
    142    /* do nothing */
    143    /* The renderbuffer texture wrapper will get deleted by the
    144     * normal mechanism for deleting renderbuffers.
    145     */
    146    (void) ctx;
    147    (void) att;
    148 }
    149