bba1b53009dcc3954deb537c20288a526a8b3a61
[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 LOCK_HARDWARE(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 (texImage->IsCompressed) {
89 dstRowStride =
90 _mesa_compressed_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 UNLOCK_HARDWARE(intel);
134 }
135
136
137 static void
138 intelTexSubImage3D(GLcontext * ctx,
139 GLenum target,
140 GLint level,
141 GLint xoffset, GLint yoffset, GLint zoffset,
142 GLsizei width, GLsizei height, GLsizei depth,
143 GLenum format, GLenum type,
144 const GLvoid * pixels,
145 const struct gl_pixelstore_attrib *packing,
146 struct gl_texture_object *texObj,
147 struct gl_texture_image *texImage)
148 {
149 intelTexSubimage(ctx, 3,
150 target, level,
151 xoffset, yoffset, zoffset,
152 width, height, depth, 0,
153 format, type, pixels, packing, texObj, texImage, GL_FALSE);
154 }
155
156
157 static void
158 intelTexSubImage2D(GLcontext * ctx,
159 GLenum target,
160 GLint level,
161 GLint xoffset, GLint yoffset,
162 GLsizei width, GLsizei height,
163 GLenum format, GLenum type,
164 const GLvoid * pixels,
165 const struct gl_pixelstore_attrib *packing,
166 struct gl_texture_object *texObj,
167 struct gl_texture_image *texImage)
168 {
169 intelTexSubimage(ctx, 2,
170 target, level,
171 xoffset, yoffset, 0,
172 width, height, 1, 0,
173 format, type, pixels, packing, texObj, texImage, GL_FALSE);
174 }
175
176
177 static void
178 intelTexSubImage1D(GLcontext * ctx,
179 GLenum target,
180 GLint level,
181 GLint xoffset,
182 GLsizei width,
183 GLenum format, GLenum type,
184 const GLvoid * pixels,
185 const struct gl_pixelstore_attrib *packing,
186 struct gl_texture_object *texObj,
187 struct gl_texture_image *texImage)
188 {
189 intelTexSubimage(ctx, 1,
190 target, level,
191 xoffset, 0, 0,
192 width, 1, 1, 0,
193 format, type, pixels, packing, texObj, texImage, GL_FALSE);
194 }
195
196 static void
197 intelCompressedTexSubImage2D(GLcontext * ctx,
198 GLenum target,
199 GLint level,
200 GLint xoffset, GLint yoffset,
201 GLsizei width, GLsizei height,
202 GLenum format, GLsizei imageSize,
203 const GLvoid * pixels,
204 struct gl_texture_object *texObj,
205 struct gl_texture_image *texImage)
206 {
207 intelTexSubimage(ctx, 2,
208 target, level,
209 xoffset, yoffset, 0,
210 width, height, 1, imageSize,
211 format, 0, pixels, &ctx->Unpack, texObj, texImage, GL_TRUE);
212 }
213
214
215
216 void
217 intelInitTextureSubImageFuncs(struct dd_function_table *functions)
218 {
219 functions->TexSubImage1D = intelTexSubImage1D;
220 functions->TexSubImage2D = intelTexSubImage2D;
221 functions->TexSubImage3D = intelTexSubImage3D;
222 functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
223 }