From 50e975e43d69b6f33ea10e2a46996edc01b1a4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Tue, 24 Jan 2017 01:37:29 +0100 Subject: dxgi: Implement setting and querying the gamma value of an output. --- dlls/dxgi/Makefile.in | 2 +- dlls/dxgi/output.c | 68 +++++++++++++++++++++++++++++++++++++++++++----- dlls/dxgi/tests/device.c | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in index ce76b8eecc6..1a0c9084d56 100644 --- a/dlls/dxgi/Makefile.in +++ b/dlls/dxgi/Makefile.in @@ -1,6 +1,6 @@ MODULE = dxgi.dll IMPORTLIB = dxgi -IMPORTS = dxguid uuid wined3d user32 +IMPORTS = dxguid uuid wined3d user32 gdi32 C_SRCS = \ adapter.c \ diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 0cf80841c27..7a215a2aad4 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -288,24 +288,80 @@ static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput *iface) static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput *iface, DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps) { - FIXME("iface %p, gamma_caps %p stub!\n", iface, gamma_caps); + int i; - return E_NOTIMPL; + TRACE("iface %p, gamma_caps %p.\n", iface, gamma_caps); + + if (!gamma_caps) + return E_INVALIDARG; + + gamma_caps->ScaleAndOffsetSupported = FALSE; + gamma_caps->MaxConvertedValue = 1.0; + gamma_caps->MinConvertedValue = 0.0; + gamma_caps->NumGammaControlPoints = 256; + + for (i = 0; i < 256; i++) + gamma_caps->ControlPointPositions[i] = i / 255.0f; + + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput *iface, const DXGI_GAMMA_CONTROL *gamma_control) { - FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + struct wined3d_gamma_ramp ramp; + HDC dc; + int i; - return E_NOTIMPL; + TRACE("iface %p, gamma_control %p.\n", iface, gamma_control); + + if (!gamma_control) + return E_INVALIDARG; + + for (i = 0; i < 256; i++) + { + ramp.red[i] = gamma_control->GammaCurve[i].Red * 65535; + ramp.green[i] = gamma_control->GammaCurve[i].Green * 65535; + ramp.blue[i] = gamma_control->GammaCurve[i].Blue * 65535; + } + + /* we can not use wined3d_swapchain_set_gamma_ramp here, because outputs don't have + * references to swapchains and the output handling of dxgi is far from complete yet */ + dc = GetDC(0); + SetDeviceGammaRamp(dc, &ramp); + ReleaseDC(0, dc); + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControl(IDXGIOutput *iface, DXGI_GAMMA_CONTROL *gamma_control) { - FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + struct wined3d_gamma_ramp ramp; + HDC dc; + int i; + + TRACE("iface %p, gamma_control %p.\n", iface, gamma_control); + + /* We can not use wined3d_swapchain_get_gamma_ramp here, because outputs don't have + * references to swapchains and the output handling of dxgi is far from complete yet */ + dc = GetDC(0); + GetDeviceGammaRamp(dc, &ramp); + ReleaseDC(0, dc); + + gamma_control->Scale.Red = 0.0f; + gamma_control->Scale.Green = 0.0f; + gamma_control->Scale.Blue = 0.0f; + gamma_control->Offset.Red = 0.0f; + gamma_control->Offset.Green = 0.0f; + gamma_control->Offset.Blue = 0.0f; + + for (i = 0; i < 256; i++) + { + gamma_control->GammaCurve[i].Red = ramp.red[i] / 65535.0f; + gamma_control->GammaCurve[i].Green = ramp.green[i] / 65535.0f; + gamma_control->GammaCurve[i].Blue = ramp.blue[i] / 65535.0f; + } - return E_NOTIMPL; + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_output_SetDisplaySurface(IDXGIOutput *iface, IDXGISurface *surface) diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 0b3891fb46a..3122e3f044a 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -1574,11 +1574,13 @@ static void test_swapchain_fullscreen_state(IDXGISwapChain *swapchain, static void test_set_fullscreen(void) { struct swapchain_fullscreen_state initial_state; + DXGI_GAMMA_CONTROL_CAPABILITIES caps; DXGI_SWAP_CHAIN_DESC swapchain_desc; IDXGISwapChain *swapchain; IDXGIFactory *factory; IDXGIAdapter *adapter; IDXGIDevice *device; + IDXGIOutput *output; ULONG refcount; HRESULT hr; @@ -1594,6 +1596,17 @@ static void test_set_fullscreen(void) hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory); ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr); + hr = IDXGIAdapter_EnumOutputs(adapter, 0, &output); + if (SUCCEEDED(hr)) + { + hr = IDXGIOutput_GetGammaControlCapabilities(output, &caps); + todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Expected DXGI_ERROR_INVALID_CALL, got %#x.\n", hr); + + IDXGIOutput_Release(output); + } + else + skip("Failed to get output, skipping gamma test.\n"); + swapchain_desc.BufferDesc.Width = 800; swapchain_desc.BufferDesc.Height = 600; swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; @@ -1624,6 +1637,38 @@ static void test_set_fullscreen(void) skip("Could not change fullscreen state.\n"); goto done; } + + hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); + if (SUCCEEDED(hr)) + { + DXGI_GAMMA_CONTROL gamma; + int i; + + memset(&caps, 0, sizeof(caps)); + hr = IDXGIOutput_GetGammaControlCapabilities(output, &caps); + ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr); + + ok(caps.MaxConvertedValue > caps.MinConvertedValue, + "Expected max gamma value (%f) to be bigger than the min value (%f).\n", + caps.MaxConvertedValue, caps.MinConvertedValue); + + for (i = 1; i < caps.NumGammaControlPoints; i++) + { + ok(caps.ControlPointPositions[i] > caps.ControlPointPositions[i-1], + "Expected control point positions to be strictly monotonically increasing (%f > %f).\n", + caps.ControlPointPositions[i], caps.ControlPointPositions[i-1]); + } + + hr = IDXGIOutput_GetGammaControl(output, &gamma); + ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr); + hr = IDXGIOutput_SetGammaControl(output, &gamma); + ok(hr == S_OK, "Expected S_OK, got %#x.\n", hr); + + IDXGIOutput_Release(output); + } + else + skip("Failed to get output, skipping gamma test.\n"); + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); refcount = IDXGISwapChain_Release(swapchain); -- 2.11.0