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