mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 03:10:09 +01:00
r600g: move the low-level buffer functions for multiple rings to drivers/radeon
Also slightly optimize r600_buffer_map_sync_with_rings.
This commit is contained in:
parent
1bb77f81db
commit
ef6680d3ee
11 changed files with 87 additions and 88 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue