f75d2ae004b6d474df5dc4a6feb00bc587ca948b
[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->MesaFormat, width);
91 assert(dims != 3);
92 }
93 else {
94 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
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 } else
109 memcpy(texImage->Data, pixels, imageSize);
110 }
111 else {
112 StoreTexImageFunc storeImage =
113 _mesa_get_texstore_func(texImage->TexFormat->MesaFormat);
114
115 if (!storeImage(ctx, dims, texImage->_BaseFormat,
116 texImage->TexFormat,
117 texImage->Data,
118 xoffset, yoffset, zoffset,
119 dstRowStride,
120 texImage->ImageOffsets,
121 width, height, depth,
122 format, type, pixels, packing)) {
123 _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
124 }
125 }
126
127 _mesa_unmap_teximage_pbo(ctx, packing);
128
129 if (intelImage->mt) {
130 intel_miptree_image_unmap(intel, intelImage->mt);
131 texImage->Data = NULL;
132 }
133
134 UNLOCK_HARDWARE(intel);
135 }
136
137
138 static void
139 intelTexSubImage3D(GLcontext * ctx,
140 GLenum target,
141 GLint level,
142 GLint xoffset, GLint yoffset, GLint zoffset,
143 GLsizei width, GLsizei height, GLsizei depth,
144 GLenum format, GLenum type,
145 const GLvoid * pixels,
146 const struct gl_pixelstore_attrib *packing,
147 struct gl_texture_object *texObj,
148 struct gl_texture_image *texImage)
149 {
150 intelTexSubimage(ctx, 3,
151 target, level,
152 xoffset, yoffset, zoffset,
153 width, height, depth, 0,
154 format, type, pixels, packing, texObj, texImage, GL_FALSE);
155 }
156
157
158 static void
159 intelTexSubImage2D(GLcontext * ctx,
160 GLenum target,
161 GLint level,
162 GLint xoffset, GLint yoffset,
163 GLsizei width, GLsizei height,
164 GLenum format, GLenum type,
165 const GLvoid * pixels,
166 const struct gl_pixelstore_attrib *packing,
167 struct gl_texture_object *texObj,
168 struct gl_texture_image *texImage)
169 {
170 intelTexSubimage(ctx, 2,
171 target, level,
172 xoffset, yoffset, 0,
173 width, height, 1, 0,
174 format, type, pixels, packing, texObj, texImage, GL_FALSE);
175 }
176
177
178 static void
179 intelTexSubImage1D(GLcontext * ctx,
180 GLenum target,
181 GLint level,
182 GLint xoffset,
183 GLsizei width,
184 GLenum format, GLenum type,
185 const GLvoid * pixels,
186 const struct gl_pixelstore_attrib *packing,
187 struct gl_texture_object *texObj,
188 struct gl_texture_image *texImage)
189 {
190 intelTexSubimage(ctx, 1,
191 target, level,
192 xoffset, 0, 0,
193 width, 1, 1, 0,
194 format, type, pixels, packing, texObj, texImage, GL_FALSE);
195 }
196
197 static void
198 intelCompressedTexSubImage2D(GLcontext * ctx,
199 GLenum target,
200 GLint level,
201 GLint xoffset, GLint yoffset,
202 GLsizei width, GLsizei height,
203 GLenum format, GLsizei imageSize,
204 const GLvoid * pixels,
205 struct gl_texture_object *texObj,
206 struct gl_texture_image *texImage)
207 {
208 intelTexSubimage(ctx, 2,
209 target, level,
210 xoffset, yoffset, 0,
211 width, height, 1, imageSize,
212 format, 0, pixels, &ctx->Unpack, texObj, texImage, GL_TRUE);
213 }
214
215
216
217 void
218 intelInitTextureSubImageFuncs(struct dd_function_table *functions)
219 {
220 functions->TexSubImage1D = intelTexSubImage1D;
221 functions->TexSubImage2D = intelTexSubImage2D;
222 functions->TexSubImage3D = intelTexSubImage3D;
223 functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
224 }