winehq.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
April 2020
----- 2025 -----
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
2 participants
1016 discussions
Start a n
N
ew thread
Chip Davis : wined3d: Use GL_APPLE_rgb_422 for UYVY and YUY2 surfaces.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 2d86752198ea3289e12909697b5d67b4cc07fc02 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=2d86752198ea3289e1290969…
Author: Chip Davis <cdavis(a)codeweavers.com> Date: Fri Apr 17 20:39:22 2020 +0430 wined3d: Use GL_APPLE_rgb_422 for UYVY and YUY2 surfaces. Theoretically, we could use it to support UYVY and YUY2 *textures* as well, but it would still require converting from YUV to RGB after sampling. Signed-off-by: Chip Davis <cdavis(a)codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/wined3d/arb_program_shader.c | 6 +++++- dlls/wined3d/glsl_shader.c | 11 +++++++++++ dlls/wined3d/utils.c | 20 +++++++++++++++++++- dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 36c920dc6e..e6daa88afd 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7649,11 +7649,15 @@ static HRESULT arbfp_blit_set(struct wined3d_arbfp_blitter *blitter, struct wine case COMPLEX_FIXUP_NV12: shader = gen_yuv_shader(gl_info, &type); break; + + default: + FIXME("Unsupported fixup %#x.\n", fixup); + return E_NOTIMPL; } if (!shader) { - FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup); + ERR("Failed to get shader for fixup %#x.\n", fixup); return E_NOTIMPL; } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index c7feff85ef..6a247f4644 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -12713,6 +12713,15 @@ static void glsl_blitter_generate_yuv_shader(struct wined3d_string_buffer *buffe gen_nv12_read(buffer, gl_info, tex_type); break; + case COMPLEX_FIXUP_YUV: + /* With APPLE_rgb_422, things are much simpler. The only thing we + * have to do here is Y'CbCr to RGB conversion. */ + shader_addline(buffer, " vec3 yuv = vec3(texture%s(sampler, out_texcoord.xy));\n", + needs_legacy_glsl_syntax(gl_info) ? tex_type : ""); + shader_addline(buffer, " luminance = yuv.y;\n"); + shader_addline(buffer, " chroma = yuv.xz;\n"); + break; + default: FIXME("Unsupported fixup %#x.\n", complex_fixup); string_buffer_free(buffer); @@ -12836,6 +12845,7 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YV12: case COMPLEX_FIXUP_NV12: + case COMPLEX_FIXUP_YUV: glsl_blitter_generate_yuv_shader(buffer, gl_info, args, output->buffer, tex_type, swizzle); break; case COMPLEX_FIXUP_NONE: @@ -13183,6 +13193,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli case COMPLEX_FIXUP_UYVY: case COMPLEX_FIXUP_YV12: case COMPLEX_FIXUP_NV12: + case COMPLEX_FIXUP_YUV: src_level = src_sub_resource_idx % src_texture->level_count; location = GL_EXTCALL(glGetUniformLocation(program->id, "size")); GL_EXTCALL(glUniform2f(location, wined3d_texture_get_level_pow2_width(src_texture, src_level), diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 0ed9eae78e..926a6a51ed 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1320,6 +1320,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_UYVY, GL_RGB_RAW_422_APPLE, GL_RGB_RAW_422_APPLE, 0, + GL_RGB_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, + WINED3DFMT_FLAG_FILTERING, + APPLE_RGB_422, NULL}, {WINED3DFMT_UYVY, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, @@ -1332,6 +1336,10 @@ static const struct wined3d_format_texture_info format_texture_info[] = GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, WINED3DFMT_FLAG_FILTERING, WINED3D_GL_LEGACY_CONTEXT, NULL}, + {WINED3DFMT_YUY2, GL_RGB_RAW_422_APPLE, GL_RGB_RAW_422_APPLE, 0, + GL_RGB_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, + WINED3DFMT_FLAG_FILTERING, + APPLE_RGB_422, NULL}, {WINED3DFMT_YUY2, GL_RGB, GL_RGB, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, 0, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_FILTERING, @@ -3577,7 +3585,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ format->f.color_fixup = create_color_fixup_desc_from_string(fixups[i].fixup); } - if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM] + if (!gl_info->supported[APPLE_YCBCR_422] && !gl_info->supported[APPLE_RGB_422] + && (gl_info->supported[ARB_FRAGMENT_PROGRAM] || (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))) { format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); @@ -3586,6 +3595,14 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_ format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY); } + else if (!gl_info->supported[APPLE_YCBCR_422] && gl_info->supported[APPLE_RGB_422]) + { + format = get_format_gl_internal(adapter, WINED3DFMT_YUY2); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUV); + + format = get_format_gl_internal(adapter, WINED3DFMT_UYVY); + format->f.color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUV); + } else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM] && (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER]))) { @@ -5389,6 +5406,7 @@ static const char *debug_complex_fixup(enum complex_fixup fixup) WINED3D_TO_STR(COMPLEX_FIXUP_YV12); WINED3D_TO_STR(COMPLEX_FIXUP_NV12); WINED3D_TO_STR(COMPLEX_FIXUP_P8); + WINED3D_TO_STR(COMPLEX_FIXUP_YUV); #undef WINED3D_TO_STR default: FIXME("Unrecognized complex fixup %#x\n", fixup); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ade1eae352..7e78cb60df 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -154,6 +154,7 @@ enum complex_fixup COMPLEX_FIXUP_YV12 = 3, COMPLEX_FIXUP_P8 = 4, COMPLEX_FIXUP_NV12 = 5, + COMPLEX_FIXUP_YUV = 6, }; #include <pshpack2.h>
1
0
0
0
Philip Rebohle : dxgi/tests: Add test for colour space support APIs.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 2c748dea407f7e3c5874651fbec6d34c8b4bea86 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=2c748dea407f7e3c5874651f…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:21 2020 +0430 dxgi/tests: Add test for colour space support APIs. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/tests/dxgi.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 0fe247016b..32aae2567f 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6306,6 +6306,112 @@ static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) ok(ref_count == !is_d3d12, "Factory has %u references left.\n", ref_count); } +static void test_colour_space_support(IUnknown *device, BOOL is_d3d12) +{ + DXGI_SWAP_CHAIN_DESC1 swapchain_desc; + IDXGISwapChain3 *swapchain3; + IDXGISwapChain1 *swapchain1; + IDXGIFactory2 *factory2; + IDXGIFactory *factory; + ULONG ref_count; + unsigned int i; + UINT support; + HWND window; + HRESULT hr; + + static const DXGI_COLOR_SPACE_TYPE colour_spaces[] = + { + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, + DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709, + DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020, + DXGI_COLOR_SPACE_RESERVED, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020, + DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020, + DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020, + DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020, + DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020, + DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020, + DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020, + DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020, + }; + + get_factory(device, is_d3d12, &factory); + + hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory2, (void**)&factory2); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + win_skip("IDXGIFactory2 not available.\n"); + return; + } + + window = create_window(); + + swapchain_desc.Width = 640; + swapchain_desc.Height = 480; + swapchain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.Stereo = FALSE; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 2; + swapchain_desc.Scaling = DXGI_SCALING_STRETCH; + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapchain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory2_CreateSwapChainForHwnd(factory2, device, + window, &swapchain_desc, NULL, NULL, &swapchain1); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void**)&swapchain3); + IDXGISwapChain1_Release(swapchain1); + if (FAILED(hr)) + { + win_skip("IDXGISwapChain3 not available.\n"); + IDXGIFactory2_Release(factory2); + DestroyWindow(window); + return; + } + + for (i = 0; i < ARRAY_SIZE(colour_spaces); ++i) + { + support = 0xdeadbeef; + hr = IDXGISwapChain3_CheckColorSpaceSupport(swapchain3, colour_spaces[i], &support); + ok(hr == S_OK, "Got unexpected hr %#x for test %u.\n", hr, i); + ok(!(support & ~DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT), + "Got unexpected support flags %#x for test %u.\n", support, i); + + if (colour_spaces[i] == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + { + ok(support & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT, + "Required colour space not supported for test %u.\n", i); + } + else if (colour_spaces[i] == DXGI_COLOR_SPACE_RESERVED) + { + ok(!support, "Invalid colour space supported for test %u.\n", i); + } + + hr = IDXGISwapChain3_SetColorSpace1(swapchain3, colour_spaces[i]); + ok(hr == (support & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) ? S_OK : E_INVALIDARG, + "Got unexpected hr %#x for text %u.\n", hr, i); + } + + ref_count = IDXGISwapChain3_Release(swapchain3); + ok(!ref_count, "Swap chain has %u references left.\n", ref_count); + DestroyWindow(window); + ref_count = IDXGIFactory2_Release(factory2); + ok(ref_count == !is_d3d12, "Factory has %u references left.\n", ref_count); +} + static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12)) { IDXGIDevice *device; @@ -6444,6 +6550,7 @@ START_TEST(dxgi) run_on_d3d12(test_output_ownership); run_on_d3d12(test_cursor_clipping); run_on_d3d12(test_frame_latency_event); + run_on_d3d12(test_colour_space_support); FreeLibrary(d3d12_module); }
1
0
0
0
Philip Rebohle : dxgi: Improve the d3d12_swapchain_SetColorSpace1() stub.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 5a1283a3e27c942ac4846543a75bad855505b81c URL:
https://source.winehq.org/git/wine.git/?a=commit;h=5a1283a3e27c942ac4846543…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:20 2020 +0430 dxgi: Improve the d3d12_swapchain_SetColorSpace1() stub. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index ad1a74e1b6..f57183879d 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2703,9 +2703,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_CheckColorSpaceSupport(IDXGISwa static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetColorSpace1(IDXGISwapChain3 *iface, DXGI_COLOR_SPACE_TYPE colour_space) { - FIXME("iface %p, colour_space %#x stub!\n", iface, colour_space); + FIXME("iface %p, colour_space %#x semi-stub!\n", iface, colour_space); - return E_NOTIMPL; + if (colour_space != DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + { + WARN("Colour space %u not supported.\n", colour_space); + return E_INVALIDARG; + } + + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_ResizeBuffers1(IDXGISwapChain3 *iface,
1
0
0
0
Philip Rebohle : dxgi: Improve the d3d12_swapchain_CheckColorSpaceSupport() stub.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: d9c69cbc481114a1e4f2d43952b357dead23ae3b URL:
https://source.winehq.org/git/wine.git/?a=commit;h=d9c69cbc481114a1e4f2d439…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:19 2020 +0430 dxgi: Improve the d3d12_swapchain_CheckColorSpaceSupport() stub. Monster Hunter World needs this function to succeed. This behaves correctly under the assumption that the system has no HDR support, and only reports standard sRGB as supported. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index bd200dddf0..ad1a74e1b6 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2685,10 +2685,19 @@ static UINT STDMETHODCALLTYPE d3d12_swapchain_GetCurrentBackBufferIndex(IDXGISwa static HRESULT STDMETHODCALLTYPE d3d12_swapchain_CheckColorSpaceSupport(IDXGISwapChain3 *iface, DXGI_COLOR_SPACE_TYPE colour_space, UINT *colour_space_support) { - FIXME("iface %p, colour_space %#x, colour_space_support %p stub!\n", + UINT support_flags = 0; + + FIXME("iface %p, colour_space %#x, colour_space_support %p semi-stub!\n", iface, colour_space, colour_space_support); - return E_NOTIMPL; + if (!colour_space_support) + return E_INVALIDARG; + + if (colour_space == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + support_flags |= DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT; + + *colour_space_support = support_flags; + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetColorSpace1(IDXGISwapChain3 *iface,
1
0
0
0
Philip Rebohle : dxgi/tests: Add a test for frame latency events using d3d12.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 03b8fa73375dbae54cd8aa4ec7b61bd4dbe000e0 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=03b8fa73375dbae54cd8aa4e…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:18 2020 +0430 dxgi/tests: Add a test for frame latency events using d3d12. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/tests/dxgi.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 3887982634..0fe247016b 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6188,6 +6188,124 @@ static void test_factory_check_feature_support(void) ok(!ref_count, "Factory has %u references left.\n", ref_count); } +static void test_frame_latency_event(IUnknown *device, BOOL is_d3d12) +{ + DXGI_SWAP_CHAIN_DESC1 swapchain_desc; + IDXGISwapChain2 *swapchain2; + IDXGISwapChain1 *swapchain1; + IDXGIFactory2 *factory2; + IDXGIFactory *factory; + UINT frame_latency; + DWORD wait_result; + ULONG ref_count; + unsigned int i; + HANDLE event; + HWND window; + HRESULT hr; + + get_factory(device, is_d3d12, &factory); + + hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory2, (void**)&factory2); + IDXGIFactory_Release(factory); + if (FAILED(hr)) + { + win_skip("IDXGIFactory2 not available.\n"); + return; + } + + window = create_window(); + + swapchain_desc.Width = 640; + swapchain_desc.Height = 480; + swapchain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.Stereo = FALSE; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = 2; + swapchain_desc.Scaling = DXGI_SCALING_STRETCH; + swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapchain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + swapchain_desc.Flags = 0; + + hr = IDXGIFactory2_CreateSwapChainForHwnd(factory2, device, + window, &swapchain_desc, NULL, NULL, &swapchain1); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain2, (void**)&swapchain2); + IDXGISwapChain1_Release(swapchain1); + if (FAILED(hr)) + { + win_skip("IDXGISwapChain2 not available.\n"); + IDXGIFactory2_Release(factory2); + DestroyWindow(window); + return; + } + + /* test swap chain without waitable object */ + frame_latency = 0xdeadbeef; + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); + ok(frame_latency == 0xdeadbeef, "Got unexpected frame latency %#x.\n", frame_latency); + hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 1); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); + event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!event, "Got unexpected event %p.\n", event); + + ref_count = IDXGISwapChain2_Release(swapchain2); + ok(!ref_count, "Swap chain has %u references left.\n", ref_count); + + /* test swap chain with waitable object */ + swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + + hr = IDXGIFactory2_CreateSwapChainForHwnd(factory2, device, + window, &swapchain_desc, NULL, NULL, &swapchain1); + ok(hr == S_OK, "Failed to create swap chain, hr %#x.\n", hr); + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain2, (void**)&swapchain2); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + IDXGISwapChain1_Release(swapchain1); + + event = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain2); + ok(!!event, "Got unexpected event %p.\n", event); + + /* auto-reset event */ + wait_result = WaitForSingleObject(event, 0); + ok(!wait_result, "Got unexpected wait result %#x.\n", wait_result); + wait_result = WaitForSingleObject(event, 0); + ok(wait_result == WAIT_TIMEOUT, "Got unexpected wait result %#x.\n", wait_result); + + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(frame_latency == 1, "Got unexpected frame latency %#x.\n", frame_latency); + + hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 0); + ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr); + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(frame_latency == 1, "Got unexpected frame latency %#x.\n", frame_latency); + + hr = IDXGISwapChain2_SetMaximumFrameLatency(swapchain2, 2); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = IDXGISwapChain2_GetMaximumFrameLatency(swapchain2, &frame_latency); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(frame_latency == 2, "Got unexpected frame latency %#x.\n", frame_latency); + + for (i = 0; i < 5; i++) + { + hr = IDXGISwapChain2_Present(swapchain2, 0, 0); + ok(hr == S_OK, "Present %u failed with hr %#x.\n", i, hr); + } + + wait_result = WaitForSingleObject(event, 1000); + ok(!wait_result, "Got unexpected wait result %#x.\n", wait_result); + + ref_count = IDXGISwapChain2_Release(swapchain2); + ok(!ref_count, "Swap chain has %u references left.\n", ref_count); + DestroyWindow(window); + ref_count = IDXGIFactory2_Release(factory2); + ok(ref_count == !is_d3d12, "Factory has %u references left.\n", ref_count); +} + static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12)) { IDXGIDevice *device; @@ -6325,6 +6443,7 @@ START_TEST(dxgi) run_on_d3d12(test_swapchain_formats); run_on_d3d12(test_output_ownership); run_on_d3d12(test_cursor_clipping); + run_on_d3d12(test_frame_latency_event); FreeLibrary(d3d12_module); }
1
0
0
0
Philip Rebohle : dxgi: Implement d3d12_swapchain_GetMaximumFrameLatency().
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 85710526c26ea7a39411c7d263b801aa27c885e6 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=85710526c26ea7a39411c7d2…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:17 2020 +0430 dxgi: Implement d3d12_swapchain_GetMaximumFrameLatency(). Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 8e0f2b2239..bd200dddf0 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2630,9 +2630,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMaximumFrameLatency(IDXGISwa static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT *max_latency) { - FIXME("iface %p, max_latency %p stub!\n", iface, max_latency); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); - return E_NOTIMPL; + TRACE("iface %p, max_latency %p.\n", iface, max_latency); + + if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + { + WARN("DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT not set for swap chain %p.\n", iface); + return DXGI_ERROR_INVALID_CALL; + } + + *max_latency = swapchain->frame_latency; + return S_OK; } static HANDLE STDMETHODCALLTYPE d3d12_swapchain_GetFrameLatencyWaitableObject(IDXGISwapChain3 *iface)
1
0
0
0
Philip Rebohle : dxgi: Implement d3d12_swapchain_SetMaximumFrameLatency().
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 440320ce39b0f7a0578e57096745a240d5303e49 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=440320ce39b0f7a0578e5709…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:16 2020 +0430 dxgi: Implement d3d12_swapchain_SetMaximumFrameLatency(). Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index c13868fdc2..8e0f2b2239 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2608,9 +2608,24 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetSourceSize(IDXGISwapChain3 * static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT max_latency) { - FIXME("iface %p, max_latency %u stub!\n", iface, max_latency); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); - return E_NOTIMPL; + TRACE("iface %p, max_latency %u.\n", iface, max_latency); + + if (!(swapchain->desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) + { + WARN("DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT not set for swap chain %p.\n", iface); + return DXGI_ERROR_INVALID_CALL; + } + + if (!max_latency) + { + WARN("Invalid maximum frame latency %u.\n", max_latency); + return DXGI_ERROR_INVALID_CALL; + } + + swapchain->frame_latency = max_latency; + return S_OK; } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwapChain3 *iface, UINT *max_latency)
1
0
0
0
Philip Rebohle : dxgi: Implement d3d12_swapchain_GetFrameLatencyWaitableObject().
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: dd3e9f304ead694e9ff0ca7abe309983cccc8876 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=dd3e9f304ead694e9ff0ca7a…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:15 2020 +0430 dxgi: Implement d3d12_swapchain_GetFrameLatencyWaitableObject(). Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 40accb2a93..c13868fdc2 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -2622,9 +2622,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetMaximumFrameLatency(IDXGISwa static HANDLE STDMETHODCALLTYPE d3d12_swapchain_GetFrameLatencyWaitableObject(IDXGISwapChain3 *iface) { - FIXME("iface %p stub!\n", iface); + struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface); - return NULL; + TRACE("iface %p.\n", iface); + + return swapchain->frame_latency_event; } static HRESULT STDMETHODCALLTYPE d3d12_swapchain_SetMatrixTransform(IDXGISwapChain3 *iface,
1
0
0
0
Philip Rebohle : dxgi: Signal the frame latency event on present.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 154ce70b5c3cc4ef573d82378e746fe895a7262d URL:
https://source.winehq.org/git/wine.git/?a=commit;h=154ce70b5c3cc4ef573d8237…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:14 2020 +0430 dxgi: Signal the frame latency event on present. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 0cb7d922f4..40accb2a93 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1097,6 +1097,9 @@ struct d3d12_swapchain ID3D12Fence *frame_latency_fence; HANDLE frame_latency_event; + + uint64_t frame_number; + uint32_t frame_latency; }; static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -2104,6 +2107,7 @@ static VkResult d3d12_swapchain_queue_present(struct d3d12_swapchain *swapchain, static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, unsigned int sync_interval, unsigned int flags) { + HANDLE frame_latency_event; VkQueue vk_queue; VkResult vr; HRESULT hr; @@ -2166,6 +2170,25 @@ static HRESULT d3d12_swapchain_present(struct d3d12_swapchain *swapchain, return hresult_from_vk_result(vr); } + if ((frame_latency_event = swapchain->frame_latency_event)) + { + ++swapchain->frame_number; + + if (FAILED(hr = ID3D12CommandQueue_Signal(swapchain->command_queue, + swapchain->frame_latency_fence, swapchain->frame_number))) + { + ERR("Failed to signal frame latency fence, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = ID3D12Fence_SetEventOnCompletion(swapchain->frame_latency_fence, + swapchain->frame_number - swapchain->frame_latency, frame_latency_event))) + { + ERR("Failed to enqueue frame latency event, hr %#x.\n", hr); + return hr; + } + } + swapchain->current_buffer_index = (swapchain->current_buffer_index + 1) % swapchain->desc.BufferCount; vr = d3d12_swapchain_acquire_next_back_buffer(swapchain); if (vr == VK_ERROR_OUT_OF_DATE_KHR) @@ -2994,6 +3017,9 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) { + swapchain->frame_number = DXGI_MAX_SWAP_CHAIN_BUFFERS; + swapchain->frame_latency = 1; + if (FAILED(hr = ID3D12Device_CreateFence(device, DXGI_MAX_SWAP_CHAIN_BUFFERS, 0, &IID_ID3D12Fence, (void **)&swapchain->frame_latency_fence))) {
1
0
0
0
Philip Rebohle : dxgi: Create frame latency events for d3d12 swapchains if requested.
by Alexandre Julliard
17 Apr '20
17 Apr '20
Module: wine Branch: master Commit: 86c1ca87602537773204e2a826f6ff056c34bf54 URL:
https://source.winehq.org/git/wine.git/?a=commit;h=86c1ca87602537773204e2a8…
Author: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Date: Fri Apr 17 20:39:13 2020 +0430 dxgi: Create frame latency events for d3d12 swapchains if requested. Signed-off-by: Philip Rebohle <philip.rebohle(a)tu-dortmund.de> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/dxgi/swapchain.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index f19b58da2e..0cb7d922f4 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -1094,6 +1094,9 @@ struct d3d12_swapchain IDXGIOutput *target; DXGI_SWAP_CHAIN_DESC1 desc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen_desc; + + ID3D12Fence *frame_latency_fence; + HANDLE frame_latency_event; }; static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format) @@ -1887,6 +1890,12 @@ static void d3d12_swapchain_destroy(struct d3d12_swapchain *swapchain) d3d12_swapchain_destroy_buffers(swapchain, TRUE); + if (swapchain->frame_latency_event) + CloseHandle(swapchain->frame_latency_event); + + if (swapchain->frame_latency_fence) + ID3D12Fence_Release(swapchain->frame_latency_fence); + if (swapchain->command_queue) ID3D12CommandQueue_Release(swapchain->command_queue); @@ -2906,7 +2915,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI FIXME("Ignoring scaling %#x.\n", swapchain_desc->Scaling); if (swapchain_desc->AlphaMode && swapchain_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE) FIXME("Ignoring alpha mode %#x.\n", swapchain_desc->AlphaMode); - if (swapchain_desc->Flags) + if (swapchain_desc->Flags & ~(DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) FIXME("Ignoring swapchain flags %#x.\n", swapchain_desc->Flags); if (fullscreen_desc->RefreshRate.Numerator || fullscreen_desc->RefreshRate.Denominator) @@ -2983,6 +2992,25 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI return hresult_from_vk_result(vr); } + if (swapchain_desc->Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) + { + if (FAILED(hr = ID3D12Device_CreateFence(device, DXGI_MAX_SWAP_CHAIN_BUFFERS, + 0, &IID_ID3D12Fence, (void **)&swapchain->frame_latency_fence))) + { + WARN("Failed to create frame latency fence, hr %#x.\n", hr); + d3d12_swapchain_destroy(swapchain); + return hr; + } + + if (!(swapchain->frame_latency_event = CreateEventW(NULL, FALSE, TRUE, NULL))) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + WARN("Failed to create frame latency event, hr %#x.\n", hr); + d3d12_swapchain_destroy(swapchain); + return hr; + } + } + IWineDXGIFactory_AddRef(swapchain->factory = factory); return S_OK;
1
0
0
0
← Newer
1
...
47
48
49
50
51
52
53
...
102
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
Results per page:
10
25
50
100
200