X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_resource_buffer.h;h=09648d2ec0976dd258c83eaad4c891a68cd2125c;hb=4087b5343d8d85f46ead6656f58c94cec0289cb0;hp=75e12c3220ceee2cf9d9d25776f814a9c0dd4f5f;hpb=005c8e01062e8e88a86904b955d5422742bd32e7;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index 75e12c3220c..09648d2ec09 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -58,10 +58,22 @@ struct svga_buffer_range struct svga_3d_update_gb_image; +/** + * This structure describes the bind flags and cache key associated + * with the host surface. + */ +struct svga_buffer_surface +{ + struct list_head list; + unsigned bind_flags; + struct svga_host_surface_cache_key key; + struct svga_winsys_surface *handle; +}; + /** * SVGA pipe buffer. */ -struct svga_buffer +struct svga_buffer { struct u_resource b; @@ -70,36 +82,47 @@ struct svga_buffer /** * Regular (non DMA'able) memory. - * + * * Used for user buffers or for buffers which we know before hand that can * never be used by the virtual hardware directly, such as constant buffers. */ void *swbuf; - - /** + + /** * Whether swbuf was created by the user or not. */ boolean user; - + + /** + * Whether swbuf is used for this buffer. + */ + boolean use_swbuf; + /** * Creation key for the host surface handle. - * - * This structure describes all the host surface characteristics so that it + * + * This structure describes all the host surface characteristics so that it * can be looked up in cache, since creating a host surface is often a slow * operation. */ struct svga_host_surface_cache_key key; - + /** * Host surface handle. - * - * This is a platform independent abstraction for host SID. We create when + * + * This is a platform independent abstraction for host SID. We create when * trying to bind. * * Only set for non-user buffers. */ struct svga_winsys_surface *handle; + /** + * List of surfaces created for this buffer resource to support + * incompatible bind flags. + */ + struct list_head surfaces; + /** * Information about ongoing and past map operations. */ @@ -192,17 +215,26 @@ struct svga_buffer unsigned size; /**< Approximate size in bytes */ boolean dirty; /**< Need to do a readback before mapping? */ + + /** In some cases we try to keep the results of the translate_indices() + * function from svga_draw_elements.c + */ + struct { + enum pipe_prim_type orig_prim, new_prim; + struct pipe_resource *buffer; + unsigned index_size; + unsigned offset; /**< first index */ + unsigned count; /**< num indices */ + } translated_indices; }; static inline struct svga_buffer * -svga_buffer(struct pipe_resource *buffer) +svga_buffer(struct pipe_resource *resource) { - if (buffer) { - assert(((struct svga_buffer *)buffer)->b.vtbl == &svga_buffer_vtbl); - return (struct svga_buffer *)buffer; - } - return NULL; + struct svga_buffer *buf = (struct svga_buffer *) resource; + assert(buf == NULL || buf->b.vtbl == &svga_buffer_vtbl); + return buf; } @@ -210,8 +242,8 @@ svga_buffer(struct pipe_resource *buffer) * Returns TRUE for user buffers. We may * decide to use an alternate upload path for these buffers. */ -static inline boolean -svga_buffer_is_user_buffer( struct pipe_resource *buffer ) +static inline boolean +svga_buffer_is_user_buffer(struct pipe_resource *buffer) { if (buffer) { return svga_buffer(buffer)->user; @@ -246,6 +278,7 @@ svga_buffer_has_hw_storage(struct svga_buffer *sbuf) /** * Map the hardware storage of a buffer. + * \param flags bitmask of PIPE_TRANSFER_* flags */ static inline void * svga_buffer_hw_storage_map(struct svga_context *svga, @@ -253,8 +286,30 @@ svga_buffer_hw_storage_map(struct svga_context *svga, unsigned flags, boolean *retry) { struct svga_winsys_screen *sws = svga_buffer_winsys_screen(sbuf); + + svga->hud.num_buffers_mapped++; + if (sws->have_gb_objects) { - return svga->swc->surface_map(svga->swc, sbuf->handle, flags, retry); + struct svga_winsys_context *swc = svga->swc; + boolean rebind; + void *map; + + if (swc->force_coherent) { + flags |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT; + } + map = swc->surface_map(swc, sbuf->handle, flags, retry, &rebind); + if (map && rebind) { + enum pipe_error ret; + + ret = SVGA3D_BindGBSurface(swc, sbuf->handle); + if (ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_BindGBSurface(swc, sbuf->handle); + assert(ret == PIPE_OK); + } + svga_context_flush(svga, NULL); + } + return map; } else { *retry = FALSE; return sws->buffer_map(sws, sbuf->hwbuf, flags); @@ -273,16 +328,10 @@ svga_buffer_hw_storage_unmap(struct svga_context *svga, if (sws->have_gb_objects) { struct svga_winsys_context *swc = svga->swc; boolean rebind; + swc->surface_unmap(swc, sbuf->handle, &rebind); if (rebind) { - enum pipe_error ret; - ret = SVGA3D_BindGBSurface(swc, sbuf->handle); - if (ret != PIPE_OK) { - /* flush and retry */ - svga_context_flush(svga, NULL); - ret = SVGA3D_BindGBSurface(swc, sbuf->handle); - assert(ret == PIPE_OK); - } + SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, sbuf->handle)); } } else sws->buffer_unmap(sws, sbuf->hwbuf); @@ -293,11 +342,11 @@ struct pipe_resource * svga_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, - unsigned usage); + unsigned usage); struct pipe_resource * svga_buffer_create(struct pipe_screen *screen, - const struct pipe_resource *template); + const struct pipe_resource *template); @@ -312,14 +361,15 @@ svga_buffer_create(struct pipe_screen *screen, */ struct svga_winsys_surface * svga_buffer_handle(struct svga_context *svga, - struct pipe_resource *buf); + struct pipe_resource *buf, + unsigned tobind_flags); void svga_context_flush_buffers(struct svga_context *svga); struct svga_winsys_buffer * svga_winsys_buffer_create(struct svga_context *svga, - unsigned alignment, + unsigned alignment, unsigned usage, unsigned size);