1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
24 **********************************************************/
28 #include "pipe/p_state.h"
29 #include "pipe/p_defines.h"
30 #include "util/u_inlines.h"
31 #include "os/os_thread.h"
32 #include "util/u_math.h"
33 #include "util/u_memory.h"
35 #include "svga_context.h"
36 #include "svga_screen.h"
37 #include "svga_screen_buffer.h"
38 #include "svga_winsys.h"
39 #include "svga_debug.h"
43 * Vertex and index buffers have to be treated slightly differently from
44 * regular guest memory regions because the SVGA device sees them as
45 * surfaces, and the state tracker can create/destroy without the pipe
46 * driver, therefore we must do the uploads from the vws.
49 svga_buffer_needs_hw_storage(unsigned usage
)
51 return usage
& (PIPE_BUFFER_USAGE_VERTEX
| PIPE_BUFFER_USAGE_INDEX
);
55 static INLINE
enum pipe_error
56 svga_buffer_create_host_surface(struct svga_screen
*ss
,
57 struct svga_buffer
*sbuf
)
62 sbuf
->key
.format
= SVGA3D_BUFFER
;
63 if(sbuf
->base
.usage
& PIPE_BUFFER_USAGE_VERTEX
)
64 sbuf
->key
.flags
|= SVGA3D_SURFACE_HINT_VERTEXBUFFER
;
65 if(sbuf
->base
.usage
& PIPE_BUFFER_USAGE_INDEX
)
66 sbuf
->key
.flags
|= SVGA3D_SURFACE_HINT_INDEXBUFFER
;
68 sbuf
->key
.size
.width
= sbuf
->base
.size
;
69 sbuf
->key
.size
.height
= 1;
70 sbuf
->key
.size
.depth
= 1;
72 sbuf
->key
.numFaces
= 1;
73 sbuf
->key
.numMipLevels
= 1;
74 sbuf
->key
.cachable
= 1;
76 SVGA_DBG(DEBUG_DMA
, "surface_create for buffer sz %d\n", sbuf
->base
.size
);
78 sbuf
->handle
= svga_screen_surface_create(ss
, &sbuf
->key
);
80 return PIPE_ERROR_OUT_OF_MEMORY
;
82 /* Always set the discard flag on the first time the buffer is written
83 * as svga_screen_surface_create might have passed a recycled host
86 sbuf
->dma
.flags
.discard
= TRUE
;
88 SVGA_DBG(DEBUG_DMA
, " --> got sid %p sz %d (buffer)\n", sbuf
->handle
, sbuf
->base
.size
);
96 svga_buffer_destroy_host_surface(struct svga_screen
*ss
,
97 struct svga_buffer
*sbuf
)
100 SVGA_DBG(DEBUG_DMA
, " ungrab sid %p sz %d\n", sbuf
->handle
, sbuf
->base
.size
);
101 svga_screen_surface_destroy(ss
, &sbuf
->key
, &sbuf
->handle
);
107 svga_buffer_destroy_hw_storage(struct svga_screen
*ss
, struct svga_buffer
*sbuf
)
109 struct svga_winsys_screen
*sws
= ss
->sws
;
111 assert(!sbuf
->map
.count
);
114 sws
->buffer_destroy(sws
, sbuf
->hwbuf
);
119 struct svga_winsys_buffer
*
120 svga_winsys_buffer_create( struct svga_screen
*ss
,
125 struct svga_winsys_screen
*sws
= ss
->sws
;
126 struct svga_winsys_buffer
*buf
;
129 buf
= sws
->buffer_create(sws
, alignment
, usage
, size
);
132 SVGA_DBG(DEBUG_DMA
|DEBUG_PERF
, "flushing screen to find %d bytes GMR\n",
135 /* Try flushing all pending DMAs */
136 svga_screen_flush(ss
, NULL
);
137 buf
= sws
->buffer_create(sws
, alignment
, usage
, size
);
146 * Allocate DMA'ble storage for the buffer.
148 * Called before mapping a buffer.
150 static INLINE
enum pipe_error
151 svga_buffer_create_hw_storage(struct svga_screen
*ss
,
152 struct svga_buffer
*sbuf
)
155 unsigned alignment
= sbuf
->base
.alignment
;
157 unsigned size
= sbuf
->base
.size
;
159 sbuf
->hwbuf
= svga_winsys_buffer_create(ss
, alignment
, usage
, size
);
161 return PIPE_ERROR_OUT_OF_MEMORY
;
163 assert(!sbuf
->dma
.pending
);
171 * Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank.
173 static enum pipe_error
174 svga_buffer_upload_command(struct svga_context
*svga
,
175 struct svga_buffer
*sbuf
)
177 struct svga_winsys_context
*swc
= svga
->swc
;
178 struct svga_winsys_buffer
*guest
= sbuf
->hwbuf
;
179 struct svga_winsys_surface
*host
= sbuf
->handle
;
180 SVGA3dTransferType transfer
= SVGA3D_WRITE_HOST_VRAM
;
181 SVGA3dCmdSurfaceDMA
*cmd
;
182 uint32 numBoxes
= sbuf
->map
.num_ranges
;
183 SVGA3dCopyBox
*boxes
;
184 SVGA3dCmdSurfaceDMASuffix
*pSuffix
;
185 unsigned region_flags
;
186 unsigned surface_flags
;
187 struct pipe_buffer
*dummy
;
189 if(transfer
== SVGA3D_WRITE_HOST_VRAM
) {
190 region_flags
= PIPE_BUFFER_USAGE_GPU_READ
;
191 surface_flags
= PIPE_BUFFER_USAGE_GPU_WRITE
;
193 else if(transfer
== SVGA3D_READ_HOST_VRAM
) {
194 region_flags
= PIPE_BUFFER_USAGE_GPU_WRITE
;
195 surface_flags
= PIPE_BUFFER_USAGE_GPU_READ
;
199 return PIPE_ERROR_BAD_INPUT
;
204 cmd
= SVGA3D_FIFOReserve(swc
,
205 SVGA_3D_CMD_SURFACE_DMA
,
206 sizeof *cmd
+ numBoxes
* sizeof *boxes
+ sizeof *pSuffix
,
209 return PIPE_ERROR_OUT_OF_MEMORY
;
211 swc
->region_relocation(swc
, &cmd
->guest
.ptr
, guest
, 0, region_flags
);
212 cmd
->guest
.pitch
= 0;
214 swc
->surface_relocation(swc
, &cmd
->host
.sid
, host
, surface_flags
);
216 cmd
->host
.mipmap
= 0;
218 cmd
->transfer
= transfer
;
220 sbuf
->dma
.boxes
= (SVGA3dCopyBox
*)&cmd
[1];
221 sbuf
->dma
.svga
= svga
;
223 /* Increment reference count */
225 pipe_buffer_reference(&dummy
, &sbuf
->base
);
227 pSuffix
= (SVGA3dCmdSurfaceDMASuffix
*)((uint8_t*)cmd
+ sizeof *cmd
+ numBoxes
* sizeof *boxes
);
228 pSuffix
->suffixSize
= sizeof *pSuffix
;
229 pSuffix
->maximumOffset
= sbuf
->base
.size
;
230 pSuffix
->flags
= sbuf
->dma
.flags
;
232 SVGA_FIFOCommitAll(swc
);
234 sbuf
->dma
.flags
.discard
= FALSE
;
241 * Patch up the upload DMA command reserved by svga_buffer_upload_command
242 * with the final ranges.
245 svga_buffer_upload_flush(struct svga_context
*svga
,
246 struct svga_buffer
*sbuf
)
248 SVGA3dCopyBox
*boxes
;
251 assert(sbuf
->handle
);
253 assert(sbuf
->map
.num_ranges
);
254 assert(sbuf
->dma
.svga
== svga
);
255 assert(sbuf
->dma
.boxes
);
258 * Patch the DMA command with the final copy box.
261 SVGA_DBG(DEBUG_DMA
, "dma to sid %p\n", sbuf
->handle
);
263 boxes
= sbuf
->dma
.boxes
;
264 for(i
= 0; i
< sbuf
->map
.num_ranges
; ++i
) {
265 SVGA_DBG(DEBUG_DMA
, " bytes %u - %u\n",
266 sbuf
->map
.ranges
[i
].start
, sbuf
->map
.ranges
[i
].end
);
268 boxes
[i
].x
= sbuf
->map
.ranges
[i
].start
;
271 boxes
[i
].w
= sbuf
->map
.ranges
[i
].end
- sbuf
->map
.ranges
[i
].start
;
274 boxes
[i
].srcx
= sbuf
->map
.ranges
[i
].start
;
279 sbuf
->map
.num_ranges
= 0;
281 assert(sbuf
->head
.prev
&& sbuf
->head
.next
);
282 LIST_DEL(&sbuf
->head
);
284 sbuf
->head
.next
= sbuf
->head
.prev
= NULL
;
286 sbuf
->dma
.pending
= FALSE
;
288 sbuf
->dma
.svga
= NULL
;
289 sbuf
->dma
.boxes
= NULL
;
291 /* Decrement reference count */
292 pipe_reference(&(sbuf
->base
.reference
), NULL
);
298 * Note a dirty range.
300 * This function only notes the range down. It doesn't actually emit a DMA
301 * upload command. That only happens when a context tries to refer to this
302 * buffer, and the DMA upload command is added to that context's command buffer.
304 * We try to lump as many contiguous DMA transfers together as possible.
307 svga_buffer_add_range(struct svga_buffer
*sbuf
,
312 unsigned nearest_range
;
313 unsigned nearest_dist
;
317 if (sbuf
->map
.num_ranges
< SVGA_BUFFER_MAX_RANGES
) {
318 nearest_range
= sbuf
->map
.num_ranges
;
321 nearest_range
= SVGA_BUFFER_MAX_RANGES
- 1;
326 * Try to grow one of the ranges.
328 * Note that it is not this function task to care about overlapping ranges,
329 * as the GMR was already given so it is too late to do anything. Situations
330 * where overlapping ranges may pose a problem should be detected via
331 * pipe_context::is_buffer_referenced and the context that refers to the
332 * buffer should be flushed.
335 for(i
= 0; i
< sbuf
->map
.num_ranges
; ++i
) {
340 left_dist
= start
- sbuf
->map
.ranges
[i
].end
;
341 right_dist
= sbuf
->map
.ranges
[i
].start
- end
;
342 dist
= MAX2(left_dist
, right_dist
);
346 * Ranges are contiguous or overlapping -- extend this one and return.
349 sbuf
->map
.ranges
[i
].start
= MIN2(sbuf
->map
.ranges
[i
].start
, start
);
350 sbuf
->map
.ranges
[i
].end
= MAX2(sbuf
->map
.ranges
[i
].end
, end
);
355 * Discontiguous ranges -- keep track of the nearest range.
358 if (dist
< nearest_dist
) {
366 * We cannot add a new range to an existing DMA command, so patch-up the
367 * pending DMA upload and start clean.
370 if(sbuf
->dma
.pending
)
371 svga_buffer_upload_flush(sbuf
->dma
.svga
, sbuf
);
373 assert(!sbuf
->dma
.pending
);
374 assert(!sbuf
->dma
.svga
);
375 assert(!sbuf
->dma
.boxes
);
377 if (sbuf
->map
.num_ranges
< SVGA_BUFFER_MAX_RANGES
) {
382 sbuf
->map
.ranges
[sbuf
->map
.num_ranges
].start
= start
;
383 sbuf
->map
.ranges
[sbuf
->map
.num_ranges
].end
= end
;
384 ++sbuf
->map
.num_ranges
;
387 * Everything else failed, so just extend the nearest range.
389 * It is OK to do this because we always keep a local copy of the
390 * host buffer data, for SW TNL, and the host never modifies the buffer.
393 assert(nearest_range
< SVGA_BUFFER_MAX_RANGES
);
394 assert(nearest_range
< sbuf
->map
.num_ranges
);
395 sbuf
->map
.ranges
[nearest_range
].start
= MIN2(sbuf
->map
.ranges
[nearest_range
].start
, start
);
396 sbuf
->map
.ranges
[nearest_range
].end
= MAX2(sbuf
->map
.ranges
[nearest_range
].end
, end
);
402 svga_buffer_map_range( struct pipe_screen
*screen
,
403 struct pipe_buffer
*buf
,
404 unsigned offset
, unsigned length
,
407 struct svga_screen
*ss
= svga_screen(screen
);
408 struct svga_winsys_screen
*sws
= ss
->sws
;
409 struct svga_buffer
*sbuf
= svga_buffer( buf
);
412 if (!sbuf
->swbuf
&& !sbuf
->hwbuf
) {
413 if (svga_buffer_create_hw_storage(ss
, sbuf
) != PIPE_OK
) {
415 * We can't create a hardware buffer big enough, so create a malloc
419 debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
421 (sbuf
->base
.size
+ 1023)/1024);
423 sbuf
->swbuf
= align_malloc(sbuf
->base
.size
, sbuf
->base
.alignment
);
428 /* User/malloc buffer */
431 else if (sbuf
->hwbuf
) {
432 map
= sws
->buffer_map(sws
, sbuf
->hwbuf
, usage
);
439 pipe_mutex_lock(ss
->swc_mutex
);
443 if (usage
& PIPE_BUFFER_USAGE_CPU_WRITE
) {
444 assert(sbuf
->map
.count
<= 1);
445 sbuf
->map
.writing
= TRUE
;
446 if (usage
& PIPE_BUFFER_USAGE_FLUSH_EXPLICIT
)
447 sbuf
->map
.flush_explicit
= TRUE
;
450 pipe_mutex_unlock(ss
->swc_mutex
);
457 svga_buffer_flush_mapped_range( struct pipe_screen
*screen
,
458 struct pipe_buffer
*buf
,
459 unsigned offset
, unsigned length
)
461 struct svga_buffer
*sbuf
= svga_buffer( buf
);
462 struct svga_screen
*ss
= svga_screen(screen
);
464 pipe_mutex_lock(ss
->swc_mutex
);
465 assert(sbuf
->map
.writing
);
466 if(sbuf
->map
.writing
) {
467 assert(sbuf
->map
.flush_explicit
);
468 svga_buffer_add_range(sbuf
, offset
, offset
+ length
);
470 pipe_mutex_unlock(ss
->swc_mutex
);
474 svga_buffer_unmap( struct pipe_screen
*screen
,
475 struct pipe_buffer
*buf
)
477 struct svga_screen
*ss
= svga_screen(screen
);
478 struct svga_winsys_screen
*sws
= ss
->sws
;
479 struct svga_buffer
*sbuf
= svga_buffer( buf
);
481 pipe_mutex_lock(ss
->swc_mutex
);
483 assert(sbuf
->map
.count
);
488 sws
->buffer_unmap(sws
, sbuf
->hwbuf
);
490 if(sbuf
->map
.writing
) {
491 if(!sbuf
->map
.flush_explicit
) {
492 /* No mapped range was flushed -- flush the whole buffer */
493 SVGA_DBG(DEBUG_DMA
, "flushing the whole buffer\n");
495 svga_buffer_add_range(sbuf
, 0, sbuf
->base
.size
);
498 sbuf
->map
.writing
= FALSE
;
499 sbuf
->map
.flush_explicit
= FALSE
;
502 pipe_mutex_unlock(ss
->swc_mutex
);
506 svga_buffer_destroy( struct pipe_buffer
*buf
)
508 struct svga_screen
*ss
= svga_screen(buf
->screen
);
509 struct svga_buffer
*sbuf
= svga_buffer( buf
);
511 assert(!p_atomic_read(&buf
->reference
.count
));
513 assert(!sbuf
->dma
.pending
);
516 svga_buffer_destroy_host_surface(ss
, sbuf
);
519 svga_buffer_destroy_hw_storage(ss
, sbuf
);
521 if(sbuf
->swbuf
&& !sbuf
->user
)
522 align_free(sbuf
->swbuf
);
527 static struct pipe_buffer
*
528 svga_buffer_create(struct pipe_screen
*screen
,
533 struct svga_screen
*ss
= svga_screen(screen
);
534 struct svga_buffer
*sbuf
;
539 sbuf
= CALLOC_STRUCT(svga_buffer
);
543 sbuf
->magic
= SVGA_BUFFER_MAGIC
;
545 pipe_reference_init(&sbuf
->base
.reference
, 1);
546 sbuf
->base
.screen
= screen
;
547 sbuf
->base
.alignment
= alignment
;
548 sbuf
->base
.usage
= usage
;
549 sbuf
->base
.size
= size
;
551 if(svga_buffer_needs_hw_storage(usage
)) {
552 if(svga_buffer_create_host_surface(ss
, sbuf
) != PIPE_OK
)
556 if(alignment
< sizeof(void*))
557 alignment
= sizeof(void*);
559 usage
|= PIPE_BUFFER_USAGE_CPU_READ_WRITE
;
561 sbuf
->swbuf
= align_malloc(size
, alignment
);
574 static struct pipe_buffer
*
575 svga_user_buffer_create(struct pipe_screen
*screen
,
579 struct svga_buffer
*sbuf
;
581 sbuf
= CALLOC_STRUCT(svga_buffer
);
585 sbuf
->magic
= SVGA_BUFFER_MAGIC
;
590 pipe_reference_init(&sbuf
->base
.reference
, 1);
591 sbuf
->base
.screen
= screen
;
592 sbuf
->base
.alignment
= 1;
593 sbuf
->base
.usage
= 0;
594 sbuf
->base
.size
= bytes
;
604 svga_screen_init_buffer_functions(struct pipe_screen
*screen
)
606 screen
->buffer_create
= svga_buffer_create
;
607 screen
->user_buffer_create
= svga_user_buffer_create
;
608 screen
->buffer_map_range
= svga_buffer_map_range
;
609 screen
->buffer_flush_mapped_range
= svga_buffer_flush_mapped_range
;
610 screen
->buffer_unmap
= svga_buffer_unmap
;
611 screen
->buffer_destroy
= svga_buffer_destroy
;
616 * Copy the contents of the user buffer / malloc buffer to a hardware buffer.
618 static INLINE
enum pipe_error
619 svga_buffer_update_hw(struct svga_screen
*ss
, struct svga_buffer
*sbuf
)
629 ret
= svga_buffer_create_hw_storage(ss
, sbuf
);
633 pipe_mutex_lock(ss
->swc_mutex
);
634 map
= ss
->sws
->buffer_map(ss
->sws
, sbuf
->hwbuf
, PIPE_BUFFER_USAGE_CPU_WRITE
);
637 pipe_mutex_unlock(ss
->swc_mutex
);
638 svga_buffer_destroy_hw_storage(ss
, sbuf
);
642 memcpy(map
, sbuf
->swbuf
, sbuf
->base
.size
);
643 ss
->sws
->buffer_unmap(ss
->sws
, sbuf
->hwbuf
);
645 /* This user/malloc buffer is now indistinguishable from a gpu buffer */
646 assert(!sbuf
->map
.count
);
647 if(!sbuf
->map
.count
) {
651 align_free(sbuf
->swbuf
);
655 pipe_mutex_unlock(ss
->swc_mutex
);
663 * Upload the buffer to the host in a piecewise fashion.
665 * Used when the buffer is too big to fit in the GMR aperture.
667 static INLINE
enum pipe_error
668 svga_buffer_upload_piecewise(struct svga_screen
*ss
,
669 struct svga_context
*svga
,
670 struct svga_buffer
*sbuf
)
672 struct svga_winsys_screen
*sws
= ss
->sws
;
673 const unsigned alignment
= sizeof(void *);
674 const unsigned usage
= 0;
677 assert(sbuf
->map
.num_ranges
);
678 assert(!sbuf
->dma
.pending
);
680 SVGA_DBG(DEBUG_DMA
, "dma to sid %p\n", sbuf
->handle
);
682 for (i
= 0; i
< sbuf
->map
.num_ranges
; ++i
) {
683 struct svga_buffer_range
*range
= &sbuf
->map
.ranges
[i
];
684 unsigned offset
= range
->start
;
685 unsigned size
= range
->end
- range
->start
;
687 while (offset
< range
->end
) {
688 struct svga_winsys_buffer
*hwbuf
;
692 if (offset
+ size
> range
->end
)
693 size
= range
->end
- offset
;
695 hwbuf
= svga_winsys_buffer_create(ss
, alignment
, usage
, size
);
699 return PIPE_ERROR_OUT_OF_MEMORY
;
700 hwbuf
= svga_winsys_buffer_create(ss
, alignment
, usage
, size
);
703 SVGA_DBG(DEBUG_DMA
, " bytes %u - %u\n",
704 offset
, offset
+ size
);
706 map
= sws
->buffer_map(sws
, hwbuf
,
707 PIPE_BUFFER_USAGE_CPU_WRITE
|
708 PIPE_BUFFER_USAGE_DISCARD
);
711 memcpy(map
, sbuf
->swbuf
, size
);
712 sws
->buffer_unmap(sws
, hwbuf
);
715 ret
= SVGA3D_BufferDMA(svga
->swc
,
717 SVGA3D_WRITE_HOST_VRAM
,
718 size
, offset
, sbuf
->dma
.flags
);
720 svga_context_flush(svga
, NULL
);
721 ret
= SVGA3D_BufferDMA(svga
->swc
,
723 SVGA3D_WRITE_HOST_VRAM
,
724 size
, offset
, sbuf
->dma
.flags
);
725 assert(ret
== PIPE_OK
);
728 sbuf
->dma
.flags
.discard
= FALSE
;
730 sws
->buffer_destroy(sws
, hwbuf
);
736 sbuf
->map
.num_ranges
= 0;
742 struct svga_winsys_surface
*
743 svga_buffer_handle(struct svga_context
*svga
,
744 struct pipe_buffer
*buf
)
746 struct pipe_screen
*screen
= svga
->pipe
.screen
;
747 struct svga_screen
*ss
= svga_screen(screen
);
748 struct svga_buffer
*sbuf
;
754 sbuf
= svga_buffer(buf
);
756 assert(!sbuf
->map
.count
);
759 ret
= svga_buffer_create_host_surface(ss
, sbuf
);
764 assert(sbuf
->handle
);
766 if (sbuf
->map
.num_ranges
) {
767 if (!sbuf
->dma
.pending
) {
769 * No pending DMA upload yet, so insert a DMA upload command now.
773 * Migrate the data from swbuf -> hwbuf if necessary.
775 ret
= svga_buffer_update_hw(ss
, sbuf
);
776 if (ret
== PIPE_OK
) {
778 * Queue a dma command.
781 ret
= svga_buffer_upload_command(svga
, sbuf
);
782 if (ret
== PIPE_ERROR_OUT_OF_MEMORY
) {
783 svga_context_flush(svga
, NULL
);
784 ret
= svga_buffer_upload_command(svga
, sbuf
);
785 assert(ret
== PIPE_OK
);
787 if (ret
== PIPE_OK
) {
788 sbuf
->dma
.pending
= TRUE
;
789 assert(!sbuf
->head
.prev
&& !sbuf
->head
.next
);
790 LIST_ADDTAIL(&sbuf
->head
, &svga
->dirty_buffers
);
793 else if (ret
== PIPE_ERROR_OUT_OF_MEMORY
) {
795 * The buffer is too big to fit in the GMR aperture, so break it in
798 ret
= svga_buffer_upload_piecewise(ss
, svga
, sbuf
);
801 if (ret
!= PIPE_OK
) {
803 * Something unexpected happened above. There is very little that
804 * we can do other than proceeding while ignoring the dirty ranges.
807 sbuf
->map
.num_ranges
= 0;
812 * There a pending dma already. Make sure it is from this context.
814 assert(sbuf
->dma
.svga
== svga
);
818 assert(!sbuf
->map
.num_ranges
|| sbuf
->dma
.pending
);
825 svga_screen_buffer_wrap_surface(struct pipe_screen
*screen
,
826 enum SVGA3dSurfaceFormat format
,
827 struct svga_winsys_surface
*srf
)
829 struct pipe_buffer
*buf
;
830 struct svga_buffer
*sbuf
;
831 struct svga_winsys_screen
*sws
= svga_winsys_screen(screen
);
833 buf
= svga_buffer_create(screen
, 0, SVGA_BUFFER_USAGE_WRAPPED
, 0);
837 sbuf
= svga_buffer(buf
);
840 * We are not the creator of this surface and therefore we must not
841 * cache it for reuse. Set the cacheable flag to zero in the key to
844 sbuf
->key
.format
= format
;
845 sbuf
->key
.cachable
= 0;
846 sws
->surface_reference(sws
, &sbuf
->handle
, srf
);
852 struct svga_winsys_surface
*
853 svga_screen_buffer_get_winsys_surface(struct pipe_buffer
*buffer
)
855 struct svga_winsys_screen
*sws
= svga_winsys_screen(buffer
->screen
);
856 struct svga_winsys_surface
*vsurf
= NULL
;
858 assert(svga_buffer(buffer
)->key
.cachable
== 0);
859 svga_buffer(buffer
)->key
.cachable
= 0;
860 sws
->surface_reference(sws
, &vsurf
, svga_buffer(buffer
)->handle
);
865 svga_context_flush_buffers(struct svga_context
*svga
)
867 struct list_head
*curr
, *next
;
868 struct svga_buffer
*sbuf
;
870 curr
= svga
->dirty_buffers
.next
;
872 while(curr
!= &svga
->dirty_buffers
) {
873 sbuf
= LIST_ENTRY(struct svga_buffer
, curr
, head
);
875 assert(p_atomic_read(&sbuf
->base
.reference
.count
) != 0);
876 assert(sbuf
->dma
.pending
);
878 svga_buffer_upload_flush(svga
, sbuf
);