5 #include "renderbuffer.h"
9 * Render-to-texture code for GL_EXT_framebuffer_object
14 * Derived from gl_renderbuffer class
16 struct texture_renderbuffer
18 struct gl_renderbuffer Base
; /* Base class object */
19 struct gl_texture_image
*TexImage
;
27 texture_get_row(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
28 GLint x
, GLint y
, void *values
)
30 const struct texture_renderbuffer
*trb
31 = (const struct texture_renderbuffer
*) rb
;
32 const GLint z
= trb
->Zoffset
;
33 GLchan
*rgbaOut
= (GLchan
*) values
;
35 for (i
= 0; i
< count
; i
++) {
36 trb
->TexImage
->FetchTexelc(trb
->TexImage
, x
+ i
, y
, z
, rgbaOut
+ 4 * i
);
41 texture_get_values(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
42 const GLint x
[], const GLint y
[], void *values
)
44 const struct texture_renderbuffer
*trb
45 = (const struct texture_renderbuffer
*) rb
;
46 const GLint z
= trb
->Zoffset
;
47 GLchan
*rgbaOut
= (GLchan
*) values
;
49 for (i
= 0; i
< count
; i
++) {
50 trb
->TexImage
->FetchTexelc(trb
->TexImage
, x
[i
], y
[i
], z
,
56 texture_put_row(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
57 GLint x
, GLint y
, const void *values
, const GLubyte
*mask
)
59 const struct texture_renderbuffer
*trb
60 = (const struct texture_renderbuffer
*) rb
;
61 const GLint z
= trb
->Zoffset
;
62 const GLchan
*rgba
= (const GLchan
*) values
;
64 for (i
= 0; i
< count
; i
++) {
65 if (!mask
|| mask
[i
]) {
66 trb
->Store(trb
->TexImage
, x
+ i
, y
, z
, rgba
);
73 texture_put_mono_row(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
74 GLint x
, GLint y
, const void *value
, const GLubyte
*mask
)
76 const struct texture_renderbuffer
*trb
77 = (const struct texture_renderbuffer
*) rb
;
78 const GLint z
= trb
->Zoffset
;
79 const GLchan
*rgba
= (const GLchan
*) value
;
81 for (i
= 0; i
< count
; i
++) {
82 if (!mask
|| mask
[i
]) {
83 trb
->Store(trb
->TexImage
, x
+ i
, y
, z
, rgba
);
89 texture_put_values(GLcontext
*ctx
, struct gl_renderbuffer
*rb
, GLuint count
,
90 const GLint x
[], const GLint y
[], const void *values
,
93 const struct texture_renderbuffer
*trb
94 = (const struct texture_renderbuffer
*) rb
;
95 const GLint z
= trb
->Zoffset
;
96 const GLchan
*rgba
= (const GLchan
*) values
;
98 for (i
= 0; i
< count
; i
++) {
99 if (!mask
|| mask
[i
]) {
100 trb
->Store(trb
->TexImage
, x
[i
], y
[i
], z
, rgba
);
107 texture_put_mono_values(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
108 GLuint count
, const GLint x
[], const GLint y
[],
109 const void *value
, const GLubyte
*mask
)
111 const struct texture_renderbuffer
*trb
112 = (const struct texture_renderbuffer
*) rb
;
113 const GLint z
= trb
->Zoffset
;
114 const GLchan
*rgba
= (const GLchan
*) value
;
116 for (i
= 0; i
< count
; i
++) {
117 if (!mask
|| mask
[i
]) {
118 trb
->Store(trb
->TexImage
, x
[i
], y
[i
], z
, rgba
);
125 delete_texture_wrapper(struct gl_renderbuffer
*rb
)
127 ASSERT(rb
->RefCount
== 0);
133 * If a render buffer attachment specifies a texture image, we'll use
134 * this function to make a gl_renderbuffer wrapper around the texture image.
135 * This allows other parts of Mesa to access the texture image as if it
136 * was a renderbuffer.
139 wrap_texture(GLcontext
*ctx
, struct gl_renderbuffer_attachment
*att
)
141 struct texture_renderbuffer
*trb
;
142 const GLuint name
= 0;
144 ASSERT(att
->Type
== GL_TEXTURE
);
145 ASSERT(att
->Renderbuffer
== NULL
);
147 ASSERT(att->Complete);
150 trb
= CALLOC_STRUCT(texture_renderbuffer
);
152 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "wrap_texture");
156 _mesa_init_renderbuffer(&trb
->Base
, name
);
158 trb
->TexImage
= att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
159 assert(trb
->TexImage
);
161 trb
->Store
= trb
->TexImage
->TexFormat
->StoreTexel
;
164 trb
->Zoffset
= att
->Zoffset
;
166 trb
->Base
.Width
= trb
->TexImage
->Width
;
167 trb
->Base
.Height
= trb
->TexImage
->Height
;
168 trb
->Base
.InternalFormat
= trb
->TexImage
->InternalFormat
; /* XXX fix? */
169 trb
->Base
._BaseFormat
= trb
->TexImage
->TexFormat
->BaseFormat
;
171 /* fix/avoid this assertion someday */
172 assert(trb
->Base
._BaseFormat
== GL_RGB
||
173 trb
->Base
._BaseFormat
== GL_RGBA
||
174 trb
->Base
._BaseFormat
== GL_DEPTH_COMPONENT
);
176 trb
->Base
.DataType
= GL_UNSIGNED_BYTE
; /* XXX fix! */
177 trb
->Base
.Data
= trb
->TexImage
->Data
;
179 trb
->Base
.GetRow
= texture_get_row
;
180 trb
->Base
.GetValues
= texture_get_values
;
181 trb
->Base
.PutRow
= texture_put_row
;
182 trb
->Base
.PutMonoRow
= texture_put_mono_row
;
183 trb
->Base
.PutValues
= texture_put_values
;
184 trb
->Base
.PutMonoValues
= texture_put_mono_values
;
186 trb
->Base
.Delete
= delete_texture_wrapper
;
187 trb
->Base
.AllocStorage
= NULL
; /* illegal! */
190 trb
->Base
.RedBits
= trb
->TexImage
->TexFormat
->RedBits
;
191 trb
->Base
.GreenBits
= trb
->TexImage
->TexFormat
->GreenBits
;
192 trb
->Base
.BlueBits
= trb
->TexImage
->TexFormat
->BlueBits
;
193 trb
->Base
.AlphaBits
= trb
->TexImage
->TexFormat
->AlphaBits
;
194 trb
->Base
.DepthBits
= trb
->TexImage
->TexFormat
->DepthBits
;
196 att
->Renderbuffer
= &(trb
->Base
);
197 trb
->Base
.RefCount
++;
203 * Called when rendering to a texture image begins, or when changing
204 * the dest mipmap level, cube face, etc.
205 * This is a fallback routine for software render-to-texture.
207 * Called via the glRenderbufferTexture1D/2D/3D() functions
208 * and elsewhere (such as glTexImage2D).
210 * The image we're rendering into is
211 * att->Texture->Image[att->CubeMapFace][att->TextureLevel];
212 * It'll never be NULL.
214 * \param fb the framebuffer object the texture is being bound to
215 * \param att the fb attachment point of the texture
217 * \sa _mesa_framebuffer_renderbuffer
220 _mesa_render_texture(GLcontext
*ctx
,
221 struct gl_framebuffer
*fb
,
222 struct gl_renderbuffer_attachment
*att
)
224 struct gl_texture_image
*newImage
225 = att
->Texture
->Image
[att
->CubeMapFace
][att
->TextureLevel
];
226 struct texture_renderbuffer
*trb
227 = (struct texture_renderbuffer
*) att
->Renderbuffer
;
228 struct gl_texture_image
*oldImage
= trb
? trb
->TexImage
: NULL
;
234 if (oldImage
!= newImage
) {
236 /* get rid of old wrapper */
237 /* XXX also if Zoffset changes? */
238 trb
->Base
.Delete(&trb
->Base
);
240 wrap_texture(ctx
, att
);
246 _mesa_finish_render_texture(GLcontext
*ctx
,
247 struct gl_renderbuffer_attachment
*att
)
250 /* The renderbuffer texture wrapper will get deleted by the
251 * normal mechanism for deleting renderbuffers.