summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/nine/buffer9.c65
-rw-r--r--src/gallium/state_trackers/nine/buffer9.h7
-rw-r--r--src/gallium/state_trackers/nine/indexbuffer9.c2
3 files changed, 64 insertions, 10 deletions
diff --git a/src/gallium/state_trackers/nine/buffer9.c b/src/gallium/state_trackers/nine/buffer9.c
index e497222434b..bd115ff70b1 100644
--- a/src/gallium/state_trackers/nine/buffer9.c
+++ b/src/gallium/state_trackers/nine/buffer9.c
@@ -32,6 +32,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
#include "util/u_box.h"
+#include "util/u_inlines.h"
#define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER)
@@ -50,7 +51,7 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
user_assert(Pool != D3DPOOL_SCRATCH, D3DERR_INVALIDCALL);
- This->maps = MALLOC(sizeof(struct pipe_transfer *));
+ This->maps = MALLOC(sizeof(struct NineTransfer));
if (!This->maps)
return E_OUTOFMEMORY;
This->nmaps = 0;
@@ -169,6 +170,25 @@ NineBuffer9_GetResource( struct NineBuffer9 *This )
return NineResource9_GetResource(&This->base);
}
+static void
+NineBuffer9_RebindIfRequired( struct NineBuffer9 *This,
+ struct NineDevice9 *device )
+{
+ int i;
+
+ if (!This->bind_count)
+ return;
+ for (i = 0; i < device->caps.MaxStreams; i++) {
+ if (device->state.stream[i] == (struct NineVertexBuffer9 *)This)
+ nine_context_set_stream_source(device, i,
+ (struct NineVertexBuffer9 *)This,
+ device->state.vtxbuf[i].buffer_offset,
+ device->state.vtxbuf[i].stride);
+ }
+ if (device->state.idxbuf == (struct NineIndexBuffer9 *)This)
+ nine_context_set_indices(device, (struct NineIndexBuffer9 *)This);
+}
+
HRESULT NINE_WINAPI
NineBuffer9_Lock( struct NineBuffer9 *This,
UINT OffsetToLock,
@@ -176,6 +196,7 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
void **ppbData,
DWORD Flags )
{
+ struct NineDevice9 *device = This->base.base.device;
struct pipe_box box;
struct pipe_context *pipe;
void *data;
@@ -241,9 +262,9 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
usage |= PIPE_TRANSFER_DONTBLOCK;
if (This->nmaps == This->maxmaps) {
- struct pipe_transfer **newmaps =
- REALLOC(This->maps, sizeof(struct pipe_transfer *)*This->maxmaps,
- sizeof(struct pipe_transfer *)*(This->maxmaps << 1));
+ struct NineTransfer *newmaps =
+ REALLOC(This->maps, sizeof(struct NineTransfer)*This->maxmaps,
+ sizeof(struct NineTransfer)*(This->maxmaps << 1));
if (newmaps == NULL)
return E_OUTOFMEMORY;
@@ -251,9 +272,29 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
This->maps = newmaps;
}
- pipe = NineDevice9_GetPipe(This->base.base.device);
+ This->maps[This->nmaps].is_pipe_secondary = FALSE;
+
+ 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);
+ if (new_res) {
+ /* Use the new resource */
+ pipe_resource_reference(&This->base.resource, new_res);
+ pipe_resource_reference(&new_res, NULL);
+ usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED;
+ NineBuffer9_RebindIfRequired(This, device);
+ This->maps[This->nmaps].is_pipe_secondary = TRUE;
+ }
+ } else if (Flags & D3DLOCK_NOOVERWRITE && device->csmt_active)
+ This->maps[This->nmaps].is_pipe_secondary = TRUE;
+
+ if (This->maps[This->nmaps].is_pipe_secondary)
+ pipe = device->pipe_secondary;
+ else
+ pipe = NineDevice9_GetPipe(device);
+
data = pipe->transfer_map(pipe, This->base.resource, 0,
- usage, &box, &This->maps[This->nmaps]);
+ usage, &box, &This->maps[This->nmaps].transfer);
if (!data) {
DBG("pipe::transfer_map failed\n"
@@ -277,15 +318,21 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
HRESULT NINE_WINAPI
NineBuffer9_Unlock( struct NineBuffer9 *This )
{
+ struct NineDevice9 *device = This->base.base.device;
struct pipe_context *pipe;
DBG("This=%p\n", This);
user_assert(This->nmaps > 0, D3DERR_INVALIDCALL);
+ This->nmaps--;
if (This->base.pool != D3DPOOL_MANAGED) {
- pipe = NineDevice9_GetPipe(This->base.base.device);
- pipe->transfer_unmap(pipe, This->maps[--(This->nmaps)]);
+ pipe = This->maps[This->nmaps].is_pipe_secondary ?
+ device->pipe_secondary :
+ NineDevice9_GetPipe(device);
+ pipe->transfer_unmap(pipe, This->maps[This->nmaps].transfer);
+ /* We need to flush in case the driver does implicit copies */
+ if (This->maps[This->nmaps].is_pipe_secondary)
+ pipe->flush(pipe, NULL, 0);
} else {
- This->nmaps--;
BASEBUF_REGISTER_UPDATE(This);
}
return D3D_OK;
diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h
index 49b67a9eaf9..d8024e4aac2 100644
--- a/src/gallium/state_trackers/nine/buffer9.h
+++ b/src/gallium/state_trackers/nine/buffer9.h
@@ -34,12 +34,17 @@ struct pipe_screen;
struct pipe_context;
struct pipe_transfer;
+struct NineTransfer {
+ struct pipe_transfer *transfer;
+ bool is_pipe_secondary;
+};
+
struct NineBuffer9
{
struct NineResource9 base;
/* G3D */
- struct pipe_transfer **maps;
+ struct NineTransfer *maps;
int nmaps, maxmaps;
UINT size;
diff --git a/src/gallium/state_trackers/nine/indexbuffer9.c b/src/gallium/state_trackers/nine/indexbuffer9.c
index 4e65ed7bc08..4029a8d6a3a 100644
--- a/src/gallium/state_trackers/nine/indexbuffer9.c
+++ b/src/gallium/state_trackers/nine/indexbuffer9.c
@@ -76,6 +76,8 @@ NineIndexBuffer9_dtor( struct NineIndexBuffer9 *This )
const struct pipe_index_buffer *
NineIndexBuffer9_GetBuffer( struct NineIndexBuffer9 *This )
{
+ /* The resource may change */
+ This->buffer.buffer = NineIndexBuffer9_GetResource(This);
return &This->buffer;
}