#include "svga_debug.h"
-#define MAX_DMA_SIZE (4 * 1024 * 1024)
-
-
/**
* Allocate a winsys_buffer (ie. DMA, aka GMR memory).
*
struct svga_winsys_screen *sws = svgascreen->sws;
struct svga_winsys_buffer *buf;
- /* XXX this shouldn't be a hard-coded number; it should be queried
- * somehow.
- */
- if (size > MAX_DMA_SIZE) {
- return NULL;
- }
-
/* 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_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)
{
unsigned i;
struct pipe_resource *dummy;
+ if (!sbuf->dma.pending) {
+ return;
+ }
+
assert(sbuf->handle);
assert(sbuf->hwbuf);
assert(sbuf->map.num_ranges);
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;
}
-
/**
* 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);
unsigned offset,
unsigned size)
{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_context *svga = svga_context(pipe);
struct svga_buffer *sbuf = svga_buffer(resource);
assert(sbuf->user);
+ assert(!sbuf->dma.pending);
+ assert(!sbuf->handle);
+ assert(!sbuf->hwbuf);
/*
- * Release any uploaded user buffer.
- *
- * TODO: As an optimization, we could try to update the uploaded buffer
- * instead.
+ * We always treat the contents of user-buffers as volatile,
+ * so no particular action needed here.
*/
- pipe_resource_reference(&sbuf->uploaded.buffer, NULL);
-
- pipe_mutex_lock(ss->swc_mutex);
-
- if (offset + size > resource->width0) {
- /*
- * User buffers shouldn't have DMA directly, unless
- * SVGA_COMBINE_USERBUFFERS is not set.
- */
-
- if (sbuf->dma.pending) {
- svga_buffer_upload_flush(svga, sbuf);
- }
-
- if (sbuf->handle) {
- svga_buffer_destroy_host_surface(ss, sbuf);
- }
-
- if (sbuf->hwbuf) {
- svga_buffer_destroy_hw_storage(ss, sbuf);
- }
-
- sbuf->key.size.width = sbuf->b.b.width0 = offset + size;
- }
-
- pipe_mutex_unlock(ss->swc_mutex);
-
- svga->curr.any_user_vertex_buffers = TRUE;
- svga->dirty |= SVGA_NEW_VBUFFER | SVGA_NEW_VELEMENT;
}