OSDN Git Service

1dcb08c0a1b4a28ddb6fc622484d812756e8c684
[android-x86/external-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    /* Compute Width/Height/DepthScale for mipmap lod computation */
89    if (texImage->TexObject->Target == GL_TEXTURE_RECTANGLE_NV) {
90       /* scale = 1.0 since texture coords directly map to texels */
91       swImg->WidthScale = 1.0;
92       swImg->HeightScale = 1.0;
93       swImg->DepthScale = 1.0;
94    }
95    else {
96       swImg->WidthScale = (GLfloat) texImage->Width;
97       swImg->HeightScale = (GLfloat) texImage->Height;
98       swImg->DepthScale = (GLfloat) texImage->Depth;
99    }
100
101    return texImage->Data != NULL;
102 }
103
104
105 /**
106  * Called via ctx->Driver.FreeTextureImageBuffer()
107  */
108 void
109 _swrast_free_texture_image_buffer(struct gl_context *ctx,
110                                   struct gl_texture_image *texImage)
111 {
112    if (texImage->Data && !texImage->IsClientData) {
113       _mesa_align_free(texImage->Data);
114    }
115
116    texImage->Data = NULL;
117 }
118
119
120 /**
121  * Error checking for debugging only.
122  */
123 static void
124 _mesa_check_map_teximage(struct gl_texture_image *texImage,
125                          GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h)
126 {
127
128    if (texImage->TexObject->Target == GL_TEXTURE_1D)
129       assert(y == 0 && h == 1);
130
131    assert(x < texImage->Width || texImage->Width == 0);
132    assert(y < texImage->Height || texImage->Height == 0);
133    assert(x + w <= texImage->Width);
134    assert(y + h <= texImage->Height);
135 }
136
137 /**
138  * Map a 2D slice of a texture image into user space.
139  * (x,y,w,h) defines a region of interest (ROI).  Reading/writing texels
140  * outside of the ROI is undefined.
141  *
142  * \param texImage  the texture image
143  * \param slice  the 3D image slice or array texture slice
144  * \param x, y, w, h  region of interest
145  * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
146  * \param mapOut  returns start of mapping of region of interest
147  * \param rowStrideOut  returns row stride (in bytes)
148  */
149 void
150 _swrast_map_teximage(struct gl_context *ctx,
151                      struct gl_texture_image *texImage,
152                      GLuint slice,
153                      GLuint x, GLuint y, GLuint w, GLuint h,
154                      GLbitfield mode,
155                      GLubyte **mapOut,
156                      GLint *rowStrideOut)
157 {
158    GLubyte *map;
159    GLint stride, texelSize;
160    GLuint bw, bh;
161
162    _mesa_check_map_teximage(texImage, slice, x, y, w, h);
163
164    texelSize = _mesa_get_format_bytes(texImage->TexFormat);
165    stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
166    _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
167
168    assert(texImage->Data);
169
170    map = texImage->Data;
171
172    if (texImage->TexObject->Target == GL_TEXTURE_3D ||
173        texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
174       GLuint sliceSize = _mesa_format_image_size(texImage->TexFormat,
175                                                  texImage->Width,
176                                                  texImage->Height,
177                                                  1);
178       assert(slice < texImage->Depth);
179       map += slice * sliceSize;
180    }
181
182    /* apply x/y offset to map address */
183    map += stride * (y / bh) + texelSize * (x / bw);
184
185    *mapOut = map;
186    *rowStrideOut = stride;
187 }
188
189 void
190 _swrast_unmap_teximage(struct gl_context *ctx,
191                        struct gl_texture_image *texImage,
192                        GLuint slice)
193 {
194    /* nop */
195 }