Rebase against 52fbaeb2c44e585cacd7f0b57e902dfbcf54d09b.

This commit is contained in:
Sebastian Lackner
2017-08-09 08:45:29 +02:00
parent 51d419bbeb
commit 6edf4d136c
11 changed files with 197 additions and 704 deletions

View File

@@ -1,270 +0,0 @@
From ff6b6ee44f1e98b9f74ddddd1d7ada999283b135 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <jkucia@codeweavers.com>
Date: Sun, 23 Jul 2017 22:00:30 +0200
Subject: wined3d: Implement support for setting uav counters.
---
dlls/d3d11/device.c | 13 +++++++------
dlls/d3d11/tests/d3d11.c | 2 +-
dlls/wined3d/cs.c | 7 ++++++-
dlls/wined3d/device.c | 15 ++++++++-------
dlls/wined3d/view.c | 18 ++++++++++++++++++
dlls/wined3d/wined3d.spec | 4 ++--
dlls/wined3d/wined3d_private.h | 4 +++-
include/wine/wined3d.h | 4 ++--
8 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 93938f98f0d..c7e19ed1313 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -1601,7 +1601,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetRenderTargetsAndUnord
wined3d_mutex_lock();
for (i = 0; i < unordered_access_view_start_slot; ++i)
{
- wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL);
+ wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL, ~0u);
}
for (i = 0; i < unordered_access_view_count; ++i)
{
@@ -1616,12 +1616,13 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_OMSetRenderTargetsAndUnord
wined3d_device_set_unordered_access_view(device->wined3d_device,
unordered_access_view_start_slot + i,
- view ? view->wined3d_view : NULL);
+ view ? view->wined3d_view : NULL,
+ initial_counts ? initial_counts[i] : ~0u);
}
for (; unordered_access_view_start_slot + i < D3D11_PS_CS_UAV_REGISTER_COUNT; ++i)
{
wined3d_device_set_unordered_access_view(device->wined3d_device,
- unordered_access_view_start_slot + i, NULL);
+ unordered_access_view_start_slot + i, NULL, ~0u);
}
wined3d_mutex_unlock();
}
@@ -2296,7 +2297,7 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CSSetUnorderedAccessViews(
FIXME("Ignoring initial count %u for slot %u.\n", initial_counts[i], start_slot + i);
wined3d_device_set_cs_uav(device->wined3d_device, start_slot + i,
- view ? view->wined3d_view : NULL);
+ view ? view->wined3d_view : NULL, initial_counts ? initial_counts[i] : ~0u);
}
wined3d_mutex_unlock();
}
@@ -3438,8 +3439,8 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_ClearState(ID3D11DeviceCon
wined3d_device_set_depth_stencil_view(device->wined3d_device, NULL);
for (i = 0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; ++i)
{
- wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL);
- wined3d_device_set_cs_uav(device->wined3d_device, i, NULL);
+ wined3d_device_set_unordered_access_view(device->wined3d_device, i, NULL, ~0u);
+ wined3d_device_set_cs_uav(device->wined3d_device, i, NULL, ~0u);
}
ID3D11DeviceContext_OMSetDepthStencilState(iface, NULL, 0);
ID3D11DeviceContext_OMSetBlendState(iface, NULL, blend_factor, D3D11_DEFAULT_SAMPLE_MASK);
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 2cfc9ce812d..7a851d924a0 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -19067,7 +19067,7 @@ static void test_uav_counters(void)
for (i = 0; i < 8; ++i)
{
data = get_readback_color(&rb, i, 0);
- todo_wine ok(data == 0xdeadbeef, "Got data %u at %u.\n", data, i);
+ ok(data == 0xdeadbeef, "Got data %u at %u.\n", data, i);
}
release_resource_readback(&rb);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 92da18576e3..66876b6d172 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -244,6 +244,7 @@ struct wined3d_cs_set_unordered_access_view
enum wined3d_pipeline pipeline;
unsigned int view_idx;
struct wined3d_unordered_access_view *view;
+ unsigned int initial_count;
};
struct wined3d_cs_set_sampler
@@ -1298,10 +1299,13 @@ static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, con
InterlockedDecrement(&prev->resource->bind_count);
device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline));
+
+ if (op->view && op->initial_count != ~0u)
+ wined3d_unordered_access_view_set_counter(op->view, op->initial_count);
}
void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline,
- unsigned int view_idx, struct wined3d_unordered_access_view *view)
+ unsigned int view_idx, struct wined3d_unordered_access_view *view, unsigned int initial_count)
{
struct wined3d_cs_set_unordered_access_view *op;
@@ -1310,6 +1314,7 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined
op->pipeline = pipeline;
op->view_idx = view_idx;
op->view = view;
+ op->initial_count = initial_count;
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a9c0a9ccc09..9841b5fd461 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3002,7 +3002,8 @@ struct wined3d_sampler * CDECL wined3d_device_get_cs_sampler(const struct wined3
}
static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_device *device,
- enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav)
+ enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav,
+ unsigned int initial_count)
{
struct wined3d_unordered_access_view *prev;
@@ -3013,14 +3014,14 @@ static void wined3d_device_set_pipeline_unordered_access_view(struct wined3d_dev
}
prev = device->update_state->unordered_access_view[pipeline][idx];
- if (uav == prev)
+ if (uav == prev && initial_count == ~0u)
return;
if (uav)
wined3d_unordered_access_view_incref(uav);
device->update_state->unordered_access_view[pipeline][idx] = uav;
if (!device->recording)
- wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav);
+ wined3d_cs_emit_set_unordered_access_view(device->cs, pipeline, idx, uav, initial_count);
if (prev)
wined3d_unordered_access_view_decref(prev);
}
@@ -3038,11 +3039,11 @@ static struct wined3d_unordered_access_view *wined3d_device_get_pipeline_unorder
}
void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
- struct wined3d_unordered_access_view *uav)
+ struct wined3d_unordered_access_view *uav, unsigned int initial_count)
{
TRACE("device %p, idx %u, uav %p.\n", device, idx, uav);
- wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav);
+ wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_COMPUTE, idx, uav, initial_count);
}
struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const struct wined3d_device *device,
@@ -3054,11 +3055,11 @@ struct wined3d_unordered_access_view * CDECL wined3d_device_get_cs_uav(const str
}
void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device,
- unsigned int idx, struct wined3d_unordered_access_view *uav)
+ unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count)
{
TRACE("device %p, idx %u, uav %p.\n", device, idx, uav);
- wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav);
+ wined3d_device_set_pipeline_unordered_access_view(device, WINED3D_PIPELINE_GRAPHICS, idx, uav, initial_count);
}
struct wined3d_unordered_access_view * CDECL wined3d_device_get_unordered_access_view(
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 788946b81c2..260002eea12 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -909,6 +909,24 @@ void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_vi
checkGLcall("clear unordered access view");
}
+void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view,
+ unsigned int initial_count)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ GLuint value = initial_count;
+
+ if (!view->counter_bo)
+ return;
+
+ context = context_acquire(view->resource->device, NULL, 0);
+ gl_info = context->gl_info;
+ GL_EXTCALL(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, view->counter_bo));
+ GL_EXTCALL(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(value), &value));
+ checkGLcall("set atomic counter");
+ context_release(context);
+}
+
static void wined3d_unordered_access_view_cs_init(void *object)
{
struct wined3d_unordered_access_view *view = object;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 5de3ef730eb..631418bdaa9 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -129,7 +129,7 @@
@ cdecl wined3d_device_set_cs_cb(ptr long ptr)
@ cdecl wined3d_device_set_cs_resource_view(ptr long ptr)
@ cdecl wined3d_device_set_cs_sampler(ptr long ptr)
-@ cdecl wined3d_device_set_cs_uav(ptr long ptr)
+@ cdecl wined3d_device_set_cs_uav(ptr long ptr long)
@ cdecl wined3d_device_set_cursor_position(ptr long long long)
@ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long)
@ cdecl wined3d_device_set_depth_stencil_view(ptr ptr)
@@ -174,7 +174,7 @@
@ cdecl wined3d_device_set_texture(ptr long ptr)
@ cdecl wined3d_device_set_texture_stage_state(ptr long long long)
@ cdecl wined3d_device_set_transform(ptr long ptr)
-@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr)
+@ cdecl wined3d_device_set_unordered_access_view(ptr long ptr long)
@ cdecl wined3d_device_set_vertex_declaration(ptr ptr)
@ cdecl wined3d_device_set_vertex_shader(ptr ptr)
@ cdecl wined3d_device_set_viewport(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e95911ed0d5..ca477b3a270 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3506,7 +3506,7 @@ void wined3d_cs_emit_set_texture_state(struct wined3d_cs *cs, UINT stage,
void wined3d_cs_emit_set_transform(struct wined3d_cs *cs, enum wined3d_transform_state state,
const struct wined3d_matrix *matrix) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, enum wined3d_pipeline pipeline,
- unsigned int view_idx, struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN;
+ unsigned int view_idx, struct wined3d_unordered_access_view *view, unsigned int initial_count) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
@@ -3680,6 +3680,8 @@ void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_vi
const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view,
DWORD location) DECLSPEC_HIDDEN;
+void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_view *view,
+ unsigned int initial_count) DECLSPEC_HIDDEN;
struct wined3d_swapchain_ops
{
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 6c5c5df83ff..22d49435caf 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2372,7 +2372,7 @@ void __cdecl wined3d_device_set_cs_resource_view(struct wined3d_device *device,
void __cdecl wined3d_device_set_cs_sampler(struct wined3d_device *device,
unsigned int idx, struct wined3d_sampler *sampler);
void __cdecl wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
- struct wined3d_unordered_access_view *uav);
+ struct wined3d_unordered_access_view *uav, unsigned int initial_count);
void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device,
int x_screen_space, int y_screen_space, DWORD flags);
HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device,
@@ -2443,7 +2443,7 @@ void __cdecl wined3d_device_set_texture_stage_state(struct wined3d_device *devic
void __cdecl wined3d_device_set_transform(struct wined3d_device *device,
enum wined3d_transform_state state, const struct wined3d_matrix *matrix);
void __cdecl wined3d_device_set_unordered_access_view(struct wined3d_device *device,
- unsigned int idx, struct wined3d_unordered_access_view *uav);
+ unsigned int idx, struct wined3d_unordered_access_view *uav, unsigned int initial_count);
void __cdecl wined3d_device_set_vertex_declaration(struct wined3d_device *device,
struct wined3d_vertex_declaration *declaration);
void __cdecl wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader);
--
2.13.1

View File

@@ -0,0 +1,102 @@
From 421a9c0b534a902617188f3eb0e4f26ce8897613 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 9 Aug 2017 06:32:43 +0200
Subject: wined3d: Remaining UAV counter changes.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Based on patches by Michael Müller and Józef Kucia.
---
dlls/d3d11/device.c | 3 +++
dlls/wined3d/cs.c | 4 +++-
dlls/wined3d/device.c | 6 ++++++
dlls/wined3d/view.c | 5 +----
4 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 0f268dfed27..5f8d0f3ec13 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -1026,6 +1026,9 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CopyStructureCount(ID3D11D
TRACE("iface %p, dst_buffer %p, dst_offset %u, src_view %p.\n",
iface, dst_buffer, dst_offset, src_view);
+ if (!dst_buffer || !src_view)
+ return;
+
buffer_impl = unsafe_impl_from_ID3D11Buffer(dst_buffer);
uav = unsafe_impl_from_ID3D11UnorderedAccessView(src_view);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index a76598ff4ca..39a85fa513d 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -1295,7 +1295,7 @@ static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, con
device_invalidate_state(cs->device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline));
- if (op->initial_count != ~0u)
+ if (op->view && op->initial_count != ~0u)
wined3d_unordered_access_view_set_counter(op->view, op->initial_count);
}
@@ -2252,6 +2252,7 @@ static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void *
context_release(context);
wined3d_resource_release(&op->buffer->resource);
+ wined3d_resource_release(view->resource);
}
void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
@@ -2266,6 +2267,7 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff
op->view = uav;
wined3d_resource_acquire(&dst_buffer->resource);
+ wined3d_resource_acquire(uav->resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 30e7fbed02a..3ecd9952893 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3966,6 +3966,12 @@ void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device,
TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n",
device, dst_buffer, offset, uav);
+ if (offset + sizeof(GLuint) > dst_buffer->resource.size)
+ {
+ WARN("Offset %u too large.\n", offset);
+ return;
+ }
+
wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav);
}
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index f4f3b35f20c..896bc12bd32 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -953,7 +953,7 @@ static void wined3d_unordered_access_view_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0);
gl_info = context->gl_info;
create_buffer_view(&view->gl_view, context, desc, buffer, view->format);
- if (desc->flags & WINED3D_VIEW_BUFFER_COUNTER)
+ if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER|WINED3D_VIEW_BUFFER_APPEND))
{
static const GLuint initial_value = 0;
GL_EXTCALL(glGenBuffers(1, &view->counter_bo));
@@ -994,9 +994,6 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces
return E_INVALIDARG;
view->desc = *desc;
- if (desc->flags & WINED3D_VIEW_BUFFER_APPEND)
- FIXME("Unhandled view flags %#x.\n", desc->flags);
-
wined3d_resource_incref(view->resource = resource);
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view);
--
2.13.1

View File

@@ -1,36 +0,0 @@
From 10ed488c6db658380491805b03172eef139ba957 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B3zef=20Kucia?= <jkucia@codeweavers.com>
Date: Sun, 23 Jul 2017 22:38:36 +0200
Subject: wined3d: Create atomic counter when uav is initialized with
WINED3D_VIEW_BUFFER_APPEND.
---
dlls/wined3d/view.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 5ef23eacbde..ed112edf4e3 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -937,7 +937,7 @@ static void wined3d_unordered_access_view_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0);
gl_info = context->gl_info;
create_buffer_view(&view->gl_view, context, desc, buffer, view->format);
- if (desc->flags & WINED3D_VIEW_BUFFER_COUNTER)
+ if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER|WINED3D_VIEW_BUFFER_APPEND))
{
static const GLuint initial_value = 0;
GL_EXTCALL(glGenBuffers(1, &view->counter_bo));
@@ -978,9 +978,6 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces
return E_INVALIDARG;
view->desc = *desc;
- if (desc->flags & WINED3D_VIEW_BUFFER_APPEND)
- FIXME("Unhandled view flags %#x.\n", desc->flags);
-
wined3d_resource_incref(view->resource = resource);
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_cs_init, view);
--
2.13.1

View File

@@ -1,297 +0,0 @@
From f7b7f46dd1865c7d71a2c5f7226f17b567d6c49e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 23 Jul 2017 22:41:09 +0200
Subject: wined3d: Implement copying structure count of uav.
---
dlls/d3d11/device.c | 16 +++++++++++-
dlls/d3d11/tests/d3d11.c | 8 +++---
dlls/wined3d/buffer.c | 55 ++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/cs.c | 41 +++++++++++++++++++++++++++++++
dlls/wined3d/device.c | 16 ++++++++++++
dlls/wined3d/wined3d.spec | 1 +
dlls/wined3d/wined3d_private.h | 4 +++
include/wine/wined3d.h | 2 ++
8 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 5662fc23a0c..b7be1194930 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -1973,8 +1973,22 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_UpdateSubresource(ID3D11De
static void STDMETHODCALLTYPE d3d11_immediate_context_CopyStructureCount(ID3D11DeviceContext *iface,
ID3D11Buffer *dst_buffer, UINT dst_offset, ID3D11UnorderedAccessView *src_view)
{
- FIXME("iface %p, dst_buffer %p, dst_offset %u, src_view %p stub!\n",
+ struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface);
+ struct d3d11_unordered_access_view *view;
+ struct d3d_buffer *buffer;
+
+ TRACE("iface %p, dst_buffer %p, dst_offset %u, src_view %p.\n",
iface, dst_buffer, dst_offset, src_view);
+
+ if (!dst_buffer || !src_view)
+ return;
+
+ buffer = unsafe_impl_from_ID3D11Buffer(dst_buffer);
+ view = unsafe_impl_from_ID3D11UnorderedAccessView(src_view);
+
+ wined3d_mutex_lock();
+ wined3d_device_copy_structure_count(device->wined3d_device, buffer->wined3d_buffer, dst_offset, view->wined3d_view);
+ wined3d_mutex_unlock();
}
static void STDMETHODCALLTYPE d3d11_immediate_context_ClearRenderTargetView(ID3D11DeviceContext *iface,
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index d2671643016..1e569fe4b9e 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -18982,7 +18982,7 @@ static void test_uav_counters(void)
data = 8;
ID3D11DeviceContext_CSSetUnorderedAccessViews(context, 0, 1, &uav, &data);
data = read_uav_counter(context, staging_buffer, uav);
- todo_wine ok(data == 8, "Got unexpected value %u.\n", data);
+ ok(data == 8, "Got unexpected value %u.\n", data);
ID3D11DeviceContext_CSSetShader(context, cs_producer, NULL, 0);
data = 0;
@@ -18994,7 +18994,7 @@ static void test_uav_counters(void)
/* produce */
ID3D11DeviceContext_Dispatch(context, 16, 1, 1);
data = read_uav_counter(context, staging_buffer, uav);
- todo_wine ok(data == 64, "Got unexpected value %u.\n", data);
+ ok(data == 64, "Got unexpected value %u.\n", data);
get_buffer_readback(buffer, &rb);
memcpy(id, rb.map_desc.pData, 64 * sizeof(*id));
release_resource_readback(&rb);
@@ -19030,12 +19030,12 @@ static void test_uav_counters(void)
data = 8;
ID3D11DeviceContext_CSSetUnorderedAccessViews(context, 0, 1, &uav, &data);
data = read_uav_counter(context, staging_buffer, uav);
- todo_wine ok(data == 8, "Got unexpected value %u.\n", data);
+ ok(data == 8, "Got unexpected value %u.\n", data);
/* consume */
ID3D11DeviceContext_Dispatch(context, 1, 1, 1);
data = read_uav_counter(context, staging_buffer, uav);
- todo_wine ok(data == 4, "Got unexpected value %u.\n", data);
+ ok(data == 4, "Got unexpected value %u.\n", data);
ID3D11DeviceContext_Dispatch(context, 1, 1, 1);
data = read_uav_counter(context, staging_buffer, uav);
ok(!data, "Got unexpected value %u.\n", data);
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 040e56625d3..ad0b677f7fa 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1259,6 +1259,61 @@ HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_
return WINED3D_OK;
}
+/* caller is responsible for tracking state of gl buffer binding */
+HRESULT wined3d_buffer_copy_from_gl_buffer(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
+ GLuint src_buffer, GLenum src_target, unsigned int src_offset, unsigned int size)
+{
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_bo_address dst;
+ struct wined3d_context *context;
+ struct wined3d_device *device;
+ DWORD dst_location;
+ BYTE *dst_ptr;
+
+ buffer_mark_used(dst_buffer);
+
+ device = dst_buffer->resource.device;
+
+ context = context_acquire(device, NULL, 0);
+ gl_info = context->gl_info;
+
+ dst_location = wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations);
+ dst.addr += dst_offset;
+
+ if (dst.buffer_object)
+ {
+ if (gl_info->supported[ARB_COPY_BUFFER])
+ {
+ GL_EXTCALL(glBindBuffer(GL_COPY_READ_BUFFER, src_buffer));
+ GL_EXTCALL(glBindBuffer(GL_COPY_WRITE_BUFFER, dst.buffer_object));
+ GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
+ src_offset, dst_offset, size));
+ checkGLcall("direct buffer copy");
+ }
+ else
+ {
+ dst_ptr = context_map_bo_address(context, &dst, size, dst_buffer->buffer_type_hint, 0);
+
+ GL_EXTCALL(glBindBuffer(src_target, src_buffer));
+ GL_EXTCALL(glGetBufferSubData(src_target, src_offset, size, dst_ptr));
+ checkGLcall("buffer download");
+
+ context_unmap_bo_address(context, &dst, dst_buffer->buffer_type_hint);
+ }
+ }
+ else
+ {
+ GL_EXTCALL(glBindBuffer(src_target, src_buffer));
+ GL_EXTCALL(glGetBufferSubData(src_target, src_offset, size, dst.addr));
+ checkGLcall("buffer download");
+ }
+
+ wined3d_buffer_invalidate_range(dst_buffer, ~dst_location, dst_offset, size);
+
+ context_release(context);
+ return WINED3D_OK;
+}
+
HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer,
const struct wined3d_box *box, const void *data)
{
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 2d6544143e4..4314a4807a8 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -71,6 +71,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION,
WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW,
WINED3D_CS_OP_COPY_SUB_RESOURCE,
+ WINED3D_CS_OP_COPY_STRUCTURE_COUNT,
WINED3D_CS_OP_STOP,
};
@@ -431,6 +432,14 @@ struct wined3d_cs_copy_sub_resource
struct wined3d_box src_box;
};
+struct wined3d_cs_copy_structure_count
+{
+ enum wined3d_cs_op opcode;
+ struct wined3d_buffer *dst_buffer;
+ unsigned int offset;
+ struct wined3d_unordered_access_view *src_view;
+};
+
struct wined3d_cs_stop
{
enum wined3d_cs_op opcode;
@@ -2380,6 +2389,37 @@ void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_res
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
}
+static void wined3d_cs_exec_copy_structure_count(struct wined3d_cs *cs, const void *data)
+{
+ const struct wined3d_cs_copy_structure_count *op = data;
+
+ if (op->src_view->counter_bo)
+ {
+ wined3d_buffer_copy_from_gl_buffer(op->dst_buffer, op->offset,
+ op->src_view->counter_bo, GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint));
+ }
+
+ wined3d_resource_release(&op->dst_buffer->resource);
+ wined3d_resource_release(op->src_view->resource);
+}
+
+void wined3d_cs_emit_copy_structure_count(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
+ unsigned int offset, struct wined3d_unordered_access_view *src_view)
+{
+ struct wined3d_cs_copy_structure_count *op;
+
+ op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+ op->opcode = WINED3D_CS_OP_COPY_STRUCTURE_COUNT;
+ op->dst_buffer = dst_buffer;
+ op->offset = offset;
+ op->src_view = src_view;
+
+ wined3d_resource_acquire(&dst_buffer->resource);
+ wined3d_resource_acquire(src_view->resource);
+
+ cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
static void wined3d_cs_emit_stop(struct wined3d_cs *cs)
{
struct wined3d_cs_stop *op;
@@ -2438,6 +2478,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION */ wined3d_cs_exec_add_dirty_texture_region,
/* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view,
/* WINED3D_CS_OP_COPY_SUB_RESOURCE */ wined3d_cs_exec_copy_sub_resource,
+ /* WINED3D_CS_OP_COPY_STRUCTURE_COUNT */ wined3d_cs_exec_copy_structure_count,
};
static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 223885272f2..7cf3e0319d4 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4289,6 +4289,22 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str
wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch);
}
+HRESULT CDECL wined3d_device_copy_structure_count(struct wined3d_device *device, struct wined3d_buffer *dst_buffer,
+ unsigned int offset, struct wined3d_unordered_access_view *src_view)
+{
+ TRACE("device %p, dst_buffer %p, offset %u, src_view %p.\n",
+ device, dst_buffer, offset, src_view);
+
+ if (offset + sizeof(GLuint) > dst_buffer->resource.size)
+ {
+ WARN("Offset %u too large.\n", offset);
+ return WINED3DERR_INVALIDCALL;
+ }
+
+ wined3d_cs_emit_copy_structure_count(device->cs, dst_buffer, offset, src_view);
+ return WINED3D_OK;
+}
+
HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *device,
struct wined3d_rendertarget_view *view, const RECT *rect, DWORD flags,
const struct wined3d_color *color, float depth, DWORD stencil)
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 631418bdaa9..f0f6871a8a2 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -37,6 +37,7 @@
@ cdecl wined3d_device_clear_rendertarget_view(ptr ptr ptr long ptr float long)
@ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr)
@ cdecl wined3d_device_copy_resource(ptr ptr ptr)
+@ cdecl wined3d_device_copy_structure_count(ptr ptr long ptr)
@ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr)
@ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr)
@ cdecl wined3d_device_decref(ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 50321f37c3a..548a9679f3f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3488,6 +3488,8 @@ void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resou
void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *resource,
unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch,
unsigned int slice_pitch) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_copy_structure_count(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer,
+ unsigned int offset, struct wined3d_unordered_access_view *src_view) DECLSPEC_HIDDEN;
void wined3d_cs_emit_copy_sub_resource(struct wined3d_cs *cs, struct wined3d_resource *dst_resource,
unsigned int dst_sub_resource_idx, const struct wined3d_box *dst_box, struct wined3d_resource *src_resource,
unsigned int src_sub_resource_idx, const struct wined3d_box *src_box) DECLSPEC_HIDDEN;
@@ -3571,6 +3573,8 @@ BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
BYTE *wined3d_buffer_load_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
struct wined3d_buffer *src_buffer, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN;
+HRESULT wined3d_buffer_copy_from_gl_buffer(struct wined3d_buffer *dst_buffer, unsigned int dst_offset,
+ GLuint src_buffer, GLenum src_target, unsigned int src_offset, unsigned int size) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer,
const struct wined3d_box *box, const void *data) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index bf182c68813..a0a5a1debcf 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2456,6 +2456,8 @@ void __cdecl wined3d_device_update_sub_resource(struct wined3d_device *device, s
HRESULT __cdecl wined3d_device_update_texture(struct wined3d_device *device,
struct wined3d_texture *src_texture, struct wined3d_texture *dst_texture);
HRESULT __cdecl wined3d_device_validate_device(const struct wined3d_device *device, DWORD *num_passes);
+HRESULT __cdecl wined3d_device_copy_structure_count(struct wined3d_device *device, struct wined3d_buffer *dst_buffer,
+ unsigned int offset, struct wined3d_unordered_access_view *src_view);
HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags,
unsigned int entry_count, const PALETTEENTRY *entries, struct wined3d_palette **palette);
--
2.13.1