14ee0ebc600304f946f2d311e9f8ee375862d4b4
[mesa.git] / src / mesa / swrast / s_texture.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2011 VMware, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * Functions for mapping/unmapping texture images.
26 */
27
28
29 #include "main/context.h"
30 #include "main/fbobject.h"
31 #include "main/teximage.h"
32 #include "swrast/swrast.h"
33 #include "swrast/s_context.h"
34
35
36 /**
37 * Allocate a new swrast_texture_image (a subclass of gl_texture_image).
38 * Called via ctx->Driver.NewTextureImage().
39 */
40 struct gl_texture_image *
41 _swrast_new_texture_image( struct gl_context *ctx )
42 {
43 (void) ctx;
44 return (struct gl_texture_image *) CALLOC_STRUCT(swrast_texture_image);
45 }
46
47
48 /**
49 * Free a swrast_texture_image (a subclass of gl_texture_image).
50 * Called via ctx->Driver.DeleteTextureImage().
51 */
52 void
53 _swrast_delete_texture_image(struct gl_context *ctx,
54 struct gl_texture_image *texImage)
55 {
56 /* Nothing special for the subclass yet */
57 _mesa_delete_texture_image(ctx, texImage);
58 }
59
60
61 /**
62 * Called via ctx->Driver.AllocTextureImageBuffer()
63 */
64 GLboolean
65 _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
66 struct gl_texture_image *texImage,
67 gl_format format, GLsizei width,
68 GLsizei height, GLsizei depth)
69 {
70 struct swrast_texture_image *swImg = swrast_texture_image(texImage);
71 GLuint bytes = _mesa_format_image_size(format, width, height, depth);
72
73 /* This _should_ be true (revisit if these ever fail) */
74 assert(texImage->Width == width);
75 assert(texImage->Height == height);
76 assert(texImage->Depth == depth);
77
78 assert(!texImage->Data);
79 texImage->Data = _mesa_align_malloc(bytes, 512);
80
81 if ((width == 1 || _mesa_is_pow_two(texImage->Width2)) &&
82 (height == 1 || _mesa_is_pow_two(texImage->Height2)) &&
83 (depth == 1 || _mesa_is_pow_two(texImage->Depth2)))
84 swImg->_IsPowerOfTwo = GL_TRUE;
85 else
86 swImg->_IsPowerOfTwo = GL_FALSE;
87
88 return texImage->Data != NULL;
89 }
90
91
92 /**
93 * Called via ctx->Driver.FreeTextureImageBuffer()
94 */
95 void
96 _swrast_free_texture_image_buffer(struct gl_context *ctx,
97 struct gl_texture_image *texImage)
98 {
99 if (texImage->Data && !texImage->IsClientData) {
100 _mesa_align_free(texImage->Data);
101 }
102
103 texImage->Data = NULL;
104 }
105
106
107 /**
108 * Error checking for debugging only.
109 */
110 static void
111 _mesa_check_map_teximage(struct gl_texture_image *texImage,
112 GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h)
113 {
114
115 if (texImage->TexObject->Target == GL_TEXTURE_1D)
116 assert(y == 0 && h == 1);
117
118 assert(x < texImage->Width || texImage->Width == 0);
119 assert(y < texImage->Height || texImage->Height == 0);
120 assert(x + w <= texImage->Width);
121 assert(y + h <= texImage->Height);
122 }
123
124 /**
125 * Map a 2D slice of a texture image into user space.
126 * (x,y,w,h) defines a region of interest (ROI). Reading/writing texels
127 * outside of the ROI is undefined.
128 *
129 * \param texImage the texture image
130 * \param slice the 3D image slice or array texture slice
131 * \param x, y, w, h region of interest
132 * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
133 * \param mapOut returns start of mapping of region of interest
134 * \param rowStrideOut returns row stride (in bytes)
135 */
136 void
137 _swrast_map_teximage(struct gl_context *ctx,
138 struct gl_texture_image *texImage,
139 GLuint slice,
140 GLuint x, GLuint y, GLuint w, GLuint h,
141 GLbitfield mode,
142 GLubyte **mapOut,
143 GLint *rowStrideOut)
144 {
145 GLubyte *map;
146 GLint stride, texelSize;
147 GLuint bw, bh;
148
149 _mesa_check_map_teximage(texImage, slice, x, y, w, h);
150
151 texelSize = _mesa_get_format_bytes(texImage->TexFormat);
152 stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
153 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
154
155 assert(texImage->Data);
156
157 map = texImage->Data;
158
159 if (texImage->TexObject->Target == GL_TEXTURE_3D ||
160 texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
161 GLuint sliceSize = _mesa_format_image_size(texImage->TexFormat,
162 texImage->Width,
163 texImage->Height,
164 1);
165 assert(slice < texImage->Depth);
166 map += slice * sliceSize;
167 }
168
169 /* apply x/y offset to map address */
170 map += stride * (y / bh) + texelSize * (x / bw);
171
172 *mapOut = map;
173 *rowStrideOut = stride;
174 }
175
176 void
177 _swrast_unmap_teximage(struct gl_context *ctx,
178 struct gl_texture_image *texImage,
179 GLuint slice)
180 {
181 /* nop */
182 }