Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=37705 Signed-off-by: Paul Gofman gofmanp@gmail.com
The final version of wined3d changes were suggested by Henri Verbeet. --- dlls/d3d9/tests/visual.c | 149 +++++++++++++++++++++++++++++++-- dlls/wined3d/context.c | 2 +- dlls/wined3d/state.c | 4 +- dlls/wined3d/wined3d_private.h | 5 ++ 4 files changed, 148 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 13cf6c7283..d0e2932db5 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -8886,11 +8886,11 @@ done:
static void srgbtexture_test(void) { - /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE - * texture stage state to render a quad using that texture. The resulting - * color components should be 0x36 (~ 0.21), per this formula: + /* The result of SRGB to linear conversion for value 0x7f (~ .5) used on + * texture mip level 0 should be 0x36 (~ 0.21), per this formula: * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4 - * This is true where srgb_color > 0.04045. */ + * This is true where srgb_color > 0.04045. + * For the value of 0x3f used on mip level 1 the result should be 0x0d (~0.05). */ struct IDirect3DTexture9 *texture; struct IDirect3DSurface9 *surface; IDirect3DDevice9 *device; @@ -8898,6 +8898,7 @@ static void srgbtexture_test(void) D3DCOLOR color; ULONG refcount; HWND window; + DWORD value; HRESULT hr;
static const float quad[] = @@ -8925,38 +8926,168 @@ static void srgbtexture_test(void) goto done; }
- hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL); + hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 2, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface); - ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr); - + ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel failed, hr %#x.\n", hr); fill_surface(surface, 0xff7f7f7f, 0); IDirect3DSurface9_Release(surface); + hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface); + ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel failed, hr %#x.\n", hr); + fill_surface(surface, 0xff3f3f3f, 0); + IDirect3DSurface9_Release(surface);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE); ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr); hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture); ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
+ /* AMD uses LSB from D3DSAMP_SRGBTEXTURE value. + * NVIDIA ignores any values except for 0 or 1 leaving previous D3DSAMP_SRGBTEXTURE state. + * Intel, WARP treat the value as boolean. */ hr = IDirect3DDevice9_BeginScene(device); ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); - - hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a); ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 0x7e41882a, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1); ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr); hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x007f7f7f, 1) || broken(color_match(color, 0x00363636, 1)), + "sRGB quad has color 0x%08x, expected 0x007f7f7f.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 100); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 100, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x007f7f7f, 1) || broken(color_match(color, 0x00363636, 1)), + "sRGB quad has color 0x%08x, expected 0x007f7f7f.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 2); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 2, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); hr = IDirect3DDevice9_EndScene(device); ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x007f7f7f, 1) || broken(color_match(color, 0x00363636, 1)), + "sRGB quad has color 0x%08x, expected 0x007f7f7f.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 3); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 3, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x007f7f7f, 1) || color_match(color, 0x00363636, 1), + "sRGB quad has color 0x%08x, expected 0x007f7f7f or 0x00363636.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == TRUE, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); color = getPixelColor(device, 320, 240); ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + /* Set the other state to verify that the sampler just inherits old D3DSAMP_SRGBTEXTURE but + * the old sampler is not preserved entirely on NVIDIA. */ + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 0x7e41882a, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x000d0d0d, 1) || color_match(color, 0x003f3f3f, 1), + "sRGB quad has color 0x%08x, expected 0x000d0d0d or 0x003f3f3f.\n", color); hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 0, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x003f3f3f, 1), "sRGB quad has color 0x%08x, expected 0x003f3f3f.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a); + ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value); + ok(SUCCEEDED(hr), "Failed to get sampler state, hr %#x.\n", hr); + ok(value == 0x7e41882a, "Unexpected D3DSAMP_SRGBTEXTURE value %#x.\n", value); + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1); + ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float)); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + color = getPixelColor(device, 320, 240); + ok(color_match(color, 0x003f3f3f, 1) || broken(color_match(color, 0x000d0d0d, 1)), + "sRGB quad has color 0x%08x, expected 0x003f3f3f.\n", color); + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr); IDirect3DTexture9_Release(texture); refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 96ba06ddf1..63ff833691 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3719,7 +3719,7 @@ static void context_preload_texture(struct wined3d_context *context, if (!(texture = state->textures[idx])) return;
- wined3d_texture_load(texture, context, state->sampler_states[idx][WINED3D_SAMP_SRGB_TEXTURE]); + wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx])); }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 0f7b030b0c..43746a4363 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3574,7 +3574,7 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc desc->max_anisotropy = 1; desc->compare = texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_SHADOW; desc->comparison_func = WINED3D_CMP_LESSEQUAL; - desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE]; + desc->srgb_decode = is_srgb_enabled(sampler_states);
if (!(texture_gl->t.resource.format_flags & WINED3DFMT_FLAG_FILTERING)) { @@ -3615,9 +3615,9 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state if (state->textures[sampler_idx]) { struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[sampler_idx]); - BOOL srgb = state->sampler_states[sampler_idx][WINED3D_SAMP_SRGB_TEXTURE]; const DWORD *sampler_states = state->sampler_states[sampler_idx]; struct wined3d_device *device = context->device; + BOOL srgb = is_srgb_enabled(sampler_states); struct wined3d_sampler_desc desc; struct wined3d_sampler *sampler; struct wine_rb_entry *entry; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 57df9f1eb2..5c5e515e50 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4591,6 +4591,11 @@ static inline void context_apply_state(struct wined3d_context *context, state_table[rep].apply(context, state, rep); }
+static inline BOOL is_srgb_enabled(const DWORD *sampler_states) +{ + return sampler_states[WINED3D_SAMP_SRGB_TEXTURE] & 0x1; +} + static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, const struct wined3d_texture *texture) {
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=47883
Your paranoid android.
=== w8 (32 bit report) ===
d3d9: visual.c:8750: Test failed: Got unexpected color 0x00007580 for quad 2 (different colors).