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