~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/intel_tex_copy.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 
4
 * All Rights Reserved.
 
5
 * 
 
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:
 
13
 * 
 
14
 * The above copyright notice and this permission notice (including the
 
15
 * next paragraph) shall be included in all copies or substantial portions
 
16
 * of the Software.
 
17
 * 
 
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.
 
25
 * 
 
26
 **************************************************************************/
 
27
 
 
28
#include "mtypes.h"
 
29
#include "enums.h"
 
30
#include "image.h"
 
31
#include "teximage.h"
 
32
#include "swrast/swrast.h"
 
33
 
 
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"
 
44
 
 
45
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
46
 
 
47
/**
 
48
 * Get the intel_region which is the source for any glCopyTex[Sub]Image call.
 
49
 *
 
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.
 
52
 */
 
53
static const struct intel_region *
 
54
get_teximage_source(struct intel_context *intel, GLenum internalFormat)
 
55
{
 
56
   struct intel_renderbuffer *irb;
 
57
 
 
58
   DBG("%s %s\n", __FUNCTION__,
 
59
       _mesa_lookup_enum_by_nr(internalFormat));
 
60
 
 
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)
 
66
         return irb->region;
 
67
      return NULL;
 
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)
 
72
         return irb->region;
 
73
      return NULL;
 
74
   case GL_RGBA:
 
75
   case GL_RGBA8:
 
76
      return intel_readbuf_region(intel);
 
77
   case GL_RGB:
 
78
      if (intel->intelScreen->cpp == 2)
 
79
         return intel_readbuf_region(intel);
 
80
      return NULL;
 
81
   default:
 
82
      return NULL;
 
83
   }
 
84
}
 
85
 
 
86
 
 
87
static GLboolean
 
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)
 
93
{
 
94
   GLcontext *ctx = &intel->ctx;
 
95
   const struct intel_region *src =
 
96
      get_teximage_source(intel, internalFormat);
 
97
 
 
98
   if (!intelImage->mt || !src) {
 
99
      DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src);
 
100
      return GL_FALSE;
 
101
   }
 
102
 
 
103
   intelFlush(ctx);
 
104
   LOCK_HARDWARE(intel);
 
105
   {
 
106
      GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
 
107
                                                       intelImage->face,
 
108
                                                       intelImage->level);
 
109
      const GLint orig_x = x;
 
110
      const GLint orig_y = y;
 
111
      const struct gl_framebuffer *fb = ctx->DrawBuffer;
 
112
 
 
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.
 
116
          */
 
117
         dstx += x - orig_x;
 
118
         dsty += y - orig_y;
 
119
 
 
120
         if (ctx->ReadBuffer->Name == 0) {
 
121
            /* reading from a window, adjust x, y */
 
122
            __DRIdrawablePrivate *dPriv = intel->driDrawable;
 
123
            GLuint window_y;
 
124
            /* window_y = position of window on screen if y=0=bottom */
 
125
            window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
 
126
            y = window_y + y;
 
127
            x += dPriv->x;
 
128
         }
 
129
         else {
 
130
            /* reading from a FBO */
 
131
            /* invert Y */
 
132
            y = ctx->ReadBuffer->Height - y - 1;
 
133
         }
 
134
 
 
135
 
 
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
 
138
          * worth it:
 
139
          */
 
140
         intelEmitCopyBlit(intel,
 
141
                           intelImage->mt->cpp,
 
142
                           -src->pitch,
 
143
                           src->buffer,
 
144
                           src->height * src->pitch * src->cpp,
 
145
                           intelImage->mt->pitch,
 
146
                           intelImage->mt->region->buffer,
 
147
                           image_offset,
 
148
                           x, y + height, dstx, dsty, width, height,
 
149
                           GL_COPY); /* ? */
 
150
 
 
151
         intel_batchbuffer_flush(intel->batch);
 
152
      }
 
153
   }
 
154
 
 
155
 
 
156
   UNLOCK_HARDWARE(intel);
 
157
 
 
158
#if 0
 
159
   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
 
160
    * XXX Add a ctx->Driver.GenerateMipmaps() function?
 
161
    */
 
162
   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
 
163
      intel_generate_mipmap(ctx, target,
 
164
                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
 
165
                            texObj);
 
166
   }
 
167
#endif
 
168
 
 
169
   return GL_TRUE;
 
170
}
 
171
 
 
172
 
 
173
 
 
174
 
 
175
 
 
176
void
 
177
intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
 
178
                    GLenum internalFormat,
 
179
                    GLint x, GLint y, GLsizei width, GLint border)
 
180
{
 
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);
 
187
 
 
188
   if (border)
 
189
      goto fail;
 
190
 
 
191
   /* Setup or redefine the texture object, mipmap tree and texture
 
192
    * image.  Don't populate yet.  
 
193
    */
 
194
   ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
 
195
                          width, border,
 
196
                          GL_RGBA, CHAN_TYPE, NULL,
 
197
                          &ctx->DefaultPacking, texObj, texImage);
 
198
 
 
199
   if (!do_copy_texsubimage(intel_context(ctx),
 
200
                            intel_texture_image(texImage),
 
201
                            internalFormat, 0, 0, x, y, width, 1))
 
202
      goto fail;
 
203
 
 
204
   return;
 
205
 
 
206
 fail:
 
207
   _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y,
 
208
                           width, border);
 
209
}
 
210
 
 
211
void
 
212
intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
 
213
                    GLenum internalFormat,
 
214
                    GLint x, GLint y, GLsizei width, GLsizei height,
 
215
                    GLint border)
 
216
{
 
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);
 
223
 
 
224
   if (border)
 
225
      goto fail;
 
226
 
 
227
   /* Setup or redefine the texture object, mipmap tree and texture
 
228
    * image.  Don't populate yet.  
 
229
    */
 
230
   ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
 
231
                          width, height, border,
 
232
                          GL_RGBA, CHAN_TYPE, NULL,
 
233
                          &ctx->DefaultPacking, texObj, texImage);
 
234
 
 
235
 
 
236
   if (!do_copy_texsubimage(intel_context(ctx),
 
237
                            intel_texture_image(texImage),
 
238
                            internalFormat, 0, 0, x, y, width, height))
 
239
      goto fail;
 
240
 
 
241
   return;
 
242
 
 
243
 fail:
 
244
   _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y,
 
245
                           width, height, border);
 
246
}
 
247
 
 
248
 
 
249
void
 
250
intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
 
251
                       GLint xoffset, GLint x, GLint y, GLsizei width)
 
252
{
 
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;
 
260
 
 
261
   /* XXX need to check <border> as in above function? */
 
262
 
 
263
   /* Need to check texture is compatible with source format. 
 
264
    */
 
265
 
 
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);
 
270
   }
 
271
}
 
272
 
 
273
 
 
274
 
 
275
void
 
276
intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
 
277
                       GLint xoffset, GLint yoffset,
 
278
                       GLint x, GLint y, GLsizei width, GLsizei height)
 
279
{
 
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;
 
287
 
 
288
 
 
289
   /* Need to check texture is compatible with source format. 
 
290
    */
 
291
 
 
292
   if (!do_copy_texsubimage(intel_context(ctx),
 
293
                            intel_texture_image(texImage),
 
294
                            internalFormat,
 
295
                            xoffset, yoffset, x, y, width, height)) {
 
296
 
 
297
      DBG("%s - fallback to swrast\n", __FUNCTION__);
 
298
 
 
299
      _swrast_copy_texsubimage2d(ctx, target, level,
 
300
                                 xoffset, yoffset, x, y, width, height);
 
301
   }
 
302
}