diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 264b3be0..2c4ce20b 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -11,9 +11,12 @@ #include "imgui_internal.h" #include "layer.h" #include "options.h" +#include "video_core/renderer_vulkan/vk_presenter.h" #include "widget/frame_dump.h" #include "widget/frame_graph.h" +extern std::unique_ptr presenter; + using namespace ImGui; using namespace Core::Devtools; using L = Core::Devtools::Layer; @@ -71,6 +74,13 @@ void L::DrawMenuBar() { open_popup_help = MenuItem("Help & Tips"); ImGui::EndMenu(); } + if (BeginMenu("Display")) { + if (BeginMenu("Brightness")) { + SliderFloat("Gamma", &presenter->GetGammaRef(), 0.1f, 2.0f); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } EndMainMenuBar(); } diff --git a/src/core/libraries/videoout/driver.h b/src/core/libraries/videoout/driver.h index 2e478b9e..ec01b621 100644 --- a/src/core/libraries/videoout/driver.h +++ b/src/core/libraries/videoout/driver.h @@ -74,7 +74,7 @@ struct ServiceThreadParams { class VideoOutDriver { public: - explicit VideoOutDriver(u32 width, u32 height); + VideoOutDriver(u32 width, u32 height); ~VideoOutDriver(); int Open(const ServiceThreadParams* params); diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 31b8a21c..0258074d 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -11,6 +11,9 @@ #include "core/libraries/videoout/video_out.h" #include "core/loader/symbols_resolver.h" #include "core/platform.h" +#include "video_core/renderer_vulkan/vk_presenter.h" + +extern std::unique_ptr presenter; namespace Libraries::VideoOut { @@ -297,6 +300,28 @@ s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle) { return ORBIS_OK; } +s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma) { + if (gamma < 0.1f || gamma > 2.0f) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE; + } + settings->gamma = gamma; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings) { + if (settings == nullptr) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + auto* port = driver->GetPort(handle); + if (!port) { + return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE; + } + + presenter->GetGammaRef() = settings->gamma; + return ORBIS_OK; +} + void RegisterLib(Core::Loader::SymbolsResolver* sym) { driver = std::make_unique(Config::getScreenWidth(), Config::getScreenHeight()); @@ -329,6 +354,10 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventId); LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventData); + LIB_FUNCTION("DYhhWbJSeRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutColorSettingsSetGamma); + LIB_FUNCTION("pv9CI5VC+R0", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutAdjustColor); // openOrbis appears to have libSceVideoOut_v1 module libSceVideoOut_v1.1 LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutOpen); diff --git a/src/core/libraries/videoout/video_out.h b/src/core/libraries/videoout/video_out.h index 63cd8fed..7f8421fb 100644 --- a/src/core/libraries/videoout/video_out.h +++ b/src/core/libraries/videoout/video_out.h @@ -88,6 +88,11 @@ struct SceVideoOutDeviceCapabilityInfo { u64 capability; }; +struct SceVideoOutColorSettings { + float gamma; + u32 reserved[3]; +}; + void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, u32 height, u32 pitchInPixel); @@ -106,6 +111,8 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 i s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle); int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev); int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data); +s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma); +s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings); // Internal system functions void sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr); diff --git a/src/video_core/renderer_vulkan/vk_presenter.h b/src/video_core/renderer_vulkan/vk_presenter.h index a231f86d..a5f6176d 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.h +++ b/src/video_core/renderer_vulkan/vk_presenter.h @@ -41,10 +41,18 @@ enum SchedulerType { class Rasterizer; class Presenter { + struct PostProcessSettings { + float gamma = 1.0f; + }; + public: Presenter(Frontend::WindowSDL& window, AmdGpu::Liverpool* liverpool); ~Presenter(); + float& GetGammaRef() { + return pp_settings.gamma; + } + Frame* PrepareFrame(const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address, bool is_eop) { const auto info = VideoCore::ImageInfo{attribute, cpu_address}; @@ -87,6 +95,7 @@ private: Frame* GetRenderFrame(); private: + PostProcessSettings pp_settings{}; Frontend::WindowSDL& window; AmdGpu::Liverpool* liverpool; Instance instance;