Files
GTASource/game/renderer/rendertargets.h
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

804 lines
27 KiB
C++

//
// renderer/rendertargets.h
//
// Copyright (C) 1999-2014 Rockstar Games. All Rights Reserved.
//
#ifndef RENDERER_RENDERTARGETS_H
#define RENDERER_RENDERTARGETS_H
#include "math/amath.h"
#include "grcore/texture.h"
#include "vfx/vfx_shared.h"
#include "control/replay/ReplaySupportClasses.h"
#define DYNAMIC_BB (1 && DYNAMIC_ESRAM)
#if __XENON
#if __ASSERT
#include "system/system.h" //thread check for rendertarget resolve
#endif // __ASSERT
enum RTMemPoolID {
XENON_RTMEMPOOL_GENERAL = 0, // contains reflection, PostFX,
XENON_RTMEMPOOL_GENERAL1, // contains SSAO, water, tiled classification, Depth Quarter, ped player damage/decoration heaps
XENON_RTMEMPOOL_GBUFFER0, // GBuffer0(Albedo), sub-sample alpha, PostFX, Ped UI 0, Volume Offscreen, Volume Offscreen Hi-Res
XENON_RTMEMPOOL_GBUFFER1, // GBuffer1(Normal) on its own, SeeThrough Targets, mirror
XENON_RTMEMPOOL_GBUFFER23, // GBuffer2 and 3, Back Buffer, Ped UI 1, Ptfx downsample Color
XENON_RTMEMPOOL_FRONTBUFFER0, // Front Buffer 0, UI Depth Buffer, Scene Depth Buffer, Scene Depth Alias (Rolls across the current front buffer, not safe to cache)
XENON_RTMEMPOOL_FRONTBUFFER1, // Front Buffer 1, UI Depth Buffer, Scene Depth Buffer, Scene Depth Alias (Rolls across the current front buffer, not safe to cache)
XENON_RTMEMPOOL_FRONTBUFFER2, // Front Buffer 2, UI Depth Buffer, Scene Depth Buffer, Scene Depth Alias (Rolls across the current front buffer, not safe to cache)
XENON_RTMEMPOOL_SHADOWS, // contains Shadows and medium/low ped damage heaps
XENON_RTMEMPOOL_SHADOW_CACHE, // contains Shadow cache (don't overwrite or reuse)
XENON_RTMEMPOOL_TEMP_BUFFER, // DO NOT REUSE: contains a temporary fullscreen buffer
XENON_RTMEMPOOL_PERLIN_NOISE, // Perlin Noise
XENON_RTMEMPOOL_MAXNUM,
RTMEMPOOL_NONE
};
enum XenonGeneralPoolHeaps { // the main render target pool on xenon uses several heaps to start from the beginning of the pool for each set.
kReflectionHeap, //Mirror Reflection, Paraboloid Reflection,
kWaterReflectionHeap, //Water Reflection
kMirrorWaterReflectionHeap, // Mirror Water Reflection
kWaterReflectionAliasHeap, //Water Reflection Alias
kPostFxGeneralPoolHeap,
kDeferredPedUIHeap3,
kDeferredPedUIHeap5,
kGeneralHeapCount,
};
enum XenonGeneral1PoolHeaps {
kSSAOWaterHeap, //Water Lighting 1/4, Water Lighting, Water Refraction, Depth Quarter Linear, TOBEADDED: Depth Quarter
kPuddleHeap,
kMainWaterHeap, //Water Lighting 1/16, Water Bump
kTiledLightingHeap0,
kTiledLightingHeap1,
kTiledLightingHeap2,
kTiledLightingHeap3,
kDepthQuarter, // Shadowed PTX Buffer
kCubeReflectionHeap,
kPedMedResDamageHeap,
kPedLowResDamageHeap,
kMinimapOffscreenBufferHeap,
kMinimapOffscreenDepthBufferHeap,
kMirrorPedDamageHeap,
kGeneral1HeapCount,
};
enum XenonGBuffer0PoolHeaps {
kGBuffersHeap,
kPostFxHeap,
kScreenShotHeap,
kVolumeLightFxHeap,
kOffscreenBuffer0,
kOffscreenBuffer2,
kVolumeLightFxHeapHiRes,
kDeferredPedUIHeap0,
kDeferredPedUIHeap1,
kDeferredPedUIHeap6,
kGBuffer0HeapCount
};
enum XenonGBuffer1PoolHeaps {
kGBuffer1Heap,
kFXHeap,
kDummyHeap,
kGBuffer1MirrorHeap,
kOffscreenBuffer1,
kGBuffer1HeapCount
};
enum XenonGBuffer23PoolHeaps { // UI Backbuffer (declared in RAGE)
kGBuffer23Heap,
kBackBufferHeap, // HDR scene back buffer (10bit float resolves to 16bit float)
kBackBuffer7e3IntAliasHeap, // HDR back buffer alias (10bit float resolves to 10bit int)
kFXAAHeap, // Used only for: final composite output / FXAA input
kPtfxDownsampleHeap, // Used only for: Downsampled render target for ptfx
kGBuffer23MirrorHeap,
kGBuffer23HeapCount
};
enum XenonShadowPoolHeaps {
kShadowMapHeap,
kShadowMapHighResHeap, // used for CASCADE_SHADOWS_ALTERNATE_SHADOW_MAPS
kShadowMapFixed24Heap, // used for CASCADE_SHADOWS_ALTERNATE_SHADOW_MAPS, CASCADE_SHADOWS_FLOAT_SHADOW_BUFFER
kPedHighResDamageHeap,
kPedMedRes2DamageHeap,
kPedLowRes2DamageHeap,
kPhotoHeap,
kHeadshotHeap,
kHeadshotSmallHeap,
kShadowHeapCount,
};
enum XenonShadowCachePoolHeaps { // so cube maps and Paraboloid maps can co exist for now...
kShadowMapCacheParaboloidHeap,
kShadowMapCacheParaboloidHeap2,
kShadowMapCacheCubeMapHeap,
kShadowCacheHeapCount,
};
enum XenonTempBufferPoolHeaps { // DO NOT REUSE: temporary new heap
kTempBufferPoolHeap,
kDeferredPedUIHeap2,
kUIPedHeadshotHeap,
kUIPedHeadshotHeap2,
kTempBufferPoolHeapCount,
};
enum XenonPerlinNoisePoolHeaps {
kPerlinNoiseHeap,
kDeferredPedUIHeap4,
kMemeEditorHeap,
kPerlinNoisePoolHeapCount
};
#endif // __XENON
enum MSDepthResolve {
depthResolve_Sample0,
depthResolve_Closest,
depthResolve_Farthest,
depthResolve_Dominant,
};
#include "grcore/device.h"
#if __BANK
#include "vectormath/vec2v.h"
#endif // __BANK
#include "renderer/Deferred/DeferredConfig.h"
#include "debug/rendering/DebugDeferred.h"
#include "renderer/Lights/LightCommon.h"
#include "renderer/TreeImposters.h"
#include "grcore/rendertarget_common.h"
namespace rage
{
class grcRenderTarget;
class grcRenderTargetMemPool;
class bkBank;
};
#define USE_DEPTHBUFFER_ZCULL_SHARING (1 && __PS3) // Force the backbuffer depth and the offscreen depth buffers to share their zcull memory
#if __PPU
#include "renderer/psnvramrendertargettotal.h"
#include "renderer/SpuPM/SpuPmMgr.h"
#define PSN_BUFFER_WIDTH (1280)
#define PSN_BUFFER_HEIGHT (720)
#define PSN_RESOLVE_TO_ALTBUFFER (0)
#define PSN_CROP_RESOLVE (0)
#define PSN_USE_FP16 (1)
enum RTMemPoolID {
PSN_RTMEMPOOL_P10240_TILED_LOCAL_COMPMODE_DISABLED, // 0
PSN_RTMEMPOOL_P1024_TILED_LOCAL_COMPMODE_DISABLED, // 1
PSN_RTMEMPOOL_P2048_TILED_LOCAL_COMPMODE_C32_2X1, // 2
PSN_RTMEMPOOL_P512_TILED_LOCAL_COMPMODE_DISABLED, // 3
PSN_RTMEMPOOL_P5120_TILED_LOCAL_COMPMODE_DISABLED_2, // 4
PSN_RTMEMPOOL_P2560_TILED_LOCAL_COMPMODE_DISABLED, // 5
PSN_RTMEMPOOL_P1024_TILED_LOCAL_COMPMODE_C32_2X1, // 6
PSN_RTMEMPOOL_P1280_TILED_LOCAL_COMPMODE_C32_2X1, // 7
// Depth buffer
PSN_RTMEMPOOL_P2560_TILED_LOCAL_COMPMODE_Z32_SEPSTENCIL_REGULAR, // 8
PSN_RTMEMPOOL_P512_TILED_LOCAL_COMPMODE_Z32_SEPSTENCIL_REGULAR, // 9
PSN_RTMEMPOOL_P1024_TILED_LOCAL_COMPMODE_Z32_SEPSTENCIL_DIAGONAL, // 10
PSN_RTMEMPOOL_P5120_TILED_LOCAL_COMPMODE_Z32_SEPSTENCIL_REGULAR_BBUFFER, // 11
PSN_RTMEMPOOL_MAXNUM,
RTMEMPOOL_NONE
};
#define RTMEMPOOL_SIZE int(PSN_RTMEMPOOL_MAXNUM)
#else // __PPU
#define PSN_BUFFER_WIDTH GRCDEVICE.GetWidth()
#define PSN_BUFFER_HEIGHT GRCDEVICE.GetHeight()
#define PSN_RESOLVE_TO_ALTBUFFER (0)
#define PSN_CROP_RESOLVE (0)
#define PSN_USE_FP16 (0)
#if __SPU
typedef int RTMemPoolID;
#endif
#if __WIN32PC || RSG_DURANGO || RSG_ORBIS
enum RTMemPoolID {RTMEMPOOL_NONE};
#endif
#if __XENON
#define RTMEMPOOL_SIZE int(XENON_RTMEMPOOL_MAXNUM)
#else
#define RTMEMPOOL_SIZE 4
#endif
#endif //__PPU...
class CRenderTargets
{
public:
static void PreAllocateRenderTargetMemPool();
static void AllocateRenderTargets();
#if RSG_PC
static void DeviceLost();
static void DeviceReset();
#endif
static void DeAllocateRenderTargets();
static void LockSceneRenderTargets(bool lockDepth = true);
static void LockSceneRenderTargets_DepthCopy();
static void UnlockSceneRenderTargets();
static void LockUIRenderTargets();
static void UnlockUIRenderTargets(bool realize = false);
#if __D3D11
static void LockUIRenderTargetsReadOnlyDepth();
#endif // __D3D11
static bool NeedsRescale();
#if __PS3
static void Rescale();
#endif
static void ResetRenderThreadInfo();
static void SetDownsampleDepthFlag(bool value) { ms_DepthDownsampleReady = value; };
static void DownsampleDepth();
#if __XENON
static int GetRenderTargetMemPoolSize(int width, int height);
static void AllocRenderTargetMemPool(int size, RTMemPoolID id, u8 heapCount = 1, void* preallocatedBuffer = NULL);
#endif
static void FreeRenderTargetMemPool();
static rage::u16 GetRenderTargetPoolID(RTMemPoolID i) { FastAssert((int)i < RTMEMPOOL_SIZE); return ms_RenderTargetMemPoolArray[i]; }
static grcRenderTarget* CreateRenderTarget(RTMemPoolID memPoolID, const char *name, grcRenderTargetType type, int width, int height, int bitsPerPixel, rage::grcTextureFactory::CreateParams *params=NULL, u8 poolHeap=0, grcRenderTarget* originalTexture = NULL);
static grcRenderTarget* CreateRenderTarget(const char* name, grcTextureObject* sourceTexture, grcRenderTarget* originalTexture = NULL);
#if __BANK
static void CheckPoolSizes();
static void UpdateBank(const bool forceLoad);
static void RenderBank(int mode);
static bool IsShowingRenderTarget();
static bool IsShowingRenderTarget(const char* name);
static bool IsShowingRenderTargetWaterDraw();
static Vec2V_Out ShowRenderTargetGetWindowMin();
static Vec2V_Out ShowRenderTargetGetWindowMax();
static void ShowRenderTarget(const char* name);
static void ShowRenderTargetOpacity(float opacity);
static void ShowRenderTargetBrightness(float brightness);
static void ShowRenderTargetNativeRes(bool nativeRes, bool flipHoriz, bool waterDraw = false);
static void ShowRenderTargetSetBounds(float x, float y, float w, float h);
static void ShowRenderTargetFullscreen(bool fullscreen);
static int& ShowRenderTargetGetMipRef();
static void ShowRenderTargetInfo(bool show);
static void ShowRenderTargetReset(); // reset back to defaults
static void AddWidgets(bkBank &bank);
static void DumpRenderTargets();
static void DisplayRenderTargetOverlaps();
static void DisplayRenderTargetMemPool(u16 index);
static void DisplayRenderTarget(u32 index);
static void BlitRenderTarget(grcRenderTarget* pRT, const Vector4 &posAndSize, float opacity = 1.0f, bool bUseDepth = false);
#endif // __BANK
#if !(__WIN32PC || RSG_DURANGO || RSG_ORBIS)
static void RefreshStencilCull(bool useEqual, int material, int mask PS3_ONLY(, bool preserveZFarCull = true));
static void ClearStencilCull(int material);
#endif
#if RSG_PS3 || RSG_XENON
static void ConvertAlphaMaskToStencilMask(int alphaRef, grcTexture* pSourceAlpha XENON_ONLY(, bool bUseStencilAsColor = false));
#endif
static void DrawFullScreenTri ( float depth );
// PSN Flicker filters (for SD res only)
#if __PPU
static void RefreshStencilZFarCull(bool useEqual, int material, int mask);
static void ResetStencilCull(bool useEqual, int material, int mask, bool clearZ = false, bool clearStencil = true);
static void RefreshZFarCull(bool useDepthGreater);
static void SetZCullControl(bool useDepthGreater);
// Render Targets
static void BeginMSAARender();
static void EndMSAARender();
#endif // __PPU
static grcRenderTarget* GetBackBuffer(bool realize = false);
#if DYNAMIC_BB
static void InitAltBackBuffer();
static void SetAltBackBuffer();
static void ResetAltBackBuffer();
static void FlushAltBackBuffer();
static bool UseAltBackBufferTest();
#endif
static grcRenderTarget* GetUIBackBuffer(bool realize = false);
static const grcRenderTarget* GetUIFrontBuffer();
static grcRenderTarget* GetDepthBuffer(bool realize = false); //Main scene depth buffer
static grcRenderTarget* GetDepthBuffer_PreAlpha() {return ms_DepthBuffer_PreAlpha;}
#if RSG_PC
static grcRenderTarget* GetUIDepthBuffer_PreAlpha() {return ms_UIDepthBuffer_PreAlpha;}
#endif
#if __PPU || __XENON
static grcRenderTarget* GetDepthBufferAsColor();
static grcRenderTarget* GetDepthBufferQuarterAsColor();
static void SetDepthBufferQuarterAsColor(grcRenderTarget* rt);
#endif // __PPU || __XENON
static grcRenderTarget* GetUIDepthBuffer(bool realize = false); //UI/Frontend depth buffer
static grcRenderTarget* GetDepthBufferQuarter();
static grcRenderTarget* GetDepthBufferQuarter_Read_Target(bool WIN32PC_ONLY(doCopy));
#if RSG_PC && __D3D11
static grcRenderTarget* GetDepthBuffer_PreAlpha_ReadOnly();
#endif // RSG_PC && __D3D11
static grcRenderTarget* GetVolumeOffscreenBuffer();
#if LIGHT_VOLUME_USE_LOW_RESOLUTION
static grcRenderTarget* GetVolumeReconstructionBuffer();
#endif
static grcRenderTarget* GetDepthBufferQuarterLinear();
#if DEVICE_MSAA
// Get a custom resolved version of the depth (min, max single sample or average).
static inline grcRenderTarget* GetDepthResolved();
#if RSG_PC
static inline grcRenderTarget* GetUIDepthResolved();
static inline grcRenderTarget* GetUIDepthBufferResolved_ReadOnly();
#endif
#if __D3D11
static inline grcRenderTarget* GetDepthBufferResolved_ReadOnly();
#endif // __D3D11
// Update the resolved light buffer
static void ResolveBackBuffer(bool depthReadOnly);
#if ENABLE_PED_PASS_AA_SOURCE
// Get the MSAA copy of the back buffer
static grcRenderTarget* GetBackBufferCopyAA( bool bDoCopy=false );
#endif // ENABLE_PED_PASS_AA_SOURCE
static void ResolveSourceDepth(MSDepthResolve depthResolveType, grcRenderTarget* sourceMSAADepthTarget, grcRenderTarget* depthResolveTarget);
static void ResolveDepth(MSDepthResolve depthResolveType, grcRenderTarget* alternateResolveTarget = NULL);
#endif // DEVICE_MSAA
static void CopyDepthManual(grcRenderTarget *srcDepthbuffer, grcRenderTarget *dstDepthBuffer);
static void CopyDepthBuffer( grcRenderTarget* srcDepthbuffer, grcRenderTarget* dstDepthBuffer);
#if DEBUG_TRACK_MSAA_RESOLVES
static bool IsBackBufferResolved();
#endif
#if RSG_PC || RSG_DURANGO
// NOTE These can`t be be inlined as they are used in draw lists.
static void CopyBackBuffer();
static void CopyDepthBufferCmd() { CopyDepthBuffer(ms_DepthBuffer, ms_DepthBufferCopy); }
static void CopyTarget(grcRenderTarget *src, grcRenderTarget *dst, grcRenderTarget *dstStencil = NULL, u8 stencilRef = 0xFF );
#if RSG_PC
static grcRenderTarget *GetBackBufferCopy( bool bDoCopy=false );
#else
static inline grcRenderTarget *GetBackBufferCopy( bool bDoCopy=false );
#endif
static inline grcRenderTarget *GetDepthBufferCopy( bool bDoCopy=false );
#if RSG_PC
static inline grcRenderTarget* SwapBackBuffer();
static inline grcRenderTarget* GetBackBufferCopyForPause();
static void ResolveForMultiGPU(int bResolve);
#endif
#if __D3D11
static inline grcRenderTarget *GetDepthBuffer_Stencil();
static inline grcRenderTarget *GetDepthBufferCopy_Stencil();
static inline grcRenderTarget *GetDepthBuffer_ReadOnly();
#if RSG_PC
static inline grcRenderTarget *GetDepthBuffer_ReadOnlyDepth();
#endif
#endif
#elif __PS3
static void CopyDepthBuffer( grcRenderTarget* srcDepthbuffer, grcRenderTarget* dstDepthBuffer, u8 stencilRef );
#elif RSG_ORBIS
static void CopyBackBuffer();
// these should return const grcTexture* ideally, but the client code expects grcRenderTarget*
static inline grcRenderTarget *GetBackBufferCopy( bool bDoCopy=false );
static inline grcRenderTarget *GetDepthBuffer_Stencil(); //actually returns AA texture
#endif // platforms
#if __D3D11
static grcRenderTarget* LockReadOnlyDepth(bool needsCopy = true, bool bLockBothDepthStencilRO = true, grcRenderTarget* depthBuffer = ms_DepthBuffer, grcRenderTarget* depthBufferCopy = ms_DepthBufferCopy, grcRenderTarget* depthBufferReadOnly = ms_DepthBuffer_ReadOnly);
static void UnlockReadOnlyDepth();
#endif //__D3D11
// In MSAA or EQAA enabled builds, perform a resolve of the specified
// offscreen buffer to the corresponding single sample buffer. Nop in
// non-MSAA/EQAA builds.
static void ResolveBuffer(unsigned index);
static void ResolveHudBuffer() { ResolveBuffer(0); }
static void ResolveOffscreenBuffer1() { ResolveBuffer(1); }
static void ResolveOffscreenBuffer2() { ResolveBuffer(2); }
static void ResolveOffscreenBuffer3() { ResolveBuffer(3); }
// Get a poitner the specified multi-sample offscreen buffer (or
// single-sample in non-MSAA/EQAA builds).
static grcRenderTarget* GetOffscreenBuffer(unsigned index);
// Get a pointer to the specified single-sample buffer.
static grcRenderTarget* GetOffscreenBuffer_SingleSample(unsigned index);
// Get a pointer to the specified single-sample buffer. In single threaded
// rendering (NUMBER_OF_RENDER_THREADS==1) beta builds, debug code will
// track whether the offscreen buffer has been resolved. Unlike
// GetOffscreenBuffer_SingleSample, this function will assert if it hasn't
// been resolved. Multithreaded rendering builds cannot correctly track the
// resolve state, so they cannot assert.
static grcRenderTarget* GetOffscreenBuffer_Resolved(unsigned index);
static grcRenderTarget* GetHudBuffer() { return GetOffscreenBuffer(0); }
static grcRenderTarget* GetOffscreenBuffer1() { return GetOffscreenBuffer(1); }
static grcRenderTarget* GetOffscreenBuffer2() { return GetOffscreenBuffer(2); }
static grcRenderTarget* GetOffscreenBuffer3() { return GetOffscreenBuffer(3); }
static grcRenderTarget* GetHudBuffer_Resolved() { return GetOffscreenBuffer_Resolved(0); }
static grcRenderTarget* GetOffscreenBuffer1_Resolved() { return GetOffscreenBuffer_Resolved(1); }
static grcRenderTarget* GetOffscreenBuffer2_Resolved() { return GetOffscreenBuffer_Resolved(2); }
static grcRenderTarget* GetOffscreenBuffer3_Resolved() { return GetOffscreenBuffer_Resolved(3); }
#if __PS3
// If USE_DEPTHBUFFER_ZCULL_SHARING then this shares zcull memory with the backbuffer
static grcRenderTarget* GetOffscreenDepthBuffer();
static grcRenderTarget* GetOffscreenDepthBufferAsColor();
static grcRenderTarget* SetOffscreenDepthBufferAsColor( grcRenderTarget* );
#endif
#if __XENON
static grcRenderTarget* GetBackBuffer7e3toInt(bool bRealize = false);
#endif // __XENON
#if __XENON
static grcRenderTarget* GetMinimapOffscreenBuffer();
static grcRenderTarget* GetMinimapOffscreenDepthBuffer();
static grcRenderTarget* GetBackBufferCopy();
#endif
#if GTA_REPLAY
#if REPLAY_USE_PER_BLOCK_THUMBNAILS
static grcTexture* GetReplayThumbnailTexture(u32 idx);
static grcRenderTarget* GetReplayThumbnailRT(u32 idx);
#endif // REPLAY_USE_PER_BLOCK_THUMBNAILS
#endif // GTA_REPLAY
private:
static rage::u16 ms_RenderTargetMemPoolArray[RTMEMPOOL_SIZE];
static DECLARE_MTR_THREAD bool ms_RenderTargetActive;
static bool ms_DepthDownsampleReady;
static grcRenderTarget* ms_BackBuffer;
#if __XENON
static grcRenderTarget* ms_BackBuffer7e3ToIntAlias;
#endif
#if DYNAMIC_BB
static grcRenderTarget* ms_AltBackBuffer;
#endif
#if RSG_PC || RSG_DURANGO
static grcRenderTarget* ms_BackBufferCopy;
static grcRenderTarget* ms_DepthBufferCopy;
#if RSG_PC
// used for multi GPU
static grcRenderTarget* ms_BackBufferRTForPause;
static grcTexture* ms_BackBufferTexForPause;
#endif
#if __D3D11
static grcRenderTarget* ms_DepthBuffer_Stencil;
static grcRenderTarget* ms_DepthBufferCopy_Stencil;
static grcRenderTarget* ms_DepthBuffer_ReadOnly;
#if RSG_PC
static grcRenderTarget* ms_DepthBuffer_ReadOnlyDepth;
#endif
static bool ms_Initialized;
#endif //__D3D11
#elif RSG_ORBIS
static grcRenderTarget* ms_BackBufferCopy;
static grcRenderTarget* ms_DepthBuffer_Stencil;
#endif // platforms
#if __XENON
static grcRenderTarget* ms_DepthBuffers[3];
#else
static grcRenderTarget* ms_DepthBuffer;
static grcRenderTarget* ms_DepthBuffer_PreAlpha;
#endif //__XENON
#if DEVICE_MSAA
static grcRenderTarget* ms_BackBuffer_Resolved;
static grcRenderTarget* ms_DepthBuffer_Resolved;
#if RSG_PC
static grcRenderTarget* ms_UIDepthBuffer_PreAlpha;
static grcRenderTarget* ms_UIDepthBuffer_Resolved;
static grcRenderTarget* ms_UIDepthBuffer_Resolved_ReadOnly;
#endif
#if __D3D11
static grcRenderTarget* ms_DepthBuffer_Resolved_ReadOnly;
#endif // __D3D11
#if ENABLE_PED_PASS_AA_SOURCE
static grcRenderTarget* ms_BackBufferCopyAA;
#endif // ENABLE_PED_PASS_AA_SOURCE
#endif //DEVICE_MSAA
#if __PPU
static grcRenderTarget* ms_PatchedDepthBuffer;
static grcRenderTarget* ms_VSDepthBuffer;
static grcRenderTarget* ms_PatchedNativeDepthBuffer;
static grcBlendStateHandle ms_Refresh_BS;
static grcDepthStencilStateHandle ms_RefreshStencil_DS;
static grcDepthStencilStateHandle ms_RefreshStencilPreserveZFar_DS;
static grcDepthStencilStateHandle ms_RefreshStencilZFar_DS;
static grcDepthStencilStateHandle ms_RefreshZFar_G_DS;
static grcDepthStencilStateHandle ms_RefreshZFar_L_DS;
static bool ms_MSAARender;
static bool ms_WithDepthRender;
#endif // __PPU
#if GTA_REPLAY
#if REPLAY_USE_PER_BLOCK_THUMBNAILS
static grcTexture *ms_ReplayThumbnailTex[REPLAY_PER_FRAME_THUMBNAILS_LIST_SIZE];
static grcRenderTarget *ms_ReplayThumbnailRT[REPLAY_PER_FRAME_THUMBNAILS_LIST_SIZE];
#endif // REPLAY_USE_PER_BLOCK_THUMBNAILS
#endif // GTA_REPLAY
static grcDepthStencilStateHandle ms_CopyDepth_DS;
#if __PS3
static grcDepthStencilStateHandle ms_CopyDepthClearStencil_DS;
#endif
#if __BANK
static grcBlendStateHandle ms_BlitTransparent_BS;
#endif
static grcDepthStencilStateHandle ms_CopyColorStencilMask_DS;
static grcBlendStateHandle ms_AlphaMaskToStencilMask_BS;
static grcDepthStencilStateHandle ms_AlphaMaskToStencilMask_DS;
};
#if DEVICE_MSAA
inline grcRenderTarget* CRenderTargets::GetDepthResolved()
{
return GRCDEVICE.GetMSAA()>1 ? ms_DepthBuffer_Resolved : GetDepthBuffer();
}
#if RSG_PC
inline grcRenderTarget* CRenderTargets::GetUIDepthResolved()
{
return GRCDEVICE.GetMSAA()>1 ? ms_UIDepthBuffer_Resolved : GetUIDepthBuffer();
}
inline grcRenderTarget* CRenderTargets::GetUIDepthBufferResolved_ReadOnly()
{
return ms_UIDepthBuffer_Resolved_ReadOnly;
}
#endif
#if __D3D11
inline grcRenderTarget* CRenderTargets::GetDepthBufferResolved_ReadOnly()
{
return GRCDEVICE.GetMSAA()>1 ? ms_DepthBuffer_Resolved_ReadOnly : GetDepthBuffer_ReadOnly();
}
#endif // __D3D11
#if ENABLE_PED_PASS_AA_SOURCE
inline grcRenderTarget* CRenderTargets::GetBackBufferCopyAA(bool bDoCopy)
{
if(bDoCopy && ms_BackBufferCopyAA)
ms_BackBufferCopyAA->Copy(ms_BackBuffer);
return ms_BackBufferCopyAA;
}
#endif // ENABLE_PED_PASS_AA_SOURCE
#endif // DEVICE_MSAA
#if RSG_PC || RSG_DURANGO
#if !RSG_PC
inline grcRenderTarget *CRenderTargets::GetBackBufferCopy(bool bDoCopy/*=false*/) { if(bDoCopy) CopyBackBuffer(); return ms_BackBufferCopy; }
#endif
inline grcRenderTarget *CRenderTargets::GetDepthBufferCopy(bool bDoCopy/*=false*/) { if(bDoCopy) CopyDepthBuffer(ms_DepthBuffer, ms_DepthBufferCopy); return ms_DepthBufferCopy; }
#if RSG_PC
inline grcRenderTarget* CRenderTargets::SwapBackBuffer() { grcRenderTarget* copy = ms_BackBufferCopy; ms_BackBufferCopy = ms_BackBuffer; ms_BackBuffer = copy; return ms_BackBufferCopy; }
inline grcRenderTarget* CRenderTargets::GetBackBufferCopyForPause() { return ms_BackBufferRTForPause; }
#endif
#if __D3D11
inline grcRenderTarget *CRenderTargets::GetDepthBuffer_Stencil() { return ms_DepthBuffer_Stencil; }
inline grcRenderTarget *CRenderTargets::GetDepthBufferCopy_Stencil() { return ms_DepthBufferCopy_Stencil; }
inline grcRenderTarget *CRenderTargets::GetDepthBuffer_ReadOnly() { /*Assert(GRCDEVICE.IsReadOnlyDepthAllowed());*/ return ms_DepthBuffer_ReadOnly; }
#if RSG_PC
inline grcRenderTarget *CRenderTargets::GetDepthBuffer_ReadOnlyDepth() { /*Assert(GRCDEVICE.IsReadOnlyDepthAllowed());*/ return ms_DepthBuffer_ReadOnlyDepth; }
#endif
#endif
#elif RSG_ORBIS
inline grcRenderTarget *CRenderTargets::GetBackBufferCopy(bool bDoCopy/*=false*/) { if(bDoCopy) CopyBackBuffer(); return ms_BackBufferCopy; }
inline grcRenderTarget *CRenderTargets::GetDepthBuffer_Stencil() { return ms_DepthBuffer_Stencil; }
#endif //RSG_ORBIS
//////////////////////////////////////////////////////////////////////////
// VideoResManager
class VideoResManager {
public:
enum eDownscaleFactor
{
DOWNSCALE_FIRST = 1,
DOWNSCALE_ONE = DOWNSCALE_FIRST,
DOWNSCALE_HALF = 2,
DOWNSCALE_QUARTER = 4,
DOWNSCALE_EIGHTH = 8,
DOWNSCALE_SIXTEENTH = 16,
DOWNSCALE_MAX = DOWNSCALE_SIXTEENTH
};
static eDownscaleFactor GetDownscaleFactor( u32 const rawDownscale );
static void Init();
static void Shutdown();
#if RSG_PC
static void DeviceLost();
static void DeviceReset();
#endif
//Gets the system native depth
static inline int GetNativeWidth();
static inline int GetNativeHeight();
//Gets the main scene width
static inline int GetSceneWidth();
static inline int GetSceneHeight();
//Gets the UI/frontend width
static inline int GetUIWidth();
static inline int GetUIHeight();
#if RSG_PC
enum ScalingMode {
MODE_1o1, // Default
MODE_1o2, // x 0.500
MODE_2o3, // x 0.667
MODE_3o4, // x 0.750
MODE_5o6, // x 0.834
MODE_5o4, // x 1.250
MODE_3o2, // x 1.500
MODE_7o4, // x 1.750
MODE_2o1, // x 2.000
MODE_5o2, // x 2.500
MODE_COUNT
};
static void SetScalingMode(int mode) { m_scalingMode = mode; Assert(mode>=0 && mode<10); }
static int GetScalingMode() { return m_scalingMode; }
static void GetSceneScale(int scalingMode, int& scaleNumerator, int& scaleDenominator);
static bool IsSceneScaled(){return(m_gameWidth != m_UIWidth || m_gameHeight != m_UIHeight);}
#endif
//Gets the Screenshot width/height with some constraints
static inline void GetScreenshotDimensions( u32& out_width, u32& out_height, eDownscaleFactor const scale = DOWNSCALE_ONE );
#if RSG_PC
static inline void GetScreenshotDimensionsOfConsoles( u32& out_width, u32& out_height, eDownscaleFactor const scale = DOWNSCALE_ONE );
#endif
static inline void ConstrainScreenshotDimensions( u32& inout_width, u32& inout_height, eDownscaleFactor const maxScale = DOWNSCALE_MAX );
#if __BANK
static void AddWidgets(bkBank &bank);
#endif
private:
#if RSG_PC
static int m_scalingMode;
#endif
static int m_nativeWidth;
static int m_nativeHeight;
static int m_gameWidth;
static int m_gameHeight;
static int m_UIWidth;
static int m_UIHeight;
};
inline int VideoResManager::GetNativeWidth()
{
return m_nativeWidth;
}
inline int VideoResManager::GetNativeHeight()
{
return m_nativeHeight;
}
inline int VideoResManager::GetSceneWidth()
{
return m_gameWidth;
}
inline int VideoResManager::GetSceneHeight()
{
return m_gameHeight;
}
inline int VideoResManager::GetUIWidth()
{
return m_UIWidth;
}
inline int VideoResManager::GetUIHeight()
{
return m_UIHeight;
}
inline void VideoResManager::GetScreenshotDimensions( u32& out_width, u32& out_height, eDownscaleFactor const scale )
{
#if SUPPORT_MULTI_MONITOR
const GridMonitor &mon = GRCDEVICE.GetMonitorConfig().getLandscapeMonitor();
out_width = mon.getWidth();
out_height = mon.getHeight();
#else
out_width = (u32)m_UIWidth;
out_height = (u32)m_UIHeight;
#endif //SUPPORT_MULTI_MONITOR
ConstrainScreenshotDimensions( out_width, out_height );
u32 downscale = Clamp<u32>( scale, DOWNSCALE_FIRST, DOWNSCALE_MAX );
out_width = out_width / downscale;
out_height = out_height / downscale;
}
#if RSG_PC
inline void VideoResManager::GetScreenshotDimensionsOfConsoles( u32& out_width, u32& out_height, eDownscaleFactor const scale )
{
#define CONSOLE_X 1920
#define CONSOLE_Y 1080
out_width = (u32)CONSOLE_X;
out_height = (u32)CONSOLE_Y;
ConstrainScreenshotDimensions( out_width, out_height );
u32 downscale = Clamp<u32>( scale, DOWNSCALE_FIRST, DOWNSCALE_MAX );
out_width = out_width / downscale;
out_height = out_height / downscale;
}
#endif
inline void VideoResManager::ConstrainScreenshotDimensions( u32& inout_width, u32& inout_height, eDownscaleFactor const maxScale )
{
//! First clamp the input sizes
u32 const c_maxWidth = 1920;
if( inout_width > c_maxWidth )
{
float const downscaleRatio = c_maxWidth / (float)inout_width;
inout_height = (u32)(inout_height * downscaleRatio);
inout_width = c_maxWidth;
}
u32 const c_maxHeight = 1080;
if( inout_height > c_maxHeight )
{
float const downscaleRatio = c_maxHeight / (float)inout_height;
inout_width = (u32)(inout_width * downscaleRatio);
inout_height = c_maxHeight;
}
// Now ensure that the width and height are able to uniformly scale
u32 const c_widthModulo = inout_width % maxScale;
inout_width = inout_width - c_widthModulo;
u32 const c_heightModulo = inout_height % maxScale;
inout_height = inout_height - c_heightModulo;
}
#endif // RENDERER_RENDERTARGETS_H
// eof