i965: Enable extension GL_ARB_shader_texture_lod.
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_copy.c
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 "main/mtypes.h"
29 #include "main/enums.h"
30 #include "main/image.h"
31 #include "main/teximage.h"
32 #include "main/texstate.h"
33
34 #include "drivers/common/meta.h"
35
36 #include "intel_screen.h"
37 #include "intel_context.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
44 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
45
46 /**
47 * Get the intel_region which is the source for any glCopyTex[Sub]Image call.
48 *
49 * Do the best we can using the blitter. A future project is to use
50 * the texture engine and fragment programs for these copies.
51 */
52 static struct intel_renderbuffer *
53 get_teximage_readbuffer(struct intel_context *intel, GLenum internalFormat)
54 {
55 DBG("%s %s\n", __FUNCTION__,
56 _mesa_lookup_enum_by_nr(internalFormat));
57
58 switch (internalFormat) {
59 case GL_DEPTH_COMPONENT:
60 case GL_DEPTH_COMPONENT16:
61 case GL_DEPTH24_STENCIL8_EXT:
62 case GL_DEPTH_STENCIL_EXT:
63 return intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH);
64 default:
65 return intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
66 }
67 }
68
69
70 GLboolean
71 intel_copy_texsubimage(struct intel_context *intel,
72 GLenum target,
73 struct intel_texture_image *intelImage,
74 GLenum internalFormat,
75 GLint dstx, GLint dsty,
76 GLint x, GLint y, GLsizei width, GLsizei height)
77 {
78 struct gl_context *ctx = &intel->ctx;
79 struct intel_renderbuffer *irb;
80 bool copy_supported = false;
81 bool copy_supported_with_alpha_override = false;
82
83 intel_prepare_render(intel);
84
85 irb = get_teximage_readbuffer(intel, internalFormat);
86 if (!intelImage->mt || !irb || !irb->region) {
87 if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
88 fprintf(stderr, "%s fail %p %p (0x%08x)\n",
89 __FUNCTION__, intelImage->mt, irb, internalFormat);
90 return GL_FALSE;
91 }
92
93 copy_supported = intelImage->base.TexFormat == irb->Base.Format;
94
95 /* Converting ARGB8888 to XRGB8888 is trivial: ignore the alpha bits */
96 if (irb->Base.Format == MESA_FORMAT_ARGB8888 &&
97 intelImage->base.TexFormat == MESA_FORMAT_XRGB8888) {
98 copy_supported = true;
99 }
100
101 /* Converting XRGB8888 to ARGB8888 requires setting the alpha bits to 1.0 */
102 if (irb->Base.Format == MESA_FORMAT_XRGB8888 &&
103 intelImage->base.TexFormat == MESA_FORMAT_ARGB8888) {
104 copy_supported_with_alpha_override = true;
105 }
106
107 if (!copy_supported && !copy_supported_with_alpha_override) {
108 if (unlikely(INTEL_DEBUG & DEBUG_FALLBACKS))
109 fprintf(stderr, "%s mismatched formats %s, %s\n",
110 __FUNCTION__,
111 _mesa_get_format_name(intelImage->base.TexFormat),
112 _mesa_get_format_name(irb->Base.Format));
113 return GL_FALSE;
114 }
115
116 {
117 drm_intel_bo *dst_bo = intel_region_buffer(intel,
118 intelImage->mt->region,
119 INTEL_WRITE_PART);
120 GLuint image_x, image_y;
121 GLshort src_pitch;
122
123 /* get dest x/y in destination texture */
124 intel_miptree_get_image_offset(intelImage->mt,
125 intelImage->level,
126 intelImage->face,
127 0,
128 &image_x, &image_y);
129
130 /* The blitter can't handle Y-tiled buffers. */
131 if (intelImage->mt->region->tiling == I915_TILING_Y) {
132 return GL_FALSE;
133 }
134
135 if (ctx->ReadBuffer->Name == 0) {
136 /* Flip vertical orientation for system framebuffers */
137 y = ctx->ReadBuffer->Height - (y + height);
138 src_pitch = -irb->region->pitch;
139 } else {
140 /* reading from a FBO, y is already oriented the way we like */
141 src_pitch = irb->region->pitch;
142 }
143
144 /* blit from src buffer to texture */
145 if (!intelEmitCopyBlit(intel,
146 intelImage->mt->cpp,
147 src_pitch,
148 irb->region->buffer,
149 0,
150 irb->region->tiling,
151 intelImage->mt->region->pitch,
152 dst_bo,
153 0,
154 intelImage->mt->region->tiling,
155 irb->draw_x + x, irb->draw_y + y,
156 image_x + dstx, image_y + dsty,
157 width, height,
158 GL_COPY)) {
159 return GL_FALSE;
160 }
161 }
162
163 if (copy_supported_with_alpha_override)
164 intel_set_teximage_alpha_to_one(ctx, intelImage);
165
166 return GL_TRUE;
167 }
168
169
170 static void
171 intelCopyTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
172 GLenum internalFormat,
173 GLint x, GLint y, GLsizei width, GLint border)
174 {
175 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
176 struct gl_texture_object *texObj =
177 _mesa_select_tex_object(ctx, texUnit, target);
178 struct gl_texture_image *texImage =
179 _mesa_select_tex_image(ctx, texObj, target, level);
180 int srcx, srcy, dstx, dsty, height;
181
182 if (border)
183 goto fail;
184
185 /* Setup or redefine the texture object, mipmap tree and texture
186 * image. Don't populate yet.
187 */
188 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
189 width, border,
190 GL_RGBA, CHAN_TYPE, NULL,
191 &ctx->DefaultPacking, texObj, texImage);
192 srcx = x;
193 srcy = y;
194 dstx = 0;
195 dsty = 0;
196 height = 1;
197 if (!_mesa_clip_copytexsubimage(ctx,
198 &dstx, &dsty,
199 &srcx, &srcy,
200 &width, &height))
201 return;
202
203 if (!intel_copy_texsubimage(intel_context(ctx), target,
204 intel_texture_image(texImage),
205 internalFormat, 0, 0, x, y, width, height))
206 goto fail;
207
208 return;
209
210 fail:
211 fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
212 _mesa_meta_CopyTexImage1D(ctx, target, level, internalFormat, x, y,
213 width, border);
214 }
215
216
217 static void
218 intelCopyTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
219 GLenum internalFormat,
220 GLint x, GLint y, GLsizei width, GLsizei height,
221 GLint border)
222 {
223 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
224 struct gl_texture_object *texObj =
225 _mesa_select_tex_object(ctx, texUnit, target);
226 struct gl_texture_image *texImage =
227 _mesa_select_tex_image(ctx, texObj, target, level);
228 int srcx, srcy, dstx, dsty;
229
230 if (border)
231 goto fail;
232
233 /* Setup or redefine the texture object, mipmap tree and texture
234 * image. Don't populate yet.
235 */
236 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
237 width, height, border,
238 GL_RGBA, GL_UNSIGNED_BYTE, NULL,
239 &ctx->DefaultPacking, texObj, texImage);
240
241 srcx = x;
242 srcy = y;
243 dstx = 0;
244 dsty = 0;
245 if (!_mesa_clip_copytexsubimage(ctx,
246 &dstx, &dsty,
247 &srcx, &srcy,
248 &width, &height))
249 return;
250
251 if (!intel_copy_texsubimage(intel_context(ctx), target,
252 intel_texture_image(texImage),
253 internalFormat, 0, 0, x, y, width, height))
254 goto fail;
255
256 return;
257
258 fail:
259 fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
260 _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y,
261 width, height, border);
262 }
263
264
265 static void
266 intelCopyTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
267 GLint xoffset, GLint x, GLint y, GLsizei width)
268 {
269 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
270 struct gl_texture_object *texObj =
271 _mesa_select_tex_object(ctx, texUnit, target);
272 struct gl_texture_image *texImage =
273 _mesa_select_tex_image(ctx, texObj, target, level);
274 GLenum internalFormat = texImage->InternalFormat;
275
276 /* XXX need to check <border> as in above function? */
277
278 /* Need to check texture is compatible with source format.
279 */
280
281 if (!intel_copy_texsubimage(intel_context(ctx), target,
282 intel_texture_image(texImage),
283 internalFormat, xoffset, 0, x, y, width, 1)) {
284 fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
285 _mesa_meta_CopyTexSubImage1D(ctx, target, level, xoffset, x, y, width);
286 }
287 }
288
289
290 static void
291 intelCopyTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
292 GLint xoffset, GLint yoffset,
293 GLint x, GLint y, GLsizei width, GLsizei height)
294 {
295 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
296 struct gl_texture_object *texObj =
297 _mesa_select_tex_object(ctx, texUnit, target);
298 struct gl_texture_image *texImage =
299 _mesa_select_tex_image(ctx, texObj, target, level);
300 GLenum internalFormat = texImage->InternalFormat;
301
302 /* Need to check texture is compatible with source format.
303 */
304
305 if (!intel_copy_texsubimage(intel_context(ctx), target,
306 intel_texture_image(texImage),
307 internalFormat,
308 xoffset, yoffset, x, y, width, height)) {
309 fallback_debug("%s - fallback to swrast\n", __FUNCTION__);
310 _mesa_meta_CopyTexSubImage2D(ctx, target, level,
311 xoffset, yoffset, x, y, width, height);
312 }
313 }
314
315
316 void
317 intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
318 {
319 functions->CopyTexImage1D = intelCopyTexImage1D;
320 functions->CopyTexImage2D = intelCopyTexImage2D;
321 functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
322 functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
323 }