mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxgi] Implement gamma control methods for DxgiOutput
This commit is contained in:
parent
ad7f0971cf
commit
dd3f4c89ac
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "dxgi_adapter.h"
|
#include "dxgi_adapter.h"
|
||||||
#include "dxgi_output.h"
|
#include "dxgi_output.h"
|
||||||
|
#include "dxgi_swapchain.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_format.h"
|
#include "../dxvk/dxvk_format.h"
|
||||||
|
|
||||||
@ -229,20 +230,32 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiOutput::GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) {
|
HRESULT STDMETHODCALLTYPE DxgiOutput::GetFrameStatistics(DXGI_FRAME_STATISTICS *pStats) {
|
||||||
Logger::err("DxgiOutput::GetFrameStatistics: Not implemented");
|
Com<DxgiSwapChain> swapChain = GetFullscreenSwapChain();
|
||||||
return E_NOTIMPL;
|
|
||||||
|
return swapChain != nullptr
|
||||||
|
? swapChain->GetFrameStatistics(pStats)
|
||||||
|
: DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControl(DXGI_GAMMA_CONTROL *pArray) {
|
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControl(DXGI_GAMMA_CONTROL *pArray) {
|
||||||
Logger::err("DxgiOutput::GetGammaControl: Not implemented");
|
Com<DxgiSwapChain> swapChain = GetFullscreenSwapChain();
|
||||||
return E_NOTIMPL;
|
|
||||||
|
return swapChain != nullptr
|
||||||
|
? swapChain->GetGammaControl(pArray)
|
||||||
|
: DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControlCapabilities(DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps) {
|
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControlCapabilities(DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps) {
|
||||||
Logger::err("DxgiOutput::GetGammaControlCapabilities: Not implemented");
|
pGammaCaps->ScaleAndOffsetSupported = TRUE;
|
||||||
return E_NOTIMPL;
|
pGammaCaps->MaxConvertedValue = 1.0f;
|
||||||
|
pGammaCaps->MinConvertedValue = 0.0f;
|
||||||
|
pGammaCaps->NumGammaControlPoints = DxgiPresenterGammaRamp::CpCount;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < pGammaCaps->NumGammaControlPoints; i++)
|
||||||
|
pGammaCaps->ControlPointPositions[i] = DxgiPresenterGammaRamp::cpLocation(i);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -258,8 +271,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE DxgiOutput::SetGammaControl(const DXGI_GAMMA_CONTROL *pArray) {
|
HRESULT STDMETHODCALLTYPE DxgiOutput::SetGammaControl(const DXGI_GAMMA_CONTROL *pArray) {
|
||||||
Logger::err("DxgiOutput::SetGammaControl: Not implemented");
|
Com<DxgiSwapChain> swapChain = GetFullscreenSwapChain();
|
||||||
return E_NOTIMPL;
|
|
||||||
|
Logger::err(str::format("DxgiOutput::SetGammaControl ", swapChain.ptr()));
|
||||||
|
return swapChain != nullptr
|
||||||
|
? swapChain->SetGammaControl(pArray)
|
||||||
|
: DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -277,6 +294,23 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL DxgiOutput::SetSwapChain(DxgiSwapChain* pExpected, DxgiSwapChain* pDesired) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (m_fullscreenSwapChain == pExpected) {
|
||||||
|
Logger::err(str::format("SetSwapChain: ", pDesired));
|
||||||
|
m_fullscreenSwapChain = pDesired;
|
||||||
|
return TRUE;
|
||||||
|
} return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Com<DxgiSwapChain> DxgiOutput::GetFullscreenSwapChain() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
return Com<DxgiSwapChain>(m_fullscreenSwapChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxgiOutput::GetFormatBpp(DXGI_FORMAT Format) const {
|
uint32_t DxgiOutput::GetFormatBpp(DXGI_FORMAT Format) const {
|
||||||
DxgiFormatInfo formatInfo = m_adapter->LookupFormat(Format, DxgiFormatMode::Any);
|
DxgiFormatInfo formatInfo = m_adapter->LookupFormat(Format, DxgiFormatMode::Any);
|
||||||
return imageFormatInfo(formatInfo.format)->elementSize * 8;
|
return imageFormatInfo(formatInfo.format)->elementSize * 8;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "dxgi_object.h"
|
#include "dxgi_object.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class DxgiAdapter;
|
class DxgiAdapter;
|
||||||
|
class DxgiSwapChain;
|
||||||
|
|
||||||
class DxgiOutput : public DxgiObject<IDXGIOutput> {
|
class DxgiOutput : public DxgiObject<IDXGIOutput> {
|
||||||
|
|
||||||
@ -64,11 +67,20 @@ namespace dxvk {
|
|||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE WaitForVBlank() final;
|
HRESULT STDMETHODCALLTYPE WaitForVBlank() final;
|
||||||
|
|
||||||
|
BOOL SetSwapChain(
|
||||||
|
DxgiSwapChain* pExpected,
|
||||||
|
DxgiSwapChain* pDesired);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Com<DxgiAdapter> m_adapter = nullptr;
|
DxgiAdapter* m_adapter = nullptr;
|
||||||
HMONITOR m_monitor = nullptr;
|
HMONITOR m_monitor = nullptr;
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
DxgiSwapChain* m_fullscreenSwapChain = nullptr;
|
||||||
|
|
||||||
|
Com<DxgiSwapChain> GetFullscreenSwapChain();
|
||||||
|
|
||||||
uint32_t GetFormatBpp(DXGI_FORMAT Format) const;
|
uint32_t GetFormatBpp(DXGI_FORMAT Format) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "dxgi_device.h"
|
#include "dxgi_device.h"
|
||||||
#include "dxgi_factory.h"
|
#include "dxgi_factory.h"
|
||||||
|
#include "dxgi_output.h"
|
||||||
#include "dxgi_swapchain.h"
|
#include "dxgi_swapchain.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -52,13 +53,14 @@ namespace dxvk {
|
|||||||
if (FAILED(CreatePresenter()) || FAILED(CreateBackBuffer()))
|
if (FAILED(CreatePresenter()) || FAILED(CreateBackBuffer()))
|
||||||
throw DxvkError("DxgiSwapChain: Failed to create presenter or back buffer");
|
throw DxvkError("DxgiSwapChain: Failed to create presenter or back buffer");
|
||||||
|
|
||||||
if (FAILED(SetDefaultGammaRamp()))
|
if (FAILED(SetDefaultGammaControl()))
|
||||||
throw DxvkError("DxgiSwapChain: Failed to set up gamma ramp");
|
throw DxvkError("DxgiSwapChain: Failed to set up gamma ramp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxgiSwapChain::~DxgiSwapChain() {
|
DxgiSwapChain::~DxgiSwapChain() {
|
||||||
|
if (m_output != nullptr)
|
||||||
|
m_output->SetSwapChain(this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -268,7 +270,52 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::SetDefaultGammaRamp() {
|
HRESULT DxgiSwapChain::GetGammaControl(DXGI_GAMMA_CONTROL* pGammaControl) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
pGammaControl->Scale = {
|
||||||
|
m_gammaControl.in_factor[0],
|
||||||
|
m_gammaControl.in_factor[1],
|
||||||
|
m_gammaControl.in_factor[2] };
|
||||||
|
|
||||||
|
pGammaControl->Offset = {
|
||||||
|
m_gammaControl.in_offset[0],
|
||||||
|
m_gammaControl.in_offset[1],
|
||||||
|
m_gammaControl.in_offset[2] };
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < DxgiPresenterGammaRamp::CpCount; i++) {
|
||||||
|
pGammaControl->GammaCurve[i] = {
|
||||||
|
m_gammaControl.cp_values[4 * i + 0],
|
||||||
|
m_gammaControl.cp_values[4 * i + 1],
|
||||||
|
m_gammaControl.cp_values[4 * i + 2] };
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT DxgiSwapChain::SetGammaControl(const DXGI_GAMMA_CONTROL* pGammaControl) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
m_gammaControl.in_factor[0] = pGammaControl->Scale.Red;
|
||||||
|
m_gammaControl.in_factor[1] = pGammaControl->Scale.Green;
|
||||||
|
m_gammaControl.in_factor[2] = pGammaControl->Scale.Blue;
|
||||||
|
|
||||||
|
m_gammaControl.in_offset[0] = pGammaControl->Offset.Red;
|
||||||
|
m_gammaControl.in_offset[1] = pGammaControl->Offset.Green;
|
||||||
|
m_gammaControl.in_offset[2] = pGammaControl->Offset.Blue;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < DxgiPresenterGammaRamp::CpCount; i++) {
|
||||||
|
m_gammaControl.cp_values[4 * i + 0] = pGammaControl->GammaCurve[i].Red;
|
||||||
|
m_gammaControl.cp_values[4 * i + 1] = pGammaControl->GammaCurve[i].Green;
|
||||||
|
m_gammaControl.cp_values[4 * i + 2] = pGammaControl->GammaCurve[i].Blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_presenter->setGammaRamp(m_gammaControl);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT DxgiSwapChain::SetDefaultGammaControl() {
|
||||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 4; i++) {
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
@ -342,10 +389,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput *pTarget) {
|
HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput *pTarget) {
|
||||||
Com<IDXGIOutput> output = pTarget;
|
m_output = static_cast<DxgiOutput*>(pTarget);
|
||||||
|
|
||||||
if (output == nullptr) {
|
if (m_output == nullptr) {
|
||||||
if (FAILED(GetContainingOutput(&output))) {
|
if (FAILED(GetContainingOutput(reinterpret_cast<IDXGIOutput**>(&m_output)))) {
|
||||||
Logger::err("DxgiSwapChain: Failed to enter fullscreen mode: Cannot query containing output");
|
Logger::err("DxgiSwapChain: Failed to enter fullscreen mode: Cannot query containing output");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
@ -372,7 +419,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Move the window so that it covers the entire output
|
// Move the window so that it covers the entire output
|
||||||
DXGI_OUTPUT_DESC desc;
|
DXGI_OUTPUT_DESC desc;
|
||||||
output->GetDesc(&desc);
|
m_output->GetDesc(&desc);
|
||||||
|
|
||||||
const RECT rect = desc.DesktopCoordinates;
|
const RECT rect = desc.DesktopCoordinates;
|
||||||
|
|
||||||
@ -380,6 +427,8 @@ namespace dxvk {
|
|||||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||||
SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
|
SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
|
||||||
|
|
||||||
|
// Assign this swap chain to the output
|
||||||
|
m_output->SetSwapChain(nullptr, this);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,6 +436,12 @@ namespace dxvk {
|
|||||||
HRESULT DxgiSwapChain::LeaveFullscreenMode() {
|
HRESULT DxgiSwapChain::LeaveFullscreenMode() {
|
||||||
m_desc.Windowed = TRUE;
|
m_desc.Windowed = TRUE;
|
||||||
|
|
||||||
|
// Remove this swap chain from the output
|
||||||
|
if (m_output != nullptr) {
|
||||||
|
m_output->SetSwapChain(this, nullptr);
|
||||||
|
m_output = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME wine only restores window flags if the application
|
// FIXME wine only restores window flags if the application
|
||||||
// has not modified them in the meantime. Some applications
|
// has not modified them in the meantime. Some applications
|
||||||
// may rely on that behaviour.
|
// may rely on that behaviour.
|
||||||
|
@ -18,6 +18,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
class DxgiDevice;
|
class DxgiDevice;
|
||||||
class DxgiFactory;
|
class DxgiFactory;
|
||||||
|
class DxgiOutput;
|
||||||
|
|
||||||
class DxgiSwapChain : public DxgiObject<IDXGISwapChain> {
|
class DxgiSwapChain : public DxgiObject<IDXGISwapChain> {
|
||||||
|
|
||||||
@ -80,7 +81,13 @@ namespace dxvk {
|
|||||||
BOOL Fullscreen,
|
BOOL Fullscreen,
|
||||||
IDXGIOutput *pTarget) final;
|
IDXGIOutput *pTarget) final;
|
||||||
|
|
||||||
HRESULT SetDefaultGammaRamp();
|
HRESULT GetGammaControl(
|
||||||
|
DXGI_GAMMA_CONTROL* pGammaControl);
|
||||||
|
|
||||||
|
HRESULT SetGammaControl(
|
||||||
|
const DXGI_GAMMA_CONTROL* pGammaControl);
|
||||||
|
|
||||||
|
HRESULT SetDefaultGammaControl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -95,6 +102,7 @@ namespace dxvk {
|
|||||||
Com<DxgiFactory> m_factory;
|
Com<DxgiFactory> m_factory;
|
||||||
Com<DxgiAdapter> m_adapter;
|
Com<DxgiAdapter> m_adapter;
|
||||||
Com<DxgiDevice> m_device;
|
Com<DxgiDevice> m_device;
|
||||||
|
Com<DxgiOutput> m_output;
|
||||||
Com<IDXGIVkPresenter> m_presentDevice;
|
Com<IDXGIVkPresenter> m_presentDevice;
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC m_desc;
|
DXGI_SWAP_CHAIN_DESC m_desc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user