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"
14 * Render-to-texture code for GL_EXT_framebuffer_object
19 * Derived from gl_renderbuffer class
21 struct texture_renderbuffer
23 struct gl_renderbuffer Base
; /**< Base class object */
24 struct swrast_texture_image
*TexImage
;
27 GLint Yoffset
; /**< Layer for 1D array textures. */
28 GLint Zoffset
; /**< Layer for 2D array textures, or slice
35 static inline struct texture_renderbuffer
*
36 texture_renderbuffer(struct gl_renderbuffer
*rb
)
38 return (struct texture_renderbuffer
*) rb
;
45 store_nop(struct swrast_texture_image
*texImage
,
46 GLint col
, GLint row
, GLint img
,
53 delete_texture_wrapper(struct gl_renderbuffer
*rb
)
55 ASSERT(rb
->RefCount
== 0);
61 * This function creates a renderbuffer object which wraps a texture image.
62 * The new renderbuffer is plugged into the given attachment point.
63 * This allows rendering into the texture as if it were a renderbuffer.
66 wrap_texture(struct gl_context
*ctx
, struct gl_renderbuffer_attachment
*att
)
68 struct texture_renderbuffer
*trb
;
69 const GLuint name
= 0;
71 ASSERT(att
->Type
== GL_TEXTURE
);
72 ASSERT(att
->Renderbuffer
== NULL
);
74 trb
= CALLOC_STRUCT(texture_renderbuffer
);
76 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "wrap_texture");
80 /* init base gl_renderbuffer fields */
81 _mesa_init_renderbuffer(&trb
->Base
, name
);
82 /* plug in our texture_renderbuffer-specific functions */
83 trb
->Base
.Delete
= delete_texture_wrapper
;
84 trb
->Base
.AllocStorage
= NULL
; /* illegal! */
86 /* update attachment point */
87 _mesa_reference_renderbuffer(&att
->Renderbuffer
, &(trb
->Base
));
91 * Update the renderbuffer wrapper for rendering to a texture.
92 * For example, update the width, height of the RB based on the texture size,
93 * update the internal format info, etc.
96 update_wrapper(struct gl_context
*ctx
, struct gl_renderbuffer_attachment
*att
)
98 struct texture_renderbuffer
*trb
99 = (struct texture_renderbuffer
*) att
->Renderbuffer
;
104 trb
->TexImage
= swrast_texture_image(_mesa_get_attachment_teximage(att
));
105 ASSERT(trb
->TexImage
);
107 trb
->Store
= _mesa_get_texel_store_func(trb
->TexImage
->Base
.TexFormat
);
109 /* we'll never draw into some textures (compressed formats) */
110 trb
->Store
= store_nop
;
113 if (!trb
->TexImage
->FetchTexel
) {
114 _mesa_update_fetch_functions(trb
->TexImage
->Base
.TexObject
);
116 trb
->Fetch
= trb
->TexImage
->FetchTexel
;
119 if (att
->Texture
->Target
== GL_TEXTURE_1D_ARRAY_EXT
) {
120 trb
->Yoffset
= att
->Zoffset
;
125 trb
->Zoffset
= att
->Zoffset
;
128 trb
->Base
.Width
= trb
->TexImage
->Base
.Width
;
129 trb
->Base
.Height
= trb
->TexImage
->Base
.Height
;
130 trb
->Base
.RowStride
= trb
->TexImage
->RowStride
;
131 trb
->Base
.InternalFormat
= trb
->TexImage
->Base
.InternalFormat
;
132 trb
->Base
.Format
= trb
->TexImage
->Base
.TexFormat
;
134 /* Set the gl_renderbuffer::Data field so that mapping the buffer
135 * in renderbuffer.c succeeds.
137 if (att
->Texture
->Target
== GL_TEXTURE_3D
||
138 att
->Texture
->Target
== GL_TEXTURE_2D_ARRAY_EXT
) {
139 trb
->Base
.Data
= trb
->TexImage
->Buffer
+
140 trb
->TexImage
->ImageOffsets
[trb
->Zoffset
] *
141 _mesa_get_format_bytes(trb
->TexImage
->Base
.TexFormat
);
144 trb
->Base
.Data
= trb
->TexImage
->Buffer
;
147 /* XXX may need more special cases here */
148 switch (trb
->TexImage
->Base
.TexFormat
) {
149 case MESA_FORMAT_Z24_S8
:
150 trb
->Base
.DataType
= GL_UNSIGNED_INT_24_8_EXT
;
151 trb
->Base
._BaseFormat
= GL_DEPTH_STENCIL
;
153 case MESA_FORMAT_S8_Z24
:
154 trb
->Base
.DataType
= GL_UNSIGNED_INT_8_24_REV_MESA
;
155 trb
->Base
._BaseFormat
= GL_DEPTH_STENCIL
;
157 case MESA_FORMAT_Z24_X8
:
158 trb
->Base
.DataType
= GL_UNSIGNED_INT_24_8_EXT
;
159 trb
->Base
._BaseFormat
= GL_DEPTH_COMPONENT
;
161 case MESA_FORMAT_X8_Z24
:
162 trb
->Base
.DataType
= GL_UNSIGNED_INT_8_24_REV_MESA
;
163 trb
->Base
._BaseFormat
= GL_DEPTH_COMPONENT
;
165 case MESA_FORMAT_Z16
:
166 trb
->Base
.DataType
= GL_UNSIGNED_SHORT
;
167 trb
->Base
._BaseFormat
= GL_DEPTH_COMPONENT
;
169 case MESA_FORMAT_Z32
:
170 trb
->Base
.DataType
= GL_UNSIGNED_INT
;
171 trb
->Base
._BaseFormat
= GL_DEPTH_COMPONENT
;
173 /* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */
174 case MESA_FORMAT_SRGB8
:
175 trb
->Fetch
= _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888
, _mesa_get_texture_dimensions(att
->Texture
->Target
));
176 trb
->Base
.DataType
= CHAN_TYPE
;
177 trb
->Base
._BaseFormat
= GL_RGBA
;
179 case MESA_FORMAT_SRGBA8
:
180 trb
->Fetch
= _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888
, _mesa_get_texture_dimensions(att
->Texture
->Target
));
181 trb
->Base
.DataType
= CHAN_TYPE
;
182 trb
->Base
._BaseFormat
= GL_RGBA
;
184 case MESA_FORMAT_SARGB8
:
185 trb
->Fetch
= _mesa_get_texel_fetch_func(MESA_FORMAT_ARGB8888
, _mesa_get_texture_dimensions(att
->Texture
->Target
));
186 trb
->Base
.DataType
= CHAN_TYPE
;
187 trb
->Base
._BaseFormat
= GL_RGBA
;
190 trb
->Base
.DataType
= CHAN_TYPE
;
191 trb
->Base
._BaseFormat
= GL_RGBA
;
198 * Called when rendering to a texture image begins, or when changing
199 * the dest mipmap level, cube face, etc.
200 * This is a fallback routine for software render-to-texture.
202 * Called via the glRenderbufferTexture1D/2D/3D() functions
203 * and elsewhere (such as glTexImage2D).
205 * The image we're rendering into is
206 * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
207 * It'll never be NULL.
209 * \param fb the framebuffer object the texture is being bound to
210 * \param att the fb attachment point of the texture
212 * \sa _mesa_framebuffer_renderbuffer
215 _swrast_render_texture(struct gl_context
*ctx
,
216 struct gl_framebuffer
*fb
,
217 struct gl_renderbuffer_attachment
*att
)
221 if (!att
->Renderbuffer
) {
222 wrap_texture(ctx
, att
);
224 update_wrapper(ctx
, att
);
229 _swrast_finish_render_texture(struct gl_context
*ctx
,
230 struct gl_renderbuffer_attachment
*att
)
233 /* The renderbuffer texture wrapper will get deleted by the
234 * normal mechanism for deleting renderbuffers.