Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Another victim of last-minute changes with not enough testing...
dlls/d3dx9_36/effect.c | 5 +++- dlls/d3dx9_36/tests/effect.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 404a36d0b54..a909d66a92f 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -4048,7 +4048,10 @@ static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface, { tech = &base->techniques[i]; if (tech == prev_tech) + { + ++i; break; + } } } else @@ -4056,7 +4059,7 @@ static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface, i = 0; }
- for (++i; i < base->technique_count; ++i) + for (; i < base->technique_count; ++i) { tech = &base->techniques[i]; if (SUCCEEDED(ID3DXEffectImpl_ValidateTechnique(iface, get_technique_handle(tech)))) diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 9693939a76b..9a8a9b65fbc 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -7832,6 +7832,38 @@ static void test_create_effect_from_file(void) DestroyWindow(window); }
+#if 0 +technique tech0 +{ + pass p0 + { + LightEnable[0] = FALSE; + FogEnable = FALSE; + } +} +technique tech1 +{ + pass p0 + { + LightEnable[0] = TRUE; + FogEnable = TRUE; + } +} +#endif +static const DWORD test_two_techniques_blob[] = +{ + 0xfeff0901, 0x000000ac, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000030, + 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, + 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000031, 0x00000000, 0x00000002, 0x00000002, + 0x00000001, 0x0000004c, 0x00000000, 0x00000001, 0x00000044, 0x00000000, 0x00000002, 0x00000091, + 0x00000000, 0x00000008, 0x00000004, 0x0000000e, 0x00000000, 0x00000028, 0x00000024, 0x000000a0, + 0x00000000, 0x00000001, 0x00000098, 0x00000000, 0x00000002, 0x00000091, 0x00000000, 0x0000005c, + 0x00000058, 0x0000000e, 0x00000000, 0x0000007c, 0x00000078, 0x00000000, 0x00000000, +}; + static void test_effect_find_next_valid_technique(void) { D3DPRESENT_PARAMETERS present_parameters = {0}; @@ -7868,6 +7900,30 @@ static void test_effect_find_next_valid_technique(void) return; }
+ hr = D3DXCreateEffectEx(device, test_two_techniques_blob, sizeof(test_two_techniques_blob), + NULL, NULL, NULL, 0, NULL, &effect, NULL); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + + hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, &tech); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name); + + hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + ok(!strcmp(desc.Name, "tech1"), "Got unexpected technique %s.\n", desc.Name); + + hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech); + ok(hr == S_FALSE, "Got result %#x.\n", hr); + hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name); + + effect->lpVtbl->Release(effect); + hr = D3DXCreateEffectEx(device, test_effect_unsupported_shader_blob, sizeof(test_effect_unsupported_shader_blob), NULL, NULL, NULL, 0, NULL, &effect, NULL); ok(hr == D3D_OK, "Got result %#x.\n", hr);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Fix extents check. v3: Get rid of some comments.
dlls/ddraw/device.c | 52 ++++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 32 deletions(-)
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 75e000aa096..35995625e45 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -5296,25 +5296,12 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO return hr; }
-/***************************************************************************** - * IDirect3DDevice7::SetViewport - * - * Sets the current viewport. - * - * Version 7 only, but IDirect3DViewport uses this call for older - * versions - * - * Params: - * Data: The new viewport to set - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface); + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; + struct ddraw_surface *surface; struct wined3d_viewport vp;
TRACE("iface %p, viewport %p.\n", iface, viewport); @@ -5322,6 +5309,23 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi if (!viewport) return DDERR_INVALIDPARAMS;
+ wined3d_mutex_lock(); + if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0))) + { + wined3d_mutex_unlock(); + return DDERR_INVALIDCAPS; + } + surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc); + + if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX + || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY) + { + WARN("Invalid viewport, returning E_INVALIDARG.\n"); + wined3d_mutex_unlock(); + return E_INVALIDARG; + } + vp.x = viewport->dwX; vp.y = viewport->dwY; vp.width = viewport->dwWidth; @@ -5329,7 +5333,6 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi vp.min_z = viewport->dvMinZ; vp.max_z = viewport->dvMaxZ;
- wined3d_mutex_lock(); wined3d_device_set_viewport(device->wined3d_device, &vp); wined3d_mutex_unlock();
@@ -5353,21 +5356,6 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac return hr; }
-/***************************************************************************** - * IDirect3DDevice::GetViewport - * - * Returns the current viewport - * - * Version 7 - * - * Params: - * Data: D3D7Viewport structure to write the viewport information to - * - * Returns: - * D3D_OK on success - * DDERR_INVALIDPARAMS if Data is NULL - * - *****************************************************************************/ static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport) { struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- It turns out that we already have some ddraw tests demonstrating that handling this in ddraw is wrong...
dlls/wined3d/cs.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 8edb74fc74c..2f0c4ed52e4 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -531,7 +531,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers; const struct wined3d_state *state = &cs->device->state; const struct wined3d_viewport *vp = &state->viewport; + struct wined3d_rendertarget_view *view; struct wined3d_cs_clear *op; + RECT view_rect; unsigned int i;
op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count]), @@ -553,12 +555,21 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * { for (i = 0; i < rt_count; ++i) { - if (state->fb->render_targets[i]) - wined3d_resource_acquire(state->fb->render_targets[i]->resource); + if ((view = state->fb->render_targets[i])) + { + SetRect(&view_rect, 0, 0, view->width, view->height); + IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect); + wined3d_resource_acquire(view->resource); + } } } if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_acquire(state->fb->depth_stencil->resource); + { + view = state->fb->depth_stencil; + SetRect(&view_rect, 0, 0, view->width, view->height); + IntersectRect(&op->draw_rect, &op->draw_rect, &view_rect); + wined3d_resource_acquire(view->resource); + }
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Properly attach a depth buffer to the offscreen surfaces, some minor cleanup, add a couple more RT sizes (actually 320x240 after 1280x960 crashed until the d3d_device_set_render_target() fix). v3: Use ARRAY_SIZE().
dlls/ddraw/tests/ddraw7.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 3f433a6765b..fb144090791 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -280,6 +280,45 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y) return color; }
+static void check_rect(IDirectDrawSurface7 *surface, RECT r, const char *message) +{ + LONG x_coords[2][2] = + { + {r.left - 1, r.left + 1}, + {r.right + 1, r.right - 1}, + }; + LONG y_coords[2][2] = + { + {r.top - 1, r.top + 1}, + {r.bottom + 1, r.bottom - 1} + }; + unsigned int i, j, x_side, y_side; + DWORD color; + LONG x, y; + + for (i = 0; i < 2; ++i) + { + for (j = 0; j < 2; ++j) + { + for (x_side = 0; x_side < 2; ++x_side) + { + for (y_side = 0; y_side < 2; ++y_side) + { + DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0x00000000; + + x = x_coords[i][x_side]; + y = y_coords[j][y_side]; + if (x < 0 || x >= 640 || y < 0 || y >= 480) + continue; + color = get_surface_color(surface, x, y); + ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n", + message, x, y, color, expected); + } + } + } + } +} + static HRESULT CALLBACK enum_z_fmt(DDPIXELFORMAT *format, void *ctx) { DDPIXELFORMAT *z_fmt = ctx; @@ -14095,6 +14134,143 @@ static void test_enum_surfaces(void) IDirectDraw7_Release(ddraw); }
+static void test_viewport(void) +{ + static struct + { + D3DVIEWPORT7 vp; + RECT expected_rect; + const char *message; + } + tests[] = + { + {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"}, + {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"}, + {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"}, + {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"}, + {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"}, + {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"}, + }; + static struct vec3 quad[] = + { + {-1.5f, -0.5f, 0.1f}, + {-1.5f, 0.5f, 0.1f}, + { 0.5f, -0.5f, 0.1f}, + { 0.5f, 0.5f, 0.1f}, + }; + static const struct vec2 rt_sizes[] = + { + {640, 480}, {1280, 960}, {320, 240}, {800, 600}, + }; + IDirectDrawSurface7 *rt, *ds; + DDSURFACEDESC2 surface_desc; + IDirect3DDevice7 *device; + IDirectDraw7 *ddraw; + DDPIXELFORMAT z_fmt; + unsigned int i, j; + IDirect3D7 *d3d; + ULONG refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice7_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr); + hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw); + ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr); + IDirect3D7_Release(d3d); + + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#x.\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE); + ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr); + + hr = IDirect3DDevice7_SetViewport(device, NULL); + ok(hr == E_INVALIDARG, "Setting NULL viewport data returned unexpected hr %#x.\n", hr); + + ds = get_depth_stencil(device); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface7_GetSurfaceDesc(ds, &surface_desc); + z_fmt = U4(surface_desc).ddpfPixelFormat; + + for (i = 0; i < ARRAY_SIZE(rt_sizes); ++i) + { + if (i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.dwWidth = rt_sizes[i].x; + surface_desc.dwHeight = rt_sizes[i].y; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &rt, NULL); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x (i %u).\n", hr, i); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + U4(surface_desc).ddpfPixelFormat = z_fmt; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &ds, NULL); + ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x (i %u).\n", hr, i); + hr = IDirectDrawSurface7_AddAttachedSurface(rt, ds); + ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x (i %u).\n", hr, i); + + hr = IDirect3DDevice7_SetRenderTarget(device, rt, 0); + ok(SUCCEEDED(hr), "Failed to set render target, hr %#x (i %u).\n", hr, i); + } + else + { + hr = IDirect3DDevice7_GetRenderTarget(device, &rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + } + + for (j = 0; j < ARRAY_SIZE(tests); ++j) + { + hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear, hr %#x (i %u, j %u).\n", hr, i, j); + + hr = IDirect3DDevice7_SetViewport(device, &tests[j].vp); + if (tests[j].vp.dwX + tests[j].vp.dwWidth > rt_sizes[i].x + || tests[j].vp.dwY + tests[j].vp.dwHeight > rt_sizes[i].y) + { + ok(hr == E_INVALIDARG, "Setting the viewport returned unexpected hr %#x (i %u, j %u).\n", hr, i, j); + continue; + } + else + { + ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr, i, j); + } + + hr = IDirect3DDevice7_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ, quad, 4, 0); + ok(SUCCEEDED(hr), "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DDevice7_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (i %u, j %u).\n", hr, i, j); + + check_rect(rt, tests[j].expected_rect, tests[j].message); + } + + hr = IDirectDrawSurface7_DeleteAttachedSurface(rt, 0, ds); + ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x (i %u).\n", hr, i); + IDirectDrawSurface7_Release(ds); + + IDirectDrawSurface7_Release(rt); + } + + refcount = IDirect3DDevice7_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -14229,4 +14405,5 @@ START_TEST(ddraw7) test_depth_readback(); test_clear(); test_enum_surfaces(); + test_viewport(); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- There are still a number of constants missing from d3d11.idl. I don't have patches for that though.
include/d3d11.idl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/d3d11.idl b/include/d3d11.idl index 8de20563651..b4cc3be5a73 100644 --- a/include/d3d11.idl +++ b/include/d3d11.idl @@ -32,6 +32,9 @@ interface ID3D11ClassLinkage; interface ID3D11Resource; interface ID3D11VideoProcessorInputView;
+cpp_quote("#ifndef _D3D11_CONSTANTS") +cpp_quote("#define _D3D11_CONSTANTS") + const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = 14; const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENTS = 4; const UINT D3D11_COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT = 32; @@ -255,9 +258,6 @@ const UINT D3D11_STANDARD_VECTOR_SIZE = 4; const UINT D3D11_STANDARD_VERTEX_ELEMENT_COUNT = 32; const UINT D3D11_STANDARD_VERTEX_TOTAL_COMPONENT_COUNT = 64;
-cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") -cpp_quote("struct CD3D11_DEFAULT {};") -cpp_quote("extern const DECLSPEC_SELECTANY CD3D11_DEFAULT D3D11_DEFAULT;") cpp_quote("#endif")
cpp_quote("#ifndef _D3D11_1_CONSTANTS") @@ -270,6 +270,11 @@ cpp_quote("#define _D3D11_2_CONSTANTS") const UINT D3D11_2_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 0x10000; cpp_quote("#endif")
+cpp_quote("#if !defined(D3D11_NO_HELPERS) && defined(__cplusplus)") +cpp_quote("struct CD3D11_DEFAULT {};") +cpp_quote("extern const DECLSPEC_SELECTANY CD3D11_DEFAULT D3D11_DEFAULT;") +cpp_quote("#endif") + typedef enum D3D11_BLEND { D3D11_BLEND_ZERO = 1,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com