Home | History | Annotate | Download | only in svga
      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_BUFFER_H
     27 #define SVGA_BUFFER_H
     28 
     29 
     30 #include "pipe/p_compiler.h"
     31 #include "pipe/p_state.h"
     32 #include "util/u_transfer.h"
     33 
     34 #include "svga_screen_cache.h"
     35 #include "svga_screen.h"
     36 #include "svga_cmd.h"
     37 #include "svga_context.h"
     38 
     39 
     40 /**
     41  * Maximum number of discontiguous ranges
     42  */
     43 #define SVGA_BUFFER_MAX_RANGES 32
     44 
     45 
     46 struct svga_context;
     47 struct svga_winsys_buffer;
     48 struct svga_winsys_surface;
     49 
     50 
     51 extern struct u_resource_vtbl svga_buffer_vtbl;
     52 
     53 struct svga_buffer_range
     54 {
     55    unsigned start;
     56    unsigned end;
     57 };
     58 
     59 struct svga_3d_update_gb_image;
     60 
     61 /**
     62  * SVGA pipe buffer.
     63  */
     64 struct svga_buffer
     65 {
     66    struct u_resource b;
     67 
     68    /** This is a superset of b.b.bind */
     69    unsigned bind_flags;
     70 
     71    /**
     72     * Regular (non DMA'able) memory.
     73     *
     74     * Used for user buffers or for buffers which we know before hand that can
     75     * never be used by the virtual hardware directly, such as constant buffers.
     76     */
     77    void *swbuf;
     78 
     79    /**
     80     * Whether swbuf was created by the user or not.
     81     */
     82    boolean user;
     83 
     84    /**
     85     * Creation key for the host surface handle.
     86     *
     87     * This structure describes all the host surface characteristics so that it
     88     * can be looked up in cache, since creating a host surface is often a slow
     89     * operation.
     90     */
     91    struct svga_host_surface_cache_key key;
     92 
     93    /**
     94     * Host surface handle.
     95     *
     96     * This is a platform independent abstraction for host SID. We create when
     97     * trying to bind.
     98     *
     99     * Only set for non-user buffers.
    100     */
    101    struct svga_winsys_surface *handle;
    102 
    103    /**
    104     * Information about ongoing and past map operations.
    105     */
    106    struct {
    107       /**
    108        * Number of concurrent mappings.
    109        */
    110       unsigned count;
    111 
    112       /**
    113        * Dirty ranges.
    114        *
    115        * Ranges that were touched by the application and need to be uploaded to
    116        * the host.
    117        *
    118        * This information will be copied into dma.boxes, when emiting the
    119        * SVGA3dCmdSurfaceDMA command.
    120        */
    121       struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
    122       unsigned num_ranges;
    123    } map;
    124 
    125    /**
    126     * Information about uploaded version of user buffers.
    127     */
    128    struct {
    129       struct pipe_resource *buffer;
    130 
    131       /**
    132        * We combine multiple user buffers into the same hardware buffer. This
    133        * is the relative offset within that buffer.
    134        */
    135       unsigned offset;
    136 
    137       /**
    138        * Range of user buffer that is uploaded in @buffer at @offset.
    139        */
    140       unsigned start;
    141       unsigned end;
    142    } uploaded;
    143 
    144    /**
    145     * DMA'ble memory.
    146     *
    147     * A piece of GMR memory, with the same size of the buffer. It is created
    148     * when mapping the buffer, and will be used to upload vertex data to the
    149     * host.
    150     *
    151     * Only set for non-user buffers.
    152     */
    153    struct svga_winsys_buffer *hwbuf;
    154 
    155    /**
    156     * Information about pending DMA uploads.
    157     *
    158     */
    159    struct {
    160       /**
    161        * Whether this buffer has an unfinished DMA upload command.
    162        *
    163        * If not set then the rest of the information is null.
    164        */
    165       boolean pending;
    166 
    167       SVGA3dSurfaceDMAFlags flags;
    168 
    169       /**
    170        * Pointer to the DMA copy box *inside* the command buffer.
    171        */
    172       SVGA3dCopyBox *boxes;
    173 
    174       /**
    175        * Pointer to the sequence of update commands
    176        * *inside* the command buffer.
    177        */
    178       struct svga_3d_update_gb_image *updates;
    179 
    180       /**
    181        * Context that has the pending DMA to this buffer.
    182        */
    183       struct svga_context *svga;
    184    } dma;
    185 
    186    /**
    187     * Linked list head, used to gather all buffers with pending dma uploads on
    188     * a context. It is only valid if the dma.pending is set above.
    189     */
    190    struct list_head head;
    191 
    192    unsigned size;  /**< Approximate size in bytes */
    193 
    194    boolean dirty;  /**< Need to do a readback before mapping? */
    195 
    196    /** In some cases we try to keep the results of the translate_indices()
    197     * function from svga_draw_elements.c
    198     */
    199    struct {
    200       enum pipe_prim_type orig_prim, new_prim;
    201       struct pipe_resource *buffer;
    202       unsigned index_size;
    203       unsigned offset;  /**< first index */
    204       unsigned count;   /**< num indices */
    205    } translated_indices;
    206 };
    207 
    208 
    209 static inline struct svga_buffer *
    210 svga_buffer(struct pipe_resource *resource)
    211 {
    212    struct svga_buffer *buf = (struct svga_buffer *) resource;
    213    assert(buf == NULL || buf->b.vtbl == &svga_buffer_vtbl);
    214    return buf;
    215 }
    216 
    217 
    218 /**
    219  * Returns TRUE for user buffers.  We may
    220  * decide to use an alternate upload path for these buffers.
    221  */
    222 static inline boolean
    223 svga_buffer_is_user_buffer( struct pipe_resource *buffer )
    224 {
    225    if (buffer) {
    226       return svga_buffer(buffer)->user;
    227    } else {
    228       return FALSE;
    229    }
    230 }
    231 
    232 /**
    233  * Returns a pointer to a struct svga_winsys_screen given a
    234  * struct svga_buffer.
    235  */
    236 static inline struct svga_winsys_screen *
    237 svga_buffer_winsys_screen(struct svga_buffer *sbuf)
    238 {
    239    return svga_screen(sbuf->b.b.screen)->sws;
    240 }
    241 
    242 
    243 /**
    244  * Returns whether a buffer has hardware storage that is
    245  * visible to the GPU.
    246  */
    247 static inline boolean
    248 svga_buffer_has_hw_storage(struct svga_buffer *sbuf)
    249 {
    250    if (svga_buffer_winsys_screen(sbuf)->have_gb_objects)
    251       return (sbuf->handle ? TRUE : FALSE);
    252    else
    253       return (sbuf->hwbuf ? TRUE : FALSE);
    254 }
    255 
    256 /**
    257  * Map the hardware storage of a buffer.
    258  */
    259 static inline void *
    260 svga_buffer_hw_storage_map(struct svga_context *svga,
    261                            struct svga_buffer *sbuf,
    262                            unsigned flags, boolean *retry)
    263 {
    264    struct svga_winsys_screen *sws = svga_buffer_winsys_screen(sbuf);
    265 
    266    svga->hud.num_buffers_mapped++;
    267 
    268    if (sws->have_gb_objects) {
    269       return svga->swc->surface_map(svga->swc, sbuf->handle, flags, retry);
    270    } else {
    271       *retry = FALSE;
    272       return sws->buffer_map(sws, sbuf->hwbuf, flags);
    273    }
    274 }
    275 
    276 /**
    277  * Unmap the hardware storage of a buffer.
    278  */
    279 static inline void
    280 svga_buffer_hw_storage_unmap(struct svga_context *svga,
    281                              struct svga_buffer *sbuf)
    282 {
    283    struct svga_winsys_screen *sws = svga_buffer_winsys_screen(sbuf);
    284 
    285    if (sws->have_gb_objects) {
    286       struct svga_winsys_context *swc = svga->swc;
    287       boolean rebind;
    288       swc->surface_unmap(swc, sbuf->handle, &rebind);
    289       if (rebind) {
    290          enum pipe_error ret;
    291          ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
    292          if (ret != PIPE_OK) {
    293             /* flush and retry */
    294             svga_context_flush(svga, NULL);
    295             ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
    296             assert(ret == PIPE_OK);
    297          }
    298       }
    299    } else
    300       sws->buffer_unmap(sws, sbuf->hwbuf);
    301 }
    302 
    303 
    304 struct pipe_resource *
    305 svga_user_buffer_create(struct pipe_screen *screen,
    306                         void *ptr,
    307                         unsigned bytes,
    308 			unsigned usage);
    309 
    310 struct pipe_resource *
    311 svga_buffer_create(struct pipe_screen *screen,
    312 		   const struct pipe_resource *template);
    313 
    314 
    315 
    316 /**
    317  * Get the host surface handle for this buffer.
    318  *
    319  * This will ensure the host surface is updated, issuing DMAs as needed.
    320  *
    321  * NOTE: This may insert new commands in the context, so it *must* be called
    322  * before reserving command buffer space. And, in order to insert commands
    323  * it may need to call svga_context_flush().
    324  */
    325 struct svga_winsys_surface *
    326 svga_buffer_handle(struct svga_context *svga,
    327                    struct pipe_resource *buf);
    328 
    329 void
    330 svga_context_flush_buffers(struct svga_context *svga);
    331 
    332 struct svga_winsys_buffer *
    333 svga_winsys_buffer_create(struct svga_context *svga,
    334                           unsigned alignment,
    335                           unsigned usage,
    336                           unsigned size);
    337 
    338 #endif /* SVGA_BUFFER_H */
    339