Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 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
February 2019
- 73 participants
- 1959 messages
[PATCH vkd3d v2 2/5] vkd3d: Implement d3d12_command_list_SetName().
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
As Józef pointed out, there is the option of restoring the vulkan object names when command list gets reset.
But then after I implemented it, it seems to much of a hassle. We need to store the name in unicode or
utf8. Then we need a strdup for unicode or a new set vk object method for utf8 names. Finally we also
need a synchronization primitive to protect the name from race conditions. So I decided not to use that approach.
Same for command allocators.
libs/vkd3d/command.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 9af1ec9..abee0e2 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1694,9 +1694,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsComman
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
- FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name, list->device->wchar_size));
+ TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size));
- return E_NOTIMPL;
+ return name ? S_OK : E_INVALIDARG;
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList *iface,
--
2.15.2 (Apple Git-101.1)
Feb. 1, 2019
[PATCH vkd3d v2 1/5] vkd3d: Implement d3d12_device_SetName().
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
Supersede 157536~157541
libs/vkd3d/device.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 4b5f522..5265ec9 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1564,9 +1564,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device *iface, const
{
struct d3d12_device *device = impl_from_ID3D12Device(iface);
- FIXME("iface %p, name %s stub!\n", iface, debugstr_w(name, device->wchar_size));
+ TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size));
- return E_NOTIMPL;
+ return vkd3d_set_vk_object_name(device, (uint64_t)(uintptr_t)device->vk_device,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name);
}
static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device *iface)
--
2.15.2 (Apple Git-101.1)
Feb. 1, 2019
Re: [PATCH v2] winetest: Add GUI to display results of individual tests.
by Zebediah Figura
On 1/30/19 9:03 AM, Isira Seneviratne wrote:
> From 81fcdd3ad885026c302105e5fb9fef6c53b59bd5 Mon Sep 17 00:00:00 2001
> From: Isira-Seneviratne <isirasen96(a)gmail.com>
> Date: Sun, 16 Dec 2018 14:59:20 +0530
> Subject: [PATCH v2] winetest: Add GUI to display results of individual tests.
>
> This patch adds a listview control displaying the results of each
> test, together with the component being tested.
>
> Signed-off-by: Isira-Seneviratne <isirasen96(a)gmail.com>
> ---
> programs/winetest/gui.c | 25 +++++++++++++--
> programs/winetest/main.c | 58 +++++++++++++++++++++++++++++++++--
> programs/winetest/resource.h | 2 ++
> programs/winetest/winetest.h | 4 +++
> programs/winetest/winetest.rc | 20 +++++++-----
> 5 files changed, 97 insertions(+), 12 deletions(-)
>
I think the UI approach here is looking good, but it doesn't seem to
work very well. I'm getting multiple entries that show up for each test.
Furthermore, I think we should also display the individual test name
(not just the DLL name).
> diff --git a/programs/winetest/gui.c b/programs/winetest/gui.c
> index bda00f3707..fd6e74aca6 100644
> --- a/programs/winetest/gui.c
> +++ b/programs/winetest/gui.c
> @@ -2,6 +2,7 @@
> * GUI support
> *
> * Copyright 2004 Ferenc Wagner
> + * Copyright 2018-2019 Isira Seneviratne
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -43,6 +44,9 @@ static int progressGroup;
>
> static WNDPROC DefEditProc;
>
> +/* List view handle */
> +HWND res_list_view;
> +
> static int
> MBdefault (int uType)
> {
> @@ -130,7 +134,7 @@ guiStep (va_list ap)
> {
> const int pgID = IDC_ST0 + progressGroup * 2;
> char *str = vstrmake (NULL, ap);
> -
> +
> progressCurr++;
> SetDlgItemTextA (dialog, pgID, str);
> SendDlgItemMessageA(dialog, pgID+1, PBM_SETPOS,
> @@ -421,6 +425,8 @@ AboutProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
> static INT_PTR CALLBACK
> DlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
> {
> + LVCOLUMNA lvCol;
> +
> switch (msg) {
> case WM_INITDIALOG:
> SendMessageA(hwnd, WM_SETICON, ICON_SMALL,
> @@ -430,6 +436,21 @@ DlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
> SendMessageA(hwnd, WM_SETICON, ICON_BIG,
> (LPARAM)LoadIconA( GetModuleHandleA(NULL), MAKEINTRESOURCEA(IDI_WINE)));
> dialog = hwnd;
> +
> + /* Initializes the list view control that the main dialog window contains */
> + res_list_view = GetDlgItem(dialog, IDD_RES_LIST);
> +
> + lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
> + lvCol.cx = 80;
> + lvCol.fmt = LVCFMT_LEFT;
> +
> + lvCol.pszText = (char *) "Component";
> + ListView_InsertColumnA(res_list_view, 0, &lvCol);
> +
> + lvCol.pszText = (char *) "No. of failures";
> + lvCol.cx = 100;
> + ListView_InsertColumnA(res_list_view, 1, &lvCol);
> +
I'm not sure if there's an unofficial policy in this respect, but I get
the impression that we try to avoid windowsx.h macros, in favour of
using e.g. SendMessageA() directly. But I'd welcome anyone else to
comment on this (or if it's not worth fixing).
Feb. 1, 2019
Re: [PATCH v2 5/5] wined3d: Store sampler states in the wined3d_stateblock_state structure.
by Zebediah Figura
On 1/31/19 8:24 AM, Henri Verbeet wrote:
> On Wed, 30 Jan 2019 at 22:06, Zebediah Figura <z.figura12(a)gmail.com> wrote:
>>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/wined3d/device.c | 8 +++-----
>> dlls/wined3d/stateblock.c | 18 +++++++++++-------
>> dlls/wined3d/wined3d_private.h | 1 +
>> 3 files changed, 15 insertions(+), 12 deletions(-)
>>
> This appears to cause a segfault in the ddraw:dsurface test.
>
>
I don't get this, even running under valgrind. Can you provide more
information, please?
Feb. 1, 2019
Re: [PATCH v3 1/4] d3d9/tests: Add Fetch4 tests
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=47055
Your paranoid android.
=== w1064 (32 bit report) ===
d3d9:
visual.c:8750: Test failed: Got unexpected color 0x00007580 for quad 2 (different colors).
Feb. 1, 2019
[PATCH v3 4/4] wined3d: Expose DF16/24 support
by Daniel Ansorregui
- This assumes FETCH4 is already supported by wine
And checks for ARB_texture_gather support before exposing DF24
Signed-off-by: Daniel Ansorregui <mailszeros(a)gmail.com>
---
dlls/wined3d/directx.c | 6 ++++++
dlls/wined3d/utils.c | 30 ++++++++++++++++++++++++++++++
include/wine/wined3d.h | 2 ++
3 files changed, 38 insertions(+)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 75622be80c..be0c514a78 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1723,6 +1723,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
return WINED3DOK_NOMIPGEN;
}
+ if ((check_format_id == WINED3DFMT_DF24) && !adapter->gl_info.supported[ARB_TEXTURE_GATHER])
+ {
+ TRACE("No Support for Fetch4 disabling DF24 support.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+
return WINED3D_OK;
}
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 82111c8bb2..24fce97594 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -65,6 +65,8 @@ format_index_remap[] =
{WINED3DFMT_R16, WINED3D_FORMAT_FOURCC_BASE + 20},
{WINED3DFMT_AL16, WINED3D_FORMAT_FOURCC_BASE + 21},
{WINED3DFMT_NV12, WINED3D_FORMAT_FOURCC_BASE + 22},
+ {WINED3DFMT_DF16, WINED3D_FORMAT_FOURCC_BASE + 23},
+ {WINED3DFMT_DF24, WINED3D_FORMAT_FOURCC_BASE + 24},
};
#define WINED3D_FORMAT_COUNT (WINED3D_FORMAT_FOURCC_BASE + ARRAY_SIZE(format_index_remap))
@@ -141,6 +143,8 @@ static const struct wined3d_format_channels formats[] =
{WINED3DFMT_NVHU, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_NVHS, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_NULL, 8, 8, 8, 8, 0, 8, 16, 24, 4, 0, 0},
+ {WINED3DFMT_DF16, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16, 0},
+ {WINED3DFMT_DF24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 24, 0},
/* Unsure about them, could not find a Windows driver that supports them */
{WINED3DFMT_R16, 16, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0},
{WINED3DFMT_AL16, 0, 0, 0, 16, 0, 0, 0, 16, 4, 0, 0},
@@ -346,6 +350,8 @@ static const struct wined3d_format_base_flags format_base_flags[] =
{WINED3DFMT_R16, WINED3DFMT_FLAG_ALLOW_FETCH4},
{WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_ALLOW_FETCH4},
{WINED3DFMT_A8_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_DF16, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_DF24, WINED3DFMT_FLAG_ALLOW_FETCH4},
};
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b)
@@ -1894,6 +1900,25 @@ static const struct wined3d_format_texture_info format_texture_info[] =
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL,
ARB_FRAMEBUFFER_OBJECT, NULL},
+ {WINED3DFMT_DF16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_DEPTH,
+ WINED3D_GL_EXT_NONE, NULL},
+ {WINED3DFMT_DF16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, 0,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH,
+ ARB_DEPTH_TEXTURE, NULL},
+ {WINED3DFMT_DF24, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH24_STENCIL8_EXT, 0,
+ GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH,
+ EXT_PACKED_DEPTH_STENCIL, NULL},
+ {WINED3DFMT_DF24, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, 0,
+ GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0,
+ WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
+ | WINED3DFMT_FLAG_DEPTH,
+ ARB_FRAMEBUFFER_OBJECT, NULL},
{WINED3DFMT_NULL, 0, 0, 0,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FBO_ATTACHABLE,
@@ -3533,6 +3558,9 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
{WINED3DFMT_INTZ, "XXXX", FALSE, WINED3D_GL_EXT_NONE},
{WINED3DFMT_INTZ, "XYZW", FALSE, WINED3D_GL_LEGACY_CONTEXT},
+ {WINED3DFMT_DF16, "X001", FALSE, WINED3D_GL_EXT_NONE},
+ {WINED3DFMT_DF24, "X001", FALSE, WINED3D_GL_EXT_NONE},
+
{WINED3DFMT_L8_UNORM, "XXX1", FALSE, ARB_TEXTURE_RG},
};
@@ -4387,6 +4415,8 @@ const char *debug_d3dformat(enum wined3d_format_id format_id)
FMT_TO_STR(WINED3DFMT_R16);
FMT_TO_STR(WINED3DFMT_AL16);
FMT_TO_STR(WINED3DFMT_NV12);
+ FMT_TO_STR(WINED3DFMT_DF16);
+ FMT_TO_STR(WINED3DFMT_DF24);
#undef FMT_TO_STR
default:
{
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index e09e4e1fce..e6c3c1b802 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -271,6 +271,8 @@ enum wined3d_format_id
WINED3DFMT_R16 = WINEMAKEFOURCC(' ','R','1','6'),
WINED3DFMT_AL16 = WINEMAKEFOURCC('A','L','1','6'),
WINED3DFMT_NV12 = WINEMAKEFOURCC('N','V','1','2'),
+ WINED3DFMT_DF16 = WINEMAKEFOURCC('D','F','1','6'),
+ WINED3DFMT_DF24 = WINEMAKEFOURCC('D','F','2','4'),
WINED3DFMT_FORCE_DWORD = 0xffffffff
};
--
2.17.1
Feb. 1, 2019
[PATCH v3 3/4] wined3d: Implement Fetch4 GLSL shader generation
by Daniel Ansorregui
- Implement shader generation of tex-ld/ldp/ldd/ldb/ldl
- FIXME: Vertex texldl unimplemented yet, since it is not possible to access
ps_compile_args. Maybe move it to another place.
Probably does not work on windows anyway
- Trigger PS re-generation at FETCH4 state change, by storing a context flag
- Add ps_compile_arg flag for fetch4
Signed-off-by: Daniel Ansorregui <mailszeros(a)gmail.com>
---
dlls/wined3d/cs.c | 5 +-
dlls/wined3d/device.c | 4 +
dlls/wined3d/glsl_shader.c | 214 ++++++++++++++++++++++-----------
dlls/wined3d/shader.c | 13 ++
dlls/wined3d/state.c | 13 ++
dlls/wined3d/wined3d_private.h | 7 +-
6 files changed, 186 insertions(+), 70 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 7471d24e7e..890540c78d 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -1372,7 +1372,10 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
if (!prev || wined3d_texture_gl(op->texture)->target != wined3d_texture_gl(prev)->target
|| (!is_same_fixup(new_format->color_fixup, old_format->color_fixup)
&& !(can_use_texture_swizzle(gl_info, new_format) && can_use_texture_swizzle(gl_info, old_format)))
- || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW))
+ || (new_fmt_flags & WINED3DFMT_FLAG_SHADOW) != (old_fmt_flags & WINED3DFMT_FLAG_SHADOW)
+ || ((new_fmt_flags & WINED3DFMT_FLAG_ALLOW_FETCH4) != (old_fmt_flags & WINED3DFMT_FLAG_ALLOW_FETCH4)
+ && cs->state.sampler_states[op->texture->sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS]
+ == MAKEFOURCC('G','E','T','4')))
device_invalidate_state(cs->device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
if (!prev && op->stage < d3d_info->limits.ffp_blend_stages)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index dee99dcde2..99248ffb1b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2082,7 +2082,11 @@ void CDECL wined3d_device_set_sampler_state(struct wined3d_device *device,
device, sampler_idx, debug_d3dsamplerstate(state), value);
if (sampler_idx >= WINED3DVERTEXTEXTURESAMPLER0 && sampler_idx <= WINED3DVERTEXTEXTURESAMPLER3)
+ {
sampler_idx -= (WINED3DVERTEXTEXTURESAMPLER0 - MAX_FRAGMENT_SAMPLERS);
+ if (state == WINED3D_SAMP_MIPMAP_LOD_BIAS && value == MAKEFOURCC('G','E','T','4'))
+ FIXME("Unsupported FETCH4 and Vertex Texture Sampler");
+ }
if (sampler_idx >= ARRAY_SIZE(device->state.sampler_states))
{
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 1950db06a9..e53306a6c2 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -49,6 +49,7 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
#define WINED3D_GLSL_SAMPLE_GRAD 0x04
#define WINED3D_GLSL_SAMPLE_LOAD 0x08
#define WINED3D_GLSL_SAMPLE_OFFSET 0x10
+#define WINED3D_GLSL_SAMPLE_GATHER 0x20
static const struct
{
@@ -3613,6 +3614,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
BOOL lod = flags & WINED3D_GLSL_SAMPLE_LOD;
BOOL grad = flags & WINED3D_GLSL_SAMPLE_GRAD;
BOOL offset = flags & WINED3D_GLSL_SAMPLE_OFFSET;
+ BOOL gather = !shadow && flags & WINED3D_GLSL_SAMPLE_GATHER;
const char *base = "texture", *type_part = "", *suffix = "";
unsigned int coord_size, deriv_size;
@@ -3658,6 +3660,19 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
type_part = "";
}
+ if (gather)
+ {
+ if (resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D)
+ FIXME("Unsupported Fetch4 and texture3D sampling");
+ else
+ {
+ base = "texture";
+ type_part = "Gather";
+ suffix = "";
+ projected = lod = grad = offset = FALSE;
+ }
+ }
+
sample_function->name = string_buffer_get(priv->string_buffers);
string_buffer_sprintf(sample_function->name, "%s%s%s%s%s%s", base, type_part, projected ? "Proj" : "",
lod ? "Lod" : grad ? "Grad" : "", offset ? "Offset" : "", suffix);
@@ -3786,12 +3801,13 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction
string_buffer_release(priv->string_buffers, reg_name);
}
-static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
- unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function, DWORD swizzle,
- const char *dx, const char *dy, const char *bias, const struct wined3d_shader_texel_offset *offset,
- const char *coord_reg_fmt, ...)
+static void PRINTF_ATTR(10, 11) shader_glsl_gen_sample_code(const struct wined3d_shader_instruction *ins,
+ unsigned int sampler_bind_idx, const struct glsl_sample_function *sample_function,
+ const DWORD swizzle, const DWORD sample_flags, const char *dx, const char *dy, const char *bias,
+ const struct wined3d_shader_texel_offset *offset, const char *coord_reg_fmt, ...)
{
const struct wined3d_shader_version *version = &ins->ctx->reg_maps->shader_version;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
char dst_swizzle[6];
struct color_fixup_desc fixup;
BOOL np2_fixup = FALSE;
@@ -3833,10 +3849,8 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
if (!string_buffer_resize(ins->ctx->buffer, ret))
break;
}
-
if (np2_fixup)
{
- const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
const unsigned char idx = priv->cur_np2fixup_info->idx[sampler_bind_idx];
switch (shader_glsl_get_write_mask_size(sample_function->coord_mask))
@@ -3859,6 +3873,20 @@ static void PRINTF_ATTR(9, 10) shader_glsl_gen_sample_code(const struct wined3d_
break;
}
}
+ if(sample_flags & WINED3D_GLSL_SAMPLE_GATHER)
+ {
+ if (sample_flags & WINED3D_GLSL_SAMPLE_PROJECTED)
+ {
+ struct wined3d_string_buffer *reg_name = string_buffer_get(priv->string_buffers);
+ shader_glsl_get_register_name(&ins->src[0].reg, ins->src[0].reg.data_type, reg_name, NULL, ins->ctx);
+ shader_addline(ins->ctx->buffer, " / %s.w", reg_name->buffer);
+ string_buffer_release(priv->string_buffers, reg_name);
+ }
+
+ /* Correct the fetch4 0.5 texel offset */
+ shader_addline(ins->ctx->buffer, " + (vec2(0.5) / textureSize(%s_sampler%u, 0).xy)",
+ shader_glsl_get_prefix(version->type), sampler_bind_idx);
+ }
if (dx && dy)
shader_addline(ins->ctx->buffer, ", %s, %s", dx, dy);
else if (bias)
@@ -5397,11 +5425,19 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
}
}
+ /* Fetch4 overwrites the other texture flags */
+ if (priv->cur_ps_args->fetch4 & (1u << resource_idx))
+ {
+ sample_flags |= WINED3D_GLSL_SAMPLE_GATHER;
+ mask = 0;
+ }
+
shader_glsl_get_sample_function(ins->ctx, resource_idx, resource_idx, sample_flags, &sample_function);
mask |= sample_function.coord_mask;
sample_function.coord_mask = mask;
if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
+ else if (sample_flags & WINED3D_GLSL_SAMPLE_GATHER) swizzle = WINED3DSP_FETCH4_SWIZZLE;
else swizzle = ins->src[1].swizzle;
/* 1.0-1.3: Use destination register as coordinate source.
@@ -5410,22 +5446,22 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
char coord_mask[6];
shader_glsl_write_mask_to_str(mask, coord_mask);
- shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL,
- "T%u%s", resource_idx, coord_mask);
+ shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, sample_flags, NULL, NULL,
+ NULL, NULL, "T%u%s", resource_idx, coord_mask);
}
else
{
struct glsl_src_param coord_param;
shader_glsl_add_src_param(ins, &ins->src[0], mask, &coord_param);
- if (ins->flags & WINED3DSI_TEXLD_BIAS)
+ if (ins->flags & WINED3DSI_TEXLD_BIAS && sample_flags != WINED3D_GLSL_SAMPLE_GATHER)
{
struct glsl_src_param bias;
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &bias);
- shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, bias.param_str,
- NULL, "%s", coord_param.param_str);
+ shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, sample_flags,
+ NULL, NULL, bias.param_str, NULL, "%s", coord_param.param_str);
} else {
- shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, NULL, NULL, NULL, NULL,
- "%s", coord_param.param_str);
+ shader_glsl_gen_sample_code(ins, resource_idx, &sample_function, swizzle, sample_flags,
+ NULL, NULL, NULL, NULL, "%s", coord_param.param_str);
}
}
shader_glsl_release_sample_function(ins->ctx, &sample_function);
@@ -5433,10 +5469,11 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
{
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
struct glsl_src_param coord_param, dx_param, dy_param;
struct glsl_sample_function sample_function;
- DWORD sampler_idx;
+ DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
DWORD swizzle = ins->src[1].swizzle;
if (!shader_glsl_has_core_grad(gl_info) && !gl_info->supported[ARB_SHADER_TEXTURE_LOD])
@@ -5446,34 +5483,48 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
return;
}
- sampler_idx = ins->src[1].reg.idx[0].offset;
+ /* Fetch4 overwrites the other texture flags */
+ if (priv->cur_ps_args->fetch4 & (1u << sampler_idx))
+ {
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_GATHER, &sample_function);
+ swizzle = WINED3DSP_FETCH4_SWIZZLE;
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, WINED3D_GLSL_SAMPLE_GATHER,
+ NULL, NULL, NULL, NULL, "%s", coord_param.param_str);
+ shader_glsl_release_sample_function(ins->ctx, &sample_function);
+ return;
+ }
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_GRAD, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[2], sample_function.deriv_mask, &dx_param);
shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dy_param);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, dx_param.param_str, dy_param.param_str,
- NULL, NULL, "%s", coord_param.param_str);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, 0,
+ dx_param.param_str, dy_param.param_str, NULL, NULL, "%s", coord_param.param_str);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
}
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
{
const struct wined3d_shader_version *shader_version = &ins->ctx->reg_maps->shader_version;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
struct glsl_src_param coord_param, lod_param;
struct glsl_sample_function sample_function;
+ DWORD sampler_idx = ins->src[1].reg.idx[0].offset;
DWORD swizzle = ins->src[1].swizzle;
- DWORD sampler_idx;
+ DWORD flags = WINED3D_GLSL_SAMPLE_LOD;
- sampler_idx = ins->src[1].reg.idx[0].offset;
+ /* This call can be used in vertex shader, without cur_ps_args */
+ if(priv->cur_ps_args && priv->cur_ps_args->fetch4 & (1u << sampler_idx))
+ {
+ flags = WINED3D_GLSL_SAMPLE_GATHER;
+ }
- shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_LOD, &sample_function);
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
- shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
-
if (shader_version->type == WINED3D_SHADER_TYPE_PIXEL && !shader_glsl_has_core_grad(gl_info)
&& !gl_info->supported[ARB_SHADER_TEXTURE_LOD])
{
@@ -5482,8 +5533,20 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
* even without the appropriate extension. */
WARN("Using %s in fragment shader.\n", sample_function.name->buffer);
}
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL, NULL, lod_param.param_str, NULL,
- "%s", coord_param.param_str);
+
+ if (flags == WINED3D_GLSL_SAMPLE_GATHER){
+ swizzle = WINED3DSP_FETCH4_SWIZZLE;
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, flags,
+ NULL, NULL, NULL, NULL, "%s", coord_param.param_str);
+ shader_glsl_release_sample_function(ins->ctx, &sample_function);
+ return;
+ }
+
+ shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, WINED3D_GLSL_SAMPLE_LOD, &sample_function);
+ shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
+ shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, flags, NULL, NULL,
+ lod_param.param_str, NULL, "%s", coord_param.param_str);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
}
@@ -6175,6 +6238,7 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
struct glsl_sample_function sample_function;
DWORD flags = WINED3D_GLSL_SAMPLE_LOAD;
BOOL has_lod_param;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
if (wined3d_shader_instruction_has_texel_offset(ins))
flags |= WINED3D_GLSL_SAMPLE_OFFSET;
@@ -6189,6 +6253,10 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
}
has_lod_param = is_mipmapped(reg_maps->resource_info[resource_idx].type);
+ if (priv->cur_ps_args && priv->cur_ps_args->fetch4 & (1u << resource_idx)){
+ FIXME("Unsupported FETCH4 and LD Sampling SM 5.0");
+ }
+
shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
@@ -6196,12 +6264,12 @@ static void shader_glsl_ld(const struct wined3d_shader_instruction *ins)
if (is_multisampled(reg_maps->resource_info[resource_idx].type))
{
shader_glsl_add_src_param(ins, &ins->src[2], WINED3DSP_WRITEMASK_0, &sample_param);
- shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
+ shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, 0,
NULL, NULL, NULL, &ins->texel_offset, "%s, %s", coord_param.param_str, sample_param.param_str);
}
else
{
- shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
+ shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle, 0,
NULL, NULL, has_lod_param ? lod_param.param_str : NULL, &ins->texel_offset,
"%s", coord_param.param_str);
}
@@ -6214,46 +6282,57 @@ static void shader_glsl_sample(const struct wined3d_shader_instruction *ins)
struct glsl_src_param coord_param, lod_param, dx_param, dy_param;
unsigned int resource_idx, sampler_idx, sampler_bind_idx;
struct glsl_sample_function sample_function;
+ const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
+ DWORD swizzle = ins->src[1].swizzle;
DWORD flags = 0;
+ resource_idx = ins->src[1].reg.idx[0].offset;
+ sampler_idx = ins->src[2].reg.idx[0].offset;
+
if (ins->handler_idx == WINED3DSIH_SAMPLE_GRAD)
flags |= WINED3D_GLSL_SAMPLE_GRAD;
if (ins->handler_idx == WINED3DSIH_SAMPLE_LOD)
flags |= WINED3D_GLSL_SAMPLE_LOD;
if (wined3d_shader_instruction_has_texel_offset(ins))
flags |= WINED3D_GLSL_SAMPLE_OFFSET;
-
- resource_idx = ins->src[1].reg.idx[0].offset;
- sampler_idx = ins->src[2].reg.idx[0].offset;
+ if (priv->cur_ps_args->fetch4 & (1u << sampler_idx))
+ {
+ flags = WINED3D_GLSL_SAMPLE_GATHER;
+ swizzle = WINED3DSP_FETCH4_SWIZZLE;
+ }
shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
- switch (ins->handler_idx)
+ /* Fetch4 overwrites the other texture flags */
+ if (flags != WINED3D_GLSL_SAMPLE_GATHER)
{
- case WINED3DSIH_SAMPLE:
- break;
- case WINED3DSIH_SAMPLE_B:
- shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
- lod_param_str = lod_param.param_str;
- break;
- case WINED3DSIH_SAMPLE_GRAD:
- shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dx_param);
- shader_glsl_add_src_param(ins, &ins->src[4], sample_function.deriv_mask, &dy_param);
- dx_param_str = dx_param.param_str;
- dy_param_str = dy_param.param_str;
- break;
- case WINED3DSIH_SAMPLE_LOD:
- shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
- lod_param_str = lod_param.param_str;
- break;
- default:
- ERR("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
- break;
+ switch (ins->handler_idx)
+ {
+ case WINED3DSIH_SAMPLE:
+ break;
+ case WINED3DSIH_SAMPLE_B:
+ shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
+ lod_param_str = lod_param.param_str;
+ break;
+ case WINED3DSIH_SAMPLE_GRAD:
+ shader_glsl_add_src_param(ins, &ins->src[3], sample_function.deriv_mask, &dx_param);
+ shader_glsl_add_src_param(ins, &ins->src[4], sample_function.deriv_mask, &dy_param);
+ dx_param_str = dx_param.param_str;
+ dy_param_str = dy_param.param_str;
+ break;
+ case WINED3DSIH_SAMPLE_LOD:
+ shader_glsl_add_src_param(ins, &ins->src[3], WINED3DSP_WRITEMASK_0, &lod_param);
+ lod_param_str = lod_param.param_str;
+ break;
+ default:
+ ERR("Unhandled opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
+ break;
+ }
}
sampler_bind_idx = shader_glsl_find_sampler(&ins->ctx->reg_maps->sampler_map, resource_idx, sampler_idx);
- shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, ins->src[1].swizzle,
+ shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, swizzle, flags,
dx_param_str, dy_param_str, lod_param_str, &ins->texel_offset, "%s", coord_param.param_str);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
}
@@ -6299,6 +6378,9 @@ static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins)
unsigned int coord_size;
DWORD flags = 0;
+ resource_idx = ins->src[1].reg.idx[0].offset;
+ sampler_idx = ins->src[2].reg.idx[0].offset;
+
if (ins->handler_idx == WINED3DSIH_SAMPLE_C_LZ)
{
lod_param = "0";
@@ -6310,8 +6392,6 @@ static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins)
if (!(resource_info = shader_glsl_get_resource_info(ins, &ins->src[1].reg)))
return;
- resource_idx = ins->src[1].reg.idx[0].offset;
- sampler_idx = ins->src[2].reg.idx[0].offset;
shader_glsl_get_sample_function(ins->ctx, resource_idx, sampler_idx, flags, &sample_function);
coord_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
@@ -6327,7 +6407,7 @@ static void shader_glsl_sample_c(const struct wined3d_shader_instruction *ins)
}
else
{
- shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, WINED3DSP_NOSWIZZLE,
+ shader_glsl_gen_sample_code(ins, sampler_bind_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0,
NULL, NULL, lod_param, &ins->texel_offset, "vec%u(%s, %s)",
coord_size, coord_param.param_str, compare_param.param_str);
}
@@ -6469,18 +6549,18 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
switch(mask_size)
{
case 1:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- NULL, "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL,
+ NULL, NULL, "dot(ffp_texcoord[%u].xyz, %s)", sampler_idx, src0_param.param_str);
break;
case 2:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- NULL, "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL,
+ NULL, NULL, "vec2(dot(ffp_texcoord[%u].xyz, %s), 0.0)", sampler_idx, src0_param.param_str);
break;
case 3:
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
- NULL, "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL,
+ NULL, NULL, "vec3(dot(ffp_texcoord[%u].xyz, %s), 0.0, 0.0)", sampler_idx, src0_param.param_str);
break;
default:
@@ -6588,7 +6668,7 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xy");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL, "tmp0.xy");
shader_glsl_release_sample_function(ins->ctx, &sample_function);
}
@@ -6609,7 +6689,7 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
shader_glsl_get_sample_function(ins->ctx, reg, reg, 0, &sample_function);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL, "tmp0.xyz");
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL, "tmp0.xyz");
shader_glsl_release_sample_function(ins->ctx, &sample_function);
tex_mx->current_row = 0;
@@ -6660,7 +6740,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask);
/* Sample the texture */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, 0,
NULL, NULL, NULL, NULL, "tmp0%s", coord_mask);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
@@ -6694,7 +6774,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
shader_glsl_write_mask_to_str(sample_function.coord_mask, coord_mask);
/* Sample the texture using the calculated coordinates */
- shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE,
+ shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, 0,
NULL, NULL, NULL, NULL, "tmp0%s", coord_mask);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
@@ -6753,7 +6833,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1, &coord_param);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL,
"T%u%s + vec4(bumpenv_mat%u * %s, 0.0, 0.0)%s", sampler_idx, coord_mask, sampler_idx,
coord_param.param_str, coord_mask);
@@ -6798,7 +6878,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
shader_glsl_get_register_name(&ins->src[0].reg, ins->src[0].reg.data_type, reg_name, NULL, ins->ctx);
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL,
"%s.wx", reg_name->buffer);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
@@ -6818,7 +6898,7 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
shader_glsl_get_register_name(&ins->src[0].reg, ins->src[0].reg.data_type, reg_name, NULL, ins->ctx);
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL,
"%s.yz", reg_name->buffer);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
@@ -6837,7 +6917,7 @@ static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
shader_glsl_get_sample_function(ins->ctx, sampler_idx, sampler_idx, 0, &sample_function);
shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
- shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, NULL,
+ shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, 0, NULL, NULL, NULL, NULL,
"%s", src0_param.param_str);
shader_glsl_release_sample_function(ins->ctx, &sample_function);
}
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index e11a37cf07..6e21444f8c 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -4027,6 +4027,19 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
}
}
+ if (gl_info->supported[ARB_TEXTURE_GATHER])
+ {
+ for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
+ {
+ if (state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] == MAKEFOURCC('G','E','T','4')
+ && state->textures[i]->resource.format_flags & WINED3DFMT_FLAG_ALLOW_FETCH4
+ && shader->reg_maps.resource_info[i].type == WINED3D_SHADER_RESOURCE_TEXTURE_2D)
+ args->fetch4 |= 1 << i;
+ else
+ args->fetch4 &= ~(1 << i);
+ }
+ }
+
if (context->d3d_info->limits.varying_count < wined3d_max_compat_varyings(context->gl_info))
{
const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 8708aa09b3..dc69e935c5 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3616,6 +3616,8 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
{
struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[sampler_idx]);
BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE];
+ BOOL fetch4 = state->sampler_states[sampler_idx][WINED3D_SAMP_MIPMAP_LOD_BIAS]
+ == MAKEFOURCC('G','E','T','4');
const DWORD *sampler_states = state->sampler_states[sampler_idx];
struct wined3d_device *device = context->device;
struct wined3d_sampler_desc desc;
@@ -3650,6 +3652,17 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
/* Trigger shader constant reloading (for NP2 texcoord fixup) */
if (!(texture_gl->t.flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
+
+ /* Trigger pixel shader recompilation for FETCH4 changes */
+ if(gl_info->supported[ARB_TEXTURE_GATHER] &&
+ ((context->last_was_fetch4 >> sampler_idx) & 0x1) ^ fetch4)
+ {
+ if (fetch4)
+ context->last_was_fetch4 |= 1 << sampler_idx;
+ else
+ context->last_was_fetch4 &= ~(1 << sampler_idx);
+ context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL);
+ }
}
else
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4224461142..654e4ff610 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -521,7 +521,8 @@ enum wined3d_immconst_type
WINED3D_IMMCONST_VEC4,
};
-#define WINED3DSP_NOSWIZZLE (0u | (1u << 2) | (2u << 4) | (3u << 6))
+#define WINED3DSP_NOSWIZZLE (0u | (1u << 2) | (2u << 4) | (3u << 6))
+#define WINED3DSP_FETCH4_SWIZZLE (2u | (0u << 2) | (1u << 4) | (3u << 6)) /* zxyw */
enum wined3d_shader_src_modifier
{
@@ -1358,7 +1359,8 @@ struct ps_compile_args
DWORD alpha_test_func : 3;
DWORD render_offscreen : 1;
DWORD rt_alpha_swizzle : 8; /* MAX_RENDER_TARGET_VIEWS, 8 */
- DWORD padding : 18;
+ WORD fetch4 : 16; /* MAX_FRAGMENT_SAMPLERS, 16 */
+ DWORD padding : 2;
};
enum fog_src_type
@@ -1893,6 +1895,7 @@ struct wined3d_context
DWORD last_was_ffp_blit : 1;
DWORD last_was_blit : 1;
DWORD last_was_ckey : 1;
+ DWORD last_was_fetch4 : 16; /* MAX_FRAGMENT_SAMPLERS */
DWORD fog_coord : 1;
DWORD fog_enabled : 1;
DWORD current : 1;
--
2.17.1
Feb. 1, 2019
[PATCH v3 2/4] wined3d: Add fetch4 to shader FFP generate texture stage
by Daniel Ansorregui
- Add flag to indicate FETCH4 support in textures
- Implementation follows AMD implementation and swizzle
projection is allowed and 0.5 texel offset is added
Signed-off-by: Daniel Ansorregui <mailszeros(a)gmail.com>
---
dlls/wined3d/glsl_shader.c | 43 ++++++++++++++++++++++++++++------
dlls/wined3d/utils.c | 11 +++++++++
dlls/wined3d/wined3d_private.h | 4 +++-
3 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 3298a604fd..1950db06a9 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -9711,6 +9711,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
shader_addline(buffer, "#extension GL_ARB_shading_language_420pack : enable\n");
if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
shader_addline(buffer, "#extension GL_ARB_texture_rectangle : enable\n");
+ if (gl_info->supported[ARB_TEXTURE_GATHER])
+ shader_addline(buffer, "#extension GL_ARB_texture_gather : enable\n");
if (!needs_legacy_glsl_syntax(gl_info))
{
@@ -9851,6 +9853,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
for (stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3D_TOP_DISABLE; ++stage)
{
const char *texture_function, *coord_mask;
+ struct wined3d_string_buffer offset;
+ BOOL fetch4 = settings->op[stage].fetch4;
+ BOOL fetch4_proj = FALSE;
BOOL proj;
if (!(tex_map & (1u << stage)))
@@ -9870,7 +9875,6 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
FIXME("Unexpected projection mode %d\n", settings->op[stage].projected);
proj = TRUE;
}
-
if (settings->op[stage].tex_type == WINED3D_GL_RES_TYPE_TEX_CUBE)
proj = FALSE;
@@ -9879,6 +9883,7 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
case WINED3D_GL_RES_TYPE_TEX_1D:
texture_function = "texture1D";
coord_mask = "x";
+ fetch4 = FALSE;
break;
case WINED3D_GL_RES_TYPE_TEX_2D:
texture_function = "texture2D";
@@ -9887,6 +9892,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
case WINED3D_GL_RES_TYPE_TEX_3D:
texture_function = "texture3D";
coord_mask = "xyz";
+ if (fetch4)
+ FIXME("Unsupported Fetch4 and texture3D sampling");
+ fetch4 = FALSE;
break;
case WINED3D_GL_RES_TYPE_TEX_CUBE:
texture_function = "textureCube";
@@ -9901,11 +9909,24 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
texture_function = "";
coord_mask = "xyzw";
proj = FALSE;
+ fetch4 = FALSE;
break;
}
if (!legacy_syntax)
texture_function = "texture";
+ string_buffer_init(&offset);
+ if (fetch4)
+ {
+ texture_function = "textureGather";
+ /* Apply a 0.5 texel offset as in AMD implementation */
+ shader_addline(&offset, " + (vec2(0.5) / textureSize(ps_sampler%u, 0).xy)", stage);
+
+ /* When projection is needed on fetch4 we have to apply it manually by dividing .w */
+ fetch4_proj = proj;
+ proj = FALSE;
+ }
+
if (stage > 0
&& (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
|| settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE))
@@ -9936,8 +9957,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
shader_addline(buffer, "ret = ffp_texcoord[%u] + ret.xyxy;\n", stage);
}
- shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ret.%s%s);\n",
- stage, texture_function, proj ? "Proj" : "", stage, coord_mask, proj ? "w" : "");
+ shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ret.%s%s%s%s);\n", stage, texture_function,
+ proj ? "Proj" : "", stage, coord_mask, proj ? "w" : "", fetch4_proj ? " / ret.w" : "", offset.buffer);
if (settings->op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
shader_addline(buffer, "tex%u *= clamp(tex%u.z * bumpenv_lum_scale%u + bumpenv_lum_offset%u, 0.0, 1.0);\n",
@@ -9945,14 +9966,22 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
}
else if (settings->op[stage].projected == WINED3D_PROJECTION_COUNT3)
{
- shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].xyz);\n",
- stage, texture_function, proj ? "Proj" : "", stage, stage);
+ shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].xyz%s);\n", stage,
+ texture_function, proj ? "Proj" : "", stage, stage, offset.buffer);
}
else
{
- shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].%s%s);\n",
- stage, texture_function, proj ? "Proj" : "", stage, stage, coord_mask, proj ? "w" : "");
+ shader_addline(buffer, "tex%u = %s%s(ps_sampler%u, ffp_texcoord[%u].%s%s", stage,
+ texture_function, proj ? "Proj" : "", stage, stage, coord_mask, proj ? "w" : "");
+ if (fetch4_proj)
+ shader_addline(buffer, " / ffp_texcoord[%u].w", stage);
+ shader_addline(buffer, "%s);\n", offset.buffer);
}
+ string_buffer_clear(&offset);
+
+ /* Match FETCH4 swizzle with textureGather swizzle */
+ if (fetch4)
+ shader_addline(buffer, "tex%u = tex%u.zxyw;\n", stage, stage);
string_buffer_sprintf(tex_reg_name, "tex%u", stage);
shader_glsl_color_correction_ext(buffer, tex_reg_name->buffer, WINED3DSP_WRITEMASK_ALL,
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 7b42202213..82111c8bb2 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -340,6 +340,12 @@ static const struct wined3d_format_base_flags format_base_flags[] =
{WINED3DFMT_NULL, WINED3DFMT_FLAG_EXTENSION},
{WINED3DFMT_NVDB, WINED3DFMT_FLAG_EXTENSION},
{WINED3DFMT_RESZ, WINED3DFMT_FLAG_EXTENSION},
+ {WINED3DFMT_L8_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_L16_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_R16_FLOAT, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_R16, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_ALLOW_FETCH4},
+ {WINED3DFMT_A8_UNORM, WINED3DFMT_FLAG_ALLOW_FETCH4},
};
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b)
@@ -5780,6 +5786,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
settings->op[i].tmp_dst = 0;
settings->op[i].tex_type = WINED3D_GL_RES_TYPE_TEX_1D;
settings->op[i].projected = WINED3D_PROJECTION_NONE;
+ settings->op[i].fetch4 = FALSE;
i++;
break;
}
@@ -5923,6 +5930,10 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
settings->op[i].aarg1 = aarg1;
settings->op[i].aarg2 = aarg2;
settings->op[i].tmp_dst = state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP;
+ settings->op[i].fetch4 = (state->textures[i] && gl_info->supported[ARB_TEXTURE_GATHER]
+ && state->sampler_states[i][WINED3D_SAMP_MIPMAP_LOD_BIAS] == MAKEFOURCC('G','E','T','4')
+ && state->textures[i]->resource.format_flags & WINED3DFMT_FLAG_ALLOW_FETCH4
+ && settings->op[i].tex_type & (WINED3D_GL_RES_TYPE_TEX_2D | WINED3D_GL_RES_TYPE_TEX_RECT));
}
/* Clear unsupported stages */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1e3ec28d6b..4224461142 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2747,7 +2747,8 @@ struct texture_stage_op
unsigned tex_type : 3;
unsigned tmp_dst : 1;
unsigned projected : 2;
- unsigned padding : 10;
+ unsigned fetch4 : 1;
+ unsigned padding : 9;
};
struct ffp_frag_settings
@@ -4434,6 +4435,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN
#define WINED3DFMT_FLAG_VERTEX_ATTRIBUTE 0x01000000
#define WINED3DFMT_FLAG_BLIT 0x02000000
#define WINED3DFMT_FLAG_MAPPABLE 0x04000000
+#define WINED3DFMT_FLAG_ALLOW_FETCH4 0x08000000
struct wined3d_rational
{
--
2.17.1
Feb. 1, 2019
[PATCH v3 1/4] d3d9/tests: Add Fetch4 tests
by Daniel Ansorregui
- Test texld/texldp/texldd/texldb/texldl in PS and FFP
- Test supported/unsupported texture formats on FFP/texld/texldp
- Test 3dtextures (Disabled, each platform has different results)
- Test depth textures DF16/DF24 with fetch4 on PS (FFP is broken on windows)
Signed-off-by: Daniel Ansorregui <mailszeros(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 644 +++++++++++++++++++++++++++++++++++++++
1 file changed, 644 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index c06acb77d4..028fc23078 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -15234,6 +15234,649 @@ done:
DestroyWindow(window);
}
+static void fetch4_test(void)
+{
+ static const DWORD vs_code[] =
+ {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
+ 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
+ 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord o1 */
+ 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
+ 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
+ 0x0000ffff
+ };
+ static const DWORD ps_code_texld[] =
+ {
+ /* Test texld */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff /* end */
+ };
+ static const DWORD ps_code_texldp[] =
+ {
+ /* Test texldp : AMD and Wine uses the projection on Fetch4, Intel UHD 620 does not apply it */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, /* def c0, 0.0, 0.0, 0.0, 2.0 */
+ 0x02000001, 0x80030000, 0x90540000, /* mov r0.xy, v0.xyyy */
+ 0x02000001, 0x800c0000, 0xa0fe0000, /* mov r0.zw, c0.zwww */
+ 0x03010042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldp r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldd[] =
+ {
+ /* Test texldd : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * Sampling LOD gradient should be ignored. Same result as texld */
+ /* NOTE: Radeon HD 5700 driver 8.17.10.1404 disables Fetch4 on texldb */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
+ 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
+ 0x02000001, 0x800f0002, 0xa0e40000, /* mov r2, c0 */
+ 0x0500005d, 0x800f0000, 0x90e40000, 0xa0e40800, 0xa0e40000, 0x80e40002, /* texldd r0, v0, s0, c0, r2 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldb[] =
+ {
+ /* Test texldb : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * Same result as texld */
+ /* NOTE: Radeon HD 5700 driver 8.17.10.1404 disables Fetch4 on texldb */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40a00000, 0x40a00000, /* def c0, 0.0, 0.0, 5.0, 5.0 */
+ 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
+ 0x03020042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldb r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_texldl[] =
+ {
+ /* Test texldl : Fetch4 uses the same D3D state as LOD bias, therefore disables LOD.
+ * The explicit LOD level is then ignored. Same result as texld */
+ /* NOTE: Radeon HD 5700 driver 8.17.10.1404 disables Fetch4 on texldl */
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f000000, 0x3f000000, /* def c0, 0.0, 0.0, 0.5, 0.5 */
+ 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
+ 0x0300005f, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldl r0, r0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff, /* end */
+ };
+ static const DWORD ps_code_3d[] =
+ {
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
+ 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
+ 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff /* end */
+ };
+
+ static const struct
+ {
+ struct vec3 position;
+ struct vec3 texcoord;
+ }
+ quad[] =
+ {
+ /* Tilted on Z axis to get a depth gradient in the depth test */
+ /* NOTE: Using 0.55f-0.6f to avoid rounding errors on depth tests */
+ {{-1.0f, 1.0f, 1.0f}, {0.0f,0.0f,0.6f} },
+ {{ 1.0f, 1.0f, 0.0f}, {1.0f,0.0f,0.6f} },
+ {{-1.0f,-1.0f, 0.0f}, {0.0f,1.0f,0.6f} },
+ {{ 1.0f,-1.0f, 0.0f}, {1.0f,1.0f,0.6f} }
+ };
+
+ static const struct
+ {
+ UINT x[4], y[4]; /* Matrix Sampling positions */
+ D3DCOLOR color_amd[16]; /* AMD original implementation swizzle with -0.5 texel coord */
+ D3DCOLOR color_intel[16]; /* Intel UHD 620 implementation swizzle with no texel coord correction */
+ /* Wine follows the AMD immplementation, and consider an error the Intel one results
+ * However, the test will accept as valid the intel only if running on windows */
+ D3DCOLOR color_3d_fetch4_off[16];
+ D3DCOLOR color_fetch4_off[16];
+ }
+ expected_colors =
+ {
+ { 40, 200, 360, 520},
+ { 30, 150, 270, 390},
+ /* AMD implementation - Wine implementation */
+ {0x131202f2, 0x1211f2f1, 0x1110f101, 0x10130102,
+ 0x02f204f4, 0xf2f1f4f3, 0xf101f303, 0x01020304,
+ 0x04f42322, 0xf4f32221, 0xf3032120, 0x03042023,
+ 0x23221312, 0x22211211, 0x21201110, 0x20231013},
+ /* Intel UHD 620 implementation */
+ {0x23102013, 0x22132312, 0x21122211, 0x20112110,
+ 0x13011002, 0x120213f2, 0x11f212f1, 0x10f11101,
+ 0x02030104, 0xf20402f4, 0xf1f4f2f3, 0x01f3f103,
+ 0x04200323, 0xf4230422, 0xf322f421, 0x0321f320},
+ /* Fetch4 off on 3D textures */
+ {0xff020202, 0xfff2f2f2, 0xfff1f1f1, 0xff010101,
+ 0xff050505, 0xfff4f4f4, 0xfff3f3f3, 0xff030303,
+ 0xff232323, 0xff222222, 0xff212121, 0xff202020,
+ 0xff131313, 0xff121212, 0xff111111, 0xff101010},
+ /* Fetch4 off on 2D texture */
+ {0x13131313, 0x12121212, 0x11111111, 0x10101010,
+ 0x02020202, 0xf2f2f2f2, 0xf1f1f1f1, 0x01010101,
+ 0x04040404, 0xf4f4f4f4, 0xf3f3f3f3, 0x03030303,
+ 0x23232323, 0x22222222, 0x21212121, 0x20202020}
+ };
+
+ static const DWORD fetch4_data[] = {0x10111213,
+ 0x01f1f202,
+ 0x03f3f404,
+ 0x20212223};
+
+ static struct
+ {
+ IDirect3DVertexShader9 *vs;
+ IDirect3DPixelShader9 *ps;
+ const DWORD *ps_code;
+ const char *name;
+ BOOL projection; /* The results should be projected (zoomed by 2) */
+ BOOL allow_off; /* Do not enforce Fetch4 enabled on this one on Windows */
+ }
+ shaders[] =
+ {
+ {NULL, NULL, NULL, "FFP", FALSE, FALSE},
+ {NULL, NULL, ps_code_texld, "texld", FALSE, FALSE},
+ {NULL, NULL, ps_code_texldp, "texldp", TRUE, FALSE},
+ {NULL, NULL, ps_code_texldd, "texldd", FALSE, TRUE},
+ {NULL, NULL, ps_code_texldb, "texldb", FALSE, TRUE},
+ {NULL, NULL, ps_code_texldl, "texldl", FALSE, TRUE},
+ };
+
+ static const struct
+ {
+ D3DFORMAT format; /* The format of the texture */
+ DWORD data; /* The data we will write to the first line */
+ UINT x, y; /* Where we expect the color to be */
+ BOOL broken_wine; /* Do not check it on wine because is known ot be broken */
+ D3DCOLOR color_amd[3]; /* Wine results. Results on AMD swizzle + texture offset */
+ D3DCOLOR color_intel[3]; /* Results with intel UHD 620, intel swizzle + no texel offset */
+ }
+ format_tests[] =
+ {
+ /* Enabled formats */
+ {D3DFMT_L8, 0xff804010, 360, 270, FALSE,
+ {0x00004010, 0x00004010, 0x10400000},
+ {0x40001000, 0x40001000, 0x40001000}
+ },
+ {D3DFMT_L16, 0xff804010, 360, 270, FALSE,
+ {0x0000ff40, 0x0000ff40, 0x40ff0000},
+ {0xff004000, 0xff004000, 0xff004000}
+ },
+ {D3DFMT_R16F, 0x38003c00, 360, 270, FALSE,
+ {0x000080ff, 0x000080ff, 0xff800000},
+ {0x8000ff00, 0x8000ff00, 0x8000ff00}
+ },
+ {D3DFMT_R32F, 0x3f000000, 360, 270, FALSE,
+ {0x00000080, 0x00000080, 0x80000000},
+ {0x00008000, 0x00008000, 0x00008000}
+ },
+
+ /* Disabled format on Intel, enabled on AMD, broken on wine
+ * since it is implemented with GL_ALPHA, and fetch4 will fetch RED value */
+ {D3DFMT_A8, 0xff804010, 360, 270, TRUE,
+ {0x00004010, 0x00004010, 0x10400000},
+ {0x00000000, 0x00000000, 0x00000000}
+ },
+
+ /* Disabled format */
+ {D3DFMT_A8R8G8B8, 0xff804010, 360, 270, FALSE,
+ {0x00000000, 0x00000000, 0xff804010},
+ {0x00000000, 0x00000000, 0xff804010}
+ },
+ };
+
+ static const struct
+ {
+ D3DCOLOR color_off, color_amd, color_intel;
+ UINT x, y;
+ }
+ expected_depth[][4] =
+ {
+ {
+ /* This is the expected result for shadow samplers */
+ {0xffffffff,0xffffffff,0xffffffff, 20, 15},
+ {0xffffffff,0xffffffff,0xffffffff,260, 15},
+ {0x00000000,0x00000000,0x00000000, 20,255},
+ {0x00000000,0x00000000,0x00000000,260,135},
+ },
+ {
+ /* This is the expected result with DF16 */
+ {0xfffe0000,0xfedfdfbf,0x202000ff, 20, 15},
+ {0xff9f0000,0x9f7f7f5f,0x00bf009f,260, 15},
+ {0xff800000,0x7f5f5f3f,0x9f000080, 20,255},
+ {0xff600000,0x5f3f3f1f,0x80809f60,260,135},
+ },
+ {
+ /* This is the expected result with DF24 */
+ {0xffff0000,0xffdfdfbf,0x202000ff, 20, 15},
+ {0xff9f0000,0x9f7f7f5f,0x00bf009f,260, 15},
+ {0xff800000,0x7f5f5f3f,0x9f000080, 20,255},
+ {0xff600000,0x5f3f3f1f,0x80809f60,260,135},
+ }
+ };
+
+ static const struct
+ {
+ D3DFORMAT format;
+ const char *name;
+ UINT index;
+ }
+ depth_tests[] =
+ {
+ {D3DFMT_D16_LOCKABLE, "D16_LOCKABLE", 0},
+ {D3DFMT_D32, "D32", 0},
+ {D3DFMT_D15S1, "D15S1", 0},
+ {D3DFMT_D24S8, "D24S8", 0},
+ {D3DFMT_D24X8, "D24X8", 0},
+ {D3DFMT_D24X4S4, "D24X4S4", 0},
+ {D3DFMT_D16, "D16", 0},
+ {D3DFMT_D32F_LOCKABLE, "D32F_LOCKABLE", 0},
+ {D3DFMT_D24FS8, "D24FS8", 0},
+ {MAKEFOURCC('D','F','1','6'), "DF16", 1},
+ {MAKEFOURCC('D','F','2','4'), "DF24", 2},
+ };
+
+ const BOOL isWin = strcmp(winetest_platform, "wine");
+
+ IDirect3DSurface9 *original_ds, *original_rt, *rt;
+ IDirect3DVolumeTexture9 *texture3D;
+ IDirect3DPixelShader9 *ps_3d;
+ struct surface_readback rb;
+ IDirect3DVertexShader9 *vs;
+ IDirect3DTexture9 *texture;
+ IDirect3DDevice9 *device;
+ D3DLOCKED_RECT lr;
+ D3DLOCKED_BOX lb;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ D3DCAPS9 caps;
+ UINT i, j, k;
+ HWND window;
+ HRESULT hr;
+
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('D','F','2','4'))))
+ {
+ skip("No DF24 support, skipping FETCH4 test.\n");
+ goto done;
+ }
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
+ if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ {
+ skip("No pixel shader 3.0 support, skipping FETCH4 test.\n");
+ IDirect3DDevice9_Release(device);
+ goto done;
+ }
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
+ ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
+ ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_CreateRenderTarget(device, 8, 8, D3DFMT_A8R8G8B8,
+ D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
+ ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
+
+ /* Create our texture for FETCH4 shader testing */
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
+ memcpy((BYTE *)lr.pBits + i*lr.Pitch, &fetch4_data[i], sizeof(fetch4_data[i]));
+ hr = IDirect3DTexture9_UnlockRect(texture, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
+
+ /* Create vertex shader */
+ hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
+ ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
+ /* Prepare the pixel shaders */
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ {
+ if (shaders[i].ps_code)
+ {
+ hr = IDirect3DDevice9_CreatePixelShader(device, shaders[i].ps_code, &shaders[i].ps);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
+ /* Copy vertex shader pointer if a PS is present */
+ shaders[i].vs = vs;
+ }
+ }
+ hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_3d, &ps_3d);
+ ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
+ ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
+
+ /* According to the spec, FETCH4 is enabled when D3DSAMP_MIPMAPLODBIAS == GET4 and also
+ * D3DSAMP_MAGFILTER == D3DTEXF_POINT. But apparently only GET4 is needed for it to get active.
+ * However, AMD HW r500 samples always as if POINT (nearest filtering) is selected with FETCH4
+ * the driver later on corrected this by adding -0.5 texel coord. */
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','4'));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /***********************************************************************
+ * Tests for FFP/PS correctness when using L8 texture with fetch4. *
+ ***********************************************************************/
+
+ /* Render with fetch4 and test if we obtain proper results for all sampler FFP/PS instructions */
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, shaders[i].vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[i].ps);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ for (j = 0; j < ARRAY_SIZE(expected_colors.color_amd); ++j)
+ {
+ UINT x = expected_colors.x[j % 4];
+ UINT y = expected_colors.y[j / 4];
+ D3DCOLOR color = get_readback_color(&rb, x, y);
+ D3DCOLOR color_amd = expected_colors.color_amd[shaders[i].projection ? (j/4/2*4 + (j%4)/2) : j];
+ D3DCOLOR color_intel = expected_colors.color_intel[j];
+ ok(color_match(color, color_amd, 1)
+ || (isWin && (color_match(color, color_intel, 1) || shaders[i].allow_off)),
+ "Test %s Expected color 0x%08x at (%u, %u), got 0x%08x.\n", shaders[i].name,
+ color_amd, x, y, color);
+ }
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ /***************************************************************************
+ * Tests for fetch4 enable/disable with different texture formats in FFP/PS. *
+ ***************************************************************************/
+
+ /* Create the textures to test FETCH4 does work/not work there as expected */
+ for (i = 0; i < ARRAY_SIZE(format_tests); ++i)
+ {
+ IDirect3DTexture9 *tex;
+ hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, format_tests[i].format,
+ D3DPOOL_MANAGED, &tex, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_LockRect(tex, 0, &lr, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture, hr %#x.\n", hr);
+ memcpy(lr.pBits, &format_tests[i].data, 4);
+ hr = IDirect3DTexture9_UnlockRect(tex, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex);
+ ok(hr == D3D_OK, "Failed to set texture, hr %#x.\n", hr);
+
+ /* Test if FETCH4 is enabled/disabled when different textures are used with FFP/texld/texldp */
+ for (j = 0; j < ARRAY_SIZE(format_tests[i].color_amd); ++j)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, shaders[j].vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[j].ps);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ D3DCOLOR color = get_readback_color(&rb, format_tests[i].x, format_tests[i].y);
+ D3DCOLOR color_amd = format_tests[i].color_amd[j];
+ D3DCOLOR color_intel = format_tests[i].color_intel[j];
+ todo_wine_if(format_tests[i].broken_wine) ok(color_match(color, color_amd, 1)
+ || (isWin && color_match(color, color_intel, 1)),
+ "Test %d,%s expected color 0x%08x at (%u, %u), got 0x%08x.\n", i, shaders[j].name,
+ color_amd, format_tests[i].x, format_tests[i].y, color);
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+ IDirect3DTexture9_Release(tex);
+ }
+
+ /**************************************************
+ * Tests that fetch4 works with 3D textures. *
+ **************************************************/
+
+ /* Create volume (3D) texture */
+ IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture3D, NULL );
+ ok(hr == D3D_OK, "Failed to create volume texture, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_LockBox(texture3D, 0, &lb, NULL, 0);
+ ok(hr == D3D_OK, "Failed to lock texture3D, hr %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
+ {
+ memcpy((BYTE *)lb.pBits + i*lb.RowPitch, &fetch4_data[i], sizeof(fetch4_data[i]));
+ /* Shift the lower level, to keep it different */
+ memcpy((BYTE *)lb.pBits + i*lb.RowPitch + lb.SlicePitch, &fetch4_data[(i+1)%4], sizeof(fetch4_data[i]));
+ }
+ hr = IDirect3DVolumeTexture9_UnlockBox(texture3D, 0);
+ ok(hr == D3D_OK, "Failed to unlock texture3D, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3D);
+ ok(hr == D3D_OK, "Failed to set texture3D, hr %#x.\n", hr);
+
+ /* Test FFP and texld with dcl_volume (ps_3d) */
+ for (i = 0; i < 2; ++i)
+ {
+ hr = IDirect3DDevice9_SetVertexShader(device, i ? vs : NULL);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, i ? ps_3d : NULL);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+ get_rt_readback(original_rt, &rb);
+ for (j = 0; j < ARRAY_SIZE(expected_colors.color_amd); ++j)
+ {
+ UINT x = expected_colors.x[j % 4];
+ UINT y = expected_colors.y[j / 4];
+ D3DCOLOR color = get_readback_color(&rb, x, y);
+ D3DCOLOR color_amd = expected_colors.color_amd[j];
+ D3DCOLOR color_intel = expected_colors.color_intel[j];
+ D3DCOLOR color_off = expected_colors.color_3d_fetch4_off[j];
+ D3DCOLOR color_zround = expected_colors.color_amd[(j+4) % ARRAY_SIZE(expected_colors.color_amd)];
+ /* FIXME: Fetch4 on 3D textures have different results based on the vendor/driver
+ * - AMD "HD 5700" rounds to nearest "z" texel, and does fetch4 normally on .xy
+ * - AMD "R500" has fetch4 disabled
+ * - AMD "R580" has fetch4 enabled sampling at .xy0
+ * - Intel UHD 620 sample with fetch4 at .xy0
+ * Currently unimplemented on wine due to lack of GL functionality to cast 3D->2DArray
+ * Wine produces same results as if fetch4 is not enabled (which probably is better)
+ * Test will pass on windows if either one of the allowed results is returned */
+ if(isWin)
+ ok(color_match(color, color_zround, 2) || color_match(color, color_off, 2)
+ || color_match(color, color_intel, 2) || color_match(color, color_amd, 2),
+ "Test 3D %s Expected colors 0x%08x || 0x%08x || 0x%08x || 0x%08x at (%u, %u), got 0x%08x.\n",
+ shaders[i].name, color_amd, color_zround, color_off, color_intel, x, y, color);
+ else
+ ok(color_match(color, color_off, 2),
+ "Test 3D %s Expected color 0x%08x at (%u, %u), got 0x%08x.\n", shaders[i].name,
+ color_off, x, y, color);
+ }
+ release_surface_readback(&rb);
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ /********************************************************
+ * Tests for fetch4 enable/disable with depth textures. *
+ ********************************************************/
+
+ for (i = 0; i < ARRAY_SIZE(depth_tests); ++i)
+ {
+ D3DFORMAT format = depth_tests[i].format;
+ IDirect3DTexture9 *depth_texture;
+ IDirect3DSurface9 *ds;
+
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
+ continue;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1,
+ D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &depth_texture, NULL);
+ ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
+ hr = IDirect3DTexture9_GetSurfaceLevel(depth_texture, 0, &ds);
+ ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
+ ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
+ ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, NULL);
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(hr == D3D_OK, "Failed to set texture3D, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0,
+ D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','1'));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /* Setup the depth/stencil surface. */
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
+
+ /* Render to the depth surface */
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
+ ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
+ IDirect3DSurface9_Release(ds);
+ hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
+ ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)depth_texture);
+ ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
+
+ /* Set a shader for depth sampling, otherwise windows does not show anything */
+ hr = IDirect3DDevice9_SetVertexShader(device, vs);
+ ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetPixelShader(device, shaders[1].ps); /* same as texld */
+ ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
+
+ for (j = 0; j < 2; ++j){
+ hr = IDirect3DDevice9_SetSamplerState(device, 0,
+ D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T', j ? '4' : '1' ));
+ ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
+
+ /* Do the actual shadow mapping. */
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
+
+ get_rt_readback(original_rt, &rb);
+ for (k = 0; k < ARRAY_SIZE(expected_depth[depth_tests[i].index]); ++k)
+ {
+ UINT x = expected_depth[depth_tests[i].index][k].x;
+ UINT y = expected_depth[depth_tests[i].index][k].y;
+ D3DCOLOR color_off = expected_depth[depth_tests[i].index][k].color_off;
+ D3DCOLOR color_amd = expected_depth[depth_tests[i].index][k].color_amd;
+ D3DCOLOR color_intel = expected_depth[depth_tests[i].index][k].color_intel;
+ D3DCOLOR color = get_readback_color(&rb, x, y);
+ /* When Fetch4 is OFF, ignore G and B channels on windows.
+ * Some implementations will copy R=G=B, some will set them to 0 */
+ if(j == 0)
+ ok((isWin && color_match(color & 0xffff0000, color_off & 0xffff0000, 2))
+ || color_match(color, color_off, 2),
+ "Test OFF Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
+ color_off, x, y, depth_tests[i].name, color);
+ else
+ ok(color_match(color, color_amd, 2)
+ || (isWin && color_match(color, color_intel, 2)),
+ "Test ON Expected colors 0x%08x || 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
+ color_amd, color_intel, x, y, depth_tests[i].name, color);
+ }
+ release_surface_readback(&rb);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
+ }
+
+ hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
+ ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
+ IDirect3DTexture9_Release(depth_texture);
+ }
+
+ IDirect3DVolumeTexture9_Release(texture3D);
+ IDirect3DTexture9_Release(texture);
+ for (i = 0; i < ARRAY_SIZE(shaders); ++i)
+ if (shaders[i].ps)
+ IDirect3DPixelShader9_Release(shaders[i].ps);
+ IDirect3DPixelShader9_Release(ps_3d);
+ IDirect3DVertexShader9_Release(vs);
+ IDirect3DSurface9_Release(rt);
+ IDirect3DSurface9_Release(original_ds);
+ IDirect3DSurface9_Release(original_rt);
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void shadow_test(void)
{
static const DWORD ps_code[] =
@@ -24660,6 +25303,7 @@ START_TEST(visual)
depth_buffer2_test();
depth_blit_test();
intz_test();
+ fetch4_test();
shadow_test();
fp_special_test();
depth_bounds_test();
--
2.17.1
Feb. 1, 2019