Merge remote branch 'origin/7.8'
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_subimage.c
1
2 /**************************************************************************
3 *
4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "main/mtypes.h"
30 #include "main/texobj.h"
31 #include "main/texstore.h"
32 #include "main/texcompress.h"
33 #include "main/enums.h"
34
35 #include "intel_context.h"
36 #include "intel_tex.h"
37 #include "intel_mipmap_tree.h"
38
39 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
40
41 static void
42 intelTexSubimage(GLcontext * ctx,
43 GLint dims,
44 GLenum target, GLint level,
45 GLint xoffset, GLint yoffset, GLint zoffset,
46 GLint width, GLint height, GLint depth,
47 GLsizei imageSize,
48 GLenum format, GLenum type, const void *pixels,
49 const struct gl_pixelstore_attrib *packing,
50 struct gl_texture_object *texObj,
51 struct gl_texture_image *texImage,
52 GLboolean compressed)
53 {
54 struct intel_context *intel = intel_context(ctx);
55 struct intel_texture_image *intelImage = intel_texture_image(texImage);
56 GLuint dstRowStride = 0;
57
58 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
59 _mesa_lookup_enum_by_nr(target),
60 level, xoffset, yoffset, width, height);
61
62 intelFlush(ctx);
63
64 if (compressed)
65 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize,
66 pixels, packing,
67 "glCompressedTexImage");
68 else
69 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
70 format, type, pixels, packing,
71 "glTexSubImage");
72 if (!pixels)
73 return;
74
75 intel_prepare_render(intel);
76
77 /* Map buffer if necessary. Need to lock to prevent other contexts
78 * from uploading the buffer under us.
79 */
80 if (intelImage->mt)
81 texImage->Data = intel_miptree_image_map(intel,
82 intelImage->mt,
83 intelImage->face,
84 intelImage->level,
85 &dstRowStride,
86 texImage->ImageOffsets);
87 else {
88 if (_mesa_is_format_compressed(texImage->TexFormat)) {
89 dstRowStride =
90 _mesa_format_row_stride(texImage->TexFormat, width);
91 assert(dims != 3);
92 }
93 else {
94 dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat);
95 }
96 }
97
98 assert(dstRowStride);
99
100 if (compressed) {
101 if (intelImage->mt) {
102 struct intel_region *dst = intelImage->mt->region;
103
104 _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
105 xoffset, yoffset / 4,
106 (width + 3) & ~3, (height + 3) / 4,
107 pixels, (width + 3) & ~3, 0, 0);
108 }
109 else {
110 memcpy(texImage->Data, pixels, imageSize);
111 }
112 }
113 else {
114 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
115 texImage->TexFormat,
116 texImage->Data,
117 xoffset, yoffset, zoffset,
118 dstRowStride,
119 texImage->ImageOffsets,
120 width, height, depth,
121 format, type, pixels, packing)) {
122 _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
123 }
124 }
125
126 _mesa_unmap_teximage_pbo(ctx, packing);
127
128 if (intelImage->mt) {
129 intel_miptree_image_unmap(intel, intelImage->mt);
130 texImage->Data = NULL;
131 }
132 }
133
134
135 static void
136 intelTexSubImage3D(GLcontext * ctx,
137 GLenum target,
138 GLint level,
139 GLint xoffset, GLint yoffset, GLint zoffset,
140 GLsizei width, GLsizei height, GLsizei depth,
141 GLenum format, GLenum type,
142 const GLvoid * pixels,
143 const struct gl_pixelstore_attrib *packing,
144 struct gl_texture_object *texObj,
145 struct gl_texture_image *texImage)
146 {
147 intelTexSubimage(ctx, 3,
148 target, level,
149 xoffset, yoffset, zoffset,
150 width, height, depth, 0,
151 format, type, pixels, packing, texObj, texImage, GL_FALSE);
152 }
153
154
155 static void
156 intelTexSubImage2D(GLcontext * ctx,
157 GLenum target,
158 GLint level,
159 GLint xoffset, GLint yoffset,
160 GLsizei width, GLsizei height,
161 GLenum format, GLenum type,
162 const GLvoid * pixels,
163 const struct gl_pixelstore_attrib *packing,
164 struct gl_texture_object *texObj,
165 struct gl_texture_image *texImage)
166 {
167 intelTexSubimage(ctx, 2,
168 target, level,
169 xoffset, yoffset, 0,
170 width, height, 1, 0,
171 format, type, pixels, packing, texObj, texImage, GL_FALSE);
172 }
173
174
175 static void
176 intelTexSubImage1D(GLcontext * ctx,
177 GLenum target,
178 GLint level,
179 GLint xoffset,
180 GLsizei width,
181 GLenum format, GLenum type,
182 const GLvoid * pixels,
183 const struct gl_pixelstore_attrib *packing,
184 struct gl_texture_object *texObj,
185 struct gl_texture_image *texImage)
186 {
187 intelTexSubimage(ctx, 1,
188 target, level,
189 xoffset, 0, 0,
190 width, 1, 1, 0,
191 format, type, pixels, packing, texObj, texImage, GL_FALSE);
192 }
193
194 static void
195 intelCompressedTexSubImage2D(GLcontext * ctx,
196 GLenum target,
197 GLint level,
198 GLint xoffset, GLint yoffset,
199 GLsizei width, GLsizei height,
200 GLenum format, GLsizei imageSize,
201 const GLvoid * pixels,
202 struct gl_texture_object *texObj,
203 struct gl_texture_image *texImage)
204 {
205 intelTexSubimage(ctx, 2,
206 target, level,
207 xoffset, yoffset, 0,
208 width, height, 1, imageSize,
209 format, 0, pixels, &ctx->Unpack, texObj, texImage, GL_TRUE);
210 }
211
212
213
214 void
215 intelInitTextureSubImageFuncs(struct dd_function_table *functions)
216 {
217 functions->TexSubImage1D = intelTexSubImage1D;
218 functions->TexSubImage2D = intelTexSubImage2D;
219 functions->TexSubImage3D = intelTexSubImage3D;
220 functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
221 }