X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_resource_buffer.c;h=6629a8cc14d96083cdb2d9a0b1a8b7d3f797a758;hb=8c9b9aac7d09e65195dca6681d59c10e4ef713d9;hp=4448b7d030867231e128b668120ff2ba33a3e26a;hpb=b549f5e6b1dfba42b96d4181116715bf218a66dc;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index 4448b7d0308..6629a8cc14d 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -42,16 +42,40 @@ /** - * Vertex and index buffers need hardware backing. Constant buffers - * do not. No other types of buffers currently supported. + * Determine what buffers eventually need hardware backing. + * + * Vertex- and index buffers need hardware backing. Constant buffers + * do on vgpu10. Staging texture-upload buffers do when they are + * supported. */ static inline boolean -svga_buffer_needs_hw_storage(unsigned usage) +svga_buffer_needs_hw_storage(const struct svga_screen *ss, + const struct pipe_resource *template) { - return (usage & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER | - PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT)) != 0; -} + unsigned bind_mask = (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER | + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT); + + if (ss->sws->have_vgpu10) { + /* + * Driver-created upload const0- and staging texture upload buffers + * tagged with PIPE_BIND_CUSTOM + */ + bind_mask |= PIPE_BIND_CUSTOM; + /* Uniform buffer objects. + * Make sure we don't create hardware storage for gallium frontend + * const0 buffers, because we frequently map them for reading. + * They are distinguished by having PIPE_USAGE_STREAM, but not + * PIPE_BIND_CUSTOM. + */ + if (template->usage != PIPE_USAGE_STREAM) + bind_mask |= PIPE_BIND_CONSTANT_BUFFER; + } + + if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) + return TRUE; + return !!(template->bind & bind_mask); +} /** * Create a buffer transfer. @@ -105,7 +129,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe, pipe_resource_reference(&sbuf->translated_indices.buffer, NULL); } - if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty) { + if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty && + !sbuf->key.coherent && !svga->swc->force_coherent) { enum pipe_error ret; /* Host-side buffers can only be dirtied with vgpu10 features @@ -117,7 +142,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe, (void) svga_buffer_handle(svga, resource, sbuf->bind_flags); } - if (sbuf->dma.pending > 0) { + if (sbuf->dma.pending) { svga_buffer_upload_flush(svga, sbuf); svga_context_finish(svga); } @@ -139,7 +164,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe, } if (usage & PIPE_TRANSFER_WRITE) { - if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { + if ((usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) && + !(resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)) { /* * Flush any pending primitives, finish writing any pending DMA * commands, and tell the host to discard the buffer contents on @@ -191,7 +217,7 @@ svga_buffer_transfer_map(struct pipe_context *pipe, /* * We have a pending DMA upload from a hardware buffer, therefore * we need to ensure that the host finishes processing that DMA - * command before the state tracker can start overwriting the + * command before the gallium frontend can start overwriting the * hardware buffer. * * XXX: This could be avoided by tying the hardware buffer to @@ -283,28 +309,30 @@ done: static void -svga_buffer_transfer_flush_region( struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) +svga_buffer_transfer_flush_region(struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) { struct svga_screen *ss = svga_screen(pipe->screen); struct svga_buffer *sbuf = svga_buffer(transfer->resource); - + struct svga_context *svga = svga_context(pipe); unsigned offset = transfer->box.x + box->x; unsigned length = box->width; assert(transfer->usage & PIPE_TRANSFER_WRITE); assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT); - mtx_lock(&ss->swc_mutex); - svga_buffer_add_range(sbuf, offset, offset + length); - mtx_unlock(&ss->swc_mutex); + if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) { + mtx_lock(&ss->swc_mutex); + svga_buffer_add_range(sbuf, offset, offset + length); + mtx_unlock(&ss->swc_mutex); + } } static void -svga_buffer_transfer_unmap( struct pipe_context *pipe, - struct pipe_transfer *transfer ) +svga_buffer_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) { struct svga_screen *ss = svga_screen(pipe->screen); struct svga_context *svga = svga_context(pipe); @@ -338,7 +366,8 @@ svga_buffer_transfer_unmap( struct pipe_context *pipe, sbuf->dma.flags.discard = TRUE; - svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0); + if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) + svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0); } } @@ -349,11 +378,11 @@ svga_buffer_transfer_unmap( struct pipe_context *pipe, static void -svga_buffer_destroy( struct pipe_screen *screen, - struct pipe_resource *buf ) +svga_buffer_destroy(struct pipe_screen *screen, + struct pipe_resource *buf) { - struct svga_screen *ss = svga_screen(screen); - struct svga_buffer *sbuf = svga_buffer( buf ); + struct svga_screen *ss = svga_screen(screen); + struct svga_buffer *sbuf = svga_buffer(buf); assert(!p_atomic_read(&buf->reference.count)); @@ -395,7 +424,7 @@ struct u_resource_vtbl svga_buffer_vtbl = struct pipe_resource * svga_buffer_create(struct pipe_screen *screen, - const struct pipe_resource *template) + const struct pipe_resource *template) { struct svga_screen *ss = svga_screen(screen); struct svga_buffer *sbuf; @@ -411,7 +440,9 @@ svga_buffer_create(struct pipe_screen *screen, sbuf->b.vtbl = &svga_buffer_vtbl; pipe_reference_init(&sbuf->b.b.reference, 1); sbuf->b.b.screen = screen; - bind_flags = template->bind; + bind_flags = template->bind & ~PIPE_BIND_CUSTOM; + + list_inithead(&sbuf->surfaces); if (bind_flags & PIPE_BIND_CONSTANT_BUFFER) { /* Constant buffers can only have the PIPE_BIND_CONSTANT_BUFFER @@ -419,28 +450,34 @@ svga_buffer_create(struct pipe_screen *screen, */ if (ss->sws->have_vgpu10) { bind_flags = PIPE_BIND_CONSTANT_BUFFER; - - /* Constant buffer size needs to be in multiples of 16. */ - sbuf->b.b.width0 = align(sbuf->b.b.width0, 16); } } - if (svga_buffer_needs_hw_storage(bind_flags)) { + /* Although svga device only requires constant buffer size to be + * in multiples of 16, in order to allow bind_flags promotion, + * we are mandating all buffer size to be in multiples of 16. + */ + sbuf->b.b.width0 = align(sbuf->b.b.width0, 16); + + if (svga_buffer_needs_hw_storage(ss, template)) { - /* If the buffer will be used for vertex/index/stream data, set all - * the flags so that the buffer will be accepted for all those uses. - * Note that the PIPE_BIND_ flags we get from the state tracker are + /* If the buffer is not used for constant buffer, set + * the vertex/index bind flags as well so that the buffer will be + * accepted for those uses. + * Note that the PIPE_BIND_ flags we get from the gallium frontend are * just a hint about how the buffer may be used. And OpenGL buffer * object may be used for many different things. + * Also note that we do not unconditionally set the streamout + * bind flag since streamout buffer is an output buffer and + * might have performance implication. */ - if (!(template->bind & PIPE_BIND_CONSTANT_BUFFER)) { - /* Not a constant buffer. The buffer may be used for vertex data, - * indexes or stream-out. + if (!(template->bind & PIPE_BIND_CONSTANT_BUFFER) && + !(template->bind & PIPE_BIND_CUSTOM)) { + /* Not a constant- or staging buffer. + * The buffer may be used for vertex data or indexes. */ bind_flags |= (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER); - if (ss->sws->have_vgpu10) - bind_flags |= PIPE_BIND_STREAM_OUTPUT; } if (svga_buffer_create_host_surface(ss, sbuf, bind_flags) != PIPE_OK) @@ -476,7 +513,7 @@ struct pipe_resource * svga_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, - unsigned bind) + unsigned bind) { struct svga_buffer *sbuf; struct svga_screen *ss = svga_screen(screen); @@ -510,6 +547,3 @@ svga_user_buffer_create(struct pipe_screen *screen, no_sbuf: return NULL; } - - -