1 /********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * 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 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26 #ifndef SVGA_TEXTURE_H 27 #define SVGA_TEXTURE_H 28 29 30 #include "pipe/p_compiler.h" 31 #include "pipe/p_state.h" 32 #include "util/u_inlines.h" 33 #include "util/u_memory.h" 34 #include "util/u_transfer.h" 35 #include "svga_screen_cache.h" 36 37 struct pipe_context; 38 struct pipe_screen; 39 struct svga_context; 40 struct svga_winsys_surface; 41 enum SVGA3dSurfaceFormat; 42 43 44 #define SVGA_MAX_TEXTURE_LEVELS 16 45 46 47 extern struct u_resource_vtbl svga_texture_vtbl; 48 49 50 struct svga_texture 51 { 52 struct u_resource b; 53 54 ushort *defined; 55 56 struct svga_sampler_view *cached_view; 57 58 unsigned view_age[SVGA_MAX_TEXTURE_LEVELS]; 59 unsigned age; 60 61 boolean views_modified; 62 63 /** 64 * Creation key for the host surface handle. 65 * 66 * This structure describes all the host surface characteristics so that it 67 * can be looked up in cache, since creating a host surface is often a slow 68 * operation. 69 */ 70 struct svga_host_surface_cache_key key; 71 72 /** 73 * Handle for the host side surface. 74 * 75 * This handle is owned by this texture. Views should hold on to a reference 76 * to this texture and never destroy this handle directly. 77 */ 78 struct svga_winsys_surface *handle; 79 80 /** 81 * Whether the host side surface is validated, either through the 82 * InvalidateGBSurface command or after the surface is updated 83 * or rendered to. 84 */ 85 boolean validated; 86 87 /** 88 * Whether the host side surface is imported and not created by this 89 * driver. 90 */ 91 boolean imported; 92 93 /** 94 * Whether texture upload buffer can be used on this texture 95 */ 96 boolean can_use_upload; 97 98 unsigned size; /**< Approximate size in bytes */ 99 100 /** array indexed by cube face or 3D/array slice, one bit per mipmap level */ 101 ushort *rendered_to; 102 103 /** array indexed by cube face or 3D/array slice, one bit per mipmap level. 104 * Set if the level is marked as dirty. 105 */ 106 ushort *dirty; 107 }; 108 109 110 111 /* Note this is only used for texture (not buffer) transfers: 112 */ 113 struct svga_transfer 114 { 115 struct pipe_transfer base; 116 117 unsigned slice; /**< array slice or cube face */ 118 119 struct svga_winsys_buffer *hwbuf; 120 121 /* Height of the hardware buffer in pixel blocks */ 122 unsigned hw_nblocksy; 123 124 /* Temporary malloc buffer when we can't allocate a hardware buffer 125 * big enough */ 126 void *swbuf; 127 128 /* True if guest backed surface is supported and we can directly map 129 * to the surface for this transfer. 130 */ 131 boolean use_direct_map; 132 133 struct { 134 struct pipe_resource *buf; /* points to the upload buffer if this 135 * transfer is done via the upload buffer 136 * instead of directly mapping to the 137 * resource's surface. 138 */ 139 void *map; 140 unsigned offset; 141 SVGA3dBox box; 142 unsigned nlayers; 143 } upload; 144 }; 145 146 147 static inline struct svga_texture * 148 svga_texture(struct pipe_resource *resource) 149 { 150 struct svga_texture *tex = (struct svga_texture *)resource; 151 assert(tex == NULL || tex->b.vtbl == &svga_texture_vtbl); 152 return tex; 153 } 154 155 156 static inline struct svga_transfer * 157 svga_transfer(struct pipe_transfer *transfer) 158 { 159 assert(transfer); 160 return (struct svga_transfer *)transfer; 161 } 162 163 164 /** 165 * Increment the age of a view into a texture 166 * This is used to track updates to textures when we draw into 167 * them via a surface. 168 */ 169 static inline void 170 svga_age_texture_view(struct svga_texture *tex, unsigned level) 171 { 172 assert(level < ARRAY_SIZE(tex->view_age)); 173 tex->view_age[level] = ++(tex->age); 174 } 175 176 177 /** For debugging, check that face and level are legal */ 178 static inline void 179 check_face_level(const struct svga_texture *tex, 180 unsigned face, unsigned level) 181 { 182 if (tex->b.b.target == PIPE_TEXTURE_CUBE) { 183 assert(face < 6); 184 } 185 else if (tex->b.b.target == PIPE_TEXTURE_3D) { 186 assert(face < tex->b.b.depth0); 187 } 188 else { 189 assert(face < tex->b.b.array_size); 190 } 191 192 assert(level < 8 * sizeof(tex->rendered_to[0])); 193 } 194 195 196 /** 197 * Mark the given texture face/level as being defined. 198 */ 199 static inline void 200 svga_define_texture_level(struct svga_texture *tex, 201 unsigned face,unsigned level) 202 { 203 check_face_level(tex, face, level); 204 tex->defined[face] |= 1 << level; 205 tex->validated = TRUE; 206 } 207 208 209 static inline bool 210 svga_is_texture_level_defined(const struct svga_texture *tex, 211 unsigned face, unsigned level) 212 { 213 check_face_level(tex, face, level); 214 return (tex->defined[face] & (1 << level)) != 0; 215 } 216 217 218 static inline void 219 svga_set_texture_rendered_to(struct svga_texture *tex, 220 unsigned face, unsigned level) 221 { 222 check_face_level(tex, face, level); 223 tex->rendered_to[face] |= 1 << level; 224 tex->validated = TRUE; 225 } 226 227 228 static inline void 229 svga_clear_texture_rendered_to(struct svga_texture *tex, 230 unsigned face, unsigned level) 231 { 232 check_face_level(tex, face, level); 233 tex->rendered_to[face] &= ~(1 << level); 234 } 235 236 237 static inline boolean 238 svga_was_texture_rendered_to(const struct svga_texture *tex, 239 unsigned face, unsigned level) 240 { 241 check_face_level(tex, face, level); 242 return !!(tex->rendered_to[face] & (1 << level)); 243 } 244 245 static inline void 246 svga_set_texture_dirty(struct svga_texture *tex, 247 unsigned face, unsigned level) 248 { 249 check_face_level(tex, face, level); 250 tex->dirty[face] |= 1 << level; 251 } 252 253 static inline void 254 svga_clear_texture_dirty(struct svga_texture *tex) 255 { 256 unsigned i; 257 for (i = 0; i < tex->b.b.depth0 * tex->b.b.array_size; i++) { 258 tex->dirty[i] = 0; 259 } 260 } 261 262 static inline boolean 263 svga_is_texture_dirty(const struct svga_texture *tex, 264 unsigned face, unsigned level) 265 { 266 check_face_level(tex, face, level); 267 return !!(tex->dirty[face] & (1 << level)); 268 } 269 270 struct pipe_resource * 271 svga_texture_create(struct pipe_screen *screen, 272 const struct pipe_resource *template); 273 274 struct pipe_resource * 275 svga_texture_from_handle(struct pipe_screen * screen, 276 const struct pipe_resource *template, 277 struct winsys_handle *whandle); 278 279 boolean 280 svga_texture_generate_mipmap(struct pipe_context *pipe, 281 struct pipe_resource *pt, 282 enum pipe_format format, 283 unsigned base_level, 284 unsigned last_level, 285 unsigned first_layer, 286 unsigned last_layer); 287 288 boolean 289 svga_texture_transfer_map_upload_create(struct svga_context *svga); 290 291 void 292 svga_texture_transfer_map_upload_destroy(struct svga_context *svga); 293 294 boolean 295 svga_texture_transfer_map_can_upload(const struct svga_screen *svgascreen, 296 const struct pipe_resource *pt); 297 298 void * 299 svga_texture_transfer_map_upload(struct svga_context *svga, 300 struct svga_transfer *st); 301 302 void 303 svga_texture_transfer_unmap_upload(struct svga_context *svga, 304 struct svga_transfer *st); 305 306 #endif /* SVGA_TEXTURE_H */ 307