1
/**************************************************************************
3
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
**************************************************************************/
32
#include "swrast/swrast.h"
34
#include "intel_screen.h"
35
#include "intel_context.h"
36
#include "intel_batchbuffer.h"
37
#include "intel_buffers.h"
38
#include "intel_mipmap_tree.h"
39
#include "intel_regions.h"
40
#include "intel_fbo.h"
41
#include "intel_tex.h"
42
#include "intel_blit.h"
43
#include "intel_pixel.h"
45
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
48
* Get the intel_region which is the source for any glCopyTex[Sub]Image call.
50
* Do the best we can using the blitter. A future project is to use
51
* the texture engine and fragment programs for these copies.
53
static const struct intel_region *
54
get_teximage_source(struct intel_context *intel, GLenum internalFormat)
56
struct intel_renderbuffer *irb;
58
DBG("%s %s\n", __FUNCTION__,
59
_mesa_lookup_enum_by_nr(internalFormat));
61
switch (internalFormat) {
62
case GL_DEPTH_COMPONENT:
63
case GL_DEPTH_COMPONENT16_ARB:
64
irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
65
if (irb && irb->region && irb->region->cpp == 2)
68
case GL_DEPTH24_STENCIL8_EXT:
69
case GL_DEPTH_STENCIL_EXT:
70
irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
71
if (irb && irb->region && irb->region->cpp == 4)
76
return intel_readbuf_region(intel);
78
if (intel->intelScreen->cpp == 2)
79
return intel_readbuf_region(intel);
88
do_copy_texsubimage(struct intel_context *intel,
89
struct intel_texture_image *intelImage,
90
GLenum internalFormat,
91
GLint dstx, GLint dsty,
92
GLint x, GLint y, GLsizei width, GLsizei height)
94
GLcontext *ctx = &intel->ctx;
95
const struct intel_region *src =
96
get_teximage_source(intel, internalFormat);
98
if (!intelImage->mt || !src) {
99
DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src);
104
LOCK_HARDWARE(intel);
106
GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
109
const GLint orig_x = x;
110
const GLint orig_y = y;
111
const struct gl_framebuffer *fb = ctx->DrawBuffer;
113
if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax,
114
&x, &y, &width, &height)) {
115
/* Update dst for clipped src. Need to also clip the source rect.
120
if (ctx->ReadBuffer->Name == 0) {
121
/* reading from a window, adjust x, y */
122
__DRIdrawablePrivate *dPriv = intel->driDrawable;
124
/* window_y = position of window on screen if y=0=bottom */
125
window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
130
/* reading from a FBO */
132
y = ctx->ReadBuffer->Height - y - 1;
136
/* A bit of fiddling to get the blitter to work with -ve
137
* pitches. But we get a nice inverted blit this way, so it's
140
intelEmitCopyBlit(intel,
144
src->height * src->pitch * src->cpp,
145
intelImage->mt->pitch,
146
intelImage->mt->region->buffer,
148
x, y + height, dstx, dsty, width, height,
151
intel_batchbuffer_flush(intel->batch);
156
UNLOCK_HARDWARE(intel);
159
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
160
* XXX Add a ctx->Driver.GenerateMipmaps() function?
162
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
163
intel_generate_mipmap(ctx, target,
164
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
177
intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
178
GLenum internalFormat,
179
GLint x, GLint y, GLsizei width, GLint border)
181
struct gl_texture_unit *texUnit =
182
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
183
struct gl_texture_object *texObj =
184
_mesa_select_tex_object(ctx, texUnit, target);
185
struct gl_texture_image *texImage =
186
_mesa_select_tex_image(ctx, texObj, target, level);
191
/* Setup or redefine the texture object, mipmap tree and texture
192
* image. Don't populate yet.
194
ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
196
GL_RGBA, CHAN_TYPE, NULL,
197
&ctx->DefaultPacking, texObj, texImage);
199
if (!do_copy_texsubimage(intel_context(ctx),
200
intel_texture_image(texImage),
201
internalFormat, 0, 0, x, y, width, 1))
207
_swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y,
212
intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
213
GLenum internalFormat,
214
GLint x, GLint y, GLsizei width, GLsizei height,
217
struct gl_texture_unit *texUnit =
218
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
219
struct gl_texture_object *texObj =
220
_mesa_select_tex_object(ctx, texUnit, target);
221
struct gl_texture_image *texImage =
222
_mesa_select_tex_image(ctx, texObj, target, level);
227
/* Setup or redefine the texture object, mipmap tree and texture
228
* image. Don't populate yet.
230
ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
231
width, height, border,
232
GL_RGBA, CHAN_TYPE, NULL,
233
&ctx->DefaultPacking, texObj, texImage);
236
if (!do_copy_texsubimage(intel_context(ctx),
237
intel_texture_image(texImage),
238
internalFormat, 0, 0, x, y, width, height))
244
_swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y,
245
width, height, border);
250
intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
251
GLint xoffset, GLint x, GLint y, GLsizei width)
253
struct gl_texture_unit *texUnit =
254
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
255
struct gl_texture_object *texObj =
256
_mesa_select_tex_object(ctx, texUnit, target);
257
struct gl_texture_image *texImage =
258
_mesa_select_tex_image(ctx, texObj, target, level);
259
GLenum internalFormat = texImage->InternalFormat;
261
/* XXX need to check <border> as in above function? */
263
/* Need to check texture is compatible with source format.
266
if (!do_copy_texsubimage(intel_context(ctx),
267
intel_texture_image(texImage),
268
internalFormat, xoffset, 0, x, y, width, 1)) {
269
_swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width);
276
intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
277
GLint xoffset, GLint yoffset,
278
GLint x, GLint y, GLsizei width, GLsizei height)
280
struct gl_texture_unit *texUnit =
281
&ctx->Texture.Unit[ctx->Texture.CurrentUnit];
282
struct gl_texture_object *texObj =
283
_mesa_select_tex_object(ctx, texUnit, target);
284
struct gl_texture_image *texImage =
285
_mesa_select_tex_image(ctx, texObj, target, level);
286
GLenum internalFormat = texImage->InternalFormat;
289
/* Need to check texture is compatible with source format.
292
if (!do_copy_texsubimage(intel_context(ctx),
293
intel_texture_image(texImage),
295
xoffset, yoffset, x, y, width, height)) {
297
DBG("%s - fallback to swrast\n", __FUNCTION__);
299
_swrast_copy_texsubimage2d(ctx, target, level,
300
xoffset, yoffset, x, y, width, height);