svga_resource_buffer.c revision a2a01853f3f40b4ef8b3f01503391877960bdaee
1287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/**********************************************************
2287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell *
4287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * Permission is hereby granted, free of charge, to any person
5287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * obtaining a copy of this software and associated documentation
6287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * files (the "Software"), to deal in the Software without
7287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * restriction, including without limitation the rights to use, copy,
8287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * modify, merge, publish, distribute, sublicense, and/or sell copies
9287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * of the Software, and to permit persons to whom the Software is
10287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * furnished to do so, subject to the following conditions:
11287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell *
12287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * The above copyright notice and this permission notice shall be
13287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * included in all copies or substantial portions of the Software.
14287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell *
15287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * SOFTWARE.
23287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell *
24287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell **********************************************************/
25287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
26287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_cmd.h"
27287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
28287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "pipe/p_state.h"
29287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "pipe/p_defines.h"
30287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_inlines.h"
31287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "os/os_thread.h"
32287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_math.h"
33287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "util/u_memory.h"
34287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
35287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_context.h"
36287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_screen.h"
37287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_resource_buffer.h"
38287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_resource_buffer_upload.h"
39287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_winsys.h"
40287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "svga_debug.h"
41287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
42287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
43287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/**
44287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * Vertex and index buffers need hardware backing.  Constant buffers
45287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * do not.  No other types of buffers currently supported.
46287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */
47287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic INLINE boolean
48287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_needs_hw_storage(unsigned usage)
49287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
50287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return usage & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER);
51287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
52287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
53287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
54287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic unsigned int
55287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_is_referenced( struct pipe_context *pipe,
56287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			     struct pipe_resource *buf,
57287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			     unsigned face, unsigned level)
58287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
59287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(pipe->screen);
60287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf = svga_buffer(buf);
61287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
62287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   /**
63287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * XXX: Check this.
64287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * The screen may cache buffer writes, but when we map, we map out
65287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * of those cached writes, so we don't need to set a
66287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
67287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    */
68287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
69287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
70287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell     return PIPE_UNREFERENCED;
71287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
72287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   /**
73287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * sws->surface_is_flushed() does not distinguish between read references
74287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * and write references. So assume a reference is both,
75287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * however, we make an exception for index- and vertex buffers, to avoid
76287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * a flush in st_bufferobj_get_subdata, during display list replay.
77287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    */
78287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
79287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (sbuf->b.b.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
80287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      return PIPE_REFERENCED_FOR_READ;
81287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
82287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
83287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
84287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
85287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
86287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
87287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
88287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
89287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
90287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void *
91287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_map_range( struct pipe_screen *screen,
92287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                       struct pipe_resource *buf,
93287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                       unsigned offset,
94287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell		       unsigned length,
95287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                       unsigned usage )
96287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
97287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(screen);
98287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_winsys_screen *sws = ss->sws;
99287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf = svga_buffer( buf );
100287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   void *map;
101287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
102287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (!sbuf->swbuf && !sbuf->hwbuf) {
103287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
104287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         /*
105287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell          * We can't create a hardware buffer big enough, so create a malloc
106287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell          * buffer instead.
107287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell          */
108287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
109287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                      __FUNCTION__,
110287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                      (sbuf->b.b.width0 + 1023)/1024);
111287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
112287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16);
113287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      }
114287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
115287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
116287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (sbuf->swbuf) {
117287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      /* User/malloc buffer */
118287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      map = sbuf->swbuf;
119287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
120287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   else if (sbuf->hwbuf) {
121287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      map = sws->buffer_map(sws, sbuf->hwbuf, usage);
122287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
123287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   else {
124287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      map = NULL;
125287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
126287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
127287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(map) {
128287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_mutex_lock(ss->swc_mutex);
129287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
130287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      ++sbuf->map.count;
131287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
132287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      if (usage & PIPE_TRANSFER_WRITE) {
133287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         assert(sbuf->map.count <= 1);
134287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         sbuf->map.writing = TRUE;
135287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT)
136287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell            sbuf->map.flush_explicit = TRUE;
137287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      }
138287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
139287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_mutex_unlock(ss->swc_mutex);
140287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
141287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
142287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return map;
143287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
144287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
145287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
146287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
147287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void
148287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_flush_mapped_range( struct pipe_screen *screen,
149287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                struct pipe_resource *buf,
150287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                unsigned offset, unsigned length)
151287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
152287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf = svga_buffer( buf );
153287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(screen);
154287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
155287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_mutex_lock(ss->swc_mutex);
156287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(sbuf->map.writing);
157287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->map.writing) {
158287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      assert(sbuf->map.flush_explicit);
159287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      svga_buffer_add_range(sbuf, offset, offset + length);
160287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
161287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_mutex_unlock(ss->swc_mutex);
162287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
163287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
164287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void
165287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_unmap( struct pipe_screen *screen,
166287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                   struct pipe_resource *buf)
167287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
168287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(screen);
169287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_winsys_screen *sws = ss->sws;
170287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf = svga_buffer( buf );
171287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
172287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_mutex_lock(ss->swc_mutex);
173287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
174287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(sbuf->map.count);
175287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->map.count)
176287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      --sbuf->map.count;
177287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
178287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->hwbuf)
179287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      sws->buffer_unmap(sws, sbuf->hwbuf);
180287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
181287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->map.writing) {
182287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      if(!sbuf->map.flush_explicit) {
183287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         /* No mapped range was flushed -- flush the whole buffer */
184287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
185287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
186287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
187287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      }
188287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
189287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      sbuf->map.writing = FALSE;
190287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      sbuf->map.flush_explicit = FALSE;
191287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
192287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
193287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_mutex_unlock(ss->swc_mutex);
194287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
195287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
196287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
197287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
198287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void
199287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_destroy( struct pipe_screen *screen,
200287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell		     struct pipe_resource *buf )
201287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
202287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(screen);
203287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf = svga_buffer( buf );
204287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
205287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(!p_atomic_read(&buf->reference.count));
206287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
207287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(!sbuf->dma.pending);
208287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
209287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->handle)
210287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      svga_buffer_destroy_host_surface(ss, sbuf);
211287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
212287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->uploaded.buffer)
213287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&sbuf->uploaded.buffer, NULL);
214287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
215287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->hwbuf)
216287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      svga_buffer_destroy_hw_storage(ss, sbuf);
217287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
218287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(sbuf->swbuf && !sbuf->user)
219287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      align_free(sbuf->swbuf);
220287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
221287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   FREE(sbuf);
222287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
223287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
224287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
225287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell/* Keep the original code more or less intact, implement transfers in
226287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell * terms of the old functions.
227287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell */
228287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void *
229287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_transfer_map( struct pipe_context *pipe,
230287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			  struct pipe_transfer *transfer )
231287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
232287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   uint8_t *map = svga_buffer_map_range( pipe->screen,
233287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					 transfer->resource,
234287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					 transfer->box.x,
235287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					 transfer->box.width,
236287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					 transfer->usage );
237287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if (map == NULL)
238287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      return NULL;
239287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
240287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   /* map_buffer() returned a pointer to the beginning of the buffer,
241287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * but transfers are expected to return a pointer to just the
242287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    * region specified in the box.
243287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    */
244287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return map + transfer->box.x;
245287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
246287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
247287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
248287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
249287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void svga_buffer_transfer_flush_region( struct pipe_context *pipe,
250287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					       struct pipe_transfer *transfer,
251287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					       const struct pipe_box *box)
252287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
253287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   assert(box->x + box->width <= transfer->box.width);
254287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
255287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_flush_mapped_range(pipe->screen,
256287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  transfer->resource,
257287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  transfer->box.x + box->x,
258287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell				  box->width);
259287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
260287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
261287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstatic void svga_buffer_transfer_unmap( struct pipe_context *pipe,
262287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			    struct pipe_transfer *transfer )
263287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
264287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_unmap(pipe->screen,
265287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell		     transfer->resource);
266287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
267287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
268287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
269287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
270287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
271287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
272287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
273287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
274287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct u_resource_vtbl svga_buffer_vtbl =
275287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
276287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_resource_get_handle,      /* get_handle */
277287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_destroy,		     /* resource_destroy */
278287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_is_referenced,	     /* is_resource_referenced */
279287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_get_transfer,	     /* get_transfer */
280287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_transfer_destroy,	     /* transfer_destroy */
281287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_transfer_map,	     /* transfer_map */
282287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_transfer_flush_region,  /* transfer_flush_region */
283287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   svga_buffer_transfer_unmap,	     /* transfer_unmap */
284287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   u_default_transfer_inline_write   /* transfer_inline_write */
285287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell};
286287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
287287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
288287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
289287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *
290287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_buffer_create(struct pipe_screen *screen,
291287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell		   const struct pipe_resource *template)
292287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
293287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_screen *ss = svga_screen(screen);
294287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf;
295287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
296287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf = CALLOC_STRUCT(svga_buffer);
297287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(!sbuf)
298287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      goto error1;
299287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
300287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b = *template;
301287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.vtbl = &svga_buffer_vtbl;
302287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_reference_init(&sbuf->b.b.reference, 1);
303287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.screen = screen;
304287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
305287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(svga_buffer_needs_hw_storage(template->bind)) {
306287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK)
307287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         goto error2;
308287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
309287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   else {
310287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      sbuf->swbuf = align_malloc(template->width0, 64);
311287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      if(!sbuf->swbuf)
312287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell         goto error2;
313287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   }
314287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
315287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return &sbuf->b.b;
316287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
317287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror2:
318287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   FREE(sbuf);
319287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellerror1:
320287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return NULL;
321287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
322287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
323287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellstruct pipe_resource *
324287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellsvga_user_buffer_create(struct pipe_screen *screen,
325287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                        void *ptr,
326287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                        unsigned bytes,
327287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell			unsigned bind)
328287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell{
329287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct svga_buffer *sbuf;
330287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
331287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf = CALLOC_STRUCT(svga_buffer);
332287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   if(!sbuf)
333287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      goto no_sbuf;
334287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
335287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_reference_init(&sbuf->b.b.reference, 1);
336287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.vtbl = &svga_buffer_vtbl;
337287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.screen = screen;
338287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
339a2a01853f3f40b4ef8b3f01503391877960bdaeeBrian Paul   sbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
340287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.bind = bind;
341287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.width0 = bytes;
342287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.height0 = 1;
343287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->b.b.depth0 = 1;
344287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
345287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->swbuf = ptr;
346287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   sbuf->user = TRUE;
347287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
348287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return &sbuf->b.b;
349287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
350287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwellno_sbuf:
351287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   return NULL;
352287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell}
353287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
354287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
355287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
356