[Mesa-dev] [PATCH 84/84] st/nine: Implement new buffer upload path
Axel Davy
axel.davy at ens.fr
Thu Dec 8 23:49:50 UTC 2016
There seems to be a regression with this patch.
I noticed one mistake: nine_upload_create_buffer should initialize
buf->resource to NULL.
However someone reports crash after GTT memory exhaustion.
I can't find the mistake. Anyone ?
Axel
On 07/12/2016 23:55, Axel Davy wrote:
> This new buffer upload path enables to lock
> faster than the normal path when using
> DISCARD/NOOVERWRITE.
>
> Signed-off-by: Axel Davy <axel.davy at ens.fr>
> ---
> src/gallium/state_trackers/nine/Makefile.sources | 2 +
> src/gallium/state_trackers/nine/buffer9.c | 75 +++++-
> src/gallium/state_trackers/nine/buffer9.h | 9 +-
> src/gallium/state_trackers/nine/device9.c | 5 +
> src/gallium/state_trackers/nine/device9.h | 3 +
> src/gallium/state_trackers/nine/indexbuffer9.c | 10 +-
> src/gallium/state_trackers/nine/indexbuffer9.h | 2 -
> .../state_trackers/nine/nine_buffer_upload.c | 288 +++++++++++++++++++++
> .../state_trackers/nine/nine_buffer_upload.h | 59 +++++
> src/gallium/state_trackers/nine/vertexbuffer9.c | 3 +-
> 10 files changed, 435 insertions(+), 21 deletions(-)
> create mode 100644 src/gallium/state_trackers/nine/nine_buffer_upload.c
> create mode 100644 src/gallium/state_trackers/nine/nine_buffer_upload.h
>
> diff --git a/src/gallium/state_trackers/nine/Makefile.sources b/src/gallium/state_trackers/nine/Makefile.sources
> index 2bb08a2..56698a1 100644
> --- a/src/gallium/state_trackers/nine/Makefile.sources
> +++ b/src/gallium/state_trackers/nine/Makefile.sources
> @@ -23,6 +23,8 @@ C_SOURCES := \
> indexbuffer9.h \
> iunknown.c \
> iunknown.h \
> + nine_buffer_upload.c \
> + nine_buffer_upload.h \
> nine_csmt_helper.h \
> nine_debug.c \
> nine_debug.h \
> diff --git a/src/gallium/state_trackers/nine/buffer9.c b/src/gallium/state_trackers/nine/buffer9.c
> index 9a7c30c..aa97cf9 100644
> --- a/src/gallium/state_trackers/nine/buffer9.c
> +++ b/src/gallium/state_trackers/nine/buffer9.c
> @@ -23,6 +23,7 @@
>
> #include "buffer9.h"
> #include "device9.h"
> +#include "nine_buffer_upload.h"
> #include "nine_helpers.h"
> #include "nine_pipe.h"
>
> @@ -100,6 +101,9 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
> else
> info->usage = PIPE_USAGE_DYNAMIC;
>
> + /* When Writeonly is not set, we don't want to enable the
> + * optimizations */
> + This->discard_nooverwrite_only = !!(Usage & D3DUSAGE_WRITEONLY);
> /* if (pDesc->Usage & D3DUSAGE_DONOTCLIP) { } */
> /* if (pDesc->Usage & D3DUSAGE_NONSECURE) { } */
> /* if (pDesc->Usage & D3DUSAGE_NPATCHES) { } */
> @@ -161,12 +165,18 @@ NineBuffer9_dtor( struct NineBuffer9 *This )
> list_del(&This->managed.list2);
> }
>
> + if (This->buf)
> + nine_upload_release_buffer(This->base.base.device->buffer_upload, This->buf);
> +
> NineResource9_dtor(&This->base);
> }
>
> struct pipe_resource *
> -NineBuffer9_GetResource( struct NineBuffer9 *This )
> +NineBuffer9_GetResource( struct NineBuffer9 *This, unsigned *offset )
> {
> + if (This->buf)
> + return nine_upload_buffer_resource_and_offset(This->buf, offset);
> + *offset = 0;
> return NineResource9_GetResource(&This->base);
> }
>
> @@ -260,6 +270,8 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
> if (Flags & D3DLOCK_DONOTWAIT && !(This->base.usage & D3DUSAGE_DYNAMIC))
> usage |= PIPE_TRANSFER_DONTBLOCK;
>
> + This->discard_nooverwrite_only &= !!(Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE));
> +
> if (This->nmaps == This->maxmaps) {
> struct NineTransfer *newmaps =
> REALLOC(This->maps, sizeof(struct NineTransfer)*This->maxmaps,
> @@ -271,8 +283,52 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
> This->maps = newmaps;
> }
>
> - This->maps[This->nmaps].is_pipe_secondary = FALSE;
> + if (This->buf &&
> + (!This->discard_nooverwrite_only ||
> + (This->discard_nooverwrite_only && (Flags & D3DLOCK_DISCARD)))) {
> + /* Release previous buffer */
> + if (This->nmaps >= 1)
> + This->maps[This->nmaps-1].should_destroy_buf = true;
> + else
> + nine_upload_release_buffer(device->buffer_upload, This->buf);
> + This->buf = NULL;
> + /* Mapping a nine_subbuffer without discard/nooverwrite.
> + * Since that will hurt (we'll wait the entire buffer
> + * to be idle), we'll won't nine_subbuffer for this buffer
> + * in fear that happens again. */
> + if (This->buf && !This->discard_nooverwrite_only) {
> + DBG("Disabling nine_subbuffer for a buffer having"
> + "used a nine_subbuffer buffer\n");
> + /* Rebind previous resource */
> + NineBuffer9_RebindIfRequired(This, device);
> + }
> + }
> +
> + This->maps[This->nmaps].transfer = NULL;
> + This->maps[This->nmaps].is_pipe_secondary = false;
> + This->maps[This->nmaps].buf = NULL;
> + This->maps[This->nmaps].should_destroy_buf = false;
> +
> + if (This->discard_nooverwrite_only) {
> + if (!This->buf) {
> + This->buf = nine_upload_create_buffer(device->buffer_upload, This->base.info.width0);
> + NineBuffer9_RebindIfRequired(This, device);
> + }
> +
> + if (This->buf) {
> + This->maps[This->nmaps].buf = This->buf;
> + This->nmaps++;
> + *ppbData = nine_upload_buffer_get_map(This->buf) + OffsetToLock;
> + return D3D_OK;
> + } else {
> + /* fallback to normal path, and don't try again */
> + This->discard_nooverwrite_only = false;
> + }
> + }
>
> + /* When csmt is active, we want to avoid stalls as much as possible,
> + * and thus we want to create a new resource on discard and map it
> + * with the secondary pipe, instead of waiting on the main pipe. */
> if (Flags & D3DLOCK_DISCARD && device->csmt_active) {
> struct pipe_screen *screen = NineDevice9_GetScreen(device);
> struct pipe_resource *new_res = screen->resource_create(screen, &This->base.info);
> @@ -324,12 +380,15 @@ NineBuffer9_Unlock( struct NineBuffer9 *This )
> user_assert(This->nmaps > 0, D3DERR_INVALIDCALL);
> This->nmaps--;
> if (This->base.pool != D3DPOOL_MANAGED) {
> - pipe = This->maps[This->nmaps].is_pipe_secondary ?
> - device->pipe_secondary :
> - nine_context_get_pipe_acquire(device);
> - pipe->transfer_unmap(pipe, This->maps[This->nmaps].transfer);
> - if (!This->maps[This->nmaps].is_pipe_secondary)
> - nine_context_get_pipe_release(device);
> + if (!This->maps[This->nmaps].buf) {
> + pipe = This->maps[This->nmaps].is_pipe_secondary ?
> + device->pipe_secondary :
> + nine_context_get_pipe_acquire(device);
> + pipe->transfer_unmap(pipe, This->maps[This->nmaps].transfer);
> + if (!This->maps[This->nmaps].is_pipe_secondary)
> + nine_context_get_pipe_release(device);
> + } else if (This->maps[This->nmaps].should_destroy_buf)
> + nine_upload_release_buffer(device->buffer_upload, This->maps[This->nmaps].buf);
> } else {
> BASEBUF_REGISTER_UPDATE(This);
> }
> diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h
> index e9ee31e..369fd86 100644
> --- a/src/gallium/state_trackers/nine/buffer9.h
> +++ b/src/gallium/state_trackers/nine/buffer9.h
> @@ -25,6 +25,7 @@
> #define _NINE_BUFFER9_H_
>
> #include "device9.h"
> +#include "nine_buffer_upload.h"
> #include "nine_state.h"
> #include "resource9.h"
> #include "pipe/p_context.h"
> @@ -38,6 +39,8 @@ struct pipe_transfer;
> struct NineTransfer {
> struct pipe_transfer *transfer;
> bool is_pipe_secondary;
> + struct nine_subbuffer *buf; /* NULL unless subbuffer are used */
> + bool should_destroy_buf; /* if the subbuffer should be destroyed */
> };
>
> struct NineBuffer9
> @@ -50,6 +53,10 @@ struct NineBuffer9
> UINT size;
>
> int16_t bind_count; /* to Device9->state.stream */
> + /* Whether only discard and nooverwrite were used so far
> + * for this buffer. Allows some optimization. */
> + boolean discard_nooverwrite_only;
> + struct nine_subbuffer *buf;
>
> /* Specific to managed buffers */
> struct {
> @@ -79,7 +86,7 @@ void
> NineBuffer9_dtor( struct NineBuffer9 *This );
>
> struct pipe_resource *
> -NineBuffer9_GetResource( struct NineBuffer9 *This );
> +NineBuffer9_GetResource( struct NineBuffer9 *This, unsigned *offset );
>
> HRESULT NINE_WINAPI
> NineBuffer9_Lock( struct NineBuffer9 *This,
> diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
> index 91f09de..9a5cfa4 100644
> --- a/src/gallium/state_trackers/nine/device9.c
> +++ b/src/gallium/state_trackers/nine/device9.c
> @@ -34,6 +34,7 @@
> #include "texture9.h"
> #include "cubetexture9.h"
> #include "volumetexture9.h"
> +#include "nine_buffer_upload.h"
> #include "nine_helpers.h"
> #include "nine_pipe.h"
> #include "nine_ff.h"
> @@ -282,6 +283,8 @@ NineDevice9_ctor( struct NineDevice9 *This,
> if (This->csmt_active)
> DBG("\033[1;32mCSMT is active\033[0m\n");
>
> + This->buffer_upload = nine_upload_create(This->pipe_secondary, 4 * 1024 * 1024, 4);
> +
> /* Initialize a dummy VBO to be used when a vertex declaration does not
> * specify all the inputs needed by vertex shader, on win default behavior
> * is to pass 0,0,0,0 to the shader */
> @@ -571,6 +574,8 @@ NineDevice9_dtor( struct NineDevice9 *This )
> FREE(This->swapchains);
> }
>
> + nine_upload_destroy(This->buffer_upload);
> +
> /* Destroy cso first */
> if (This->context.cso) { cso_destroy_context(This->context.cso); }
> if (This->cso_sw) { cso_destroy_context(This->cso_sw); }
> diff --git a/src/gallium/state_trackers/nine/device9.h b/src/gallium/state_trackers/nine/device9.h
> index 81c4ef9..71b88a4 100644
> --- a/src/gallium/state_trackers/nine/device9.h
> +++ b/src/gallium/state_trackers/nine/device9.h
> @@ -63,6 +63,9 @@ struct NineDevice9
> struct csmt_context *csmt_ctx;
> BOOL csmt_active;
>
> + /* For DISCARD/NOOVERWRITE */
> + struct nine_buffer_upload *buffer_upload;
> +
> /* creation parameters */
> D3DCAPS9 caps;
> D3DDEVICE_CREATION_PARAMETERS params;
> diff --git a/src/gallium/state_trackers/nine/indexbuffer9.c b/src/gallium/state_trackers/nine/indexbuffer9.c
> index 4029a8d..cbd75fb 100644
> --- a/src/gallium/state_trackers/nine/indexbuffer9.c
> +++ b/src/gallium/state_trackers/nine/indexbuffer9.c
> @@ -49,7 +49,7 @@ NineIndexBuffer9_ctor( struct NineIndexBuffer9 *This,
> if (FAILED(hr))
> return hr;
>
> - This->buffer.buffer = NineIndexBuffer9_GetResource(This);
> + This->buffer.buffer = NULL;
> This->buffer.offset = 0;
>
> switch (pDesc->Format) {
> @@ -77,16 +77,10 @@ const struct pipe_index_buffer *
> NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This )
> {
> /* The resource may change */
> - This->buffer.buffer = NineIndexBuffer9_GetResource(This);
> + This->buffer.buffer = NineBuffer9_GetResource(&This->base, &This->buffer.offset);
> return &This->buffer;
> }
>
> -struct pipe_resource *
> -NineIndexBuffer9_GetResource( struct NineIndexBuffer9 *This )
> -{
> - return NineBuffer9_GetResource(&This->base);
> -}
> -
> HRESULT NINE_WINAPI
> NineIndexBuffer9_Lock( struct NineIndexBuffer9 *This,
> UINT OffsetToLock,
> diff --git a/src/gallium/state_trackers/nine/indexbuffer9.h b/src/gallium/state_trackers/nine/indexbuffer9.h
> index 4802105..e695082 100644
> --- a/src/gallium/state_trackers/nine/indexbuffer9.h
> +++ b/src/gallium/state_trackers/nine/indexbuffer9.h
> @@ -66,8 +66,6 @@ NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This );
> const struct pipe_index_buffer *
> NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This );
>
> -struct pipe_resource *
> -NineIndexBuffer9_GetResource( struct NineIndexBuffer9 *This );
> /*** Direct3D public ***/
>
> HRESULT NINE_WINAPI
> diff --git a/src/gallium/state_trackers/nine/nine_buffer_upload.c b/src/gallium/state_trackers/nine/nine_buffer_upload.c
> new file mode 100644
> index 0000000..d2a030a
> --- /dev/null
> +++ b/src/gallium/state_trackers/nine/nine_buffer_upload.c
> @@ -0,0 +1,288 @@
> +/**************************************************************************
> + *
> + * Copyright 2009 VMware, Inc.
> + * Copyright 2016 Axel Davy <axel.davy at ens.fr>
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + *
> + **************************************************************************/
> +/* Adapted from u_upload_mgr.
> + * Makes suballocations from bigger allocations,
> + * while enabling fast mapping. */
> +
> +#include "pipe/p_defines.h"
> +#include "util/u_inlines.h"
> +#include "pipe/p_context.h"
> +#include "util/u_memory.h"
> +#include "util/u_math.h"
> +#include "util/slab.h"
> +
> +#include "nine_buffer_upload.h"
> +
> +#include "nine_debug.h"
> +
> +#define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER)
> +
> +struct nine_buffer_group {
> + unsigned refcount; /* How many sub-buffers live inside the buffer */
> + struct pipe_resource *resource;
> + struct pipe_transfer *transfer;
> + uint8_t *map;
> + unsigned free_offset; /* Aligned offset to the upload buffer, pointing
> + * at the first unused byte. */
> +};
> +
> +struct nine_subbuffer {
> + struct nine_buffer_group *parent; /* Can be NULL */
> + struct pipe_resource *resource; /* The parent resource if apply */
> + unsigned offset; /* offset inside the resource */
> + /* If there is no parent, the resource map. Else NULL. */
> + struct pipe_transfer *transfer;
> + uint8_t *map;
> +};
> +
> +struct nine_buffer_upload {
> + struct pipe_context *pipe;
> + struct slab_mempool buffer_pool;
> +
> + unsigned buffers_size; /* Size of the big allocated buffers */
> + unsigned num_buffers;
> + boolean map_persistent; /* If persistent mappings are supported.
> + * If not just behaves like normal allocator */
> + struct nine_buffer_group *buffers;
> +};
> +
> +static void
> +nine_upload_create_buffer_group(struct nine_buffer_upload *upload,
> + struct nine_buffer_group *group)
> +{
> + struct pipe_resource resource;
> + struct pipe_screen *screen = upload->pipe->screen;
> + DBG("%p %p\n", upload, group);
> +
> + memset(&resource, 0, sizeof resource);
> + resource.target = PIPE_BUFFER;
> + resource.format = PIPE_FORMAT_R8_UNORM;
> + resource.bind = PIPE_BIND_VERTEX_BUFFER;
> + resource.usage = PIPE_USAGE_STREAM;
> + resource.width0 = upload->buffers_size;
> + resource.height0 = 1;
> + resource.depth0 = 1;
> + resource.array_size = 1;
> + resource.flags = PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
> + PIPE_RESOURCE_FLAG_MAP_COHERENT;
> +
> + group->refcount = 0;
> + group->resource = screen->resource_create(screen, &resource);
> + if (group->resource == NULL)
> + return;
> +
> + group->map = pipe_buffer_map_range(upload->pipe, group->resource,
> + 0, upload->buffers_size,
> + PIPE_TRANSFER_WRITE |
> + PIPE_TRANSFER_PERSISTENT |
> + PIPE_TRANSFER_COHERENT,
> + &group->transfer);
> + if (group->map == NULL) {
> + group->transfer = NULL;
> + pipe_resource_reference(&group->resource, NULL);
> + return;
> + }
> +
> + group->free_offset = 0;
> +}
> +
> +static void
> +nine_upload_destroy_buffer_group(struct nine_buffer_upload *upload,
> + struct nine_buffer_group *group)
> +{
> + DBG("%p %p\n", upload, group);
> + assert(group->refcount == 0);
> +
> + if (group->transfer)
> + pipe_transfer_unmap(upload->pipe, group->transfer);
> + if (group->resource)
> + pipe_resource_reference(&group->resource, NULL);
> + group->transfer = NULL;
> + group->map = NULL;
> +}
> +
> +struct nine_buffer_upload *
> +nine_upload_create(struct pipe_context *pipe, unsigned buffers_size,
> + unsigned num_buffers)
> +{
> + struct nine_buffer_upload *upload = CALLOC_STRUCT(nine_buffer_upload);
> + int i;
> +
> + DBG("\n");
> +
> + if (!upload)
> + return NULL;
> +
> + slab_create(&upload->buffer_pool, sizeof(struct nine_subbuffer), 4096);
> +
> + upload->pipe = pipe;
> + upload->buffers_size = align(buffers_size, 4096);
> + upload->num_buffers = num_buffers;
> + upload->map_persistent =
> + pipe->screen->get_param(pipe->screen,
> + PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT);
> +
> + upload->buffers = CALLOC(num_buffers, sizeof(struct nine_buffer_group));
> + if (!upload->buffers)
> + goto buffers_fail;
> +
> + if (upload->map_persistent) {
> + for (i = 0; i < num_buffers; i++)
> + nine_upload_create_buffer_group(upload, &upload->buffers[i]);
> + }
> + return upload;
> +
> +buffers_fail:
> + slab_destroy(&upload->buffer_pool);
> + FREE(upload);
> + return NULL;
> +}
> +
> +void
> +nine_upload_destroy(struct nine_buffer_upload *upload)
> +{
> + int i;
> +
> + DBG("%p\n", upload);
> +
> + for (i = 0; i < upload->num_buffers; i++)
> + nine_upload_destroy_buffer_group(upload, &upload->buffers[i]);
> + FREE(upload);
> +}
> +
> +struct nine_subbuffer *
> +nine_upload_create_buffer(struct nine_buffer_upload *upload,
> + unsigned buffer_size)
> +{
> + struct nine_subbuffer *buf = slab_alloc_st(&upload->buffer_pool);
> + struct nine_buffer_group *group = NULL;
> + unsigned size = align(buffer_size, 4096);
> + int i = 0;
> +
> + DBG("%p %d\n", upload, buffer_size);
> +
> + if (!buf)
> + return NULL;
> +
> + for (i = 0; i < upload->num_buffers; i++) {
> + group = &upload->buffers[i];
> + if (group->resource &&
> + group->free_offset + size <= upload->buffers_size)
> + break;
> + }
> +
> + if (i == upload->num_buffers) {
> + /* Allocate lonely buffer */
> + struct pipe_resource resource;
> + struct pipe_screen *screen = upload->pipe->screen;
> +
> + buf->parent = NULL;
> +
> + memset(&resource, 0, sizeof resource);
> + resource.target = PIPE_BUFFER;
> + resource.format = PIPE_FORMAT_R8_UNORM;
> + resource.bind = PIPE_BIND_VERTEX_BUFFER;
> + resource.usage = PIPE_USAGE_STREAM;
> + resource.width0 = upload->buffers_size;
> + resource.height0 = 1;
> + resource.depth0 = 1;
> + resource.array_size = 1;
> + resource.flags = 0;
> +
> + buf->resource = screen->resource_create(screen, &resource);
> + if (buf->resource == NULL) {
> + slab_free_st(&upload->buffer_pool, buf);
> + return NULL;
> + }
> +
> + buf->map = pipe_buffer_map_range(upload->pipe, buf->resource,
> + 0, upload->buffers_size,
> + PIPE_TRANSFER_WRITE |
> + PIPE_TRANSFER_PERSISTENT |
> + PIPE_TRANSFER_COHERENT,
> + &buf->transfer);
> + if (buf->map == NULL) {
> + pipe_resource_reference(&buf->resource, NULL);
> + slab_free_st(&upload->buffer_pool, buf);
> + return NULL;
> + }
> + buf->offset = 0;
> + return buf;
> + }
> +
> + buf->parent = group;
> + pipe_resource_reference(&buf->resource, group->resource);
> + buf->offset = group->free_offset;
> +
> + group->free_offset += size;
> + group->refcount += 1;
> +
> + return buf;
> +}
> +
> +void
> +nine_upload_release_buffer(struct nine_buffer_upload *upload,
> + struct nine_subbuffer *buf)
> +{
> + DBG("%p %p %p\n", upload, buf, buf->parent);
> +
> + if (buf->parent) {
> + pipe_resource_reference(&buf->resource, NULL);
> + buf->parent->refcount--;
> + if (buf->parent->refcount == 0) {
> + /* Allocate new buffer */
> + nine_upload_destroy_buffer_group(upload, buf->parent);
> + nine_upload_create_buffer_group(upload, buf->parent);
> + }
> + } else {
> + /* lonely buffer */
> + if (buf->transfer)
> + pipe_transfer_unmap(upload->pipe, buf->transfer);
> + pipe_resource_reference(&buf->resource, NULL);
> + }
> +
> + slab_free_st(&upload->buffer_pool, buf);
> +}
> +
> +uint8_t *
> +nine_upload_buffer_get_map(struct nine_subbuffer *buf)
> +{
> + if (buf->parent) {
> + return buf->parent->map + buf->offset;
> + }
> + /* lonely buffer */
> + return buf->map;
> +}
> +
> +struct pipe_resource *
> +nine_upload_buffer_resource_and_offset(struct nine_subbuffer *buf,
> + unsigned *offset)
> +{
> + *offset = buf->offset;
> + return buf->resource;
> +}
> diff --git a/src/gallium/state_trackers/nine/nine_buffer_upload.h b/src/gallium/state_trackers/nine/nine_buffer_upload.h
> new file mode 100644
> index 0000000..b708825
> --- /dev/null
> +++ b/src/gallium/state_trackers/nine/nine_buffer_upload.h
> @@ -0,0 +1,59 @@
> +/**************************************************************************
> + *
> + * Copyright 2009 VMware, Inc.
> + * Copyright 2016 Axel Davy <axel.davy at ens.fr>
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + *
> + **************************************************************************/
> +
> +#ifndef _NINE_BUFFER_UPLOAD_H_
> +#define _NINE_BUFFER_UPLOAD_H_
> +
> +#include "pipe/p_defines.h"
> +
> +struct nine_buffer_upload;
> +struct nine_subbuffer;
> +
> +struct nine_buffer_upload *
> +nine_upload_create(struct pipe_context *pipe, unsigned buffers_size,
> + unsigned num_buffers);
> +
> +void
> +nine_upload_destroy(struct nine_buffer_upload *upload);
> +
> +struct nine_subbuffer *
> +nine_upload_create_buffer(struct nine_buffer_upload *upload,
> + unsigned buffer_size);
> +
> +void
> +nine_upload_release_buffer(struct nine_buffer_upload *upload,
> + struct nine_subbuffer *buf);
> +
> +uint8_t *
> +nine_upload_buffer_get_map(struct nine_subbuffer *buf);
> +
> +struct pipe_resource *
> +nine_upload_buffer_resource_and_offset(struct nine_subbuffer *buf,
> + unsigned *offset);
> +
> +#endif /* _NINE_BUFFER_UPLOAD_H_ */
> diff --git a/src/gallium/state_trackers/nine/vertexbuffer9.c b/src/gallium/state_trackers/nine/vertexbuffer9.c
> index 027f290..df1d171 100644
> --- a/src/gallium/state_trackers/nine/vertexbuffer9.c
> +++ b/src/gallium/state_trackers/nine/vertexbuffer9.c
> @@ -65,8 +65,7 @@ NineVertexBuffer9_dtor( struct NineVertexBuffer9 *This )
> struct pipe_resource *
> NineVertexBuffer9_GetResource( struct NineVertexBuffer9 *This, unsigned *offset )
> {
> - *offset = 0;
> - return NineBuffer9_GetResource(&This->base);
> + return NineBuffer9_GetResource(&This->base, offset);
> }
>
> HRESULT NINE_WINAPI
More information about the mesa-dev
mailing list