diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c index 3ffa5d16408..632b44526c1 100644 --- a/dlls/dxgi/output.c +++ b/dlls/dxgi/output.c @@ -420,10 +420,45 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOu return S_OK; } +static WORD uint16_from_float(float f) +{ + f *= 65535.0f; + if (f < 0.0f) + f = 0.0f; + else if (f > 65535.0f) + f = 65535.0f; + + return f + 0.5f; +} + static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput6 *iface, const DXGI_GAMMA_CONTROL *gamma_control) { - FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + struct dxgi_output *output = impl_from_IDXGIOutput6(iface); + struct wined3d_gamma_ramp ramp; + const DXGI_RGB *p; + unsigned int i; + + TRACE("iface %p, gamma_control %p.\n", iface, gamma_control); + + if (gamma_control->Scale.Red != 1.0f || gamma_control->Scale.Green != 1.0f || gamma_control->Scale.Blue != 1.0f) + FIXME("Ignoring unhandled scale {%.8e, %.8e, %.8e}.\n", gamma_control->Scale.Red, + gamma_control->Scale.Green, gamma_control->Scale.Blue); + if (gamma_control->Offset.Red != 0.0f || gamma_control->Offset.Green != 0.0f || gamma_control->Offset.Blue != 0.0f) + FIXME("Ignoring unhandled offset {%.8e, %.8e, %.8e}.\n", gamma_control->Offset.Red, + gamma_control->Offset.Green, gamma_control->Offset.Blue); + + for (i = 0; i < 256; ++i) + { + p = &gamma_control->GammaCurve[i]; + ramp.red[i] = uint16_from_float(p->Red); + ramp.green[i] = uint16_from_float(p->Green); + ramp.blue[i] = uint16_from_float(p->Blue); + } + + wined3d_mutex_lock(); + wined3d_output_set_gamma_ramp(output->wined3d_output, &ramp); + wined3d_mutex_unlock(); return S_OK; } diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c673f61e429..95fa744d64d 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1496,6 +1496,19 @@ HRESULT CDECL wined3d_output_set_display_mode(struct wined3d_output *output, return WINED3D_OK; } +HRESULT CDECL wined3d_output_set_gamma_ramp(struct wined3d_output *output, const struct wined3d_gamma_ramp *ramp) +{ + HDC dc; + + TRACE("output %p, ramp %p.\n", output, ramp); + + dc = CreateDCW(output->device_name, NULL, NULL, NULL); + SetDeviceGammaRamp(dc, (void *)ramp); + DeleteDC(dc); + + return WINED3D_OK; +} + HRESULT CDECL wined3d_adapter_get_identifier(const struct wined3d_adapter *adapter, DWORD flags, struct wined3d_adapter_identifier *identifier) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 4f0d1e8e0b3..fb9973354a0 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -192,6 +192,7 @@ @ cdecl wined3d_output_get_raster_status(ptr ptr) @ cdecl wined3d_output_release_ownership(ptr) @ cdecl wined3d_output_set_display_mode(ptr ptr) +@ cdecl wined3d_output_set_gamma_ramp(ptr ptr) @ cdecl wined3d_output_take_ownership(ptr long) @ cdecl wined3d_palette_create(ptr long long ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index e8f5e824bc3..1f8b4a89648 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2606,6 +2606,7 @@ HRESULT __cdecl wined3d_output_get_raster_status(const struct wined3d_output *ou void __cdecl wined3d_output_release_ownership(const struct wined3d_output *output); HRESULT __cdecl wined3d_output_set_display_mode(struct wined3d_output *output, const struct wined3d_display_mode *mode); +HRESULT __cdecl wined3d_output_set_gamma_ramp(struct wined3d_output *output, const struct wined3d_gamma_ramp *ramp); HRESULT __cdecl wined3d_output_take_ownership(const struct wined3d_output *output, BOOL exclusive); HRESULT __cdecl wined3d_palette_create(struct wined3d_device *device, DWORD flags,