summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast/s_texrender.c
blob: 643f2bc2c24e3b8d636a8d98c7bebe5e64344be5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

#include "main/context.h"
#include "main/colormac.h"
#include "main/fbobject.h"
#include "main/macros.h"
#include "main/teximage.h"
#include "main/renderbuffer.h"
#include "swrast/swrast.h"
#include "swrast/s_context.h"
#include "swrast/s_texfetch.h"


/*
 * Render-to-texture code for GL_EXT_framebuffer_object
 */


static void
delete_texture_wrapper(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
   ASSERT(rb->RefCount == 0);
   free(rb);
}

/**
 * Update the renderbuffer wrapper for rendering to a texture.
 * For example, update the width, height of the RB based on the texture size,
 * update the internal format info, etc.
 */
static void
update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
{
   struct gl_renderbuffer *rb = att->Renderbuffer;
   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
   struct swrast_texture_image *swImage;
   gl_format format;
   GLuint zOffset;

   (void) ctx;

   swImage = swrast_texture_image(rb->TexImage);
   assert(swImage);

   format = swImage->Base.TexFormat;

   if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
      zOffset = 0;
   }
   else {
      zOffset = att->Zoffset;
   }

   /* Want to store linear values, not sRGB */
   rb->Format = _mesa_get_srgb_format_linear(format);

   srb->Buffer = swImage->ImageSlices[zOffset];
}



/**
 * Called when rendering to a texture image begins, or when changing
 * the dest mipmap level, cube face, etc.
 * This is a fallback routine for software render-to-texture.
 *
 * Called via the glRenderbufferTexture1D/2D/3D() functions
 * and elsewhere (such as glTexImage2D).
 *
 * The image we're rendering into is
 * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
 * It'll never be NULL.
 *
 * \param fb  the framebuffer object the texture is being bound to
 * \param att  the fb attachment point of the texture
 *
 * \sa _mesa_framebuffer_renderbuffer
 */
void
_swrast_render_texture(struct gl_context *ctx,
                       struct gl_framebuffer *fb,
                       struct gl_renderbuffer_attachment *att)
{
   struct gl_renderbuffer *rb = att->Renderbuffer;
   (void) fb;

   /* plug in our texture_renderbuffer-specific functions */
   rb->Delete = delete_texture_wrapper;

   update_wrapper(ctx, att);
}


void
_swrast_finish_render_texture(struct gl_context *ctx,
                              struct gl_renderbuffer_attachment *att)
{
   /* do nothing */
   /* The renderbuffer texture wrapper will get deleted by the
    * normal mechanism for deleting renderbuffers.
    */
   (void) ctx;
   (void) att;
}