Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45978 Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - Check resource bind flags before searching for texture among render targets.
dlls/d3d9/tests/visual.c | 162 +++++++++++++++++++++++++++++++++ dlls/wined3d/adapter_gl.c | 7 ++ dlls/wined3d/context.c | 52 +++++++++++ dlls/wined3d/wined3d_gl.h | 2 + dlls/wined3d/wined3d_private.h | 3 +- 5 files changed, 225 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index e7076aeed6..f3ff26b773 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -26263,6 +26263,167 @@ static void test_draw_mapped_buffer(void) DestroyWindow(window); }
+static void test_sample_attached_rendertarget(void) +{ + D3DADAPTER_IDENTIFIER9 identifier; + IDirect3DQuery9 *event_query; + IDirect3DTexture9 *texture; + IDirect3DVertexBuffer9 *vb; + IDirect3DPixelShader9 *ps; + IDirect3DDevice9 *device; + IDirect3DSurface9 *rt; + IDirect3D9 *d3d; + unsigned int i; + ULONG refcount; + D3DCOLOR color; + BOOL is_warp; + HWND window; + HRESULT hr; + void *data; + + static const struct + { + struct vec3 posistion; + struct vec2 texcoord; + } + quad[] = + { + {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}}, + {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}}, + {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}}, + {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}}, + }; + + static const DWORD pixel_shader_code[] = + { + 0xffff0200, /* ps_2_0 */ + 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, + /* def c0, 0.25, 0.25, 0.25, 0.25 */ + 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */ + 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */ + 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */ + 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40000, /* add r0, r0, c0 */ + 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */ + 0x0000ffff + }; + + window = create_window(); + ok(!!window, "Failed to create a window.\n"); + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + is_warp = adapter_is_warp(&identifier); + + if (!(device = create_device(d3d, window, window, TRUE))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, NULL); + if (hr == D3DERR_NOTAVAILABLE) + { + /* Without synchronization native d3d seems to show race condition on + * render target update, similar to opengl without using texture barrier. */ + skip("Event queries are not supported, skipping test.\n"); + IDirect3DDevice9_Release(device); + IDirect3D9_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &event_query); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), D3DUSAGE_DYNAMIC, + D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &vb, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + memcpy(data, quad, sizeof(quad)); + hr = IDirect3DVertexBuffer9_Unlock(vb); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0])); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x01010101, 0.0, 0); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + check_rt_color(rt, 0x00010101); + + hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_SetPixelShader(device, ps); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < 3; ++i) + { + while (IDirect3DQuery9_GetData(event_query, NULL, 0, D3DGETDATA_FLUSH) == S_FALSE) + ; + + hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + IDirect3DQuery9_Issue(event_query, D3DISSUE_END); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + } + + hr = IDirect3DDevice9_EndScene(device); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + + color = getPixelColor(device, 0, 0); + if (is_warp || color == 0x00010101) + skip("Sampling attached render targets is not supported.\n"); + else + check_rt_color(rt, 0x00c1c1c1); + + IDirect3DQuery9_Release(event_query); + + IDirect3DVertexBuffer9_Release(vb); + + IDirect3DPixelShader9_Release(ps); + IDirect3DSurface9_Release(rt); + IDirect3DTexture9_Release(texture); + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + + IDirect3D9_Release(d3d); + DestroyWindow(window); +}
START_TEST(visual) { @@ -26409,4 +26570,5 @@ START_TEST(visual) test_desktop_window(); test_mismatched_sample_types(); test_draw_mapped_buffer(); + test_sample_attached_rendertarget(); } diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index ed1022030b..e83aebfa56 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -159,6 +159,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_vertex_shader", ARB_VERTEX_SHADER }, {"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV}, {"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY }, + {"GL_ARB_texture_barrier", ARB_TEXTURE_BARRIER },
/* ATI */ {"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER }, @@ -228,6 +229,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, + {"GL_NV_texture_barrier", NV_TEXTURE_BARRIER }, };
static const struct wined3d_extension_map wgl_extension_map[] = @@ -2454,6 +2456,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glViewportArrayv) USE_GL_FUNC(glViewportIndexedf) USE_GL_FUNC(glViewportIndexedfv) + /* GL_ARB_texture_barrier */ + USE_GL_FUNC(glTextureBarrier); /* GL_ATI_fragment_shader */ USE_GL_FUNC(glAlphaFragmentOp1ATI) USE_GL_FUNC(glAlphaFragmentOp2ATI) @@ -2644,6 +2648,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info) USE_GL_FUNC(glCombinerParameteriNV) USE_GL_FUNC(glCombinerParameterivNV) USE_GL_FUNC(glFinalCombinerInputNV) + /* GL_NV_texture_barrier */ + USE_GL_FUNC(glTextureBarrierNV); /* WGL extensions */ USE_GL_FUNC(wglChoosePixelFormatARB) USE_GL_FUNC(wglGetExtensionsStringARB) @@ -3406,6 +3412,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, {ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)}, {ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)}, {ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)}, + {ARB_TEXTURE_BARRIER, MAKEDWORD_VERSION(4, 5)},
{ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)}, {ARB_POLYGON_OFFSET_CLAMP, MAKEDWORD_VERSION(4, 6)}, diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 9cd6a6e3de..edd6c9f08e 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3687,6 +3687,29 @@ static void context_update_stream_info(struct wined3d_context *context, const st } }
+static void context_texture_check_fbo_attached(struct wined3d_context *context, + const struct wined3d_state *state, const struct wined3d_resource *resource) +{ + struct wined3d_rendertarget_view * const *rts = &state->fb->render_targets[0]; + unsigned int i; + + if (state->fb->depth_stencil && state->fb->depth_stencil->resource == resource) + { + context->uses_fbo_attached_resources = 1; + return; + } + + if (!(resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) + return; + + for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i) + if (rts[i] && rts[i]->resource == resource) + { + context->uses_fbo_attached_resources = 1; + return; + } +} + /* Context activation is done by the caller. */ static void context_preload_texture(struct wined3d_context *context, const struct wined3d_state *state, unsigned int idx) @@ -3696,6 +3719,9 @@ static void context_preload_texture(struct wined3d_context *context, if (!(texture = state->textures[idx])) return;
+ if (texture->resource.bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_DEPTH_STENCIL)) + context_texture_check_fbo_attached(context, state, &texture->resource); + wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx])); }
@@ -3929,6 +3955,8 @@ static BOOL context_apply_draw_state(struct wined3d_context *context, unsigned int i, base; WORD map;
+ context->uses_fbo_attached_resources = 0; + if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil)) { if (!gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS]) @@ -4984,6 +5012,30 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s checkGLcall("glPatchParameteri"); }
+ if (context->uses_fbo_attached_resources) + { + static unsigned int fixme_once; + + if (gl_info->supported[ARB_TEXTURE_BARRIER]) + { + GL_EXTCALL(glTextureBarrier()); + } + else if (gl_info->supported[NV_TEXTURE_BARRIER]) + { + GL_EXTCALL(glTextureBarrierNV()); + } + else + { + if (!fixme_once++) + FIXME("Sampling attached render targets is not supported.\n"); + + WARN("Sampling attached render targets is not supported, skipping draw.\n"); + context_release(context); + return; + } + checkGLcall("glTextureBarrier"); + } + if (parameters->indirect) { if (!context->use_immediate_mode_draw && !emulation) diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 678ad1a4ef..3372b4b6be 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -142,6 +142,7 @@ enum wined3d_gl_extension ARB_VERTEX_SHADER, ARB_VERTEX_TYPE_2_10_10_10_REV, ARB_VIEWPORT_ARRAY, + ARB_TEXTURE_BARRIER, /* ATI */ ATI_FRAGMENT_SHADER, ATI_SEPARATE_STENCIL, @@ -204,6 +205,7 @@ enum wined3d_gl_extension NV_VERTEX_PROGRAM2, NV_VERTEX_PROGRAM2_OPTION, NV_VERTEX_PROGRAM3, + NV_TEXTURE_BARRIER, /* WGL extensions */ WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 307f7a42ad..7bf2b798e6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1961,6 +1961,7 @@ struct wined3d_context
DWORD use_immediate_mode_draw : 1; DWORD uses_uavs : 1; + DWORD uses_fbo_attached_resources : 1; DWORD transform_feedback_active : 1; DWORD transform_feedback_paused : 1; DWORD fog_coord : 1; @@ -1969,7 +1970,7 @@ struct wined3d_context DWORD destroyed : 1; DWORD destroy_delayed : 1; DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */ - DWORD padding : 15; + DWORD padding : 14;
DWORD constant_update_mask; DWORD numbered_array_mask;
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: - added patch.
dlls/d3d11/tests/d3d11.c | 180 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index da4627d7a8..bc79b52efd 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -29394,6 +29394,185 @@ static void test_desktop_window(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_sample_attached_rtv(void) +{ + struct d3d11_test_context test_context; + ID3D11RenderTargetView *rtv, *rtvs[2]; + ID3D11Texture2D *texture, *texture2; + D3D11_TEXTURE2D_DESC texture_desc; + D3D11_SAMPLER_DESC sampler_desc; + ID3D11ShaderResourceView *srv; + ID3D11DeviceContext *context; + ID3D11SamplerState *sampler; + struct resource_readback rb; + ID3D11PixelShader *ps; + ID3D11Device *device; + unsigned int x, y; + DWORD color; + HRESULT hr; + + static const DWORD ps_ld_code[] = + { +#if 0 + Texture2D t; + + struct PS_OUTPUT + { + float4 color0: SV_Target0; + float4 color1: SV_Target1; + }; + + PS_OUTPUT main(float4 position : SV_POSITION) + { + PS_OUTPUT output; + float3 p; + + t.GetDimensions(0, p.x, p.y, p.z); + p.z = 0; + p *= float3(position.x / 640.0f, position.y / 480.0f, 1.0f); + output.color0 = output.color1 = t.Load(int3(p)) + float4(0.25, 0.25, 0.25, 0.25); + return output; + } +#endif + 0x43425844, 0x08dd0517, 0x07d7e538, 0x4cad261f, 0xa2ae5942, 0x00000001, 0x00000200, 0x00000003, + 0x0000002c, 0x00000060, 0x000000ac, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, + 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, + 0x4e47534f, 0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, + 0x00000000, 0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, + 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000014c, 0x00000040, 0x00000053, 0x04001858, + 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, + 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000001, 0x0700003d, + 0x001000f2, 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100032, + 0x00000000, 0x00100046, 0x00000000, 0x00101046, 0x00000000, 0x0a000038, 0x00100032, 0x00000000, + 0x00100046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036, + 0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0500001b, + 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00107e46, 0x00000000, 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000, + 0x00004002, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, 0x05000036, 0x001020f2, 0x00000000, + 0x00100e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00100e46, 0x00000000, 0x0100003e, + }; + + static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f}; + + if (!init_test_context(&test_context, NULL)) + return; + + device = test_context.device; + context = test_context.immediate_context; + + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D11_USAGE_DEFAULT; + texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sampler_desc.MipLODBias = 0.0f; + sampler_desc.MaxAnisotropy = 0; + sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER; + sampler_desc.BorderColor[0] = 0.0f; + sampler_desc.BorderColor[1] = 0.0f; + sampler_desc.BorderColor[2] = 0.0f; + sampler_desc.BorderColor[3] = 0.0f; + sampler_desc.MinLOD = 0.0f; + sampler_desc.MaxLOD = D3D11_FLOAT32_MAX; + + hr = ID3D11Device_CreatePixelShader(device, ps_ld_code, sizeof(ps_ld_code), NULL, &ps); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0); + + texture_desc.Width = 64; + texture_desc.Height = 64; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + texture_desc.Width = 640; + texture_desc.Height = 480; + + hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture2); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.MipLODBias = 0.0f; + sampler_desc.MinLOD = 0.0f; + sampler_desc.MaxLOD = 0.0f; + + hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler); + + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red); + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)texture2, NULL, &rtv); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + rtvs[0] = test_context.backbuffer_rtv; + rtvs[1] = rtv; + + ID3D11DeviceContext_OMSetRenderTargets(context, 2, rtvs, NULL); + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, NULL, &srv); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv); + + draw_quad(&test_context); + ID3D11ShaderResourceView_Release(srv); + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture2, NULL, &srv); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv); + + ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red); + + /* The texture is sampled from SRV but is not updated through RTV. */ + draw_quad(&test_context); + draw_quad(&test_context); + + get_texture_readback(test_context.backbuffer, 0, &rb); + for (y = 0; y < 4; ++y) + { + for (x = 0; x < 4; ++x) + { + color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120, 0); + todo_wine ok(compare_color(color, 0x40404040, 2), + "Got unexpected color 0x%08x at (%u, %u).\n", color, x, y); + } + } + release_resource_readback(&rb); + + get_texture_readback(texture2, 0, &rb); + for (y = 0; y < 4; ++y) + { + for (x = 0; x < 4; ++x) + { + color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120, 0); + todo_wine ok(compare_color(color, 0x40404040, 2), + "Got unexpected color 0x%08x at (%u, %u).\n", color, x, y); + } + } + + release_resource_readback(&rb); + ID3D11RenderTargetView_Release(rtv); + ID3D11ShaderResourceView_Release(srv); + ID3D11SamplerState_Release(sampler); + ID3D11PixelShader_Release(ps); + ID3D11Texture2D_Release(texture2); + ID3D11Texture2D_Release(texture); + ID3D11SamplerState_Release(sampler); + + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -29553,6 +29732,7 @@ START_TEST(d3d11) queue_test(test_render_a8); queue_test(test_standard_pattern); queue_test(test_desktop_window); + queue_test(test_sample_attached_rtv);
run_queued_tests(); }
Hi,
While running your changed tests, 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=58138
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5623: Test failed: Got unexpected query result 0x0000000000000000.
=== w1064v1809_zh_CN (32 bit report) ===
d3d11: d3d11.c:5776: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5777: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5778: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5781: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5782: Test failed: Got unexpected CPrimitives count: 0.
=== debian10 (32 bit report) ===
Report errors: d3d11:d3d11 has no test summary line (early exit of the main process?) d3d11:d3d11 has unaccounted for failure messages d3d11:d3d11 has unaccounted for todo messages d3d11:d3d11 has unaccounted for skip messages d3d11:d3d11 returned success despite having failures
=== debian10 (32 bit French report) ===
d3d11: d3d11.c:6109: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:6119: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0.
=== debian10 (32 bit Japanese:Japan report) ===
d3d11: d3d11.c:6109: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:6119: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0.
=== debian10 (32 bit Chinese:China report) ===
d3d11: d3d11.c:6109: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:6119: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:16860: Test failed: Got {-1.00787401e+000, 0.00000000e+000, 1.00000000e+000, 5.03937006e-001}, expected {-1.00000000e+000, 0.00000000e+000, 1.00000000e+000, 5.03937006e-001} at (0, 0), sub-resource 0.
=== debian10 (build log) ===
X Error of failed request: GLXBadFBConfig Major opcode of failed request: 150 (GLX) Minor opcode of failed request: 34 ()
=== debian10 (32 bit WoW report) ===
d3d11: d3d11.c:6109: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:6119: Test succeeded inside todo block: Got unexpected PrimitivesStorageNeeded: 0. d3d11.c:16860: Test failed: Got {-1.00787401e+000, 0.00000000e+000, 1.00000000e+000, 5.03937006e-001}, expected {-1.00000000e+000, 0.00000000e+000, 1.00000000e+000, 5.03937006e-001} at (0, 0), sub-resource 0.
Hi,
while this test passes on Windows, I believe it doesn't tests the intended thing, especially given the following comment in the code:
/* The texture is sampled from SRV but is not updated through RTV. */
D3D11 does not actually support sampling a currently bound render target, and you'll find that binding an SRV has no effect if it conflicts with an active RTV. Consider the following snippet:
ID3D11RenderTargetView *rtv = ...; ID3D11ShaderResourceView *srv = ..., *test;
OMSetRenderTargets(1, &rtv, NULL); PSSetShaderResources(0, 1, &srv); PSGetShaderResources(0, 1, &test);
ok(!test); /* this will succeed on Windows */
Moreover, binding an RTV will unbind any conflicting SRVs, so that changing the order of the OMSetRenderTargets and PSSetShaderResources call will not chage the result.
This is (for once) in line with the MSDN documentation, see "Remarks": https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devi...
- Philip
Am 21.10.19 um 18:06 schrieb Paul Gofman:
Signed-off-by: Paul Gofman gofmanp@gmail.com
v2: - added patch.
dlls/d3d11/tests/d3d11.c | 180 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index da4627d7a8..bc79b52efd 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -29394,6 +29394,185 @@ static void test_desktop_window(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_sample_attached_rtv(void) +{
- struct d3d11_test_context test_context;
- ID3D11RenderTargetView *rtv, *rtvs[2];
- ID3D11Texture2D *texture, *texture2;
- D3D11_TEXTURE2D_DESC texture_desc;
- D3D11_SAMPLER_DESC sampler_desc;
- ID3D11ShaderResourceView *srv;
- ID3D11DeviceContext *context;
- ID3D11SamplerState *sampler;
- struct resource_readback rb;
- ID3D11PixelShader *ps;
- ID3D11Device *device;
- unsigned int x, y;
- DWORD color;
- HRESULT hr;
- static const DWORD ps_ld_code[] =
- {
+#if 0
Texture2D t;
struct PS_OUTPUT
{
float4 color0: SV_Target0;
float4 color1: SV_Target1;
};
PS_OUTPUT main(float4 position : SV_POSITION)
{
PS_OUTPUT output;
float3 p;
t.GetDimensions(0, p.x, p.y, p.z);
p.z = 0;
p *= float3(position.x / 640.0f, position.y / 480.0f, 1.0f);
output.color0 = output.color1 = t.Load(int3(p)) + float4(0.25, 0.25, 0.25, 0.25);
return output;
}
+#endif
0x43425844, 0x08dd0517, 0x07d7e538, 0x4cad261f, 0xa2ae5942, 0x00000001, 0x00000200, 0x00000003,
0x0000002c, 0x00000060, 0x000000ac, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x0000014c, 0x00000040, 0x00000053, 0x04001858,
0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065,
0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x02000068, 0x00000001, 0x0700003d,
0x001000f2, 0x00000000, 0x00004001, 0x00000000, 0x00107e46, 0x00000000, 0x07000038, 0x00100032,
0x00000000, 0x00100046, 0x00000000, 0x00101046, 0x00000000, 0x0a000038, 0x00100032, 0x00000000,
0x00100046, 0x00000000, 0x00004002, 0x3acccccd, 0x3b088889, 0x00000000, 0x00000000, 0x08000036,
0x001000c2, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0500001b,
0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x0700002d, 0x001000f2, 0x00000000, 0x00100e46,
0x00000000, 0x00107e46, 0x00000000, 0x0a000000, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
0x00004002, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, 0x05000036, 0x001020f2, 0x00000000,
0x00100e46, 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00100e46, 0x00000000, 0x0100003e,
- };
- static const float red[] = {1.0f, 0.0f, 0.0f, 0.5f};
- if (!init_test_context(&test_context, NULL))
return;
- device = test_context.device;
- context = test_context.immediate_context;
- texture_desc.SampleDesc.Count = 1;
- texture_desc.SampleDesc.Quality = 0;
- texture_desc.Usage = D3D11_USAGE_DEFAULT;
- texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
- texture_desc.CPUAccessFlags = 0;
- texture_desc.MiscFlags = 0;
- sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
- sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
- sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
- sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
- sampler_desc.MipLODBias = 0.0f;
- sampler_desc.MaxAnisotropy = 0;
- sampler_desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
- sampler_desc.BorderColor[0] = 0.0f;
- sampler_desc.BorderColor[1] = 0.0f;
- sampler_desc.BorderColor[2] = 0.0f;
- sampler_desc.BorderColor[3] = 0.0f;
- sampler_desc.MinLOD = 0.0f;
- sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
- hr = ID3D11Device_CreatePixelShader(device, ps_ld_code, sizeof(ps_ld_code), NULL, &ps);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
- texture_desc.Width = 64;
- texture_desc.Height = 64;
- texture_desc.MipLevels = 1;
- texture_desc.ArraySize = 1;
- texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- texture_desc.Width = 640;
- texture_desc.Height = 480;
- hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, &texture2);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
- sampler_desc.MipLODBias = 0.0f;
- sampler_desc.MinLOD = 0.0f;
- sampler_desc.MaxLOD = 0.0f;
- hr = ID3D11Device_CreateSamplerState(device, &sampler_desc, &sampler);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &sampler);
- ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
- hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)texture2, NULL, &rtv);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- rtvs[0] = test_context.backbuffer_rtv;
- rtvs[1] = rtv;
- ID3D11DeviceContext_OMSetRenderTargets(context, 2, rtvs, NULL);
- hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, NULL, &srv);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv);
- draw_quad(&test_context);
- ID3D11ShaderResourceView_Release(srv);
- hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture2, NULL, &srv);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ID3D11DeviceContext_PSSetShaderResources(context, 0, 1, &srv);
- ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
- /* The texture is sampled from SRV but is not updated through RTV. */
- draw_quad(&test_context);
- draw_quad(&test_context);
- get_texture_readback(test_context.backbuffer, 0, &rb);
- for (y = 0; y < 4; ++y)
- {
for (x = 0; x < 4; ++x)
{
color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120, 0);
todo_wine ok(compare_color(color, 0x40404040, 2),
"Got unexpected color 0x%08x at (%u, %u).\n", color, x, y);
}
- }
- release_resource_readback(&rb);
- get_texture_readback(texture2, 0, &rb);
- for (y = 0; y < 4; ++y)
- {
for (x = 0; x < 4; ++x)
{
color = get_readback_color(&rb, 80 + x * 160, 60 + y * 120, 0);
todo_wine ok(compare_color(color, 0x40404040, 2),
"Got unexpected color 0x%08x at (%u, %u).\n", color, x, y);
}
- }
- release_resource_readback(&rb);
- ID3D11RenderTargetView_Release(rtv);
- ID3D11ShaderResourceView_Release(srv);
- ID3D11SamplerState_Release(sampler);
- ID3D11PixelShader_Release(ps);
- ID3D11Texture2D_Release(texture2);
- ID3D11Texture2D_Release(texture);
- ID3D11SamplerState_Release(sampler);
- release_test_context(&test_context);
+}
- START_TEST(d3d11) { unsigned int argc, i;
@@ -29553,6 +29732,7 @@ START_TEST(d3d11) queue_test(test_render_a8); queue_test(test_standard_pattern); queue_test(test_desktop_window);
queue_test(test_sample_attached_rtv);
run_queued_tests(); }
Hello Philip,
yes, thanks, the comment in the test is actually wrong, while the test itself still seem to test intended thing to me (while it tests setting SRV after RTV only and not doing that in the reverse order). The color in the 'backbuffer' (which is checked in the first loop) would be '0x80808080' if the texture was actually sampled or contain some other mix of values in case of race condition. Consistently keeping the constant value added in PS shader suggests the input from texture sampling is 0 (while the texture has 0x40404040 as checked in the next loop). I will change the comment and maybe tweak a test a bit to make it more explicit.
Regards, Paul.
On 10/22/19 17:04, Philip Rebohle wrote:
Hi,
while this test passes on Windows, I believe it doesn't tests the intended thing, especially given the following comment in the code:
/* The texture is sampled from SRV but is not updated through RTV. */
I also verified now that not just conflicting OMSetRenderTargets resets SRV, but also PSGetShaderResources also returns NULL SRV right after PSSetShaderResources if the resource is already bound as RTV, which makes fixing it very straightforward. So I will probably send the fix along with the test.
On 10/22/19 17:45, Paul Gofman wrote:
Hello Philip,
yes, thanks, the comment in the test is actually wrong, while the test itself still seem to test intended thing to me (while it tests setting SRV after RTV only and not doing that in the reverse order). The color in the 'backbuffer' (which is checked in the first loop) would be '0x80808080' if the texture was actually sampled or contain some other mix of values in case of race condition. Consistently keeping the constant value added in PS shader suggests the input from texture sampling is 0 (while the texture has 0x40404040 as checked in the next loop). I will change the comment and maybe tweak a test a bit to make it more explicit.
Regards, Paul.
On 10/22/19 17:04, Philip Rebohle wrote:
Hi,
while this test passes on Windows, I believe it doesn't tests the intended thing, especially given the following comment in the code:
/* The texture is sampled from SRV but is not updated through RTV. */