diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 733d7204..3c474935 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -447,6 +447,7 @@ patch_enable_all () enable_wined3d_Revert_Buffer_Upload="$1" enable_wined3d_SM4_OP_NOP="$1" enable_wined3d_Silence_FIXMEs="$1" + enable_wined3d_UAV_Counters="$1" enable_wined3d_WINED3DFMT_R32G32_UINT="$1" enable_wined3d_WINED3D_RS_COLORWRITEENABLE="$1" enable_wined3d_buffer_create="$1" @@ -1604,6 +1605,9 @@ patch_enable () wined3d-Silence_FIXMEs) enable_wined3d_Silence_FIXMEs="$2" ;; + wined3d-UAV_Counters) + enable_wined3d_UAV_Counters="$2" + ;; wined3d-WINED3DFMT_R32G32_UINT) enable_wined3d_WINED3DFMT_R32G32_UINT="$2" ;; @@ -2224,6 +2228,9 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then if test "$enable_wined3d_Silence_FIXMEs" -gt 1; then abort "Patchset wined3d-Silence_FIXMEs disabled, but wined3d-CSMT_Helper depends on that." fi + if test "$enable_wined3d_UAV_Counters" -gt 1; then + abort "Patchset wined3d-UAV_Counters disabled, but wined3d-CSMT_Helper depends on that." + fi enable_d3d11_Deferred_Context=1 enable_d3d9_Tests=1 enable_makedep_PARENTSPEC=1 @@ -2235,6 +2242,18 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then enable_wined3d_QUERY_Stubs=1 enable_wined3d_Revert_Buffer_Upload=1 enable_wined3d_Silence_FIXMEs=1 + enable_wined3d_UAV_Counters=1 +fi + +if test "$enable_wined3d_UAV_Counters" -eq 1; then + if test "$enable_wined3d_Copy_Resource_Typeless" -gt 1; then + abort "Patchset wined3d-Copy_Resource_Typeless disabled, but wined3d-UAV_Counters depends on that." + fi + if test "$enable_wined3d_Revert_Buffer_Upload" -gt 1; then + abort "Patchset wined3d-Revert_Buffer_Upload disabled, but wined3d-UAV_Counters depends on that." + fi + enable_wined3d_Copy_Resource_Typeless=1 + enable_wined3d_Revert_Buffer_Upload=1 fi if test "$enable_wined3d_Copy_Resource_Typeless" -eq 1; then @@ -9359,12 +9378,36 @@ if test "$enable_wined3d_Silence_FIXMEs" -eq 1; then ) >> "$patchlist" fi +# Patchset wined3d-UAV_Counters +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * d3d11-Depth_Bias, wined3d-1DTextures, wined3d-Copy_Resource_Typeless, wined3d-Revert_Buffer_Upload +# | +# | This patchset fixes the following Wine bugs: +# | * [#43405] Implement copying structure count of UAV +# | +# | Modified files: +# | * dlls/d3d11/device.c, dlls/d3d11/tests/d3d11.c, dlls/wined3d/buffer.c, dlls/wined3d/cs.c, dlls/wined3d/device.c, +# | dlls/wined3d/view.c, dlls/wined3d/wined3d.spec, dlls/wined3d/wined3d_private.h, include/wine/wined3d.h +# | +if test "$enable_wined3d_UAV_Counters" -eq 1; then + patch_apply wined3d-UAV_Counters/0001-wined3d-Implement-support-for-setting-uav-counters.patch + patch_apply wined3d-UAV_Counters/0002-wined3d-Create-atomic-counter-when-uav-is-initialize.patch + patch_apply wined3d-UAV_Counters/0003-wined3d-Implement-copying-structure-count-of-uav.patch + ( + printf '%s\n' '+ { "Józef Kucia", "wined3d: Implement support for setting uav counters.", 1 },'; + printf '%s\n' '+ { "Józef Kucia", "wined3d: Create atomic counter when uav is initialized with WINED3D_VIEW_BUFFER_APPEND.", 1 },'; + printf '%s\n' '+ { "Michael Müller", "wined3d: Implement copying structure count of uav.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wined3d-CSMT_Helper # | # | This patchset has the following (direct or indirect) dependencies: # | * d3d11-Deferred_Context, d3d9-Tests, makedep-PARENTSPEC, ntdll-Attach_Process_DLLs, ntdll-DllOverrides_WOW64, ntdll- # | Loader_Machine_Type, ntdll-DllRedirects, wined3d-1DTextures, wined3d-Accounting, d3d11-Depth_Bias, wined3d- -# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs +# | Copy_Resource_Typeless, wined3d-DXTn, wined3d-QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, +# | wined3d-UAV_Counters # | # | Modified files: # | * configure.ac, dlls/wined3d-csmt/Makefile.in, dlls/wined3d-csmt/version.rc @@ -9538,7 +9581,7 @@ fi # | * d3d11-Deferred_Context, d3d9-Tests, makedep-PARENTSPEC, ntdll-Attach_Process_DLLs, ntdll-DllOverrides_WOW64, ntdll- # | Loader_Machine_Type, ntdll-DllRedirects, wined3d-1DTextures, wined3d-Accounting, d3d11-Depth_Bias, wined3d- # | Copy_Resource_Typeless, wined3d-DXTn, wined3d-QUERY_Stubs, wined3d-Revert_Buffer_Upload, wined3d-Silence_FIXMEs, -# | wined3d-CSMT_Helper +# | wined3d-UAV_Counters, wined3d-CSMT_Helper # | # | This patchset fixes the following Wine bugs: # | * [#11674] Support for CSMT (command stream) to increase graphic performance diff --git a/patches/wined3d-CSMT_Helper/definition b/patches/wined3d-CSMT_Helper/definition index 7f50538d..0965ea1a 100644 --- a/patches/wined3d-CSMT_Helper/definition +++ b/patches/wined3d-CSMT_Helper/definition @@ -5,6 +5,7 @@ Depends: wined3d-1DTextures Depends: wined3d-Silence_FIXMEs Depends: wined3d-Revert_Buffer_Upload Depends: wined3d-Copy_Resource_Typeless +Depends: wined3d-UAV_Counters Depends: d3d9-Tests Depends: d3d11-Deferred_Context Depends: makedep-PARENTSPEC diff --git a/patches/wined3d-CSMT_Main/0045-wined3d-Improve-wined3d_cs_emit_update_sub_resource.patch b/patches/wined3d-CSMT_Main/0045-wined3d-Improve-wined3d_cs_emit_update_sub_resource.patch index 57656490..5a8d2fde 100644 --- a/patches/wined3d-CSMT_Main/0045-wined3d-Improve-wined3d_cs_emit_update_sub_resource.patch +++ b/patches/wined3d-CSMT_Main/0045-wined3d-Improve-wined3d_cs_emit_update_sub_resource.patch @@ -1,4 +1,4 @@ -From 1c8d189c654011204d1c15673ae128930778c4b6 Mon Sep 17 00:00:00 2001 +From c2675926347686e6a56f4925abb72568ddf8e3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Mon, 20 Feb 2017 00:27:25 +0100 Subject: wined3d: Improve wined3d_cs_emit_update_sub_resource. @@ -10,10 +10,10 @@ Subject: wined3d: Improve wined3d_cs_emit_update_sub_resource. 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c -index c2b5a2f965f..8a4f4358e9d 100644 +index 4314a4807a8..b8710137a3c 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c -@@ -403,6 +403,7 @@ struct wined3d_cs_update_sub_resource +@@ -405,6 +405,7 @@ struct wined3d_cs_update_sub_resource unsigned int sub_resource_idx; struct wined3d_box box; struct wined3d_sub_resource_data data; @@ -21,7 +21,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 }; struct wined3d_cs_add_dirty_texture_region -@@ -2150,6 +2151,51 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r +@@ -2164,6 +2165,51 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r unsigned int slice_pitch) { struct wined3d_cs_update_sub_resource *op; @@ -73,7 +73,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; -@@ -2163,8 +2209,6 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r +@@ -2177,8 +2223,6 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r wined3d_resource_acquire(resource); cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); @@ -82,8 +82,8 @@ index c2b5a2f965f..8a4f4358e9d 100644 cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); } -@@ -2435,6 +2479,11 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_COPY_SUB_RESOURCE */ wined3d_cs_exec_copy_sub_resource, +@@ -2481,6 +2525,11 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_COPY_STRUCTURE_COUNT */ wined3d_cs_exec_copy_structure_count, }; +static BOOL wined3d_cs_st_check_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) @@ -94,7 +94,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (size > (cs->data_size - cs->end)) -@@ -2488,6 +2537,7 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2534,6 +2583,7 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_st_ops = { @@ -102,7 +102,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 wined3d_cs_st_require_space, wined3d_cs_st_submit, wined3d_cs_st_finish, -@@ -2520,6 +2570,19 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2566,6 +2616,19 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id wined3d_cs_queue_submit(&cs->queue[queue_id], cs); } @@ -122,7 +122,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs) { size_t queue_size = ARRAY_SIZE(queue->data); -@@ -2581,6 +2644,14 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size +@@ -2627,6 +2690,14 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size return packet->data; } @@ -137,7 +137,7 @@ index c2b5a2f965f..8a4f4358e9d 100644 static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (cs->thread_id == GetCurrentThreadId()) -@@ -2600,6 +2671,7 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2646,6 +2717,7 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_mt_ops = { @@ -146,10 +146,10 @@ index c2b5a2f965f..8a4f4358e9d 100644 wined3d_cs_mt_submit, wined3d_cs_mt_finish, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c -index 56171835762..23f14349a62 100644 +index 489e8eb6bb3..1125bb33f70 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c -@@ -4285,8 +4285,6 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str +@@ -4284,8 +4284,6 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str return; } @@ -159,10 +159,10 @@ index 56171835762..23f14349a62 100644 } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h -index bd43fc55dea..e1a79f6282c 100644 +index 1574b9c9c9e..3f1184349b5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h -@@ -3398,6 +3398,7 @@ struct wined3d_cs_queue +@@ -3399,6 +3399,7 @@ struct wined3d_cs_queue struct wined3d_cs_ops { diff --git a/patches/wined3d-CSMT_Main/9999-IfDefined.patch b/patches/wined3d-CSMT_Main/9999-IfDefined.patch index 49309b55..ac6c0808 100644 --- a/patches/wined3d-CSMT_Main/9999-IfDefined.patch +++ b/patches/wined3d-CSMT_Main/9999-IfDefined.patch @@ -9,7 +9,7 @@ Based on patches by: diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c -@@ -1263,6 +1263,9 @@ HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, +@@ -1318,6 +1318,9 @@ HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, const struct wined3d_box *box, const void *data) { UINT offset, size; @@ -19,7 +19,7 @@ diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c HRESULT hr; BYTE *ptr; -@@ -1277,7 +1280,14 @@ HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, +@@ -1332,7 +1335,14 @@ HRESULT wined3d_buffer_upload_data(struct wined3d_buffer *buffer, size = buffer->resource.size; } @@ -37,7 +37,7 @@ diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c -@@ -403,6 +403,9 @@ struct wined3d_cs_update_sub_resource +@@ -405,6 +405,9 @@ struct wined3d_cs_update_sub_resource unsigned int sub_resource_idx; struct wined3d_box box; struct wined3d_sub_resource_data data; @@ -47,7 +47,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c }; struct wined3d_cs_add_dirty_texture_region -@@ -2150,6 +2153,53 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r +@@ -2164,6 +2167,53 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r unsigned int slice_pitch) { struct wined3d_cs_update_sub_resource *op; @@ -101,7 +101,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_MAP); op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; -@@ -2163,8 +2213,10 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r +@@ -2177,8 +2227,10 @@ void wined3d_cs_emit_update_sub_resource(struct wined3d_cs *cs, struct wined3d_r wined3d_resource_acquire(resource); cs->ops->submit(cs, WINED3D_CS_QUEUE_MAP); @@ -112,8 +112,8 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c cs->ops->finish(cs, WINED3D_CS_QUEUE_MAP); } -@@ -2435,6 +2487,13 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void - /* WINED3D_CS_OP_COPY_SUB_RESOURCE */ wined3d_cs_exec_copy_sub_resource, +@@ -2481,6 +2533,13 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void + /* WINED3D_CS_OP_COPY_STRUCTURE_COUNT */ wined3d_cs_exec_copy_structure_count, }; +#if defined(STAGING_CSMT) @@ -126,7 +126,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (size > (cs->data_size - cs->end)) -@@ -2488,6 +2547,9 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2534,6 +2593,9 @@ static void wined3d_cs_st_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_st_ops = { @@ -136,7 +136,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c wined3d_cs_st_require_space, wined3d_cs_st_submit, wined3d_cs_st_finish, -@@ -2520,6 +2582,21 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2566,6 +2628,21 @@ static void wined3d_cs_mt_submit(struct wined3d_cs *cs, enum wined3d_cs_queue_id wined3d_cs_queue_submit(&cs->queue[queue_id], cs); } @@ -158,7 +158,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size_t size, struct wined3d_cs *cs) { size_t queue_size = ARRAY_SIZE(queue->data); -@@ -2581,6 +2658,16 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size +@@ -2627,6 +2704,16 @@ static void *wined3d_cs_queue_require_space(struct wined3d_cs_queue *queue, size return packet->data; } @@ -175,7 +175,7 @@ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c static void *wined3d_cs_mt_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) { if (cs->thread_id == GetCurrentThreadId()) -@@ -2600,6 +2687,9 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id +@@ -2646,6 +2733,9 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id static const struct wined3d_cs_ops wined3d_cs_mt_ops = { @@ -198,7 +198,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c wined3d_device_delete_opengl_contexts(device); if (device->fb.depth_stencil) -@@ -4178,6 +4181,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev +@@ -4179,6 +4182,7 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev return WINED3DERR_INVALIDCALL; } @@ -206,7 +206,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c if (dst_texture->sub_resources[dst_sub_resource_idx].map_count) { WARN("Destination sub-resource %u is mapped.\n", dst_sub_resource_idx); -@@ -4188,6 +4192,19 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev +@@ -4189,6 +4193,19 @@ HRESULT CDECL wined3d_device_copy_sub_resource_region(struct wined3d_device *dev { WARN("Source sub-resource %u is mapped.\n", src_sub_resource_idx); return WINED3DERR_INVALIDCALL; @@ -226,7 +226,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c } if (!src_box) -@@ -4281,8 +4298,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str +@@ -4282,8 +4299,10 @@ void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, str return; } @@ -237,7 +237,7 @@ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c wined3d_cs_emit_update_sub_resource(device->cs, resource, sub_resource_idx, box, data, row_pitch, depth_pitch); } -@@ -5231,3 +5250,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL +@@ -5248,3 +5267,58 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL else return CallWindowProcA(proc, window, message, wparam, lparam); } @@ -580,7 +580,7 @@ diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_cs_init, view); return WINED3D_OK; -@@ -946,6 +953,10 @@ static void wined3d_unordered_access_view_cs_init(void *object) +@@ -964,6 +971,10 @@ static void wined3d_unordered_access_view_cs_init(void *object) desc, texture, view->format); } } @@ -591,7 +591,7 @@ diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c } static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view, -@@ -965,6 +976,9 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces +@@ -980,6 +991,9 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces wined3d_resource_incref(view->resource = resource); diff --git a/patches/wined3d-UAV_Counters/0001-wined3d-Implement-support-for-setting-uav-counters.patch b/patches/wined3d-UAV_Counters/0001-wined3d-Implement-support-for-setting-uav-counters.patch new file mode 100644 index 00000000..c29af50a --- /dev/null +++ b/patches/wined3d-UAV_Counters/0001-wined3d-Implement-support-for-setting-uav-counters.patch @@ -0,0 +1,270 @@ +From ff6b6ee44f1e98b9f74ddddd1d7ada999283b135 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=B3zef=20Kucia?= +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 + diff --git a/patches/wined3d-UAV_Counters/0002-wined3d-Create-atomic-counter-when-uav-is-initialize.patch b/patches/wined3d-UAV_Counters/0002-wined3d-Create-atomic-counter-when-uav-is-initialize.patch new file mode 100644 index 00000000..0d8253d3 --- /dev/null +++ b/patches/wined3d-UAV_Counters/0002-wined3d-Create-atomic-counter-when-uav-is-initialize.patch @@ -0,0 +1,36 @@ +From 10ed488c6db658380491805b03172eef139ba957 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=B3zef=20Kucia?= +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 + diff --git a/patches/wined3d-UAV_Counters/0003-wined3d-Implement-copying-structure-count-of-uav.patch b/patches/wined3d-UAV_Counters/0003-wined3d-Implement-copying-structure-count-of-uav.patch new file mode 100644 index 00000000..12aea526 --- /dev/null +++ b/patches/wined3d-UAV_Counters/0003-wined3d-Implement-copying-structure-count-of-uav.patch @@ -0,0 +1,297 @@ +From f7b7f46dd1865c7d71a2c5f7226f17b567d6c49e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +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 + diff --git a/patches/wined3d-UAV_Counters/definition b/patches/wined3d-UAV_Counters/definition new file mode 100644 index 00000000..d1cbd344 --- /dev/null +++ b/patches/wined3d-UAV_Counters/definition @@ -0,0 +1,3 @@ +Fixes: [43405] Implement copying structure count of UAV +Depends: wined3d-Copy_Resource_Typeless +Depends: wined3d-Revert_Buffer_Upload