Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/ddraw/ddraw.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 5f90a75c5849..d3e491c3e8bb 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1420,23 +1420,10 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) caps->dwMinTextureHeight = 1;
/* Convert DWORDs safely to WORDs */ - if (wined3d_caps.MaxTextureBlendStages > 0xffff) - caps->wMaxTextureBlendStages = 0xffff; - else - caps->wMaxTextureBlendStages = (WORD)wined3d_caps.MaxTextureBlendStages; - if (wined3d_caps.MaxSimultaneousTextures > 0xffff) - caps->wMaxSimultaneousTextures = 0xffff; - else - caps->wMaxSimultaneousTextures = (WORD)wined3d_caps.MaxSimultaneousTextures; - - if (wined3d_caps.MaxUserClipPlanes > 0xffff) - caps->wMaxUserClipPlanes = 0xffff; - else - caps->wMaxUserClipPlanes = (WORD)wined3d_caps.MaxUserClipPlanes; - if (wined3d_caps.MaxVertexBlendMatrices > 0xffff) - caps->wMaxVertexBlendMatrices = 0xffff; - else - caps->wMaxVertexBlendMatrices = (WORD)wined3d_caps.MaxVertexBlendMatrices; + caps->wMaxTextureBlendStages = min(wined3d_caps.MaxTextureBlendStages, 0xffff); + caps->wMaxSimultaneousTextures = min(wined3d_caps.MaxSimultaneousTextures, 0xffff); + caps->wMaxUserClipPlanes = min(wined3d_caps.MaxUserClipPlanes, D3DMAXUSERCLIPPLANES); + caps->wMaxVertexBlendMatrices = min(wined3d_caps.MaxVertexBlendMatrices, 0xffff);
caps->deviceGUID = IID_IDirect3DTnLHalDevice;
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d9/tests/device.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 388cda1d7ab0..bcdfd0e1708f 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -11985,6 +11985,98 @@ todo_wine DestroyWindow(window); }
+static void test_clip_planes_limits(void) +{ + static const DWORD device_flags[] = {0, CREATE_DEVICE_SWVP_ONLY}; + IDirect3DDevice9 *device; + struct device_desc desc; + unsigned int i, j; + IDirect3D9 *d3d; + ULONG refcount; + float plane[4]; + D3DCAPS9 caps; + DWORD state; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + for (i = 0; i < ARRAY_SIZE(device_flags); ++i) + { + desc.device_window = window; + desc.width = 640; + desc.height = 480; + desc.flags = device_flags[i]; + if (!(device = create_device(d3d, window, &desc))) + { + skip("Failed to create D3D device, flags %#x.\n", desc.flags); + continue; + } + + memset(&caps, 0, sizeof(caps)); + hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); + ok(hr == D3D_OK, "Failed to get caps, hr %#x.\n", hr); + + trace("Max user clip planes: %u.\n", caps.MaxUserClipPlanes); + + for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j) + { + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice9_GetClipPlane(device, j, plane); + todo_wine_if(j >= caps.MaxUserClipPlanes) + { + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); + ok(!plane[0] && !plane[1] && !plane[2] && !plane[3], + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + j, plane[0], plane[1], plane[2], plane[3]); + } + } + + plane[0] = 2.0f; + plane[1] = 8.0f; + plane[2] = 5.0f; + for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j) + { + plane[3] = j; + hr = IDirect3DDevice9_SetClipPlane(device, j, plane); + todo_wine_if(j >= caps.MaxUserClipPlanes) + ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#x.\n", j, hr); + } + for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j) + { + float expected_d = j >= caps.MaxUserClipPlanes - 1 ? 2 * D3DMAXUSERCLIPPLANES - 1 : j; + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice9_GetClipPlane(device, j, plane); + todo_wine_if(j >= caps.MaxUserClipPlanes) + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); + todo_wine_if(j >= caps.MaxUserClipPlanes - 1) + ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == expected_d, + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + j, plane[0], plane[1], plane[2], plane[3]); + } + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0xffffffff, "Got unexpected state %#x.\n", state); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x80000000); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0x80000000, "Got unexpected state %#x.\n", state); + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + } + + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(device) { WNDCLASSA wc = {0}; @@ -12105,6 +12197,7 @@ START_TEST(device) test_format_unknown(); test_destroyed_window(); test_lockable_backbuffer(); + test_clip_planes_limits();
UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL)); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Calling SetClipPlane() with high indices seems to corrupt memory on Windows.
--- dlls/d3d8/tests/device.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 94b3e2e407d4..915ab8b0c3b9 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -28,6 +28,8 @@ #include <d3d8.h> #include "wine/test.h"
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + struct vec3 { float x, y, z; @@ -8401,6 +8403,91 @@ static void test_destroyed_window(void) ok(!refcount, "Device has %u references left.\n", refcount); }
+static void test_clip_planes_limits(void) +{ + static const DWORD device_flags[] = {0, CREATE_DEVICE_SWVP_ONLY}; + IDirect3DDevice8 *device; + struct device_desc desc; + unsigned int i, j; + IDirect3D8 *d3d; + ULONG refcount; + float plane[4]; + D3DCAPS8 caps; + DWORD state; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + d3d = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + + for (i = 0; i < ARRAY_SIZE(device_flags); ++i) + { + desc.device_window = window; + desc.width = 640; + desc.height = 480; + desc.flags = device_flags[i]; + if (!(device = create_device(d3d, window, &desc))) + { + skip("Failed to create D3D device, flags %#x.\n", desc.flags); + continue; + } + + memset(&caps, 0, sizeof(caps)); + hr = IDirect3DDevice8_GetDeviceCaps(device, &caps); + ok(hr == D3D_OK, "Failed to get caps, hr %#x.\n", hr); + + trace("Max user clip planes: %u.\n", caps.MaxUserClipPlanes); + + for (j = 0; j < caps.MaxUserClipPlanes; ++j) + { + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice8_GetClipPlane(device, j, plane); + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); + ok(!plane[0] && !plane[1] && !plane[2] && !plane[3], + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + j, plane[0], plane[1], plane[2], plane[3]); + } + + plane[0] = 2.0f; + plane[1] = 8.0f; + plane[2] = 5.0f; + for (j = 0; j < caps.MaxUserClipPlanes; ++j) + { + plane[3] = j; + hr = IDirect3DDevice8_SetClipPlane(device, j, plane); + ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#x.\n", j, hr); + } + for (j = 0; j < caps.MaxUserClipPlanes; ++j) + { + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice8_GetClipPlane(device, j, plane); + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); + ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == j, + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + j, plane[0], plane[1], plane[2], plane[3]); + } + + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0xffffffff, "Got unexpected state %#x.\n", state); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x80000000); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_GetRenderState(device, D3DRS_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0x80000000, "Got unexpected state %#x.\n", state); + + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + } + + IDirect3D8_Release(d3d); + DestroyWindow(window); +} + START_TEST(device) { HMODULE d3d8_handle = LoadLibraryA( "d3d8.dll" ); @@ -8508,6 +8595,7 @@ START_TEST(device) test_render_target_device_mismatch(); test_format_unknown(); test_destroyed_window(); + test_clip_planes_limits();
UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL)); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/ddraw/tests/ddraw7.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 00c7919049e2..17abdf4d44a2 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -13297,6 +13297,82 @@ static void test_compute_sphere_visibility(void) DestroyWindow(window); }
+static void test_clip_planes_limits(void) +{ + IDirect3DDevice7 *device; + D3DDEVICEDESC7 caps; + unsigned int i; + ULONG refcount; + float plane[4]; + HWND window; + DWORD state; + HRESULT hr; + + window = create_window(); + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create 3D device.\n"); + DestroyWindow(window); + return; + } + + memset(&caps, 0, sizeof(caps)); + hr = IDirect3DDevice7_GetCaps(device, &caps); + ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr); + + trace("Max user clip planes: %u.\n", caps.wMaxUserClipPlanes); + + for (i = 0; i < D3DMAXUSERCLIPPLANES; ++i) + { + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice7_GetClipPlane(device, i, plane); + todo_wine_if(i >= caps.wMaxUserClipPlanes) + { + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", i, hr); + ok(!plane[0] && !plane[1] && !plane[2] && !plane[3], + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + i, plane[0], plane[1], plane[2], plane[3]); + } + } + + plane[0] = 2.0f; + plane[1] = 8.0f; + plane[2] = 5.0f; + for (i = 0; i < D3DMAXUSERCLIPPLANES; ++i) + { + plane[3] = i; + hr = IDirect3DDevice7_SetClipPlane(device, i, plane); + todo_wine_if(i >= caps.wMaxUserClipPlanes) + ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#x.\n", i, hr); + } + for (i = 0; i < D3DMAXUSERCLIPPLANES; ++i) + { + memset(plane, 0xff, sizeof(plane)); + hr = IDirect3DDevice7_GetClipPlane(device, i, plane); + todo_wine_if(i >= caps.wMaxUserClipPlanes) + ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", i, hr); + todo_wine_if(i >= caps.wMaxUserClipPlanes) + ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == i, + "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", + i, plane[0], plane[1], plane[2], plane[3]); + } + + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPLANEENABLE, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0xffffffff, "Got unexpected state %#x.\n", state); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CLIPPLANEENABLE, 0x80000000); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_CLIPPLANEENABLE, &state); + ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr); + ok(state == 0x80000000, "Got unexpected state %#x.\n", state); + + refcount = IDirect3DDevice7_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { HMODULE module = GetModuleHandleA("ddraw.dll"); @@ -13414,4 +13490,5 @@ START_TEST(ddraw7) test_ck_operation(); test_vb_refcount(); test_compute_sphere_visibility(); + test_clip_planes_limits(); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d9/d3d9_private.h | 2 ++ dlls/d3d9/device.c | 19 ++++++++++--------- dlls/d3d9/tests/device.c | 6 ------ 3 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index c7b67e577437..7cbb54055954 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -97,6 +97,8 @@ struct d3d9_device BOOL in_scene; BOOL has_vertex_declaration;
+ unsigned int max_user_clip_planes; + UINT implicit_swapchain_count; struct d3d9_swapchain **implicit_swapchains; }; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index f6086bf77a2b..655318eab5c6 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -2030,6 +2030,8 @@ static HRESULT WINAPI d3d9_device_SetClipPlane(IDirect3DDevice9Ex *iface, DWORD
TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+ index = min(index, device->max_user_clip_planes - 1); + wined3d_mutex_lock(); hr = wined3d_device_set_clip_plane(device->wined3d_device, index, (const struct wined3d_vec4 *)plane); wined3d_mutex_unlock(); @@ -2044,6 +2046,8 @@ static HRESULT WINAPI d3d9_device_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD
TRACE("iface %p, index %u, plane %p.\n", iface, index, plane);
+ index = min(index, device->max_user_clip_planes - 1); + wined3d_mutex_lock(); hr = wined3d_device_get_clip_plane(device->wined3d_device, index, (struct wined3d_vec4 *)plane); wined3d_mutex_unlock(); @@ -4012,7 +4016,8 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode) { struct wined3d_swapchain_desc *swapchain_desc; - UINT i, count = 1; + unsigned i, count = 1; + WINED3DCAPS caps; HRESULT hr;
if (mode) @@ -4025,22 +4030,18 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
wined3d_mutex_lock(); - hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, - &device->device_parent, &device->wined3d_device); - if (FAILED(hr)) + if (FAILED(hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4, + &device->device_parent, &device->wined3d_device))) { WARN("Failed to create wined3d device, hr %#x.\n", hr); wined3d_mutex_unlock(); return hr; }
+ wined3d_get_device_caps(wined3d, adapter, device_type, &caps); + device->max_user_clip_planes = caps.MaxUserClipPlanes; if (flags & D3DCREATE_ADAPTERGROUP_DEVICE) - { - WINED3DCAPS caps; - - wined3d_get_device_caps(wined3d, adapter, device_type, &caps); count = caps.NumberOfAdaptersInGroup; - }
if (flags & D3DCREATE_MULTITHREADED) wined3d_device_set_multithreaded(device->wined3d_device); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index bcdfd0e1708f..866f435f8368 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -12026,13 +12026,10 @@ static void test_clip_planes_limits(void) { memset(plane, 0xff, sizeof(plane)); hr = IDirect3DDevice9_GetClipPlane(device, j, plane); - todo_wine_if(j >= caps.MaxUserClipPlanes) - { ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); ok(!plane[0] && !plane[1] && !plane[2] && !plane[3], "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", j, plane[0], plane[1], plane[2], plane[3]); - } }
plane[0] = 2.0f; @@ -12042,7 +12039,6 @@ static void test_clip_planes_limits(void) { plane[3] = j; hr = IDirect3DDevice9_SetClipPlane(device, j, plane); - todo_wine_if(j >= caps.MaxUserClipPlanes) ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#x.\n", j, hr); } for (j = 0; j < 2 * D3DMAXUSERCLIPPLANES; ++j) @@ -12050,9 +12046,7 @@ static void test_clip_planes_limits(void) float expected_d = j >= caps.MaxUserClipPlanes - 1 ? 2 * D3DMAXUSERCLIPPLANES - 1 : j; memset(plane, 0xff, sizeof(plane)); hr = IDirect3DDevice9_GetClipPlane(device, j, plane); - todo_wine_if(j >= caps.MaxUserClipPlanes) ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", j, hr); - todo_wine_if(j >= caps.MaxUserClipPlanes - 1) ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == expected_d, "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", j, plane[0], plane[1], plane[2], plane[3]);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/ddraw/tests/ddraw7.c | 6 ------ dlls/wined3d/device.c | 12 ++++++++---- dlls/wined3d/wined3d_private.h | 6 ++++-- include/wine/wined3d.h | 1 - 4 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 17abdf4d44a2..5e176c77205c 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -13326,13 +13326,10 @@ static void test_clip_planes_limits(void) { memset(plane, 0xff, sizeof(plane)); hr = IDirect3DDevice7_GetClipPlane(device, i, plane); - todo_wine_if(i >= caps.wMaxUserClipPlanes) - { ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", i, hr); ok(!plane[0] && !plane[1] && !plane[2] && !plane[3], "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", i, plane[0], plane[1], plane[2], plane[3]); - } }
plane[0] = 2.0f; @@ -13342,16 +13339,13 @@ static void test_clip_planes_limits(void) { plane[3] = i; hr = IDirect3DDevice7_SetClipPlane(device, i, plane); - todo_wine_if(i >= caps.wMaxUserClipPlanes) ok(hr == D3D_OK, "Failed to set clip plane %u, hr %#x.\n", i, hr); } for (i = 0; i < D3DMAXUSERCLIPPLANES; ++i) { memset(plane, 0xff, sizeof(plane)); hr = IDirect3DDevice7_GetClipPlane(device, i, plane); - todo_wine_if(i >= caps.wMaxUserClipPlanes) ok(hr == D3D_OK, "Failed to get clip plane %u, hr %#x.\n", i, hr); - todo_wine_if(i >= caps.wMaxUserClipPlanes) ok(plane[0] == 2.0f && plane[1] == 8.0f && plane[2] == 5.0f && plane[3] == i, "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n", i, plane[0], plane[1], plane[2], plane[3]); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index de6f1c5ffab6..7340488d7c89 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1757,8 +1757,7 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device, { TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
- /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) + if (plane_idx >= WINED3D_MAX_USER_CLIP_PLANES) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; @@ -1775,6 +1774,12 @@ HRESULT CDECL wined3d_device_set_clip_plane(struct wined3d_device *device,
device->update_state->clip_planes[plane_idx] = *plane;
+ if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) + { + WARN("Clip plane %u is not supported.\n", plane_idx); + return WINED3D_OK; + } + if (!device->recording) wined3d_cs_emit_set_clip_plane(device->cs, plane_idx, plane);
@@ -1786,8 +1791,7 @@ HRESULT CDECL wined3d_device_get_clip_plane(const struct wined3d_device *device, { TRACE("device %p, plane_idx %u, plane %p.\n", device, plane_idx, plane);
- /* Validate plane_idx. */ - if (plane_idx >= device->adapter->gl_info.limits.user_clip_distances) + if (plane_idx >= WINED3D_MAX_USER_CLIP_PLANES) { TRACE("Application has requested clipplane this device doesn't support.\n"); return WINED3DERR_INVALIDCALL; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 0daa8612841f..bb5ed786a3fb 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -259,6 +259,8 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup return complex_fixup; }
+#define WINED3D_MAX_USER_CLIP_PLANES 32 + /* Device caps */ #define MAX_STREAMS 16 #define MAX_TEXTURES 8 @@ -266,7 +268,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define MAX_VERTEX_SAMPLERS 4 #define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS) #define MAX_ACTIVE_LIGHTS 8 -#define MAX_CLIP_DISTANCES WINED3DMAXUSERCLIPPLANES +#define MAX_CLIP_DISTANCES WINED3D_MAX_USER_CLIP_PLANES #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 @@ -3352,7 +3354,7 @@ struct wined3d_saved_states DWORD renderState[(WINEHIGHEST_RENDER_STATE >> 5) + 1]; DWORD textureState[MAX_TEXTURES]; /* WINED3D_HIGHEST_TEXTURE_STATE + 1, 18 */ WORD samplerState[MAX_COMBINED_SAMPLERS]; /* WINED3D_HIGHEST_SAMPLER_STATE + 1, 14 */ - DWORD clipplane; /* WINED3DMAXUSERCLIPPLANES, 32 */ + DWORD clipplane; /* WINED3D_MAX_USER_CLIP_PLANES, 32 */ WORD pixelShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ WORD pixelShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ BOOL ps_consts_f[WINED3D_MAX_PS_CONSTS_F]; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a0ac7ba02f03..ad9fd1362b6a 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -928,7 +928,6 @@ enum wined3d_shader_byte_code_format #define WINED3DPRESENT_INTERVAL_FOUR 0x00000008 #define WINED3DPRESENT_INTERVAL_IMMEDIATE 0x80000000
-#define WINED3DMAXUSERCLIPPLANES 32 #define WINED3DCLIPPLANE0 (1u << 0) #define WINED3DCLIPPLANE1 (1u << 1) #define WINED3DCLIPPLANE2 (1u << 2)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
We never supported, and we should never need to support more than 8 user clip planes in wined3d.
OpenGL drivers do not expose more than 8 clip distances. Similarly, other APIs, D3D10, D3D11 and D3D12 provide exactly 8 clip distances.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Software vertex processing in D3D9 provides 6 user clip planes on configuration I have tested.
We still store all 32 clip planes in wined3d, but the state for not supported clip planes is never invalidated. I'll probably submit patches to move tracking of unsupported clip planes to client libraries.
--- dlls/wined3d/glsl_shader.c | 48 ------------------------------------------ dlls/wined3d/state.c | 31 ++------------------------- dlls/wined3d/wined3d_private.h | 4 ++-- 3 files changed, 4 insertions(+), 79 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 98cd32177f10..04ab66bebf0b 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -11557,54 +11557,6 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE }, {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE }, - {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), glsl_vertex_pipe_clip_plane}, WINED3D_GLSL_130 }, - {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE }, /* Lights */ {STATE_LIGHT_TYPE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {STATE_ACTIVELIGHT(0), {STATE_ACTIVELIGHT(0), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 61337392f773..ea497fabc6ad 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -654,11 +654,8 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state disable_mask = ~0u; }
- if (clipplane_count < 32) - { - enable_mask &= (1u << clipplane_count) - 1; - disable_mask &= (1u << clipplane_count) - 1; - } + enable_mask &= (1u << clipplane_count) - 1; + disable_mask &= (1u << clipplane_count) - 1;
for (i = 0; enable_mask && i < clipplane_count; enable_mask >>= 1, ++i) if (enable_mask & 1) @@ -5261,30 +5258,6 @@ static const struct StateEntryTemplate vp_ffp_states[] = { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE }, { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE }, { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE }, - { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE }, /* Lights */ { STATE_LIGHT_TYPE, { STATE_LIGHT_TYPE, state_nop }, WINED3D_GL_EXT_NONE }, { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bb5ed786a3fb..2e8eec24c2dc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -268,7 +268,7 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup #define MAX_VERTEX_SAMPLERS 4 #define MAX_COMBINED_SAMPLERS (MAX_FRAGMENT_SAMPLERS + MAX_VERTEX_SAMPLERS) #define MAX_ACTIVE_LIGHTS 8 -#define MAX_CLIP_DISTANCES WINED3D_MAX_USER_CLIP_PLANES +#define MAX_CLIP_DISTANCES 8 #define MAX_CONSTANT_BUFFERS 15 #define MAX_SAMPLER_OBJECTS 16 #define MAX_SHADER_RESOURCE_VIEWS 128 @@ -2825,7 +2825,7 @@ struct wined3d_state DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
struct wined3d_matrix transforms[HIGHEST_TRANSFORMSTATE + 1]; - struct wined3d_vec4 clip_planes[MAX_CLIP_DISTANCES]; + struct wined3d_vec4 clip_planes[WINED3D_MAX_USER_CLIP_PLANES]; struct wined3d_material material; struct wined3d_viewport viewport; RECT scissor_rect;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
GL_CLIP_PLANE0 and GL_CLIP_DISTANCE0 has the same value.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/context.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index ba9e19c06ec6..3dc6ca7c0249 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2530,12 +2530,9 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con context->last_was_rhw = TRUE; context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
- gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i); + checkGLcall("disable clip planes"); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
/* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/wined3d_private.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2e8eec24c2dc..9fe7fbcd72d9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1869,6 +1869,7 @@ struct wined3d_context /* Stores some information about the context state for optimization */ DWORD render_offscreen : 1; DWORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */ + DWORD last_swizzle_map : 16; /* MAX_ATTRIBS, 16 */ DWORD last_was_pshader : 1; DWORD last_was_vshader : 1; DWORD last_was_normal : 1; @@ -1899,9 +1900,8 @@ struct wined3d_context DWORD destroy_delayed : 1; DWORD transform_feedback_active : 1; DWORD transform_feedback_paused : 1; - DWORD padding : 7; - DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */ - DWORD shader_update_mask; + DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */ + DWORD padding : 17; DWORD constant_update_mask; DWORD numbered_array_mask; GLenum tracking_parm; /* Which source is tracking current colour */
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/wined3d/context.c | 31 +++++++++++++++++++++++++--- dlls/wined3d/state.c | 47 ++++++++---------------------------------- dlls/wined3d/wined3d_private.h | 4 +++- 3 files changed, 40 insertions(+), 42 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 3dc6ca7c0249..8af9e4bb8264 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -2352,6 +2352,33 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz size->cy = wined3d_texture_get_level_height(rt, level); }
+void context_enable_clip_distances(struct wined3d_context *context, unsigned int enable_mask) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + unsigned int clip_distance_count = gl_info->limits.user_clip_distances; + unsigned int i, disable_mask, current_mask; + + disable_mask = ~enable_mask; + enable_mask &= (1u << clip_distance_count) - 1; + disable_mask &= (1u << clip_distance_count) - 1; + current_mask = context->clip_distance_mask; + context->clip_distance_mask = enable_mask; + + enable_mask &= ~current_mask; + for (i = 0; enable_mask; enable_mask >>= 1, ++i) + { + if (enable_mask & 1) + gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i); + } + disable_mask &= current_mask; + for (i = 0; disable_mask; disable_mask >>= 1, ++i) + { + if (disable_mask & 1) + gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i); + } + checkGLcall("toggle clip distances"); +} + /***************************************************************************** * SetupForBlit * @@ -2530,9 +2557,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con context->last_was_rhw = TRUE; context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
- for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i); - checkGLcall("disable clip planes"); + context_enable_clip_distances(context, 0); context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
/* FIXME: Make draw_textured_quad() able to work with a upper left origin. */ diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index ea497fabc6ad..f3ec7df1863a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -611,9 +611,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat
void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = context->gl_info; - unsigned int clipplane_count = gl_info->limits.user_clip_distances; - unsigned int i, enable_mask, disable_mask; + unsigned int enable_mask;
if (use_vs(state) && !context->d3d_info->vs_clipping) { @@ -626,7 +624,7 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state * disables all clip planes because of that - don't do anything here * and keep them disabled. */ if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++) - FIXME("Clipping not supported with vertex shaders\n"); + FIXME("Clipping not supported with vertex shaders.\n"); return; }
@@ -636,36 +634,12 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state * need to update the clipping field from ffp_vertex_settings. */ context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
- /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting - * of already set values - */ - /* If enabling / disabling all * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum? */ - if (state->render_states[WINED3D_RS_CLIPPING]) - { - enable_mask = state->render_states[WINED3D_RS_CLIPPLANEENABLE]; - disable_mask = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE]; - } - else - { - enable_mask = 0; - disable_mask = ~0u; - } - - enable_mask &= (1u << clipplane_count) - 1; - disable_mask &= (1u << clipplane_count) - 1; - - for (i = 0; enable_mask && i < clipplane_count; enable_mask >>= 1, ++i) - if (enable_mask & 1) - gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i); - checkGLcall("clip plane enable"); - - for (i = 0; disable_mask && i < clipplane_count; disable_mask >>= 1, ++i) - if (disable_mask & 1) - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i); - checkGLcall("clip plane disable"); + enable_mask = state->render_states[WINED3D_RS_CLIPPING] ? + state->render_states[WINED3D_RS_CLIPPLANEENABLE] : 0; + context_enable_clip_distances(context, enable_mask); }
static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4532,22 +4506,19 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine } else { - if(!context->last_was_vshader) { + if (!context->last_was_vshader) + { static BOOL warned = FALSE; if (!context->d3d_info->vs_clipping) { /* Disable all clip planes to get defined results on all drivers. See comment in the * state_clipping state handler */ - for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - { - gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i); - checkGLcall("glDisable(GL_CLIP_PLANE0 + i)"); - } + context_enable_clip_distances(context, 0);
if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE]) { - FIXME("Clipping not supported with vertex shaders\n"); + FIXME("Clipping not supported with vertex shaders.\n"); warned = TRUE; } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9fe7fbcd72d9..da06ba159f79 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1901,7 +1901,8 @@ struct wined3d_context DWORD transform_feedback_active : 1; DWORD transform_feedback_paused : 1; DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */ - DWORD padding : 17; + DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */ + DWORD padding : 9; DWORD constant_update_mask; DWORD numbered_array_mask; GLenum tracking_parm; /* Which source is tracking current colour */ @@ -2146,6 +2147,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru const struct wined3d_format *ds_format) DECLSPEC_HIDDEN; HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN; void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN; +void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN; void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN; void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN; void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
D3DRS_CLIPPLANEENABLE is mask, not a boolean value.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3dx9_36/sprite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/d3dx9_36/sprite.c b/dlls/d3dx9_36/sprite.c index 17ad16a1ad57..2ff2b415c815 100644 --- a/dlls/d3dx9_36/sprite.c +++ b/dlls/d3dx9_36/sprite.c @@ -209,7 +209,7 @@ static void set_states(struct d3dx9_sprite *object) IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHATESTENABLE, object->alphacmp_caps); IDirect3DDevice9_SetRenderState(object->device, D3DRS_BLENDOP, D3DBLENDOP_ADD); IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPING, TRUE); - IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPLANEENABLE, FALSE); + IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPLANEENABLE, 0); IDirect3DDevice9_SetRenderState(object->device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); IDirect3DDevice9_SetRenderState(object->device, D3DRS_CULLMODE, D3DCULL_NONE);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com