Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 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. /**
  27.  * @file
  28.  * SVGA buffer manager for Guest Memory Regions (GMRs).
  29.  *
  30.  * GMRs are used for pixel and vertex data upload/download to/from the virtual
  31.  * SVGA hardware. There is a limited number of GMRs available, and
  32.  * creating/destroying them is also a slow operation so we must suballocate
  33.  * them.
  34.  *
  35.  * This file implements a pipebuffer library's buffer manager, so that we can
  36.  * use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs.
  37.  *
  38.  * @author Jose Fonseca <jfonseca@vmware.com>
  39.  */
  40.  
  41.  
  42. #include "svga_cmd.h"
  43.  
  44. #include "util/u_inlines.h"
  45. #include "util/u_memory.h"
  46. #include "pipebuffer/pb_buffer.h"
  47. #include "pipebuffer/pb_bufmgr.h"
  48.  
  49. #include "svga_winsys.h"
  50.  
  51. #include "vmw_screen.h"
  52. #include "vmw_buffer.h"
  53.  
  54.  
  55. struct vmw_gmr_bufmgr;
  56.  
  57.  
  58. struct vmw_gmr_buffer
  59. {
  60.    struct pb_buffer base;
  61.    
  62.    struct vmw_gmr_bufmgr *mgr;
  63.    
  64.    struct vmw_region *region;
  65.    void *map;
  66. };
  67.  
  68.  
  69. extern const struct pb_vtbl vmw_gmr_buffer_vtbl;
  70.  
  71.  
  72. static INLINE struct vmw_gmr_buffer *
  73. vmw_gmr_buffer(struct pb_buffer *buf)
  74. {
  75.    assert(buf);
  76.    assert(buf->vtbl == &vmw_gmr_buffer_vtbl);
  77.    return (struct vmw_gmr_buffer *)buf;
  78. }
  79.  
  80.  
  81. struct vmw_gmr_bufmgr
  82. {
  83.    struct pb_manager base;
  84.    
  85.    struct vmw_winsys_screen *vws;
  86. };
  87.  
  88.  
  89. static INLINE struct vmw_gmr_bufmgr *
  90. vmw_gmr_bufmgr(struct pb_manager *mgr)
  91. {
  92.    assert(mgr);
  93.    return (struct vmw_gmr_bufmgr *)mgr;
  94. }
  95.  
  96.  
  97. static void
  98. vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
  99. {
  100.    struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
  101.  
  102.    vmw_ioctl_region_unmap(buf->region);
  103.    
  104.    vmw_ioctl_region_destroy(buf->region);
  105.  
  106.    FREE(buf);
  107. }
  108.  
  109.  
  110. static void *
  111. vmw_gmr_buffer_map(struct pb_buffer *_buf,
  112.                    unsigned flags,
  113.                    void *flush_ctx)
  114. {
  115.    struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
  116.    return buf->map;
  117. }
  118.  
  119.  
  120. static void
  121. vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
  122. {
  123.    /* Do nothing */
  124.    (void)_buf;
  125. }
  126.  
  127.  
  128. static void
  129. vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf,
  130.                            struct pb_buffer **base_buf,
  131.                            unsigned *offset)
  132. {
  133.    *base_buf = buf;
  134.    *offset = 0;
  135. }
  136.  
  137.  
  138. static enum pipe_error
  139. vmw_gmr_buffer_validate( struct pb_buffer *_buf,
  140.                          struct pb_validate *vl,
  141.                          unsigned flags )
  142. {
  143.    /* Always pinned */
  144.    return PIPE_OK;
  145. }
  146.  
  147.  
  148. static void
  149. vmw_gmr_buffer_fence( struct pb_buffer *_buf,
  150.                       struct pipe_fence_handle *fence )
  151. {
  152.    /* We don't need to do anything, as the pipebuffer library
  153.     * will take care of delaying the destruction of fenced buffers */  
  154. }
  155.  
  156.  
  157. const struct pb_vtbl vmw_gmr_buffer_vtbl = {
  158.    vmw_gmr_buffer_destroy,
  159.    vmw_gmr_buffer_map,
  160.    vmw_gmr_buffer_unmap,
  161.    vmw_gmr_buffer_validate,
  162.    vmw_gmr_buffer_fence,
  163.    vmw_gmr_buffer_get_base_buffer
  164. };
  165.  
  166.  
  167. static struct pb_buffer *
  168. vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr,
  169.                          pb_size size,
  170.                          const struct pb_desc *desc)
  171. {
  172.    struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
  173.    struct vmw_winsys_screen *vws = mgr->vws;
  174.    struct vmw_gmr_buffer *buf;
  175.    
  176.    buf = CALLOC_STRUCT(vmw_gmr_buffer);
  177.    if(!buf)
  178.       goto error1;
  179.  
  180.    pipe_reference_init(&buf->base.reference, 1);
  181.    buf->base.alignment = desc->alignment;
  182.    buf->base.usage = desc->usage;
  183.    buf->base.size = size;
  184.    buf->base.vtbl = &vmw_gmr_buffer_vtbl;
  185.    buf->mgr = mgr;
  186.  
  187.    buf->region = vmw_ioctl_region_create(vws, size);
  188.    if(!buf->region)
  189.       goto error2;
  190.          
  191.    buf->map = vmw_ioctl_region_map(buf->region);
  192.    if(!buf->map)
  193.       goto error3;
  194.  
  195.    return &buf->base;
  196.  
  197. error3:
  198.    vmw_ioctl_region_destroy(buf->region);
  199. error2:
  200.    FREE(buf);
  201. error1:
  202.    return NULL;
  203. }
  204.  
  205.  
  206. static void
  207. vmw_gmr_bufmgr_flush(struct pb_manager *mgr)
  208. {
  209.    /* No-op */
  210. }
  211.  
  212.  
  213. static void
  214. vmw_gmr_bufmgr_destroy(struct pb_manager *_mgr)
  215. {
  216.    struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
  217.    FREE(mgr);
  218. }
  219.  
  220.  
  221. struct pb_manager *
  222. vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws)
  223. {
  224.    struct vmw_gmr_bufmgr *mgr;
  225.    
  226.    mgr = CALLOC_STRUCT(vmw_gmr_bufmgr);
  227.    if(!mgr)
  228.       return NULL;
  229.  
  230.    mgr->base.destroy = vmw_gmr_bufmgr_destroy;
  231.    mgr->base.create_buffer = vmw_gmr_bufmgr_create_buffer;
  232.    mgr->base.flush = vmw_gmr_bufmgr_flush;
  233.    
  234.    mgr->vws = vws;
  235.    
  236.    return &mgr->base;
  237. }
  238.  
  239.  
  240. boolean
  241. vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
  242.                           struct SVGAGuestPtr *ptr)
  243. {
  244.    struct pb_buffer *base_buf;
  245.    unsigned offset = 0;
  246.    struct vmw_gmr_buffer *gmr_buf;
  247.    
  248.    pb_get_base_buffer( buf, &base_buf, &offset );
  249.    
  250.    gmr_buf = vmw_gmr_buffer(base_buf);
  251.    if(!gmr_buf)
  252.       return FALSE;
  253.    
  254.    *ptr = vmw_ioctl_region_ptr(gmr_buf->region);
  255.    
  256.    ptr->offset += offset;
  257.    
  258.    return TRUE;
  259. }
  260.