13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**********************************************************
23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2009 VMware, Inc.  All rights reserved.
33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person
53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation
63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without
73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy,
83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies
93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is
103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions:
113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be
133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software.
143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE.
233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/
253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_cmd.h"
283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_debug.h"
303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h"
313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_debug_stack.h"
323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipebuffer/pb_buffer.h"
333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipebuffer/pb_validate.h"
343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_winsys.h"
363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_context.h"
373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_screen.h"
383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_buffer.h"
393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_surface.h"
403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_fence.h"
413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_COMMAND_SIZE (64*1024)
433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_SURFACE_RELOCS (1024)
44383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca#define VMW_REGION_RELOCS (512)
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#define VMW_MUST_FLUSH_STACK 8
473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
48383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonsecastruct vmw_region_relocation
49383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca{
50383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   struct SVGAGuestPtr *where;
51383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   struct pb_buffer *buffer;
52383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   /* TODO: put offset info inside where */
53383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   uint32 offset;
54383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca};
55383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vmw_svga_winsys_context
573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_winsys_context base;
593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_winsys_screen *vws;
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean must_flush;
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK];
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct {
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint8_t buffer[VMW_COMMAND_SIZE];
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t size;
703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t used;
713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t reserved;
723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } command;
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct {
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS];
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t size;
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t used;
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t staged;
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      uint32_t reserved;
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } surface;
81383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
82383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   struct {
83383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      struct vmw_region_relocation relocs[VMW_REGION_RELOCS];
84383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      uint32_t size;
85383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      uint32_t used;
86383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      uint32_t staged;
87383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      uint32_t reserved;
88383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   } region;
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pb_validate *validate;
913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
92a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   /**
93a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * The amount of GMR that is referred by the commands currently batched
94a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * in the context.
95a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    */
96a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   uint32_t seen_regions;
97a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca
98a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   /**
99a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * Whether this context should fail to reserve more commands, not because it
100a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * ran out of command space, but because a substantial ammount of GMR was
101a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * referred.
102a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    */
103a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   boolean preemptive_flush;
1043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
1053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct vmw_svga_winsys_context *
1083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_svga_winsys_context(struct svga_winsys_context *swc)
1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(swc);
1113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (struct vmw_svga_winsys_context *)swc;
1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
115aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantzstatic INLINE unsigned
116aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantzvmw_translate_to_pb_flags(unsigned flags)
117aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz{
118aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   unsigned f = 0;
119aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   if (flags & SVGA_RELOC_READ)
120aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz      f |= PB_USAGE_GPU_READ;
121aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz
122aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   if (flags & SVGA_RELOC_WRITE)
123aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz      f |= PB_USAGE_GPU_WRITE;
124aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz
125aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   return f;
126aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz}
127aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz
1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic enum pipe_error
1293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_flush(struct svga_winsys_context *swc,
1303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              struct pipe_fence_handle **pfence)
1313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
1333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pipe_fence_handle *fence = NULL;
1343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = pb_validate_validate(vswc->validate);
1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(ret == PIPE_OK);
1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(ret == PIPE_OK) {
140383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
141383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      /* Apply relocations */
142383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      for(i = 0; i < vswc->region.used; ++i) {
143383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca         struct vmw_region_relocation *reloc = &vswc->region.relocs[i];
144383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca         struct SVGAGuestPtr ptr;
145383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
146383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca         if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr))
147383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca            assert(0);
148383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
149383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca         ptr.offset += reloc->offset;
150383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
151383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca         *reloc->where = ptr;
152383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      }
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1545a6ca7e9f24939cfacf2e8cd163a4efa9550ce1fThomas Hellstrom      if (vswc->command.used || pfence != NULL)
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         vmw_ioctl_command(vswc->vws,
156d12f2bb9c03a9e8a08824c849200f5b23c05914cThomas Hellstrom			   vswc->base.cid,
157ca21c85ab062f18649445fdbc4e494e31e5ca535Jakob Bornecrantz			   0,
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vswc->command.buffer,
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vswc->command.used,
160e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom                           &fence);
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      pb_validate_fence(vswc->validate, fence);
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.used = 0;
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.reserved = 0;
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) {
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct vmw_svga_winsys_surface *vsurf =
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz	 vswc->surface.handles[i];
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      p_atomic_dec(&vsurf->validated);
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.used = 0;
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.reserved = 0;
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
178383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   for(i = 0; i < vswc->region.used + vswc->region.staged; ++i) {
179383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      pb_reference(&vswc->region.relocs[i].buffer, NULL);
180383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   }
181383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
182383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.used = 0;
183383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.reserved = 0;
184383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG
1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->must_flush = FALSE;
1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif
188a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   vswc->preemptive_flush = FALSE;
189a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   vswc->seen_regions = 0;
1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(pfence)
192e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom      vmw_fence_reference(vswc->vws, pfence, fence);
193e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom
194e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom   vmw_fence_reference(vswc->vws, &fence, NULL);
1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return ret;
1973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void *
2013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_reserve(struct svga_winsys_context *swc,
2023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                uint32_t nr_bytes, uint32_t nr_relocs )
2033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
2053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG
2073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Check if somebody forgot to check the previous failure */
2083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(vswc->must_flush) {
2093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      debug_printf("Forgot to flush:\n");
2103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK);
2113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(!vswc->must_flush);
2123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif
2143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(nr_bytes <= vswc->command.size);
2163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(nr_bytes > vswc->command.size)
2173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return NULL;
2183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
219a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   if(vswc->preemptive_flush ||
220a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca      vswc->command.used + nr_bytes > vswc->command.size ||
221383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      vswc->surface.used + nr_relocs > vswc->surface.size ||
222383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      vswc->region.used + nr_relocs > vswc->region.size) {
2233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#ifdef DEBUG
2243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      vswc->must_flush = TRUE;
2253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      debug_backtrace_capture(vswc->must_flush_stack, 1,
2263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              VMW_MUST_FLUSH_STACK);
2273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif
2283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return NULL;
2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->command.used + nr_bytes <= vswc->command.size);
2323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
233383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   assert(vswc->region.used + nr_relocs <= vswc->region.size);
234383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
2353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.reserved = nr_bytes;
2363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.reserved = nr_relocs;
2373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.staged = 0;
238383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.reserved = nr_relocs;
239383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.staged = 0;
240383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
2413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return vswc->command.buffer + vswc->command.used;
2423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
2463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_surface_relocation(struct svga_winsys_context *swc,
2473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           uint32 *where,
2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct svga_winsys_surface *surface,
2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           unsigned flags)
2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_surface *vsurf;
2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(!surface) {
2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      *where = SVGA3D_INVALID_ID;
2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return;
2573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->surface.staged < vswc->surface.reserved);
2603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vsurf = vmw_svga_winsys_surface(surface);
2623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   *where = vsurf->sid;
2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf);
2663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   p_atomic_inc(&vsurf->validated);
2673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ++vswc->surface.staged;
2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_region_relocation(struct svga_winsys_context *swc,
2733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          struct SVGAGuestPtr *where,
2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          struct svga_winsys_buffer *buffer,
2753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          uint32 offset,
2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          unsigned flags)
2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
279383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   struct vmw_region_relocation *reloc;
280aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   unsigned translated_flags;
2813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
282383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
283383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   assert(vswc->region.staged < vswc->region.reserved);
2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
285383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged];
286383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   reloc->where = where;
287383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   pb_reference(&reloc->buffer, vmw_pb_buffer(buffer));
288383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   reloc->offset = offset;
2893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
290383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   ++vswc->region.staged;
2913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
292aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   translated_flags = vmw_translate_to_pb_flags(flags);
293aa857509bd0032f636ebf45bebb143cc6a8e408eJakob Bornecrantz   ret = pb_validate_add_buffer(vswc->validate, reloc->buffer, translated_flags);
2943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* TODO: Update pipebuffer to reserve buffers and not fail here */
2953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(ret == PIPE_OK);
296f700370946972d26dae7ab54cbb186feea50579cJakob Bornecrantz   (void)ret;
297a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca
298a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca   /*
299a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * Flush preemptively the FIFO commands to keep the GMR working set within
300a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * the GMR pool size.
301a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    *
302a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * This is necessary for applications like SPECviewperf that generate huge
303a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * amounts of immediate vertex data, so that we don't pile up too much of
304a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * that vertex data neither in the guest nor in the host.
305a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    *
306a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * Note that in the current implementation if a region is referred twice in
307a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * a command stream, it will be accounted twice. We could detect repeated
308a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * regions and count only once, but there is no incentive to do that, since
309a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * regions are typically short-lived; always referred in a single command;
310a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * and at the worst we just flush the commands a bit sooner, which for the
311a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * SVGA virtual device it's not a performance issue since flushing commands
312a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    * to the FIFO won't cause flushing in the host.
313a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca    */
3144682e706012fe26627a2f827db01b5068cc62814Marek Olšák   vswc->seen_regions += reloc->buffer->size;
315637ed52f597098ac556b27a4403056bd54343426José Fonseca   if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/3)
316a626565178fb810f439fbdfdaf6cc28a973a6a81José Fonseca      vswc->preemptive_flush = TRUE;
3173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
3213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_commit(struct svga_winsys_context *swc)
3223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
3243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->command.reserved);
3263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->command.used + vswc->command.reserved <= vswc->command.size);
3273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.used += vswc->command.reserved;
3283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.reserved = 0;
3293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->surface.staged <= vswc->surface.reserved);
3313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size);
3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.used += vswc->surface.staged;
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.staged = 0;
3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.reserved = 0;
335383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
336383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   assert(vswc->region.staged <= vswc->region.reserved);
337383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   assert(vswc->region.used + vswc->region.staged <= vswc->region.size);
338383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.used += vswc->region.staged;
339383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.staged = 0;
340383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.reserved = 0;
3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void
3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_swc_destroy(struct svga_winsys_context *swc)
3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
349383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
350383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   for(i = 0; i < vswc->region.used; ++i) {
351383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca      pb_reference(&vswc->region.relocs[i].buffer, NULL);
352383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   }
353383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for(i = 0; i < vswc->surface.used; ++i) {
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      p_atomic_dec(&vswc->surface.handles[i]->validated);
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   pb_validate_destroy(vswc->validate);
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vmw_ioctl_context_destroy(vswc->vws, swc->cid);
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   FREE(vswc);
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_winsys_context *
3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct vmw_svga_winsys_context *vswc;
3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc = CALLOC_STRUCT(vmw_svga_winsys_context);
3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(!vswc)
3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return NULL;
3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.destroy = vmw_swc_destroy;
3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.reserve = vmw_swc_reserve;
3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.surface_relocation = vmw_swc_surface_relocation;
3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.region_relocation = vmw_swc_region_relocation;
3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.commit = vmw_swc_commit;
3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.flush = vmw_swc_flush;
3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->base.cid = vmw_ioctl_context_create(vws);
3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->vws = vws;
3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->command.size = VMW_COMMAND_SIZE;
3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->surface.size = VMW_SURFACE_RELOCS;
387383f460cf7472af4a526668c2412ab08ea30c0ecJosé Fonseca   vswc->region.size = VMW_REGION_RELOCS;
3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vswc->validate = pb_validate_create();
3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if(!vswc->validate) {
3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      FREE(vswc);
3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return NULL;
3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return &vswc->base;
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
397