r600g: move the low-level buffer functions for multiple rings to drivers/radeon
authorMarek Olšák <marek.olsak@amd.com>
Mon, 23 Sep 2013 00:37:05 +0000 (02:37 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 29 Sep 2013 13:18:09 +0000 (15:18 +0200)
Also slightly optimize r600_buffer_map_sync_with_rings.

src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_query.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_pipe_common.h

index 581fd0e5e87b3bf726c53c002ffdb0db8f6474e6..3cd14fc8291b7fbfd51ae847b887c7cefc4bb808 100644 (file)
@@ -2415,7 +2415,7 @@ void *r600_create_vertex_fetch_shader(struct pipe_context *ctx,
                return NULL;
        }
 
-       bytecode = r600_buffer_mmap_sync_with_rings(rctx, shader->buffer, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED);
+       bytecode = r600_buffer_map_sync_with_rings(&rctx->b, shader->buffer, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED);
        bytecode += shader->offset / 4;
 
        if (R600_BIG_ENDIAN) {
index d240c292f12bbda42161c92405bca68361f8e7f7..20faabd4b4e9bf780a4a29397a1897c9f0cb9808 100644 (file)
@@ -649,7 +649,7 @@ static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *ds
                /* Flush again in case the 3D engine has been prefetching the resource. */
                r600_flag_resource_cache_flush(rctx, dst);
        } else {
-               uint32_t *map = r600_buffer_mmap_sync_with_rings(rctx, r600_resource(dst),
+               uint32_t *map = r600_buffer_map_sync_with_rings(&rctx->b, r600_resource(dst),
                                                                 PIPE_TRANSFER_WRITE);
                size /= 4;
                for (unsigned i = 0; i < size; i++)
index 7fdd2ad9a55c62e791e91213f0eadd489e4037bf..8fe78c3f5219fe4d6c327800c610643d3b5a9370 100644 (file)
@@ -112,7 +112,7 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
                assert(usage & PIPE_TRANSFER_WRITE);
 
                /* Check if mapping this buffer would cause waiting for the GPU. */
-               if (r600_rings_is_buffer_referenced(rctx, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
+               if (r600_rings_is_buffer_referenced(&rctx->b, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
                    rctx->b.ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
                        unsigned i, mask;
 
@@ -158,7 +158,7 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
                assert(usage & PIPE_TRANSFER_WRITE);
 
                /* Check if mapping this buffer would cause waiting for the GPU. */
-               if (r600_rings_is_buffer_referenced(rctx, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
+               if (r600_rings_is_buffer_referenced(&rctx->b, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
                    rctx->b.ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
                        /* Do a wait-free write-only transfer using a temporary buffer. */
                        unsigned offset;
@@ -176,7 +176,7 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
        }
 
        /* mmap and synchronize with rings */
-       data = r600_buffer_mmap_sync_with_rings(rctx, rbuffer, usage);
+       data = r600_buffer_map_sync_with_rings(&rctx->b, rbuffer, usage);
        if (!data) {
                return NULL;
        }
index 3714cd7be37cdb45f3a7fb48987209032efccd9f..d8ae30cbddefabec42ca00fc40c83bdf945dc2c2 100644 (file)
@@ -75,7 +75,7 @@ void r600_get_backend_mask(struct r600_context *ctx)
        va = r600_resource_va(&ctx->screen->b.b, (void*)buffer);
 
        /* initialize buffer with zeroes */
-       results = r600_buffer_mmap_sync_with_rings(ctx, buffer, PIPE_TRANSFER_WRITE);
+       results = r600_buffer_map_sync_with_rings(&ctx->b, buffer, PIPE_TRANSFER_WRITE);
        if (results) {
                memset(results, 0, ctx->max_db * 4 * 4);
                ctx->b.ws->buffer_unmap(buffer->cs_buf);
@@ -90,7 +90,7 @@ void r600_get_backend_mask(struct r600_context *ctx)
                cs->buf[cs->cdw++] = r600_context_bo_reloc(&ctx->b, &ctx->b.rings.gfx, buffer, RADEON_USAGE_WRITE);
 
                /* analyze results */
-               results = r600_buffer_mmap_sync_with_rings(ctx, buffer, PIPE_TRANSFER_READ);
+               results = r600_buffer_map_sync_with_rings(&ctx->b, buffer, PIPE_TRANSFER_READ);
                if (results) {
                        for(i = 0; i < ctx->max_db; i++) {
                                /* at least highest bit will be set if backend is used */
index 87581b42e245e9b5844d97ef30d8468c3ee2c0da..8ee9487c5851f98f3158948c54282e455fc57ae8 100644 (file)
@@ -84,7 +84,7 @@ static struct r600_fence *r600_create_fence(struct r600_context *rctx)
                        R600_ERR("r600: failed to create bo for fence objects\n");
                        goto out;
                }
-               rscreen->fences.data = r600_buffer_mmap_sync_with_rings(rctx, rscreen->fences.bo, PIPE_TRANSFER_READ_WRITE);
+               rscreen->fences.data = r600_buffer_map_sync_with_rings(&rctx->b, rscreen->fences.bo, PIPE_TRANSFER_READ_WRITE);
        }
 
        if (!LIST_IS_EMPTY(&rscreen->fences.pool)) {
@@ -213,73 +213,6 @@ static void r600_flush_dma_ring(void *ctx, unsigned flags)
        rctx->b.rings.dma.flushing = false;
 }
 
-boolean r600_rings_is_buffer_referenced(struct r600_context *ctx,
-                                       struct radeon_winsys_cs_handle *buf,
-                                       enum radeon_bo_usage usage)
-{
-       if (ctx->b.ws->cs_is_buffer_referenced(ctx->b.rings.gfx.cs, buf, usage)) {
-               return TRUE;
-       }
-       if (ctx->b.rings.dma.cs) {
-               if (ctx->b.ws->cs_is_buffer_referenced(ctx->b.rings.dma.cs, buf, usage)) {
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-void *r600_buffer_mmap_sync_with_rings(struct r600_context *ctx,
-                                       struct r600_resource *resource,
-                                       unsigned usage)
-{
-       enum radeon_bo_usage rusage = RADEON_USAGE_READWRITE;
-       unsigned flags = 0;
-       bool sync_flush = TRUE;
-
-       if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
-               return ctx->b.ws->buffer_map(resource->cs_buf, NULL, usage);
-       }
-
-       if (!(usage & PIPE_TRANSFER_WRITE)) {
-               /* have to wait for pending read */
-               rusage = RADEON_USAGE_WRITE;
-       }
-       if (usage & PIPE_TRANSFER_DONTBLOCK) {
-               flags |= RADEON_FLUSH_ASYNC;
-       }
-
-       if (ctx->b.ws->cs_is_buffer_referenced(ctx->b.rings.gfx.cs, resource->cs_buf, rusage) && ctx->b.rings.gfx.cs->cdw) {
-               ctx->b.rings.gfx.flush(ctx, flags);
-               if (usage & PIPE_TRANSFER_DONTBLOCK) {
-                       return NULL;
-               }
-       }
-       if (ctx->b.rings.dma.cs) {
-               if (ctx->b.ws->cs_is_buffer_referenced(ctx->b.rings.dma.cs, resource->cs_buf, rusage) && ctx->b.rings.dma.cs->cdw) {
-                       ctx->b.rings.dma.flush(ctx, flags);
-                       if (usage & PIPE_TRANSFER_DONTBLOCK) {
-                               return NULL;
-                       }
-               }
-       }
-
-       if (usage & PIPE_TRANSFER_DONTBLOCK) {
-               if (ctx->b.ws->buffer_is_busy(resource->buf, rusage)) {
-                       return NULL;
-               }
-       }
-       if (sync_flush) {
-               /* Try to avoid busy-waiting in radeon_bo_wait. */
-               ctx->b.ws->cs_sync_flush(ctx->b.rings.gfx.cs);
-               if (ctx->b.rings.dma.cs) {
-                       ctx->b.ws->cs_sync_flush(ctx->b.rings.dma.cs);
-               }
-       }
-
-       /* at this point everything is synchronized */
-       return ctx->b.ws->buffer_map(resource->cs_buf, NULL, usage);
-}
-
 static void r600_flush_from_winsys(void *ctx, unsigned flags)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
index 80a96ca71d4b152d698af0956cad831008c73292..dc8274bf54d265b4aa5bc94d5afa25c99ba5d60e 100644 (file)
@@ -637,12 +637,6 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
                                         unsigned alignment);
 
 /* r600_pipe.c */
-boolean r600_rings_is_buffer_referenced(struct r600_context *ctx,
-                                       struct radeon_winsys_cs_handle *buf,
-                                       enum radeon_bo_usage usage);
-void *r600_buffer_mmap_sync_with_rings(struct r600_context *ctx,
-                                       struct r600_resource *resource,
-                                       unsigned usage);
 const char * r600_llvm_gpu_string(enum radeon_family family);
 
 
index 457c9ad39038c6a9ad19ef6005aa0f0407eaa8ae..b9ff6a621550194fad50d95de9fc376678098a9a 100644 (file)
@@ -62,7 +62,7 @@ static struct r600_resource *r600_new_query_buffer(struct r600_context *ctx, uns
        switch (type) {
        case PIPE_QUERY_OCCLUSION_COUNTER:
        case PIPE_QUERY_OCCLUSION_PREDICATE:
-               results = r600_buffer_mmap_sync_with_rings(ctx, buf, PIPE_TRANSFER_WRITE);
+               results = r600_buffer_map_sync_with_rings(&ctx->b, buf, PIPE_TRANSFER_WRITE);
                memset(results, 0, buf_size);
 
                /* Set top bits for unused backends. */
@@ -86,7 +86,7 @@ static struct r600_resource *r600_new_query_buffer(struct r600_context *ctx, uns
        case PIPE_QUERY_SO_STATISTICS:
        case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
        case PIPE_QUERY_PIPELINE_STATISTICS:
-               results = r600_buffer_mmap_sync_with_rings(ctx, buf, PIPE_TRANSFER_WRITE);
+               results = r600_buffer_map_sync_with_rings(&ctx->b, buf, PIPE_TRANSFER_WRITE);
                memset(results, 0, buf_size);
                ctx->b.ws->buffer_unmap(buf->cs_buf);
                break;
@@ -415,7 +415,7 @@ static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
        }
 
        /* Obtain a new buffer if the current one can't be mapped without a stall. */
-       if (r600_rings_is_buffer_referenced(rctx, rquery->buffer.buf->cs_buf, RADEON_USAGE_READWRITE) ||
+       if (r600_rings_is_buffer_referenced(&rctx->b, rquery->buffer.buf->cs_buf, RADEON_USAGE_READWRITE) ||
            rctx->b.ws->buffer_is_busy(rquery->buffer.buf->buf, RADEON_USAGE_READWRITE)) {
                pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL);
                rquery->buffer.buf = r600_new_query_buffer(rctx, rquery->type);
@@ -496,7 +496,7 @@ static boolean r600_get_query_buffer_result(struct r600_context *ctx,
                return TRUE;
        }
 
-       map = r600_buffer_mmap_sync_with_rings(ctx, qbuf->buf,
+       map = r600_buffer_map_sync_with_rings(&ctx->b, qbuf->buf,
                                                PIPE_TRANSFER_READ |
                                                (wait ? 0 : PIPE_TRANSFER_DONTBLOCK));
        if (!map)
index 71818c7f0dc996070e7d006abddd1a2746a3649f..80cdcd500f69cf0bcf33c5bfd64c434f6064645a 100644 (file)
@@ -164,7 +164,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
                if (shader->bo == NULL) {
                        return -ENOMEM;
                }
-               ptr = r600_buffer_mmap_sync_with_rings(rctx, shader->bo, PIPE_TRANSFER_WRITE);
+               ptr = r600_buffer_map_sync_with_rings(&rctx->b, shader->bo, PIPE_TRANSFER_WRITE);
                if (R600_BIG_ENDIAN) {
                        for (i = 0; i < shader->shader.bc.ndw; ++i) {
                                ptr[i] = util_bswap32(shader->shader.bc.bytecode[i]);
index 481c6543923825523346e8095f5024ed06d4fbef..d505d6b6f82705e4d6c746203ca84230abaf352d 100644 (file)
@@ -791,7 +791,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
 
        /* Use a staging texture for uploads if the underlying BO is busy. */
        if (!(usage & PIPE_TRANSFER_READ) &&
-           (r600_rings_is_buffer_referenced(rctx, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
+           (r600_rings_is_buffer_referenced(&rctx->b, rtex->resource.cs_buf, RADEON_USAGE_READWRITE) ||
             rctx->b.ws->buffer_is_busy(rtex->resource.buf, RADEON_USAGE_READWRITE))) {
                use_staging_texture = TRUE;
        }
@@ -898,7 +898,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
                buf = &rtex->resource;
        }
 
-       if (!(map = r600_buffer_mmap_sync_with_rings(rctx, buf, usage))) {
+       if (!(map = r600_buffer_map_sync_with_rings(&rctx->b, buf, usage))) {
                pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL);
                FREE(trans);
                return NULL;
index 06484553b0241bea3b30277a71f002c7f77859f5..8f0798a03ecdc0c1bf0ef1970548005e79a2a03d 100644 (file)
@@ -271,3 +271,69 @@ void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_re
        rscreen->aux_context->flush(rscreen->aux_context, NULL, 0);
        pipe_mutex_unlock(rscreen->aux_context_lock);
 }
+
+boolean r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
+                                       struct radeon_winsys_cs_handle *buf,
+                                       enum radeon_bo_usage usage)
+{
+       if (ctx->ws->cs_is_buffer_referenced(ctx->rings.gfx.cs, buf, usage)) {
+               return TRUE;
+       }
+       if (ctx->rings.dma.cs &&
+           ctx->ws->cs_is_buffer_referenced(ctx->rings.dma.cs, buf, usage)) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
+                                      struct r600_resource *resource,
+                                      unsigned usage)
+{
+       enum radeon_bo_usage rusage = RADEON_USAGE_READWRITE;
+
+       if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
+               return ctx->ws->buffer_map(resource->cs_buf, NULL, usage);
+       }
+
+       if (!(usage & PIPE_TRANSFER_WRITE)) {
+               /* have to wait for the last write */
+               rusage = RADEON_USAGE_WRITE;
+       }
+
+       if (ctx->rings.gfx.cs->cdw &&
+           ctx->ws->cs_is_buffer_referenced(ctx->rings.gfx.cs,
+                                            resource->cs_buf, rusage)) {
+               if (usage & PIPE_TRANSFER_DONTBLOCK) {
+                       ctx->rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC);
+                       return NULL;
+               } else {
+                       ctx->rings.gfx.flush(ctx, 0);
+               }
+       }
+       if (ctx->rings.dma.cs &&
+           ctx->rings.dma.cs->cdw &&
+           ctx->ws->cs_is_buffer_referenced(ctx->rings.dma.cs,
+                                            resource->cs_buf, rusage)) {
+               if (usage & PIPE_TRANSFER_DONTBLOCK) {
+                       ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC);
+                       return NULL;
+               } else {
+                       ctx->rings.dma.flush(ctx, 0);
+               }
+       }
+
+       if (ctx->ws->buffer_is_busy(resource->buf, rusage)) {
+               if (usage & PIPE_TRANSFER_DONTBLOCK) {
+                       return NULL;
+               } else {
+                       /* We will be wait for the GPU. Wait for any offloaded
+                        * CS flush to complete to avoid busy-waiting in the winsys. */
+                       ctx->ws->cs_sync_flush(ctx->rings.gfx.cs);
+                       if (ctx->rings.dma.cs)
+                               ctx->ws->cs_sync_flush(ctx->rings.dma.cs);
+               }
+       }
+
+       return ctx->ws->buffer_map(resource->cs_buf, NULL, usage);
+}
index e5e79b08d6168307cac91ff0804556daf69e7b47..84fdff1847eef8854ec32df3ebec87b806f62c16 100644 (file)
@@ -257,6 +257,12 @@ bool r600_can_dump_shader(struct r600_common_screen *rscreen,
                          const struct tgsi_token *tokens);
 void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_resource *dst,
                              unsigned offset, unsigned size, unsigned value);
+boolean r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
+                                       struct radeon_winsys_cs_handle *buf,
+                                       enum radeon_bo_usage usage);
+void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
+                                      struct r600_resource *resource,
+                                      unsigned usage);
 
 /* r600_streamout.c */
 void r600_streamout_buffers_dirty(struct r600_common_context *rctx);