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
.RefCount
= 1;
167 trb
->Base
.Width
= trb
->TexImage
->Width
;
168 trb
->Base
.Height
= trb
->TexImage
->Height
;
169 trb
->Base
.InternalFormat
= trb
->TexImage
->InternalFormat
; /* XXX fix? */
170 trb
->Base
._BaseFormat
= trb
->TexImage
->TexFormat
->BaseFormat
;
172 /* fix/avoid this assertion someday */
173 assert(trb
->Base
._BaseFormat
== GL_RGB
||
174 trb
->Base
._BaseFormat
== GL_RGBA
||
175 trb
->Base
._BaseFormat
== GL_DEPTH_COMPONENT
);
177 trb
->Base
.DataType
= GL_UNSIGNED_BYTE
; /* XXX fix! */
178 trb
->Base
.Data
= trb
->TexImage
->Data
;
180 trb
->Base
.GetRow
= texture_get_row
;
181 trb
->Base
.GetValues
= texture_get_values
;
182 trb
->Base
.PutRow
= texture_put_row
;
183 trb
->Base
.PutMonoRow
= texture_put_mono_row
;
184 trb
->Base
.PutValues
= texture_put_values
;
185 trb
->Base
.PutMonoValues
= texture_put_mono_values
;
187 trb
->Base
.Delete
= delete_texture_wrapper
;
188 trb
->Base
.AllocStorage
= NULL
; /* illegal! */
191 trb
->Base
.RedBits
= trb
->TexImage
->TexFormat
->RedBits
;
192 trb
->Base
.GreenBits
= trb
->TexImage
->TexFormat
->GreenBits
;
193 trb
->Base
.BlueBits
= trb
->TexImage
->TexFormat
->BlueBits
;
194 trb
->Base
.AlphaBits
= trb
->TexImage
->TexFormat
->AlphaBits
;
195 trb
->Base
.DepthBits
= trb
->TexImage
->TexFormat
->DepthBits
;
197 att
->Renderbuffer
= &(trb
->Base
);
203 * Software fallback for ctx->Driver.RenderbufferTexture.
204 * This is called via the glRenderbufferTexture1D/2D/3D() functions.
205 * If we're unbinding a texture, texObj will be NULL.
206 * The framebuffer of interest is ctx->DrawBuffer.
207 * \sa _mesa_framebuffer_renderbuffer
210 _mesa_renderbuffer_texture(GLcontext
*ctx
,
211 struct gl_renderbuffer_attachment
*att
,
212 struct gl_texture_object
*texObj
,
213 GLenum texTarget
, GLuint level
, GLuint zoffset
)
216 _mesa_set_texture_attachment(ctx
, att
, texObj
,
217 texTarget
, level
, zoffset
);
218 if (!att
->Renderbuffer
)
219 wrap_texture(ctx
, att
);
222 _mesa_remove_attachment(ctx
, att
);