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