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