st_texture.c revision b859cdf6f191b4d8b56537c8dc30082a7e2d94b3
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "st_context.h" 29#include "st_format.h" 30#include "st_texture.h" 31#include "enums.h" 32 33#include "pipe/p_state.h" 34#include "pipe/p_context.h" 35#include "pipe/p_defines.h" 36#include "pipe/p_inlines.h" 37#include "pipe/p_util.h" 38#include "pipe/p_inlines.h" 39#include "pipe/p_winsys.h" 40 41 42#define DBG if(0) printf 43 44#if 0 45static GLenum 46target_to_target(GLenum target) 47{ 48 switch (target) { 49 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 50 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 51 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 52 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 53 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 54 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 55 return GL_TEXTURE_CUBE_MAP_ARB; 56 default: 57 return target; 58 } 59} 60#endif 61 62struct pipe_texture * 63st_texture_create(struct st_context *st, 64 unsigned target, 65 unsigned format, 66 GLenum internal_format, 67 GLuint first_level, 68 GLuint last_level, 69 GLuint width0, 70 GLuint height0, 71 GLuint depth0, 72 GLuint compress_byte) 73{ 74 struct pipe_texture *pt = CALLOC_STRUCT(pipe_texture); 75 76 assert(target <= PIPE_TEXTURE_CUBE); 77 78 DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, 79 _mesa_lookup_enum_by_nr(target), 80 _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); 81 82 if (!pt) 83 return NULL; 84 85 assert(format); 86 87 pt->target = target; 88 pt->format = format; 89 pt->internal_format = internal_format; 90 pt->first_level = first_level; 91 pt->last_level = last_level; 92 pt->width[0] = width0; 93 pt->height[0] = height0; 94 pt->depth[0] = depth0; 95 pt->compressed = compress_byte ? 1 : 0; 96 pt->cpp = pt->compressed ? compress_byte : st_sizeof_format(format); 97 pt->refcount = 1; 98 99 st->pipe->texture_create(st->pipe, &pt); 100 101 return pt; 102} 103 104 105 106 107/* Can the image be pulled into a unified mipmap texture. This mirrors 108 * the completeness test in a lot of ways. 109 * 110 * Not sure whether I want to pass gl_texture_image here. 111 */ 112GLboolean 113st_texture_match_image(struct pipe_texture *pt, 114 struct gl_texture_image *image, 115 GLuint face, GLuint level) 116{ 117 /* Images with borders are never pulled into mipmap textures. 118 */ 119 if (image->Border) 120 return GL_FALSE; 121 122 if (image->InternalFormat != pt->internal_format || 123 image->IsCompressed != pt->compressed) 124 return GL_FALSE; 125 126 /* Test image dimensions against the base level image adjusted for 127 * minification. This will also catch images not present in the 128 * texture, changed targets, etc. 129 */ 130 if (image->Width != pt->width[level] || 131 image->Height != pt->height[level] || 132 image->Depth != pt->depth[level]) 133 return GL_FALSE; 134 135 return GL_TRUE; 136} 137 138 139#if 000 140/* Although we use the image_offset[] array to store relative offsets 141 * to cube faces, Mesa doesn't know anything about this and expects 142 * each cube face to be treated as a separate image. 143 * 144 * These functions present that view to mesa: 145 */ 146const GLuint * 147st_texture_depth_offsets(struct pipe_texture *pt, GLuint level) 148{ 149 static const GLuint zero = 0; 150 151 if (pt->target != PIPE_TEXTURE_3D || pt->level[level].nr_images == 1) 152 return &zero; 153 else 154 return pt->level[level].image_offset; 155} 156 157 158/** 159 * Return the offset to the given mipmap texture image within the 160 * texture memory buffer, in bytes. 161 */ 162GLuint 163st_texture_image_offset(const struct pipe_texture * pt, 164 GLuint face, GLuint level) 165{ 166 if (pt->target == PIPE_TEXTURE_CUBE) 167 return (pt->level[level].level_offset + 168 pt->level[level].image_offset[face] * pt->cpp); 169 else 170 return pt->level[level].level_offset; 171} 172#endif 173 174 175/** 176 * Map a teximage in a mipmap texture. 177 * \param row_stride returns row stride in bytes 178 * \param image_stride returns image stride in bytes (for 3D textures). 179 * \return address of mapping 180 */ 181GLubyte * 182st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, 183 GLuint zoffset) 184{ 185 struct pipe_texture *pt = stImage->pt; 186 DBG("%s \n", __FUNCTION__); 187 188 stImage->surface = st->pipe->get_tex_surface(st->pipe, pt, stImage->face, 189 stImage->level, zoffset); 190 191 return pipe_surface_map(stImage->surface); 192} 193 194void 195st_texture_image_unmap(struct st_texture_image *stImage) 196{ 197 DBG("%s\n", __FUNCTION__); 198 199 pipe_surface_unmap(stImage->surface); 200 201 pipe_surface_reference(&stImage->surface, NULL); 202} 203 204 205 206/* Upload data for a particular image. 207 */ 208void 209st_texture_image_data(struct pipe_context *pipe, 210 struct pipe_texture *dst, 211 GLuint face, 212 GLuint level, 213 void *src, 214 GLuint src_row_pitch, GLuint src_image_pitch) 215{ 216 GLuint depth = dst->depth[level]; 217 GLuint i; 218 GLuint height = 0; 219 const GLubyte *srcUB = src; 220 struct pipe_surface *dst_surface; 221 222 DBG("%s\n", __FUNCTION__); 223 for (i = 0; i < depth; i++) { 224 height = dst->height[level]; 225 if(dst->compressed) 226 height /= 4; 227 228 dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i); 229 230 pipe->surface_data(pipe, dst_surface, 231 0, 0, /* dstx, dsty */ 232 srcUB, 233 src_row_pitch, 234 0, 0, /* source x, y */ 235 dst->width[level], height); /* width, height */ 236 237 pipe_surface_reference(&dst_surface, NULL); 238 239 srcUB += src_image_pitch * dst->cpp; 240 } 241} 242 243/* Copy mipmap image between textures 244 */ 245void 246st_texture_image_copy(struct pipe_context *pipe, 247 struct pipe_texture *dst, 248 GLuint face, GLuint level, 249 struct pipe_texture *src) 250{ 251 GLuint width = src->width[level]; 252 GLuint height = src->height[level]; 253 GLuint depth = src->depth[level]; 254 struct pipe_surface *src_surface; 255 struct pipe_surface *dst_surface; 256 GLuint i; 257 258 if (dst->compressed) 259 height /= 4; 260 for (i = 0; i < depth; i++) { 261 dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i); 262 src_surface = pipe->get_tex_surface(pipe, src, face, level, i); 263 264 pipe->surface_copy(pipe, 265 dst_surface, 266 0, 0, /* destX, Y */ 267 src_surface, 268 0, 0, /* srcX, Y */ 269 width, height); 270 271 pipe_surface_reference(&dst_surface, NULL); 272 pipe_surface_reference(&src_surface, NULL); 273 } 274 275} 276