Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/surface.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index df0481feee1f..00bc4e4279b2 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -3778,7 +3778,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst DWORD src_ds_flags, dst_ds_flags; struct wined3d_context *context; enum wined3d_blit_op blit_op; - BOOL scale, convert; + BOOL scale, convert, resolve;
static const DWORD simple_blit = WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE @@ -3844,6 +3844,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top; convert = src_texture->resource.format->id != dst_texture->resource.format->id; + resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type;
dst_ds_flags = dst_texture->resource.format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); @@ -3954,7 +3955,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
return WINED3D_OK; } - else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert)) + else if ((flags & WINED3D_BLT_RAW) || (!scale && !convert && !resolve)) { blit_op = WINED3D_BLIT_OP_RAW_BLIT; }
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/device.c | 72 +++++++++++++++++++++++++++++++++++++---------- dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 4 +++ 3 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7881bca02b20..3961f558eb76 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1926,27 +1926,23 @@ void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, stru *viewport = device->state.viewport; }
-static void resolve_depth_buffer(struct wined3d_state *state) +static void resolve_depth_buffer(struct wined3d_device *device) { - struct wined3d_texture *dst_texture = state->textures[0]; + const struct wined3d_state *state = &device->state; struct wined3d_rendertarget_view *src_view; - RECT src_rect, dst_rect; + struct wined3d_resource *dst_resource; + struct wined3d_texture *dst_texture;
- if (!dst_texture || !(dst_texture->resource.format_flags & WINED3DFMT_FLAG_DEPTH)) + if (!(dst_texture = state->textures[0])) return; - - if (!(src_view = state->fb->depth_stencil)) + dst_resource = &dst_texture->resource; + if (!(dst_resource->format_flags & WINED3DFMT_FLAG_DEPTH)) return; - if (src_view->resource->type == WINED3D_RTYPE_BUFFER) - { - FIXME("Not supported on buffer resources.\n"); + if (!(src_view = state->fb->depth_stencil)) return; - }
- SetRect(&dst_rect, 0, 0, dst_texture->resource.width, dst_texture->resource.height); - SetRect(&src_rect, 0, 0, src_view->width, src_view->height); - wined3d_texture_blt(dst_texture, 0, &dst_rect, texture_from_resource(src_view->resource), - src_view->sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); + wined3d_device_resolve_sub_resource(device, dst_resource, 0, + src_view->resource, src_view->sub_resource_idx, dst_resource->format->id); }
void CDECL wined3d_device_set_blend_state(struct wined3d_device *device, struct wined3d_blend_state *blend_state) @@ -2033,7 +2029,7 @@ void CDECL wined3d_device_set_render_state(struct wined3d_device *device, if (state == WINED3D_RS_POINTSIZE && value == WINED3D_RESZ_CODE) { TRACE("RESZ multisampled depth buffer resolve triggered.\n"); - resolve_depth_buffer(&device->state); + resolve_depth_buffer(device); } }
@@ -4305,6 +4301,52 @@ 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); }
+void CDECL wined3d_device_resolve_sub_resource(struct wined3d_device *device, + struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, + struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, + enum wined3d_format_id format_id) +{ + struct wined3d_texture *dst_texture, *src_texture; + unsigned int dst_level, src_level; + RECT dst_rect, src_rect; + + TRACE("device %p, dst_resource %p, dst_sub_resource_idx %u, " + "src_resource %p, src_sub_resource_idx %u, format %s.\n", + device, dst_resource, dst_sub_resource_idx, + src_resource, src_sub_resource_idx, debug_d3dformat(format_id)); + + if (wined3d_format_is_typeless(dst_resource->format) + || wined3d_format_is_typeless(src_resource->format)) + { + FIXME("Unhandled multisample resolve, dst_format %s, src_format %s, format %s.\n", + debug_d3dformat(dst_resource->format->id), debug_d3dformat(src_resource->format->id), + debug_d3dformat(format_id)); + return; + } + if (dst_resource->type != WINED3D_RTYPE_TEXTURE_2D) + { + WARN("Invalid destination resource type %s.\n", debug_d3dresourcetype(dst_resource->type)); + return; + } + if (src_resource->type != WINED3D_RTYPE_TEXTURE_2D) + { + WARN("Invalid source resource type %s.\n", debug_d3dresourcetype(src_resource->type)); + return; + } + + dst_texture = texture_from_resource(dst_resource); + src_texture = texture_from_resource(src_resource); + + dst_level = dst_sub_resource_idx % dst_texture->level_count; + SetRect(&dst_rect, 0, 0, wined3d_texture_get_level_width(dst_texture, dst_level), + wined3d_texture_get_level_height(dst_texture, dst_level)); + src_level = src_sub_resource_idx % src_texture->level_count; + SetRect(&src_rect, 0, 0, wined3d_texture_get_level_width(src_texture, src_level), + wined3d_texture_get_level_height(src_texture, src_level)); + wined3d_texture_blt(dst_texture, dst_sub_resource_idx, &dst_rect, + src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT); +} + 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 7c1b5e309e68..035746d86aa7 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -129,6 +129,7 @@ @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long) @ cdecl wined3d_device_release_focus_window(ptr) @ cdecl wined3d_device_reset(ptr ptr ptr ptr long) +@ cdecl wined3d_device_resolve_sub_resource(ptr ptr long ptr long long) @ cdecl wined3d_device_restore_fullscreen_window(ptr ptr ptr) @ cdecl wined3d_device_set_base_vertex_index(ptr long) @ cdecl wined3d_device_set_blend_state(ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 9d551d87e58d..ed7445ea5a31 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2342,6 +2342,10 @@ void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device); HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state); +void __cdecl wined3d_device_resolve_sub_resource(struct wined3d_device *device, + struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, + struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, + enum wined3d_format_id format_id); void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window, const RECT *window_rect); void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
On 12 February 2018 at 21:16, Józef Kucia jkucia@codeweavers.com wrote:
- dst_level = dst_sub_resource_idx % dst_texture->level_count;
- SetRect(&dst_rect, 0, 0, wined3d_texture_get_level_width(dst_texture, dst_level),
wined3d_texture_get_level_height(dst_texture, dst_level));
- src_level = src_sub_resource_idx % src_texture->level_count;
- SetRect(&src_rect, 0, 0, wined3d_texture_get_level_width(src_texture, src_level),
wined3d_texture_get_level_height(src_texture, src_level));
- wined3d_texture_blt(dst_texture, dst_sub_resource_idx, &dst_rect,
src_texture, src_sub_resource_idx, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+}
Would there be any value in calling wined3d_cs_emit_blt_sub_resource() directly?
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d11/device.c | 21 +++++++++++++++++---- dlls/d3d11/tests/d3d11.c | 3 --- 2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index f9db15f12fdc..5873be680dc8 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1179,10 +1179,23 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_ResolveSubresource(ID3D11D ID3D11Resource *src_resource, UINT src_subresource_idx, DXGI_FORMAT format) { - FIXME("iface %p, dst_resource %p, dst_subresource_idx %u, src_resource %p, src_subresource_idx %u, " - "format %s stub!\n", - iface, dst_resource, dst_subresource_idx, src_resource, src_subresource_idx, - debug_dxgi_format(format)); + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface); + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + enum wined3d_format_id wined3d_format; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, " + "src_resource %p, src_subresource_idx %u, format %s.\n", + iface, dst_resource, dst_subresource_idx, + src_resource, src_subresource_idx, debug_dxgi_format(format)); + + wined3d_dst_resource = wined3d_resource_from_d3d11_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d11_resource(src_resource); + wined3d_format = wined3dformat_from_dxgi_format(format); + wined3d_mutex_lock(); + wined3d_device_resolve_sub_resource(device->wined3d_device, + wined3d_dst_resource, dst_subresource_idx, + wined3d_src_resource, src_subresource_idx, wined3d_format); + wined3d_mutex_unlock(); }
static void STDMETHODCALLTYPE d3d11_immediate_context_ExecuteCommandList(ID3D11DeviceContext *iface, diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 93184ada6015..e0769a75a11e 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -24999,13 +24999,10 @@ static void test_alpha_to_coverage(void)
get_texture_readback(readback_texture, 0, &rb); SetRect(&rect, 0, 0, 200, 200); - todo_wine check_readback_data_color(&rb, &rect, expected_color, 1); SetRect(&rect, 200, 0, 640, 200); - todo_wine check_readback_data_color(&rb, &rect, 0xffffffff, 1); SetRect(&rect, 0, 200, 640, 480); - todo_wine check_readback_data_color(&rb, &rect, 0xffffffff, 1); release_resource_readback(&rb); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d11/device.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 5873be680dc8..f65c9947cb1a 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -4252,10 +4252,23 @@ static void STDMETHODCALLTYPE d3d10_device_ResolveSubresource(ID3D10Device1 *ifa ID3D10Resource *dst_resource, UINT dst_subresource_idx, ID3D10Resource *src_resource, UINT src_subresource_idx, DXGI_FORMAT format) { - FIXME("iface %p, dst_resource %p, dst_subresource_idx %u, " - "src_resource %p, src_subresource_idx %u, format %s stub!\n", + struct wined3d_resource *wined3d_dst_resource, *wined3d_src_resource; + struct d3d_device *device = impl_from_ID3D10Device(iface); + enum wined3d_format_id wined3d_format; + + TRACE("iface %p, dst_resource %p, dst_subresource_idx %u, " + "src_resource %p, src_subresource_idx %u, format %s.\n", iface, dst_resource, dst_subresource_idx, src_resource, src_subresource_idx, debug_dxgi_format(format)); + + wined3d_dst_resource = wined3d_resource_from_d3d10_resource(dst_resource); + wined3d_src_resource = wined3d_resource_from_d3d10_resource(src_resource); + wined3d_format = wined3dformat_from_dxgi_format(format); + wined3d_mutex_lock(); + wined3d_device_resolve_sub_resource(device->wined3d_device, + wined3d_dst_resource, dst_subresource_idx, + wined3d_src_resource, src_subresource_idx, wined3d_format); + wined3d_mutex_unlock(); }
static void STDMETHODCALLTYPE d3d10_device_VSGetConstantBuffers(ID3D10Device1 *iface,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/utils.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index c4d6e6534c5a..6f7740deda01 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2805,6 +2805,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, { GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; unsigned int i, max_log2; + GLenum target;
if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2]) { @@ -2877,17 +2878,17 @@ static void query_internal_format(struct wined3d_adapter *adapter, { if (gl_info->supported[ARB_INTERNALFORMAT_QUERY]) { + target = gl_info->supported[ARB_TEXTURE_MULTISAMPLE] ? GL_TEXTURE_2D_MULTISAMPLE : GL_RENDERBUFFER; count = 0; - GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_NUM_SAMPLE_COUNTS, 1, &count)); - checkGLcall("glGetInternalformativ(GL_NUM_SAMPLE_COUNTS)"); count = min(count, MAX_MULTISAMPLE_TYPES); - GL_EXTCALL(glGetInternalformativ(GL_RENDERBUFFER, format->glInternal, + GL_EXTCALL(glGetInternalformativ(target, format->glInternal, GL_SAMPLES, count, multisample_types)); - checkGLcall("glGetInternalformativ(GL_SAMPLES)"); + checkGLcall("query sample counts"); for (i = 0; i < count; ++i) { - if (multisample_types[i] > sizeof(format->multisample_types) * 8) + if (multisample_types[i] > sizeof(format->multisample_types) * CHAR_BIT) continue; format->multisample_types |= 1u << (multisample_types[i] - 1); } @@ -2895,7 +2896,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, else { max_log2 = wined3d_log2i(min(gl_info->limits.samples, - sizeof(format->multisample_types) * 8)); + sizeof(format->multisample_types) * CHAR_BIT)); for (i = 1; i <= max_log2; ++i) format->multisample_types |= 1u << ((1u << i) - 1); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
On 12 February 2018 at 21:16, Józef Kucia jkucia@codeweavers.com wrote:
@@ -3844,6 +3844,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst scale = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top; convert = src_texture->resource.format->id != dst_texture->resource.format->id;
- resolve = src_texture->resource.multisample_type != dst_texture->resource.multisample_type;
That's probably fine to start with, but generally speaking I suspect we still allow some blits we shouldn't, like e.g. sample count 4 -> sample count 4 or "resolving" from sample count 4 to sample count 2.