-
Notifications
You must be signed in to change notification settings - Fork 47
D3D11 gamma support #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
D3D11 gamma support #117
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| #include "dxgi_interfaces.h" | ||
| #include "dxgi_monitor.hpp" | ||
|
|
||
| namespace dxmt { | ||
|
|
||
| MTLDXGIMonitor::MTLDXGIMonitor(IUnknown *pParent) : parent_(pParent) { | ||
| monitorData.gammaCurve.gammaIsIdentity = true; | ||
| } | ||
|
|
||
| ULONG | ||
| STDMETHODCALLTYPE | ||
| MTLDXGIMonitor::AddRef() { | ||
| return parent_->AddRef(); | ||
| } | ||
|
|
||
| ULONG | ||
| STDMETHODCALLTYPE | ||
| MTLDXGIMonitor::Release() { | ||
| return parent_->Release(); | ||
| } | ||
|
|
||
| HRESULT | ||
| STDMETHODCALLTYPE | ||
| MTLDXGIMonitor::QueryInterface(REFIID riid, void **ppvObject) { | ||
| return parent_->QueryInterface(riid, ppvObject); | ||
| } | ||
|
|
||
| HRESULT | ||
| STDMETHODCALLTYPE | ||
| MTLDXGIMonitor::SetMonitorData(const MTLDXGI_MONITOR_DATA *pData) { | ||
| if (!pData) | ||
| return DXGI_ERROR_INVALID_CALL; | ||
|
|
||
| monitorData = *pData; | ||
|
|
||
| return S_OK; | ||
| } | ||
|
|
||
| HRESULT | ||
| STDMETHODCALLTYPE | ||
| MTLDXGIMonitor::GetMonitorData(MTLDXGI_MONITOR_DATA **ppData) { | ||
| if (!ppData) | ||
| return DXGI_ERROR_INVALID_CALL; | ||
|
|
||
| *ppData = &monitorData; | ||
|
|
||
| return S_OK; | ||
| } | ||
|
|
||
| } // namespace dxmt |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #pragma once | ||
|
|
||
| #include "dxgi.h" | ||
| #include "dxgi_interfaces.h" | ||
| #include "dxmt_presenter.hpp" | ||
|
|
||
| struct MTLDXGI_MONITOR_DATA { | ||
| dxmt::DXMTGammaCurve gammaCurve; | ||
| }; | ||
|
|
||
| namespace dxmt { | ||
|
|
||
| class MTLDXGIMonitor : public IMTLDXGIMonitor { | ||
| public: | ||
| MTLDXGIMonitor(IUnknown* pParent); | ||
| ULONG STDMETHODCALLTYPE AddRef(); | ||
| ULONG STDMETHODCALLTYPE Release(); | ||
| HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); | ||
|
|
||
| HRESULT STDMETHODCALLTYPE SetMonitorData(const MTLDXGI_MONITOR_DATA *pData); | ||
| HRESULT STDMETHODCALLTYPE GetMonitorData(MTLDXGI_MONITOR_DATA **ppData); | ||
|
|
||
| private: | ||
| IUnknown *parent_; | ||
| MTLDXGI_MONITOR_DATA monitorData{}; | ||
| }; | ||
|
|
||
| } // namespace dxmt |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| #include "com/com_guid.hpp" | ||
| #include "com/com_pointer.hpp" | ||
| #include "dxgi_interfaces.h" | ||
| #include "dxgi_monitor.hpp" | ||
| #include "dxgi_object.hpp" | ||
| #include "dxgi_options.hpp" | ||
| #include "dxmt_format.hpp" | ||
|
|
@@ -13,6 +14,10 @@ | |
|
|
||
| namespace dxmt { | ||
|
|
||
| inline float GetGammaControlPointPosition(uint32_t cp_index) { | ||
| return float(cp_index) / float(DXMT_DXGI_GAMMA_CP_COUNT - 1); | ||
| } | ||
|
|
||
| /* | ||
| * \see | ||
| * https://github.com/microsoft/DirectXTex/blob/main/DirectXTex/DirectXTexUtil.cpp | ||
|
|
@@ -136,12 +141,21 @@ void FilterModesByDesc(std::vector<DXGI_MODE_DESC1> &Modes, | |
|
|
||
| class MTLDXGIOutput : public MTLDXGIObject<IDXGIOutput6> { | ||
| public: | ||
| MTLDXGIOutput(IMTLDXGIAdapter *adapter, HMONITOR monitor, DxgiOptions &options) | ||
| : adapter_(adapter), monitor_(monitor), options_(options) { | ||
| MTLDXGIOutput(IMTLDXGIAdapter *adapter, IMTLDXGIFactory *factory, HMONITOR monitor, DxgiOptions &options) | ||
| : adapter_(adapter), factory_(factory), monitor_(monitor), options_(options) { | ||
| WMTGetDisplayDescription(monitor_ == wsi::getDefaultMonitor() | ||
| ? WMTGetPrimaryDisplayId() | ||
| : WMTGetSecondaryDisplayId(), | ||
| &native_desc_); | ||
| monitor_info_ = factory_->GetMonitor(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why |
||
| MTLDXGI_MONITOR_DATA monitorData; | ||
| for (uint32_t i = 0; i < DXMT_DXGI_GAMMA_CP_COUNT; i++) { | ||
| float pos = GetGammaControlPointPosition(i); | ||
| monitorData.gammaCurve.Red[i] = monitorData.gammaCurve.Green[i] = monitorData.gammaCurve.Blue[i] = pos; | ||
| } | ||
| monitorData.gammaCurve.gammaIsIdentity = true; | ||
| monitorData.gammaCurve.updated = false; | ||
| monitor_info_->SetMonitorData(&monitorData); | ||
|
Comment on lines
+150
to
+158
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the "source of truth" for gamma curve is from
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realized you may need to get access to some DXMT-internal methods from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
concept was a bit influenced from DXVK, due connection between
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I cannot fetch from |
||
| } | ||
|
|
||
| ~MTLDXGIOutput() {} | ||
|
|
@@ -287,22 +301,56 @@ class MTLDXGIOutput : public MTLDXGIObject<IDXGIOutput6> { | |
| gamma_caps->ScaleAndOffsetSupported = false; | ||
| gamma_caps->MaxConvertedValue = 1.0f; | ||
| gamma_caps->MinConvertedValue = 0.0f; | ||
| gamma_caps->NumGammaControlPoints = 1; | ||
| gamma_caps->NumGammaControlPoints = DXMT_DXGI_GAMMA_CP_COUNT; | ||
| for (uint32_t i = 0; i < gamma_caps->NumGammaControlPoints; i++) | ||
| gamma_caps->ControlPointPositions[i] = GetGammaControlPointPosition(i); | ||
| return S_OK; | ||
| } | ||
|
|
||
| HRESULT | ||
| STDMETHODCALLTYPE | ||
| SetGammaControl(const DXGI_GAMMA_CONTROL *gamma_control) final { | ||
| ERR("Not implemented"); | ||
| return E_NOTIMPL; | ||
| MTLDXGI_MONITOR_DATA *monitorData = nullptr; | ||
| if (gamma_control == nullptr) | ||
| return E_NOTIMPL; | ||
|
|
||
| HRESULT hr = monitor_info_->GetMonitorData(&monitorData); | ||
| if (FAILED(hr)) | ||
| return hr; | ||
|
|
||
| for (uint32_t i = 0; i < DXMT_DXGI_GAMMA_CP_COUNT; i++) { | ||
| monitorData->gammaCurve.Red[i] = gamma_control->GammaCurve[i].Red; | ||
| monitorData->gammaCurve.Green[i] = gamma_control->GammaCurve[i].Green; | ||
| monitorData->gammaCurve.Blue[i] = gamma_control->GammaCurve[i].Blue; | ||
| float identity = GetGammaControlPointPosition(i); | ||
| monitorData->gammaCurve.gammaIsIdentity &= gamma_control->GammaCurve[i].Red == identity | ||
| && gamma_control->GammaCurve[i].Green == identity | ||
| && gamma_control->GammaCurve[i].Blue == identity; | ||
| } | ||
| monitorData->gammaCurve.updated = true; | ||
|
|
||
| return S_OK; | ||
| } | ||
|
|
||
| HRESULT | ||
| STDMETHODCALLTYPE | ||
| GetGammaControl(DXGI_GAMMA_CONTROL *gamma_control) final { | ||
| ERR("Not implemented"); | ||
| return E_NOTIMPL; | ||
| MTLDXGI_MONITOR_DATA *monitorData = nullptr; | ||
| if (gamma_control == nullptr) | ||
| return E_NOTIMPL; | ||
|
|
||
| HRESULT hr = monitor_info_->GetMonitorData(&monitorData); | ||
| if (FAILED(hr)) | ||
| return hr; | ||
|
|
||
| gamma_control->Scale = { 1.0f, 1.0f, 1.0f }; | ||
| gamma_control->Offset = { 0.0f, 0.0f, 0.0f }; | ||
| for (uint32_t i = 0; i < DXMT_DXGI_GAMMA_CP_COUNT; i++) { | ||
| gamma_control->GammaCurve[i].Red = monitorData->gammaCurve.Red[i]; | ||
| gamma_control->GammaCurve[i].Green = monitorData->gammaCurve.Green[i]; | ||
| gamma_control->GammaCurve[i].Blue = monitorData->gammaCurve.Blue[i]; | ||
| } | ||
| return S_OK; | ||
| } | ||
|
|
||
| HRESULT | ||
|
|
@@ -603,13 +651,15 @@ class MTLDXGIOutput : public MTLDXGIObject<IDXGIOutput6> { | |
|
|
||
| private: | ||
| Com<IMTLDXGIAdapter> adapter_ = nullptr; | ||
| Com<IMTLDXGIFactory> factory_ = nullptr; | ||
| MTLDXGIMonitor *monitor_info_ = nullptr; | ||
| HMONITOR monitor_ = nullptr; | ||
| WMTDisplayDescription native_desc_; | ||
| DxgiOptions &options_; | ||
| }; | ||
|
|
||
| Com<IDXGIOutput> CreateOutput(IMTLDXGIAdapter *pAadapter, HMONITOR monitor, DxgiOptions &options) { | ||
| return Com<IDXGIOutput>::transfer(new MTLDXGIOutput(pAadapter, monitor, options)); | ||
| Com<IDXGIOutput> CreateOutput(IMTLDXGIAdapter *pAadapter, IMTLDXGIFactory *pFactory, HMONITOR monitor, DxgiOptions &options) { | ||
| return Com<IDXGIOutput>::transfer(new MTLDXGIOutput(pAadapter, pFactory, monitor, options)); | ||
| }; | ||
|
|
||
| } // namespace dxmt | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm strongly against introducing new COM interfaces and I've been always working on removing existing one. The only valid use case is when I want to export DXMT functionality for 3rd party users, which doesn't apply here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly the whole concept of
monitoris unnecessary. How is it different fromoutput?