#include "svga_debug.h"
-/* Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+/**
+ * Allocate a winsys_buffer (ie. DMA, aka GMR memory).
+ *
+ * It will flush and retry in case the first attempt to create a DMA buffer
+ * fails, so it should not be called from any function involved in flushing
+ * to avoid recursion.
*/
struct svga_winsys_buffer *
-svga_winsys_buffer_create( struct svga_screen *ss,
+svga_winsys_buffer_create( struct svga_context *svga,
unsigned alignment,
unsigned usage,
unsigned size )
{
- struct svga_winsys_screen *sws = ss->sws;
+ struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+ struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_winsys_buffer *buf;
/* Just try */
buf = sws->buffer_create(sws, alignment, usage, size);
- if(!buf) {
-
- SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing screen to find %d bytes GMR\n",
+ if (!buf) {
+ SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n",
size);
/* Try flushing all pending DMAs */
- svga_screen_flush(ss, NULL);
+ svga_context_flush(svga, NULL);
buf = sws->buffer_create(sws, alignment, usage, size);
-
}
return buf;
assert(!sbuf->user);
if(!sbuf->hwbuf) {
+ struct svga_winsys_screen *sws = ss->sws;
unsigned alignment = 16;
unsigned usage = 0;
unsigned size = sbuf->b.b.width0;
- sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ sbuf->hwbuf = sws->buffer_create(sws, alignment, usage, size);
if(!sbuf->hwbuf)
return PIPE_ERROR_OUT_OF_MEMORY;
svga_buffer_create_host_surface(struct svga_screen *ss,
struct svga_buffer *sbuf)
{
+ assert(!sbuf->user);
+
if(!sbuf->handle) {
sbuf->key.flags = 0;
* Patch up the upload DMA command reserved by svga_buffer_upload_command
* with the final ranges.
*/
-static void
+void
svga_buffer_upload_flush(struct svga_context *svga,
struct svga_buffer *sbuf)
{
SVGA3dCopyBox *boxes;
unsigned i;
+ struct pipe_resource *dummy;
+
+ if (!sbuf->dma.pending) {
+ return;
+ }
assert(sbuf->handle);
assert(sbuf->hwbuf);
sbuf->head.next = sbuf->head.prev = NULL;
#endif
sbuf->dma.pending = FALSE;
+ sbuf->dma.flags.discard = FALSE;
+ sbuf->dma.flags.unsynchronized = FALSE;
sbuf->dma.svga = NULL;
sbuf->dma.boxes = NULL;
- /* Decrement reference count */
- pipe_reference(&(sbuf->b.b.reference), NULL);
- sbuf = NULL;
+ /* Decrement reference count (and potentially destroy) */
+ dummy = &sbuf->b.b;
+ pipe_resource_reference(&dummy, NULL);
}
-
/**
* Note a dirty range.
*
/*
* Try to grow one of the ranges.
- *
- * Note that it is not this function task to care about overlapping ranges,
- * as the GMR was already given so it is too late to do anything. Situations
- * where overlapping ranges may pose a problem should be detected via
- * pipe_context::is_resource_referenced and the context that refers to the
- * buffer should be flushed.
*/
for(i = 0; i < sbuf->map.num_ranges; ++i) {
if (dist <= 0) {
/*
* Ranges are contiguous or overlapping -- extend this one and return.
+ *
+ * Note that it is not this function's task to prevent overlapping
+ * ranges, as the GMR was already given so it is too late to do
+ * anything. If the ranges overlap here it must surely be because
+ * PIPE_TRANSFER_UNSYNCHRONIZED was set.
*/
sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
* pending DMA upload and start clean.
*/
- if(sbuf->dma.pending)
- svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
+ svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
assert(!sbuf->dma.pending);
assert(!sbuf->dma.svga);
if (offset + size > range->end)
size = range->end - offset;
- hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ hwbuf = sws->buffer_create(sws, alignment, usage, size);
while (!hwbuf) {
size /= 2;
if (!size)
return PIPE_ERROR_OUT_OF_MEMORY;
- hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
+ hwbuf = sws->buffer_create(sws, alignment, usage, size);
}
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
next = curr->next;
}
}
+
+
+void
+svga_redefine_user_buffer(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned offset,
+ unsigned size)
+{
+ struct svga_buffer *sbuf = svga_buffer(resource);
+
+ assert(sbuf->user);
+ assert(!sbuf->dma.pending);
+ assert(!sbuf->handle);
+ assert(!sbuf->hwbuf);
+
+ /*
+ * We always treat the contents of user-buffers as volatile,
+ * so no particular action needed here.
+ */
+
+}