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