diff options
author | Axel Davy <[email protected]> | 2016-02-06 13:39:58 +0100 |
---|---|---|
committer | Axel Davy <[email protected]> | 2016-02-12 23:26:36 +0100 |
commit | cc0114f30b587a10766ec212afb3ad356099ef23 (patch) | |
tree | 0a1c7bb8e508d73a04977e85af25c2a6eaa9cd68 /src/gallium/state_trackers/nine/buffer9.c | |
parent | 77d6c11f8fa87ba1070028cb036807dc8a115633 (diff) |
st/nine: Implement Managed vertex/index buffers
We were implementing those the same way than
the default pool, which is sub-optimal.
The buffer is supposed to return pointer to
a ram copy when user locks, and automatically
update the vram copy when needed.
v2: Rename NineBuffer9_Validate to NineBuffer9_Upload
Rename validate_buffers to update_managed_buffers
Initialize NineBuffer9 managed fields after the resource
is allocated. In case of allocation failure, when the dtor
is executed, This->base.pool is then rightfully set.
Signed-off-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/nine/buffer9.c')
-rw-r--r-- | src/gallium/state_trackers/nine/buffer9.c | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/src/gallium/state_trackers/nine/buffer9.c b/src/gallium/state_trackers/nine/buffer9.c index 82aa000e365..e066fc59f45 100644 --- a/src/gallium/state_trackers/nine/buffer9.c +++ b/src/gallium/state_trackers/nine/buffer9.c @@ -93,7 +93,26 @@ NineBuffer9_ctor( struct NineBuffer9 *This, hr = NineResource9_ctor(&This->base, pParams, NULL, TRUE, Type, Pool, Usage); - return hr; + + if (FAILED(hr)) + return hr; + + if (Pool == D3DPOOL_MANAGED) { + This->managed.data = align_malloc( + nine_format_get_level_alloc_size(This->base.info.format, + Size, 1, 0), 32); + if (!This->managed.data) + return E_OUTOFMEMORY; + memset(This->managed.data, 0, Size); + This->managed.dirty = TRUE; + u_box_1d(0, Size, &This->managed.dirty_box); + list_inithead(&This->managed.list); + list_inithead(&This->managed.list2); + list_add(&This->managed.list, &pParams->device->update_buffers); + list_add(&This->managed.list2, &pParams->device->managed_buffers); + } + + return D3D_OK; } void @@ -106,6 +125,15 @@ NineBuffer9_dtor( struct NineBuffer9 *This ) FREE(This->maps); } + if (This->base.pool == D3DPOOL_MANAGED) { + if (This->managed.data) + align_free(This->managed.data); + if (This->managed.list.prev != NULL && This->managed.list.next != NULL) + list_del(&This->managed.list); + if (This->managed.list2.prev != NULL && This->managed.list2.next != NULL) + list_del(&This->managed.list2); + } + NineResource9_dtor(&This->base); } @@ -138,6 +166,28 @@ NineBuffer9_Lock( struct NineBuffer9 *This, D3DLOCK_READONLY | D3DLOCK_NOOVERWRITE)), D3DERR_INVALIDCALL); + if (SizeToLock == 0) { + SizeToLock = This->size - OffsetToLock; + user_warn(OffsetToLock != 0); + } + + u_box_1d(OffsetToLock, SizeToLock, &box); + + if (This->base.pool == D3DPOOL_MANAGED) { + if (!This->managed.dirty) { + assert(LIST_IS_EMPTY(&This->managed.list)); + list_add(&This->managed.list, &This->base.base.device->update_buffers); + This->managed.dirty = TRUE; + This->managed.dirty_box = box; + } else { + u_box_union_2d(&This->managed.dirty_box, &This->managed.dirty_box, &box); + } + *ppbData = (char *)This->managed.data + OffsetToLock; + DBG("returning pointer %p\n", *ppbData); + This->nmaps++; + return D3D_OK; + } + if (This->nmaps == This->maxmaps) { struct pipe_transfer **newmaps = REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps, @@ -149,13 +199,6 @@ NineBuffer9_Lock( struct NineBuffer9 *This, This->maps = newmaps; } - if (SizeToLock == 0) { - SizeToLock = This->size - OffsetToLock; - user_warn(OffsetToLock != 0); - } - - u_box_1d(OffsetToLock, SizeToLock, &box); - data = This->pipe->transfer_map(This->pipe, This->base.resource, 0, usage, &box, &This->maps[This->nmaps]); @@ -184,6 +227,22 @@ NineBuffer9_Unlock( struct NineBuffer9 *This ) DBG("This=%p\n", This); user_assert(This->nmaps > 0, D3DERR_INVALIDCALL); - This->pipe->transfer_unmap(This->pipe, This->maps[--(This->nmaps)]); + if (This->base.pool != D3DPOOL_MANAGED) + This->pipe->transfer_unmap(This->pipe, This->maps[--(This->nmaps)]); + else + This->nmaps--; return D3D_OK; } + +void +NineBuffer9_SetDirty( struct NineBuffer9 *This ) +{ + assert(This->base.pool == D3DPOOL_MANAGED); + + if (!This->managed.dirty) { + assert(LIST_IS_EMPTY(&This->managed.list)); + list_add(&This->managed.list, &This->base.base.device->update_buffers); + This->managed.dirty = TRUE; + } + u_box_1d(0, This->size, &This->managed.dirty_box); +} |