/** * Looking Glass * Copyright © 2017-2026 The Looking Glass Authors * https://looking-glass.io * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #pragma once #include #include #include #include #include #include "postprocess/D12FrameFormat.h" struct CD3D12Device; using namespace Microsoft::WRL; enum class PostProcessStatus { SUCCESS, BYPASS_EFFECT, FAILED }; class CPostProcessEffect { public: virtual ~CPostProcessEffect() {} virtual const char * GetName() const = 0; virtual void ShareState(const CPostProcessEffect& other) { UNREFERENCED_PARAMETER(other); } virtual void Update(const D12FrameFormat& format) { UNREFERENCED_PARAMETER(format); } virtual bool NeedsReconfigure() const { return false; } virtual bool RequiresFullDamage() const { return false; } virtual uint64_t GetTimingToken() const { return 0; } virtual void RecordTiming( uint64_t token, bool fullCopy, uint64_t totalTime) { UNREFERENCED_PARAMETER(token); UNREFERENCED_PARAMETER(fullCopy); UNREFERENCED_PARAMETER(totalTime); } // A final effect with a non-texture output owns its framebuffer copy. virtual bool GetCopyLayout( unsigned * pitch, unsigned * dataHeight) const { UNREFERENCED_PARAMETER(pitch); UNREFERENCED_PARAMETER(dataHeight); return false; } virtual bool ShouldCopyFully( const RECT dirtyRects[], unsigned nbDirtyRects) const { UNREFERENCED_PARAMETER(dirtyRects); UNREFERENCED_PARAMETER(nbDirtyRects); return false; } virtual void CopyFrame( const ComPtr& commandList, ID3D12Resource * dst, ID3D12Resource * src, const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const { UNREFERENCED_PARAMETER(commandList); UNREFERENCED_PARAMETER(dst); UNREFERENCED_PARAMETER(src); UNREFERENCED_PARAMETER(dirtyRects); UNREFERENCED_PARAMETER(nbDirtyRects); UNREFERENCED_PARAMETER(fullCopy); } virtual PostProcessStatus SetFormat(const ComPtr& device, const D12FrameFormat& src, D12FrameFormat& dst) = 0; virtual void AdjustDamage(RECT dirtyRects[], unsigned * nbDirtyRects) { UNREFERENCED_PARAMETER(dirtyRects); UNREFERENCED_PARAMETER(nbDirtyRects); } virtual ComPtr Run(const ComPtr& device, const ComPtr& commandList, const ComPtr& src, RECT dirtyRects[], unsigned * nbDirtyRects) = 0; bool Enabled = false; }; class CPostProcessor { private: std::shared_ptr m_dx12Device; ComPtr m_device; std::vector> m_effects; D12FrameFormat m_srcFormat = {}; D12FrameFormat m_dstFormat = {}; D3D12_PLACED_SUBRESOURCE_FOOTPRINT m_copyLayout = {}; CPostProcessEffect * m_copyEffect = nullptr; size_t m_frameSize = 0; unsigned m_pitch = 0; bool m_effectsActive = false; bool m_configured = false; public: bool Init(std::shared_ptr dx12Device, bool enableEffects); void Reset(); bool HasSameEffectChain(const CPostProcessor& other) const; bool ShareEffectState(const CPostProcessor& other); void Update(const D12FrameFormat& srcFormat); bool NeedsReconfigure(const D12FrameFormat& srcFormat) const; bool RequiresFullDamage() const; bool Configure(const D12FrameFormat& srcFormat, bool * formatChanged); void AdjustFrameDamage(RECT dirtyRects[], unsigned * nbDirtyRects); ComPtr Run( const ComPtr& commandList, const ComPtr& src, RECT dirtyRects[], unsigned * nbDirtyRects); const D12FrameFormat& GetOutputFormat() const { return m_dstFormat; } bool HasActiveEffects() const { return m_effectsActive; } void GetTimingToken(unsigned * effectIndex, uint64_t * token) const; void RecordTiming(unsigned effectIndex, uint64_t token, bool fullCopy, uint64_t totalTime); unsigned GetOutputPitch() const { return m_pitch; } size_t GetOutputSize () const { return m_frameSize; } bool ShouldCopyFully( const RECT dirtyRects[], unsigned nbDirtyRects) const; void CopyToFrameBuffer( const ComPtr& commandList, ID3D12Resource * dst, ID3D12Resource * src, const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const; void CopyToCandidate( const ComPtr& commandList, ID3D12Resource * dst, ID3D12Resource * src) const; void CopyFromCandidate( const ComPtr& commandList, ID3D12Resource * dst, ID3D12Resource * src, const RECT dirtyRects[], unsigned nbDirtyRects, bool fullCopy) const; };