1 /* $Id: s_texstore.c,v 1.2 2001/03/28 20:40:52 gareth Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 * The functions in this file are mostly related to software texture fallbacks.
35 * This includes texture image transfer/packing and texel fetching.
36 * Hardware drivers will likely override most of this.
47 #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
*) MALLOC(width
* height
* 4 * sizeof(GLchan
));
74 /* Select buffer to read from */
75 (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->ReadBuffer
,
76 ctx
->Pixel
.DriverReadBuffer
);
78 RENDER_START(swrast
,ctx
);
82 for (i
= 0; i
< height
; i
++) {
83 _mesa_read_rgba_span( ctx
, ctx
->ReadBuffer
, width
, x
, y
+ i
,
84 (GLchan (*)[4]) dst
);
88 RENDER_FINISH(swrast
,ctx
);
90 /* Read from draw buffer (the default) */
91 (*swrast
->Driver
.SetReadBuffer
)( ctx
, ctx
->DrawBuffer
,
92 ctx
->Color
.DriverDrawBuffer
);
99 * As above, but read data from depth buffer.
102 read_depth_image( GLcontext
*ctx
, GLint x
, GLint y
,
103 GLsizei width
, GLsizei height
)
105 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
106 GLfloat
*image
, *dst
;
109 image
= (GLfloat
*) MALLOC(width
* height
* sizeof(GLfloat
));
113 RENDER_START(swrast
,ctx
);
116 for (i
= 0; i
< height
; i
++) {
117 _mesa_read_depth_span_float(ctx
, width
, x
, y
+ i
, dst
);
121 RENDER_FINISH(swrast
,ctx
);
129 is_depth_format(GLenum format
)
132 case GL_DEPTH_COMPONENT
:
133 case GL_DEPTH_COMPONENT16_SGIX
:
134 case GL_DEPTH_COMPONENT24_SGIX
:
135 case GL_DEPTH_COMPONENT32_SGIX
:
144 * Fallback for Driver.CopyTexImage1D().
147 _swrast_copy_teximage1d( GLcontext
*ctx
, GLenum target
, GLint level
,
148 GLenum internalFormat
,
149 GLint x
, GLint y
, GLsizei width
, GLint border
)
151 struct gl_texture_unit
*texUnit
;
152 struct gl_texture_object
*texObj
;
153 struct gl_texture_image
*texImage
;
155 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
156 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
158 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
161 ASSERT(ctx
->Driver
.TexImage1D
);
163 if (is_depth_format(internalFormat
)) {
164 /* read depth image from framebuffer */
165 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, 1);
167 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
171 /* call glTexImage1D to redefine the texture */
172 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
174 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
175 &_mesa_native_packing
, texObj
, texImage
);
179 /* read RGBA image from framebuffer */
180 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, 1);
182 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D");
186 /* call glTexImage1D to redefine the texture */
187 (*ctx
->Driver
.TexImage1D
)(ctx
, target
, level
, internalFormat
,
189 GL_RGBA
, CHAN_TYPE
, image
,
190 &_mesa_native_packing
, texObj
, texImage
);
197 * Fallback for Driver.CopyTexImage2D().
200 _swrast_copy_teximage2d( GLcontext
*ctx
, GLenum target
, GLint level
,
201 GLenum internalFormat
,
202 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
205 struct gl_texture_unit
*texUnit
;
206 struct gl_texture_object
*texObj
;
207 struct gl_texture_image
*texImage
;
209 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
210 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
212 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
215 ASSERT(ctx
->Driver
.TexImage2D
);
217 if (is_depth_format(internalFormat
)) {
218 /* read depth image from framebuffer */
219 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
221 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
225 /* call glTexImage2D to redefine the texture */
226 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
227 width
, height
, border
,
228 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
229 &_mesa_native_packing
, texObj
, texImage
);
233 /* read RGBA image from framebuffer */
234 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
236 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D");
240 /* call glTexImage2D to redefine the texture */
241 (*ctx
->Driver
.TexImage2D
)(ctx
, target
, level
, internalFormat
,
242 width
, height
, border
,
243 GL_RGBA
, CHAN_TYPE
, image
,
244 &_mesa_native_packing
, texObj
, texImage
);
251 * Fallback for Driver.CopyTexSubImage1D().
254 _swrast_copy_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
255 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
257 struct gl_texture_unit
*texUnit
;
258 struct gl_texture_object
*texObj
;
259 struct gl_texture_image
*texImage
;
261 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
262 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
264 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
267 ASSERT(ctx
->Driver
.TexImage1D
);
269 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
270 /* read RGBA image from framebuffer */
271 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, 1);
273 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D" );
277 /* now call glTexSubImage1D to do the real work */
278 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
279 GL_RGBA
, CHAN_TYPE
, image
,
280 &_mesa_native_packing
, texObj
, texImage
);
284 /* read depth image from framebuffer */
285 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, 1);
287 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage1D");
291 /* call glTexSubImage1D to redefine the texture */
292 (*ctx
->Driver
.TexSubImage1D
)(ctx
, target
, level
, xoffset
, width
,
293 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
294 &_mesa_native_packing
, texObj
, texImage
);
301 * Fallback for Driver.CopyTexSubImage2D().
304 _swrast_copy_texsubimage2d( GLcontext
*ctx
,
305 GLenum target
, GLint level
,
306 GLint xoffset
, GLint yoffset
,
307 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
309 struct gl_texture_unit
*texUnit
;
310 struct gl_texture_object
*texObj
;
311 struct gl_texture_image
*texImage
;
313 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
314 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
316 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
319 ASSERT(ctx
->Driver
.TexImage2D
);
321 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
322 /* read RGBA image from framebuffer */
323 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
325 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D" );
329 /* now call glTexSubImage2D to do the real work */
330 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
,
331 xoffset
, yoffset
, width
, height
,
332 GL_RGBA
, CHAN_TYPE
, image
,
333 &_mesa_native_packing
, texObj
, texImage
);
337 /* read depth image from framebuffer */
338 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
340 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage2D");
344 /* call glTexImage1D to redefine the texture */
345 (*ctx
->Driver
.TexSubImage2D
)(ctx
, target
, level
,
346 xoffset
, yoffset
, width
, height
,
347 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
348 &_mesa_native_packing
, texObj
, texImage
);
355 * Fallback for Driver.CopyTexSubImage3D().
358 _swrast_copy_texsubimage3d( GLcontext
*ctx
,
359 GLenum target
, GLint level
,
360 GLint xoffset
, GLint yoffset
, GLint zoffset
,
361 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
363 struct gl_texture_unit
*texUnit
;
364 struct gl_texture_object
*texObj
;
365 struct gl_texture_image
*texImage
;
367 texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
368 texObj
= _mesa_select_tex_object(ctx
, texUnit
, target
);
370 texImage
= _mesa_select_tex_image(ctx
, texUnit
, target
, level
);
373 ASSERT(ctx
->Driver
.TexImage3D
);
375 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
376 /* read RGBA image from framebuffer */
377 GLchan
*image
= read_color_image(ctx
, x
, y
, width
, height
);
379 _mesa_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage3D" );
383 /* now call glTexSubImage3D to do the real work */
384 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
385 xoffset
, yoffset
, zoffset
, width
, height
, 1,
386 GL_RGBA
, CHAN_TYPE
, image
,
387 &_mesa_native_packing
, texObj
, texImage
);
391 /* read depth image from framebuffer */
392 GLfloat
*image
= read_depth_image(ctx
, x
, y
, width
, height
);
394 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCopyTexSubImage3D");
398 /* call glTexImage1D to redefine the texture */
399 (*ctx
->Driver
.TexSubImage3D
)(ctx
, target
, level
,
400 xoffset
, yoffset
, zoffset
, width
, height
, 1,
401 GL_DEPTH_COMPONENT
, GL_FLOAT
, image
,
402 &_mesa_native_packing
, texObj
, texImage
);