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 37struct pipe_context; 38struct pipe_screen; 39struct svga_context; 40struct svga_winsys_surface; 41enum SVGA3dSurfaceFormat; 42 43 44#define SVGA_MAX_TEXTURE_LEVELS 16 45 46struct svga_texture 47{ 48 struct pipe_resource b; 49 50 ushort *defined; 51 52 struct svga_sampler_view *cached_view; 53 54 unsigned view_age[SVGA_MAX_TEXTURE_LEVELS]; 55 unsigned age; 56 57 boolean views_modified; 58 59 /** 60 * Creation key for the host surface handle. 61 * 62 * This structure describes all the host surface characteristics so that it 63 * can be looked up in cache, since creating a host surface is often a slow 64 * operation. 65 */ 66 struct svga_host_surface_cache_key key; 67 68 /** 69 * Handle for the host side surface. 70 * 71 * This handle is owned by this texture. Views should hold on to a reference 72 * to this texture and never destroy this handle directly. 73 */ 74 struct svga_winsys_surface *handle; 75 76 /** 77 * Whether the host side surface is validated, either through the 78 * InvalidateGBSurface command or after the surface is updated 79 * or rendered to. 80 */ 81 boolean validated; 82 83 /** 84 * Whether the host side surface is imported and not created by this 85 * driver. 86 */ 87 boolean imported; 88 89 /** 90 * Whether texture upload buffer can be used on this texture 91 */ 92 boolean can_use_upload; 93 94 unsigned size; /**< Approximate size in bytes */ 95 96 /** array indexed by cube face or 3D/array slice, one bit per mipmap level */ 97 ushort *rendered_to; 98 99 /** array indexed by cube face or 3D/array slice, one bit per mipmap level. 100 * Set if the level is marked as dirty. 101 */ 102 ushort *dirty; 103 104 /** 105 * A cached backing host side surface to be used if this texture is being 106 * used for rendering and sampling at the same time. 107 * Currently we only cache one handle. If needed, we can extend this to 108 * support multiple handles. 109 */ 110 struct svga_host_surface_cache_key backed_key; 111 struct svga_winsys_surface *backed_handle; 112 unsigned backed_age; 113}; 114 115 116 117/* Note this is only used for texture (not buffer) transfers: 118 */ 119struct svga_transfer 120{ 121 struct pipe_transfer base; 122 123 unsigned slice; /**< array slice or cube face */ 124 SVGA3dBox box; /* The adjusted box with slice index removed from z */ 125 126 struct svga_winsys_buffer *hwbuf; 127 128 /* Height of the hardware buffer in pixel blocks */ 129 unsigned hw_nblocksy; 130 131 /* Temporary malloc buffer when we can't allocate a hardware buffer 132 * big enough */ 133 void *swbuf; 134 135 /* True if guest backed surface is supported and we can directly map 136 * to the surface for this transfer. 137 */ 138 boolean use_direct_map; 139 140 struct { 141 struct pipe_resource *buf; /* points to the upload buffer if this 142 * transfer is done via the upload buffer 143 * instead of directly mapping to the 144 * resource's surface. 145 */ 146 void *map; 147 unsigned offset; 148 SVGA3dBox box; 149 unsigned nlayers; 150 } upload; 151}; 152 153 154static inline struct svga_texture * 155svga_texture(struct pipe_resource *resource) 156{ 157 struct svga_texture *tex = (struct svga_texture *)resource; 158 assert(tex == NULL || tex->b.target != PIPE_BUFFER); 159 return tex; 160} 161 162 163static inline struct svga_transfer * 164svga_transfer(struct pipe_transfer *transfer) 165{ 166 assert(transfer); 167 return (struct svga_transfer *)transfer; 168} 169 170 171/** 172 * Increment the age of a view into a texture 173 * This is used to track updates to textures when we draw into 174 * them via a surface. 175 */ 176static inline void 177svga_age_texture_view(struct svga_texture *tex, unsigned level) 178{ 179 assert(level < ARRAY_SIZE(tex->view_age)); 180 tex->view_age[level] = ++(tex->age); 181} 182 183 184/** For debugging, check that face and level are legal */ 185static inline void 186check_face_level(const struct svga_texture *tex, 187 unsigned face, unsigned level) 188{ 189 if (tex->b.target == PIPE_TEXTURE_CUBE) { 190 assert(face < 6); 191 } 192 else if (tex->b.target == PIPE_TEXTURE_3D) { 193 assert(face < tex->b.depth0); 194 } 195 else { 196 assert(face < tex->b.array_size); 197 } 198 199 assert(level < 8 * sizeof(tex->rendered_to[0])); 200} 201 202 203/** 204 * Mark the given texture face/level as being defined. 205 */ 206static inline void 207svga_define_texture_level(struct svga_texture *tex, 208 unsigned face,unsigned level) 209{ 210 check_face_level(tex, face, level); 211 tex->defined[face] |= 1 << level; 212 tex->validated = TRUE; 213} 214 215 216static inline bool 217svga_is_texture_level_defined(const struct svga_texture *tex, 218 unsigned face, unsigned level) 219{ 220 check_face_level(tex, face, level); 221 return (tex->defined[face] & (1 << level)) != 0; 222} 223 224 225static inline void 226svga_set_texture_rendered_to(struct svga_texture *tex, 227 unsigned face, unsigned level) 228{ 229 check_face_level(tex, face, level); 230 tex->rendered_to[face] |= 1 << level; 231 tex->validated = TRUE; 232} 233 234 235static inline void 236svga_clear_texture_rendered_to(struct svga_texture *tex, 237 unsigned face, unsigned level) 238{ 239 check_face_level(tex, face, level); 240 tex->rendered_to[face] &= ~(1 << level); 241} 242 243 244static inline boolean 245svga_was_texture_rendered_to(const struct svga_texture *tex, 246 unsigned face, unsigned level) 247{ 248 check_face_level(tex, face, level); 249 return !!(tex->rendered_to[face] & (1 << level)); 250} 251 252static inline void 253svga_set_texture_dirty(struct svga_texture *tex, 254 unsigned face, unsigned level) 255{ 256 check_face_level(tex, face, level); 257 tex->dirty[face] |= 1 << level; 258} 259 260static inline void 261svga_clear_texture_dirty(struct svga_texture *tex) 262{ 263 unsigned i; 264 for (i = 0; i < tex->b.depth0 * tex->b.array_size; i++) { 265 tex->dirty[i] = 0; 266 } 267} 268 269static inline boolean 270svga_is_texture_dirty(const struct svga_texture *tex, 271 unsigned face, unsigned level) 272{ 273 check_face_level(tex, face, level); 274 return !!(tex->dirty[face] & (1 << level)); 275} 276 277struct pipe_resource * 278svga_texture_create(struct pipe_screen *screen, 279 const struct pipe_resource *template); 280 281bool 282svga_resource_get_handle(struct pipe_screen *screen, 283 struct pipe_context *context, 284 struct pipe_resource *texture, 285 struct winsys_handle *whandle, 286 unsigned usage); 287 288struct pipe_resource * 289svga_texture_from_handle(struct pipe_screen * screen, 290 const struct pipe_resource *template, 291 struct winsys_handle *whandle); 292 293bool 294svga_texture_generate_mipmap(struct pipe_context *pipe, 295 struct pipe_resource *pt, 296 enum pipe_format format, 297 unsigned base_level, 298 unsigned last_level, 299 unsigned first_layer, 300 unsigned last_layer); 301 302boolean 303svga_texture_transfer_map_upload_create(struct svga_context *svga); 304 305void 306svga_texture_transfer_map_upload_destroy(struct svga_context *svga); 307 308boolean 309svga_texture_transfer_map_can_upload(const struct svga_screen *svgascreen, 310 const struct pipe_resource *pt); 311 312void * 313svga_texture_transfer_map_upload(struct svga_context *svga, 314 struct svga_transfer *st); 315 316void 317svga_texture_transfer_unmap_upload(struct svga_context *svga, 318 struct svga_transfer *st); 319 320boolean 321svga_texture_device_format_has_alpha(struct pipe_resource *texture); 322 323void * 324svga_texture_transfer_map(struct pipe_context *pipe, 325 struct pipe_resource *texture, 326 unsigned level, 327 unsigned usage, 328 const struct pipe_box *box, 329 struct pipe_transfer **ptransfer); 330 331void 332svga_texture_transfer_unmap(struct pipe_context *pipe, 333 struct pipe_transfer *transfer); 334 335#endif /* SVGA_TEXTURE_H */ 336