aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine/buffer9.c
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2016-02-06 13:39:58 +0100
committerAxel Davy <[email protected]>2016-02-12 23:26:36 +0100
commitcc0114f30b587a10766ec212afb3ad356099ef23 (patch)
tree0a1c7bb8e508d73a04977e85af25c2a6eaa9cd68 /src/gallium/state_trackers/nine/buffer9.c
parent77d6c11f8fa87ba1070028cb036807dc8a115633 (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.c77
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);
+}