2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 * The functions in this file are mostly related to software texture fallbacks.
33 * This includes texture image transfer/packing and texel fetching.
34 * Hardware drivers will likely override most of this.
46 #include "texformat.h"
50 #include "s_context.h"
55 * Read an RGBA image from the frame buffer.
56 * This is used by glCopyTex[Sub]Image[12]D().
57 * Input: ctx - the context
58 * x, y - lower left corner
59 * width, height - size of region to read
60 * Return: pointer to block of GL_RGBA, GLchan data.
63 read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
64 GLsizei width
, GLsizei height
)
66 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
70 image
= (GLchan
*) _mesa_malloc(width
* height
* 4 * sizeof(GLchan
));
74 /* Select buffer to read from */
75 _swrast_use_read_buffer(ctx
);
77 RENDER_START(swrast
,ctx
);
81 for (i
= 0; i
< height
; i
++) {
82 _swrast_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
83 (GLchan (*)[4]) dst
);
87 RENDER_FINISH(swrast
,ctx
);
89 /* Read from draw buffer (the default) */
90 _swrast_use_draw_buffer(ctx
);
97 * As above, but read data from depth buffer.
100 read_depth_image( GLcontext
*ctx
, GLint x
, GLint y
,
101 GLsizei width
, GLsizei height
)
103 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
104 GLfloat
*image
, *dst
;
107 image
= (GLfloat
*) _mesa_malloc(width
* height
* sizeof(GLfloat
));
111 RENDER_START(swrast
,ctx
);
114 for (i
= 0; i
< height
; i
++) {
115 _swrast_read_depth_span_float(ctx
, width
, x
, y
+ i
, dst
);
119 RENDER_FINISH(swrast
,ctx
);
127 is_depth_format(GLenum format
)
130 case GL_DEPTH_COMPONENT
:
131 case GL_DEPTH_COMPONENT16_SGIX
:
132 case GL_DEPTH_COMPONENT24_SGIX
:
133 case GL_DEPTH_COMPONENT32_SGIX
:
142 * Fallback for Driver.CopyTexImage1D().
145 _swrast_copy_teximage1d( GLcontext
*ctx
, GLenum target
, GLint level
,
146 GLenum internalFormat
,
147 GLint x
, GLint y
, GLsizei width
, GLint border
)
149 struct gl_texture_unit
*texUnit
;
150 struct gl_texture_object
*texObj
;
151 struct gl_texture_image
*texImage
;
153 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
154 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
156 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
159 ASSERT(ctx
->Driver
.TexImage1D
);
161 if (is_depth_format(internalFormat
)) {
162 /* read depth image from framebuffer */
163 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, 1);
165 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
169 /* call glTexImage1D to redefine the texture */
170 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
172 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
173 &ctx
->DefaultPacking
, texObj
, texImage
);
177 /* read RGBA image from framebuffer */
178 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, 1);
180 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
184 /* call glTexImage1D to redefine the texture */
185 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
187 GL_RGBA
, CHAN_TYPE
, image
,
188 &ctx
->DefaultPacking
, texObj
, texImage
);
192 /* GL_SGIS_generate_mipmap */
193 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
194 _mesa_generate_mipmap(ctx
, target
, texUnit
, texObj
);
200 * Fallback for Driver.CopyTexImage2D().
203 _swrast_copy_teximage2d( GLcontext
*ctx
, GLenum target
, GLint level
,
204 GLenum internalFormat
,
205 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
208 struct gl_texture_unit
*texUnit
;
209 struct gl_texture_object
*texObj
;
210 struct gl_texture_image
*texImage
;
212 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
213 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
215 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
218 ASSERT(ctx
->Driver
.TexImage2D
);
220 if (is_depth_format(internalFormat
)) {
221 /* read depth image from framebuffer */
222 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
224 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
228 /* call glTexImage2D to redefine the texture */
229 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
230 width
, height
, border
,
231 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
232 &ctx
->DefaultPacking
, texObj
, texImage
);
236 /* read RGBA image from framebuffer */
237 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
239 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
243 /* call glTexImage2D to redefine the texture */
244 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
245 width
, height
, border
,
246 GL_RGBA
, CHAN_TYPE
, image
,
247 &ctx
->DefaultPacking
, texObj
, texImage
);
251 /* GL_SGIS_generate_mipmap */
252 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
253 _mesa_generate_mipmap(ctx
, target
, texUnit
, texObj
);
259 * Fallback for Driver.CopyTexSubImage1D().
262 _swrast_copy_texsubimage1d( GLcontext
*ctx
, GLenum target
, GLint level
,
263 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
265 struct gl_texture_unit
*texUnit
;
266 struct gl_texture_object
*texObj
;
267 struct gl_texture_image
*texImage
;
269 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
270 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
272 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
275 ASSERT(ctx
->Driver
.TexImage1D
);
277 if (texImage
->Format
== GL_DEPTH_COMPONENT
) {
278 /* read depth image from framebuffer */
279 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, 1);
281 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D");
285 /* call glTexSubImage1D to redefine the texture */
286 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
287 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
288 &ctx
->DefaultPacking
, texObj
, texImage
);
292 /* read RGBA image from framebuffer */
293 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, 1);
295 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D" );
299 /* now call glTexSubImage1D to do the real work */
300 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
301 GL_RGBA
, CHAN_TYPE
, image
,
302 &ctx
->DefaultPacking
, texObj
, texImage
);
306 /* GL_SGIS_generate_mipmap */
307 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
308 _mesa_generate_mipmap(ctx
, target
, texUnit
, texObj
);
314 * Fallback for Driver.CopyTexSubImage2D().
317 _swrast_copy_texsubimage2d( GLcontext
*ctx
,
318 GLenum target
, GLint level
,
319 GLint xoffset
, GLint yoffset
,
320 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
322 struct gl_texture_unit
*texUnit
;
323 struct gl_texture_object
*texObj
;
324 struct gl_texture_image
*texImage
;
326 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
327 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
329 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
332 ASSERT(ctx
->Driver
.TexImage2D
);
334 if (texImage
->Format
== GL_DEPTH_COMPONENT
) {
335 /* read depth image from framebuffer */
336 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
338 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D");
342 /* call glTexImage1D to redefine the texture */
343 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
,
344 xoffset
, yoffset
, width
, height
,
345 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
346 &ctx
->DefaultPacking
, texObj
, texImage
);
350 /* read RGBA image from framebuffer */
351 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
353 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
357 /* now call glTexSubImage2D to do the real work */
358 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
,
359 xoffset
, yoffset
, width
, height
,
360 GL_RGBA
, CHAN_TYPE
, image
,
361 &ctx
->DefaultPacking
, texObj
, texImage
);
365 /* GL_SGIS_generate_mipmap */
366 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
367 _mesa_generate_mipmap(ctx
, target
, texUnit
, texObj
);
373 * Fallback for Driver.CopyTexSubImage3D().
376 _swrast_copy_texsubimage3d( GLcontext
*ctx
,
377 GLenum target
, GLint level
,
378 GLint xoffset
, GLint yoffset
, GLint zoffset
,
379 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
381 struct gl_texture_unit
*texUnit
;
382 struct gl_texture_object
*texObj
;
383 struct gl_texture_image
*texImage
;
385 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
386 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
388 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
391 ASSERT(ctx
->Driver
.TexImage3D
);
393 if (texImage
->Format
== GL_DEPTH_COMPONENT
) {
394 /* read depth image from framebuffer */
395 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
397 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage3D");
401 /* call glTexImage1D to redefine the texture */
402 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
403 xoffset
, yoffset
, zoffset
, width
, height
, 1,
404 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
405 &ctx
->DefaultPacking
, texObj
, texImage
);
409 /* read RGBA image from framebuffer */
410 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
412 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage3D" );
416 /* now call glTexSubImage3D to do the real work */
417 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
418 xoffset
, yoffset
, zoffset
, width
, height
, 1,
419 GL_RGBA
, CHAN_TYPE
, image
,
420 &ctx
->DefaultPacking
, texObj
, texImage
);
424 /* GL_SGIS_generate_mipmap */
425 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
426 _mesa_generate_mipmap(ctx
, target
, texUnit
, texObj
);