3057 lines
102 KiB
C++
3057 lines
102 KiB
C++
![]() |
#include "grcore/config.h"
|
||
|
#if __WIN32PC && __D3D11
|
||
|
|
||
|
#include "diag/diagerrorcodes.h"
|
||
|
#include "grcore/device.h"
|
||
|
|
||
|
//#include "renderer/RenderPhases/RenderPhaseCascadeShadows.h"
|
||
|
//#include "renderer/ParaboloidShadow.h"
|
||
|
//#include "renderer/SpotShadows.h"
|
||
|
//#include "system/systemInfo.h"
|
||
|
|
||
|
#include "grcore/d3dwrapper.h"
|
||
|
#include "grcore/resourcecache.h"
|
||
|
#include "grcore/adapter_d3d11.h"
|
||
|
#include "grcore/texture.h"
|
||
|
#include "grcore/texturefactory_d3d11.h"
|
||
|
#include "math/amath.h"
|
||
|
|
||
|
#include "system/SettingsDefaults.h"
|
||
|
#include "camera/viewports/ViewportManager.h"
|
||
|
#include "Peds/rendering/PedDamage.h"
|
||
|
#include "renderer/rendertargets.h"
|
||
|
#include "renderer/Deferred/GBuffer.h"
|
||
|
#include "renderer/Water.h"
|
||
|
#include "renderer/PostProcessFX.h"
|
||
|
#include "renderer/Debug/EntitySelect.h"
|
||
|
#include "renderer/Mirrors.h"
|
||
|
#include "renderer/SSAO.h"
|
||
|
#include "renderer/RenderPhases/RenderPhaseReflection.h"
|
||
|
#include "renderer/RenderPhases/RenderPhaseCascadeShadows.h"
|
||
|
#include "renderer/RenderPhases/RenderPhaseHeightMap.h"
|
||
|
#include "renderer/RenderPhases/RenderPhaseFX.h"
|
||
|
#include "renderer/Shadows/ParaboloidShadows.h"
|
||
|
#include "vfx/particles/PtFxManager.h"
|
||
|
|
||
|
#include "../../shader_source/Lighting/Shadows/cascadeshadows_common.fxh" // for CASCADE_SHADOWS_DO_SOFT_FILTERING
|
||
|
|
||
|
#include "frontend/MobilePhone.h"
|
||
|
|
||
|
#if NV_SUPPORT
|
||
|
#if __D3D11
|
||
|
#define NO_STEREO_D3D9
|
||
|
#define NO_STEREO_D3D10
|
||
|
#else
|
||
|
#define NO_STEREO_D3D10
|
||
|
#define NO_STEREO_D3D11
|
||
|
#endif // __D3D11
|
||
|
|
||
|
#include "../../3rdParty/NVidia/nvapi.h"
|
||
|
#include "../../3rdParty/NVidia/nvstereo.h"
|
||
|
#endif
|
||
|
|
||
|
#if ATI_SUPPORT
|
||
|
#include "../../3rdParty/amd/ADL_SDK_7.0/include/adl_sdk.h"
|
||
|
#endif
|
||
|
|
||
|
PARAM(MinPower, "Minimum Rating Considered Low End");
|
||
|
PARAM(MaxPower, "Maximum Rating Considered High End");
|
||
|
PARAM(SuperMaxPower, "Super Maximum Rating Considered Ultrahigh End");
|
||
|
PARAM(MinWidth, "Lowest Allowed Resolution (Width)");
|
||
|
PARAM(MinHeight, "Lowest Allowed Resolution (Height)");
|
||
|
|
||
|
XPARAM(highColorPrecision);
|
||
|
XPARAM(DX11Use8BitTargets);
|
||
|
XPARAM(UseDefaultResReflection);
|
||
|
XPARAM(dx11shadowres);
|
||
|
XPARAM(disableBokeh);
|
||
|
|
||
|
XPARAM(postfxusesFP16);
|
||
|
|
||
|
XPARAM(runscript);
|
||
|
|
||
|
NOSTRIP_XPARAM(availablevidmem);
|
||
|
|
||
|
namespace rage
|
||
|
{
|
||
|
NOSTRIP_XPARAM(width);
|
||
|
NOSTRIP_XPARAM(height);
|
||
|
}
|
||
|
|
||
|
namespace SmokeTests
|
||
|
{
|
||
|
XPARAM(smoketest);
|
||
|
};
|
||
|
|
||
|
s64 totalTextureSize = 0;
|
||
|
extern float g_fPercentForStreamer;
|
||
|
|
||
|
#if __DEV
|
||
|
fiStream* SettingsDefaults::m_pLoggingStream = NULL;
|
||
|
#endif // __DEV
|
||
|
|
||
|
#if RSG_PC
|
||
|
namespace PostFX
|
||
|
{
|
||
|
extern bool g_EnableFilmEffect;
|
||
|
};
|
||
|
#endif // RSG_PC
|
||
|
|
||
|
float SettingsDefaults::sm_fMaxLodScaleMinRange = 1.0f;
|
||
|
float SettingsDefaults::sm_fMaxLodScaleMaxRange = 1.75f;
|
||
|
|
||
|
float SettingsDefaults::sm_fPedVarietyMultMinRange = 1.0f;
|
||
|
float SettingsDefaults::sm_fPedVarietyMultMaxRange = 6.0f;
|
||
|
float SettingsDefaults::sm_fVehVarietyMultMinRange = 1.0f;
|
||
|
float SettingsDefaults::sm_fVehVarietyMultMaxRange = 6.0f;
|
||
|
|
||
|
// Minimum System Hardware Requirements
|
||
|
const int MINREQ_CPU_CORE_COUNT = 4;
|
||
|
const s64 MINREQ_AMD_CPU_FREQUENCY = 2400000;
|
||
|
const s64 MINREQ_INTEL_CPU_FREQUENCY = 2300000;
|
||
|
const u64 MINREQ_PHYSICAL_MEMORY = ((u64)4 * 1024 * 1024 * 1024) - ((u64)500 * 1024 * 1024); // 4 GB minus slack as queries always return less
|
||
|
const s64 MINREQ_VIDEO_MEMORY = (1024 * 1024 * 1024) - (80 * 1024 * 1024); // 1024 MB minus slack as queries always return less
|
||
|
|
||
|
bool renderTargetStereoMode = false;
|
||
|
static int iTargetAdapter = 0;
|
||
|
|
||
|
#if RSG_PC
|
||
|
void applySceneScale(int scaleMode, int& iWidth, int& iHeight)
|
||
|
{
|
||
|
int scaleNumer,scaleDenom;
|
||
|
VideoResManager::GetSceneScale(scaleMode,scaleNumer,scaleDenom);
|
||
|
iWidth *= scaleNumer;
|
||
|
iHeight *= scaleNumer;
|
||
|
iWidth /= scaleDenom;
|
||
|
iHeight /= scaleDenom;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void CreateRenderTarget(const char * DEV_ONLY(pName), grcRenderTargetType , int nWidth, int nHeight, int nBitsPerPixel, grcTextureFactory::CreateParams *params = NULL)
|
||
|
{
|
||
|
if (((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount() == 1 && renderTargetStereoMode)
|
||
|
{
|
||
|
if (params && params->StereoRTMode != grcDevice::MONO)
|
||
|
nWidth *= 2;
|
||
|
}
|
||
|
#if __DEV
|
||
|
if (SettingsDefaults::GetLoggingStream())
|
||
|
{
|
||
|
char theText[200];
|
||
|
formatf(theText, 200, "%s width: %d height: %d bits: %d multisample: %d\r\n", pName, nWidth, nHeight, nBitsPerPixel, (params ? (params->Multisample ? params->Multisample : 1) : 1));
|
||
|
SettingsDefaults::GetLoggingStream()->Write(theText, (int)strlen(theText));
|
||
|
}
|
||
|
#endif
|
||
|
s64 textureSize = nWidth * nHeight * (nBitsPerPixel / 8) * (params ? (params->Multisample ? params->Multisample : 1) : 1);
|
||
|
const u64 RequiredAlignment = (nWidth < 256 || nHeight < 256) ? D3DRUNTIME_MEMORYALIGNMENT : D3D_AMD_LARGEALIGNMENT;
|
||
|
textureSize = (textureSize + (RequiredAlignment - 1)) & ~(RequiredAlignment - 1);
|
||
|
|
||
|
totalTextureSize += textureSize;
|
||
|
if (params && params->Lockable && !params->Multisample)
|
||
|
{
|
||
|
totalTextureSize += textureSize;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void calculateRenderTargetsSize(Settings &settings)
|
||
|
{
|
||
|
int iWidth = settings.m_video.m_ScreenWidth;
|
||
|
int iHeight = settings.m_video.m_ScreenHeight;
|
||
|
#if RSG_PC
|
||
|
applySceneScale(settings.m_graphics.m_SamplingMode, iWidth, iHeight);
|
||
|
#endif
|
||
|
int UIWidth = settings.m_video.m_ScreenWidth;
|
||
|
int UIHeight = settings.m_video.m_ScreenHeight;
|
||
|
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
// color
|
||
|
params.Multisample = 0;
|
||
|
u32 bpp = 64;
|
||
|
if (!PARAM_highColorPrecision.Get())
|
||
|
{
|
||
|
bpp = 32;
|
||
|
}
|
||
|
|
||
|
#if RSG_DURANGO && LIGHT_VOLUME_USE_LOW_RESOLUTION
|
||
|
grcTextureFactory::CreateParams volParams;
|
||
|
volParams.Multisample = 0;
|
||
|
volParams.UseFloat = true;
|
||
|
volParams.Format = grctfA16B16G16R16F; // up-sampling & reconstruction optimizations require that we have an alpha channel
|
||
|
const int nVolumeBPP = 64;
|
||
|
const int nVolWidth = iWidth/2;
|
||
|
const int nVolHeight =iHeight/2;
|
||
|
|
||
|
CreateRenderTarget("Volume Lights Offscreen buffer", grcrtPermanent, nVolWidth, nVolHeight, nVolumeBPP, &volParams);
|
||
|
CreateRenderTarget("Volume Lights Reconstruction buffer", grcrtPermanent, nVolWidth, nVolHeight, nVolumeBPP, &volParams);
|
||
|
#endif
|
||
|
|
||
|
// set render target descriptions
|
||
|
params.Multisample = 0;
|
||
|
bpp = 64;
|
||
|
|
||
|
#if !__FINAL && (__D3D11 || RSG_ORBIS)
|
||
|
if( PARAM_DX11Use8BitTargets.Get() )
|
||
|
{
|
||
|
bpp = 32;
|
||
|
}
|
||
|
else
|
||
|
#endif // !__FINAL
|
||
|
{
|
||
|
bpp = 64;
|
||
|
// Back Buffer needs alpha but BackBUfferCopy only needs alpha for fxaa
|
||
|
}
|
||
|
|
||
|
|
||
|
grcDevice::MSAAMode multisample = settings.m_graphics.m_MSAA;
|
||
|
params.Multisample = multisample;
|
||
|
|
||
|
CreateRenderTarget("BackBuffer", grcrtPermanent, iWidth, iHeight, bpp, ¶ms);
|
||
|
|
||
|
#if DEVICE_MSAA
|
||
|
if(multisample)
|
||
|
{
|
||
|
CreateRenderTarget("BackBufferCopyAA", grcrtPermanent, iWidth, iHeight, bpp, ¶ms);
|
||
|
grcTextureFactory::CreateParams ResolvedParams = params;
|
||
|
ResolvedParams.Multisample = grcDevice::MSAA_None;
|
||
|
CreateRenderTarget("BackBuffer_Resolved", grcrtPermanent, iWidth, iHeight, bpp, &ResolvedParams);
|
||
|
}
|
||
|
#endif // DEVICE_MSAA
|
||
|
|
||
|
if (!multisample)
|
||
|
CreateRenderTarget("BackBufferCopy", grcrtPermanent, iWidth, iHeight, bpp, ¶ms);
|
||
|
|
||
|
params.UseHierZ = true;
|
||
|
params.Format = grctfD32FS8;
|
||
|
params.Lockable = 0;
|
||
|
int depthBpp = 40;
|
||
|
|
||
|
// DX11: TODO: Could set this up so the lockable textures are created on first use.
|
||
|
// Current method creates extra lockable render targets with associated extra memory usage
|
||
|
ENTITYSELECT_ONLY(params.Lockable = __BANK); // In __BANK these are lockable as they're used for entity select.
|
||
|
|
||
|
//We need a copy of the depth buffer pre alpha for the depth of field through windows, etc...
|
||
|
CreateRenderTarget("DepthBuffer Pre Alpha", grcrtDepthBuffer, iWidth, iHeight, depthBpp, ¶ms);
|
||
|
|
||
|
params.Multisample = multisample;
|
||
|
CreateRenderTarget("DepthBuffer", grcrtDepthBuffer, iWidth, iHeight, depthBpp, ¶ms);
|
||
|
#if RSG_PC
|
||
|
if (VideoResManager::IsSceneScaled())
|
||
|
CreateRenderTarget("UIDepthBuffer", grcrtDepthBuffer, UIWidth, UIHeight, depthBpp, ¶ms);
|
||
|
#endif
|
||
|
|
||
|
if( GRCDEVICE.IsReadOnlyDepthAllowed() )
|
||
|
{
|
||
|
// no need for the copy, we use read-only depth instead
|
||
|
// ms_DepthBufferCopy = textureFactory11.CreateRenderTarget("DepthBufferCopy (read-only)", depthObjectMSAA, params.Format, DepthReadOnly WIN32PC_ONLY(, ms_DepthBufferCopy) DURANGO_ONLY(, ms_DepthBufferCopy));
|
||
|
}else
|
||
|
{
|
||
|
CreateRenderTarget("DepthBufferCopy", grcrtDepthBuffer, iWidth, iHeight, depthBpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
#if DEVICE_MSAA
|
||
|
if (multisample)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams ResolvedParams = params;
|
||
|
ResolvedParams.Multisample = grcDevice::MSAA_None;
|
||
|
CreateRenderTarget("DepthBuffer_Resolved", grcrtPermanent, iWidth, iHeight, depthBpp, &ResolvedParams);
|
||
|
#if RSG_PC
|
||
|
if (VideoResManager::IsSceneScaled())
|
||
|
CreateRenderTarget("UIDepthBuffer_Resolved", grcrtPermanent, UIWidth, UIHeight, depthBpp, &ResolvedParams);
|
||
|
#endif
|
||
|
|
||
|
if( GRCDEVICE.IsReadOnlyDepthAllowed())
|
||
|
{
|
||
|
// ms_DepthBuffer_Resolved_ReadOnly = textureFactory11.CreateRenderTarget("DepthBuffer_Resolved (read-only)", depthObject, ResolvedParams.Format, DepthReadOnly WIN32PC_ONLY(, ms_DepthBuffer_Resolved_ReadOnly) DURANGO_ONLY(, ms_DepthBuffer_Resolved_ReadOnly));
|
||
|
}
|
||
|
}
|
||
|
#endif // DEVICE_MSAA
|
||
|
|
||
|
grcTextureFactory::CreateParams depthParams;
|
||
|
CreateRenderTarget("Depth Quarter", grcrtDepthBuffer, iWidth/2, iHeight/2, 32, &depthParams);
|
||
|
|
||
|
//R32F Version
|
||
|
depthParams.StereoRTMode = grcDevice::STEREO;
|
||
|
CreateRenderTarget("Depth Quarter Linear", grcrtPermanent, iWidth/2, iHeight/2, 32, &depthParams);
|
||
|
|
||
|
#if DEVICE_MSAA
|
||
|
grcTextureFactory::CreateParams osbparams;
|
||
|
|
||
|
#if RSG_DURANGO
|
||
|
osbparams.Multisample = multisample;
|
||
|
CreateRenderTarget("OffscreenBuffer1", grcrtPermanent, UIWidth, UIHeight, 32, &osbparams);
|
||
|
#endif // RSG_DURANGO
|
||
|
osbparams.Multisample = multisample;
|
||
|
CreateRenderTarget("OffscreenBuffer2", grcrtPermanent, UIWidth, UIHeight, 32, &osbparams);
|
||
|
osbparams.Multisample = 0;
|
||
|
CreateRenderTarget("UI Buffer", grcrtPermanent, UIWidth, UIHeight, 32, &osbparams);
|
||
|
|
||
|
osbparams.Multisample = multisample;
|
||
|
|
||
|
grcTextureFactory::CreateParams resolvedParams = osbparams;
|
||
|
resolvedParams.Multisample = grcDevice::MSAA_None;
|
||
|
|
||
|
if (settings.m_graphics.m_MSAA) {
|
||
|
CreateRenderTarget("OffscreenBuffer1_Resolved", grcrtPermanent, UIWidth, UIHeight, 32, &resolvedParams);
|
||
|
CreateRenderTarget("OffscreenBuffer2_Resolved", grcrtPermanent, UIWidth, UIHeight, 32, &resolvedParams);
|
||
|
}
|
||
|
#endif // DEVICE_MSAA
|
||
|
|
||
|
// ms_DepthBuffer_Stencil = textureFactory11.CreateRenderTarget( "StencilBuffer", depthObjectMSAA, eStencilFormat, DepthStencilRW WIN32PC_ONLY(, ms_DepthBuffer_Stencil) );
|
||
|
// ms_DepthBufferCopy_Stencil = textureFactory11.CreateRenderTarget( "StencilBufferCopy", depthCopy ? depthCopy->GetTexturePtr() : NULL, eStencilFormat );
|
||
|
// ms_DepthBuffer_ReadOnly = textureFactory11.CreateRenderTarget( "DepthBufferReadOnly", depthObjectMSAA, params.Format, DepthStencilReadOnly WIN32PC_ONLY(, ms_DepthBuffer_ReadOnly) );
|
||
|
|
||
|
#if PTFX_APPLY_DOF_TO_PARTICLES
|
||
|
if (CPtFxManager::UseParticleDOF())
|
||
|
{
|
||
|
// grcTextureFactory::CreateParams params;
|
||
|
|
||
|
const int ptfxDepthbpp = 16;
|
||
|
const grcTextureFormat ptfxDepthFormat = grctfR16F;
|
||
|
|
||
|
const int ptfxAlphabpp = 8;
|
||
|
const grcTextureFormat ptfxAlphaFormat = grctfL8;
|
||
|
const grcRenderTargetType type = grcrtPermanent;
|
||
|
|
||
|
multisample = GRCDEVICE.GetMSAA();
|
||
|
params.Multisample = multisample;
|
||
|
#if DEVICE_EQAA
|
||
|
multisample.DisableCoverage();
|
||
|
params.ForceFragmentMask = false;
|
||
|
params.SupersampleFrequency = multisample.m_uFragments;
|
||
|
#else // DEVICE_EQAA
|
||
|
u32 multisampleQuality = GRCDEVICE.GetMSAAQuality();
|
||
|
params.MultisampleQuality = (u8)multisampleQuality;
|
||
|
#endif // DEVICE_EQAA
|
||
|
|
||
|
//Create as an MSAA render target as its bound as a secondary target alongside the MSAA backbuffer. May be able to get around this on PS4 and Xbox?
|
||
|
//Also using RGBA format even though only need R and A channels. Needs to be R and A as different blends to both, isnt a target that has just R and A, might be better having 2 targets.
|
||
|
//added bug url:bugstar:1852743 to look at this.
|
||
|
params.Format = ptfxDepthFormat;
|
||
|
CreateRenderTarget("PARTICLE_DEPTH_MAP", type, iWidth, iHeight, ptfxDepthbpp, ¶ms);
|
||
|
|
||
|
params.Format = ptfxAlphaFormat;
|
||
|
CreateRenderTarget("PARTICLE_ALPHA_MAP", type, iWidth, iHeight, ptfxAlphabpp, ¶ms);
|
||
|
}
|
||
|
#endif //PTFX_APPLY_DOF_TO_PARTICLES
|
||
|
|
||
|
}
|
||
|
|
||
|
void calculateGBufferRenderTargetSize(Settings &settings)
|
||
|
{
|
||
|
int iWidth = settings.m_video.m_ScreenWidth;
|
||
|
int iHeight = settings.m_video.m_ScreenHeight;
|
||
|
#if RSG_PC
|
||
|
applySceneScale(settings.m_graphics.m_SamplingMode, iWidth, iHeight);
|
||
|
#endif
|
||
|
u32 bitsPerPixel = 32;
|
||
|
|
||
|
grcTextureFactory::CreateParams Params;
|
||
|
grcDevice::MSAAMode multisample = settings.m_graphics.m_MSAA;
|
||
|
Params.Multisample = multisample;
|
||
|
|
||
|
#if DEVICE_EQAA
|
||
|
bool needFmask = GRCDEVICE.IsEQAA();
|
||
|
Params.ForceFragmentMask = needFmask;
|
||
|
Params.SupersampleFrequency = multisample.m_uFragments;
|
||
|
#else // DEVICE_EQAA
|
||
|
u32 multisampleQuality = GRCDEVICE.GetMSAAQuality();
|
||
|
Params.MultisampleQuality = (u8)multisampleQuality;
|
||
|
#endif // DEVICE_EQAA
|
||
|
CreateRenderTarget("GBUFFER_0", grcrtPermanent, iWidth, iHeight, bitsPerPixel, &Params);
|
||
|
CreateRenderTarget("GBUFFER_1", grcrtPermanent, iWidth, iHeight, bitsPerPixel, &Params);
|
||
|
CreateRenderTarget("GBUFFER_3", grcrtPermanent, iWidth, iHeight, bitsPerPixel, &Params);
|
||
|
CreateRenderTarget("GBUFFER_2", grcrtPermanent, iWidth, iHeight, bitsPerPixel, &Params);
|
||
|
}
|
||
|
|
||
|
void calculateCascadeShadowsRenderTargetSize(Settings &settings)
|
||
|
{
|
||
|
s32 iWidth = settings.m_video.m_ScreenWidth;
|
||
|
s32 iHeight = settings.m_video.m_ScreenHeight;
|
||
|
#if RSG_PC
|
||
|
applySceneScale(settings.m_graphics.m_SamplingMode, iWidth, iHeight);
|
||
|
#endif
|
||
|
int res = 0;
|
||
|
if (!PARAM_dx11shadowres.Get(res))
|
||
|
{
|
||
|
#define SHADOW_RES_BASELINE 256
|
||
|
res = settings.m_graphics.m_ShadowQuality >=3 && settings.m_graphics.m_UltraShadows_Enabled ? 4096 : SHADOW_RES_BASELINE << settings.m_graphics.m_ShadowQuality;
|
||
|
if (settings.m_graphics.m_ShadowQuality == (CSettings::eSettingsLevel) (0)) res = 1;
|
||
|
}
|
||
|
|
||
|
const int shadowResX = res;
|
||
|
#if CASCADE_SHADOW_TEXARRAY
|
||
|
const int shadowResY = res;
|
||
|
#else
|
||
|
const int shadowResY = res*CASCADE_SHADOWS_COUNT;
|
||
|
#endif
|
||
|
|
||
|
if (1) // create depth target (shadow texture)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
int bpp = 32;
|
||
|
|
||
|
const grcRenderTargetType type = (RSG_PC || RSG_DURANGO /*|| RSG_ORBIS*/) ? grcrtPermanent : grcrtShadowMap;
|
||
|
|
||
|
#if CASCADE_SHADOW_TEXARRAY
|
||
|
params.ArraySize = 4;
|
||
|
params.PerArraySliceRTV = CRenderPhaseCascadeShadowsInterface::IsInstShadowEnabled() ? 0 : params.ArraySize;
|
||
|
#endif
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_DEPTH", type, shadowResX, shadowResY, bpp, ¶ms);
|
||
|
|
||
|
#if RMPTFX_USE_PARTICLE_SHADOWS
|
||
|
// m_shadowMapReadOnly = textureFactory11.CreateRenderTarget("SHADOW_MAP_CSM_DEPTH", m_shadowMapBase->GetTexturePtr(), params.Format, DepthStencilReadOnly, NULL, ¶ms);
|
||
|
#endif // RMPTFX_USE_PARTICLE_SHADOWS && __D3D11
|
||
|
|
||
|
#if CASCADE_SHADOW_TEXARRAY
|
||
|
params.ArraySize = 1;
|
||
|
params.PerArraySliceRTV = 0;
|
||
|
#endif
|
||
|
|
||
|
const int resX = CASCADE_SHADOWS_RES_MINI_X;
|
||
|
const int resY = CASCADE_SHADOWS_RES_MINI_Y;
|
||
|
|
||
|
if (resX != 0 && resY != 0)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
int bpp = 0;
|
||
|
bpp = 32;
|
||
|
|
||
|
const grcRenderTargetType type = PS3_SWITCH(grcrtShadowMap, grcrtPermanent);
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_MINI", type, resX, resY, bpp, ¶ms);
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_MINI 2", type, resX, resY * 4, bpp, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if 0 //CSM_USE_DUMMY_COLOUR_TARGET
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
const int bpp = 32;
|
||
|
const grcRenderTargetType type = grcrtPermanent;
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_DUMMY", type, shadowResX, shadowResY, bpp, ¶ms);
|
||
|
}
|
||
|
#endif // CSM_USE_DUMMY_COLOUR_TARGET
|
||
|
|
||
|
#if RMPTFX_USE_PARTICLE_SHADOWS
|
||
|
if (settings.m_graphics.m_ShadowQuality != (CSettings::eSettingsLevel) (0))
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
const int bpp = 32;
|
||
|
const grcRenderTargetType type = grcrtPermanent;
|
||
|
#if CASCADE_SHADOW_TEXARRAY
|
||
|
params.ArraySize = 4;
|
||
|
params.PerArraySliceRTV = CRenderPhaseCascadeShadowsInterface::IsInstShadowEnabled() ? 0 : params.ArraySize;
|
||
|
#endif
|
||
|
CreateRenderTarget("SHADOW_MAP_PARTICLES", type, shadowResX, shadowResY, bpp, ¶ms);
|
||
|
#if CASCADE_SHADOW_TEXARRAY
|
||
|
params.ArraySize = 1;
|
||
|
params.PerArraySliceRTV = 0;
|
||
|
#endif
|
||
|
}
|
||
|
#endif // RMPTFX_USE_PARTICLE_SHADOWS
|
||
|
|
||
|
#if CASCADE_SHADOWS_ENTITY_ID_TARGET && ENTITYSELECT_ENABLED_BUILD
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
const int bpp = 32; // could be 32 or 16
|
||
|
const grcRenderTargetType type = grcrtPermanent;
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_ENTITY_ID", type, shadowResX, shadowResY, bpp, ¶ms);
|
||
|
}
|
||
|
#endif // CASCADE_SHADOWS_ENTITY_ID_TARGET && ENTITYSELECT_ENABLED_BUILD
|
||
|
|
||
|
#if CASCADE_SHADOWS_DO_SOFT_FILTERING
|
||
|
if ((settings.m_graphics.m_ShaderQuality != CSettings::Low) && (settings.m_graphics.m_Shadow_SoftShadows != CSettings::Low) &&
|
||
|
(settings.m_graphics.m_Shadow_SoftShadows != CSettings::Custom) && (settings.m_graphics.m_Shadow_SoftShadows != CSettings::Special))
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
const int bpp = 8;
|
||
|
params.Multisample = GRCDEVICE.GetMSAA();
|
||
|
# if DEVICE_EQAA
|
||
|
params.Multisample.DisableCoverage();
|
||
|
# else
|
||
|
params.MultisampleQuality = (u8)GRCDEVICE.GetMSAAQuality();
|
||
|
# endif // DEVICE_EQAA
|
||
|
|
||
|
const grcRenderTargetType type = grcrtPermanent;
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_SOFT_SHADOW_INTERMEDIATE1", type, iWidth, iHeight, bpp, ¶ms);
|
||
|
|
||
|
params.Multisample = 0;
|
||
|
|
||
|
#if DEVICE_MSAA
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_SOFT_SHADOW_INTERMEDIATE1_RESOLVED", type, iWidth, iHeight, bpp, ¶ms);
|
||
|
#endif //DEVICE_MSAA
|
||
|
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_SOFT_SHADOW_EARLY_OUT1", type, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
//
|
||
|
CreateRenderTarget("SHADOW_MAP_CSM_SOFT_SHADOW_EARLY_OUT2", type, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
}
|
||
|
#endif // CASCADE_SHADOWS_DO_SOFT_FILTERING
|
||
|
|
||
|
{
|
||
|
#define smoothStepRTSize 128
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Format = grctfL8;
|
||
|
|
||
|
CreateRenderTarget("Smooth Step RT", grcrtPermanent, smoothStepRTSize, 1, 8, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void calcualteUIRenderTargetSize(Settings &settings)
|
||
|
{
|
||
|
int rt_Width = settings.m_video.m_ScreenWidth / 2;
|
||
|
int rt_Height = settings.m_video.m_ScreenHeight / 2;
|
||
|
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
|
||
|
// Depth buffer
|
||
|
params.Format = grctfD24S8;
|
||
|
params.IsResolvable = true;
|
||
|
params.Multisample = 0;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
CreateRenderTarget("UI Depth Buffer", grcrtDepthBuffer, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// Readonly
|
||
|
#if RSG_PC
|
||
|
// GBuffer 0
|
||
|
params.IsResolvable = false;
|
||
|
params.HasParent = true;
|
||
|
|
||
|
if(GRCDEVICE.IsReadOnlyDepthAllowed())
|
||
|
{
|
||
|
CreateRenderTarget("UI Depth Buffer Only", grcrtDepthBuffer, rt_Width, rt_Height, 32, ¶ms);
|
||
|
} else
|
||
|
CreateRenderTarget("UI Depth Buffer Copy", grcrtDepthBuffer, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
params.IsResolvable = true;
|
||
|
#endif // RSG_PC
|
||
|
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
CreateRenderTarget("UI Depth Buffer Alias", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// Light buffer
|
||
|
#if RSG_PC
|
||
|
if (settings.m_graphics.m_ShaderQuality == (CSettings::eSettingsLevel) (0))
|
||
|
params.Format = grctfA2B10G10R10ATI;
|
||
|
else
|
||
|
params.Format = grctfA16B16G16R16F;
|
||
|
#else
|
||
|
params.Format = grctfA16B16G16R16F;
|
||
|
#endif
|
||
|
params.UseFloat = true;
|
||
|
params.IsResolvable = true;
|
||
|
params.HasParent = true;
|
||
|
|
||
|
CreateRenderTarget("UI Deferred Light Buffer", grcrtPermanent, rt_Width, rt_Height, params.Format == grctfA16B16G16R16F ? 64:32, ¶ms);
|
||
|
|
||
|
#if RSG_PC
|
||
|
CreateRenderTarget("UI Deferred Light Buffer Copy", grcrtPermanent, rt_Width, rt_Height, 64, ¶ms);
|
||
|
#endif // RSG_PC
|
||
|
|
||
|
// Composite Buffer 0
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
params.UseFloat = false;
|
||
|
params.IsSRGB = false;
|
||
|
|
||
|
CreateRenderTarget("UI Deferred Composite Buffer", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// Composite Buffer 1
|
||
|
CreateRenderTarget("UI Deferred Composite Lum Buffer", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
#if RSG_PC
|
||
|
CreateRenderTarget("UI Deferred Composite Lum Buffer Copy", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
#endif // RSG_PC
|
||
|
|
||
|
// GBuffer 0
|
||
|
CreateRenderTarget("UI Deferred Buffer 0", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// GBuffer 1
|
||
|
CreateRenderTarget("UI Deferred Buffer 1", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// GBuffer 2
|
||
|
CreateRenderTarget("UI Deferred Buffer 2", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
// GBuffer 3
|
||
|
CreateRenderTarget("UI Deferred Buffer 3", grcrtPermanent, rt_Width, rt_Height, 32, ¶ms);
|
||
|
|
||
|
}
|
||
|
|
||
|
void calculateParaboloidShadowRenderTargetsSize(Settings &settings)
|
||
|
{
|
||
|
int res;
|
||
|
if (settings.m_graphics.m_ShadowQuality == (CSettings::eSettingsLevel) (0))
|
||
|
res = 1;
|
||
|
else
|
||
|
res = (settings.m_graphics.m_ShadowQuality < 2) ? 256 : 512;
|
||
|
|
||
|
int bpp = 16;
|
||
|
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
|
||
|
params.Multisample = grcDevice::MSAA_None;
|
||
|
|
||
|
#if USE_LOCAL_LIGHT_SHADOW_TEXTURE_ARRAYS
|
||
|
char name[256];
|
||
|
for (int i = 0; i < MAX_CACHED_PARABOLOID_SHADOWS; i++)
|
||
|
{
|
||
|
int cmRes = Max(res/(CParaboloidShadow::IsCacheEntryHighRes(i)?1:2), 1);
|
||
|
|
||
|
formatf(name,256,"POINT_SHADOW_%02d",i);
|
||
|
|
||
|
CreateRenderTarget(name, grcrtCubeMap, cmRes, cmRes, bpp, ¶ms);
|
||
|
|
||
|
// extra one that is 2x for spot light shadows, this should over lap the 6, but I don't know how to do that on win32
|
||
|
formatf(name,256,"SPOT_SHADOW_%02d",i);
|
||
|
CreateRenderTarget(name, grcrtPermanent, cmRes*2, cmRes*3, bpp, ¶ms);
|
||
|
}
|
||
|
#else
|
||
|
char nameBuffer[256];
|
||
|
|
||
|
int loRes = Max(1, res/2);
|
||
|
|
||
|
u32 count = MAX_STATIC_CACHED_LORES_PARABOLOID_SHADOWS+MAX_ACTIVE_LORES_PARABOLOID_SHADOWS+MAX_ACTIVE_LORES_OVERLAPPING;
|
||
|
for (int i=0;i<count;i++)
|
||
|
{
|
||
|
params.ArraySize = (u8)6;
|
||
|
params.PerArraySliceRTV = params.ArraySize;
|
||
|
|
||
|
formatf(nameBuffer, 256, "POINT_SHADOW_%s_%d","LORES",i);
|
||
|
|
||
|
CreateRenderTarget(nameBuffer, RSG_ORBIS?grcrtDepthBufferCubeMap:grcrtCubeMap, loRes, loRes, bpp, ¶ms);
|
||
|
|
||
|
// TODO: this could overlap with the cubemap version above
|
||
|
params.ArraySize = (u8)1;
|
||
|
params.PerArraySliceRTV = params.ArraySize;
|
||
|
|
||
|
formatf(nameBuffer, 256, "SPOT_SHADOW_%s_%d","LORES",i);
|
||
|
|
||
|
CreateRenderTarget(nameBuffer, RSG_ORBIS?grcrtShadowMap:grcrtPermanent, loRes*2, loRes*3, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
|
||
|
count = MAX_STATIC_CACHED_HIRES_PARABOLOID_SHADOWS+MAX_ACTIVE_HIRES_PARABOLOID_SHADOWS;
|
||
|
for (int i=0;i<count;i++)
|
||
|
{
|
||
|
params.ArraySize = (u8)6;
|
||
|
params.PerArraySliceRTV = params.ArraySize;
|
||
|
|
||
|
formatf(nameBuffer, 256, "POINT_SHADOW_%s_%d","HIRES",i);
|
||
|
|
||
|
CreateRenderTarget(nameBuffer, RSG_ORBIS?grcrtDepthBufferCubeMap:grcrtCubeMap, res, res, bpp, ¶ms);
|
||
|
|
||
|
// TODO: this could overlap with the cubemap version above
|
||
|
params.ArraySize = (u8)1;
|
||
|
params.PerArraySliceRTV = params.ArraySize;
|
||
|
|
||
|
formatf(nameBuffer, 256, "SPOT_SHADOW_%s_%d","HIRES",i);
|
||
|
|
||
|
CreateRenderTarget(nameBuffer, RSG_ORBIS?grcrtShadowMap:grcrtPermanent, res*2, res*3, bpp, ¶ms);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void calculateSSAORenderTargetsSize(Settings &settings)
|
||
|
{
|
||
|
#define SSOAPositionSize 16
|
||
|
#define SSAODitherSize 32
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
CreateRenderTarget( "SSAO Dither", grcrtPermanent, SSAODitherSize, SSAODitherSize, 32, ¶ms);
|
||
|
|
||
|
CreateRenderTarget( "SSAO Position", grcrtPermanent, SSOAPositionSize, SSOAPositionSize, 64, ¶ms);
|
||
|
|
||
|
s32 width = settings.m_video.m_ScreenWidth;
|
||
|
s32 height = settings.m_video.m_ScreenHeight;
|
||
|
#if RSG_PC
|
||
|
applySceneScale(settings.m_graphics.m_SamplingMode, width, height);
|
||
|
#endif
|
||
|
|
||
|
#if __WIN32PC
|
||
|
params.StereoRTMode = grcDevice::STEREO;
|
||
|
#endif
|
||
|
CreateRenderTarget( "SSAO 0", grcrtPermanent, width/2, height/2, 8, ¶ms);
|
||
|
CreateRenderTarget( "SSAO 1", grcrtPermanent, width/2, height/2, 8, ¶ms);
|
||
|
|
||
|
CreateRenderTarget( "CP/QS mix SSAO final", grcrtPermanent, width, height, 8, ¶ms);
|
||
|
|
||
|
#if SSAO_USE_LINEAR_DEPTH_TARGETS
|
||
|
params.Format = grctfR32F;
|
||
|
|
||
|
params.StereoRTMode = grcDevice::MONO;
|
||
|
|
||
|
CreateRenderTarget( "SSAO Full Screen linear", grcrtPermanent, width, height, 32, ¶ms);
|
||
|
|
||
|
#endif // SSAO_USE_LINEAR_DEPTH_TARGETS
|
||
|
|
||
|
|
||
|
#if SUPPORT_MRSSAO
|
||
|
|
||
|
if (__DEV)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
params.Format = grctfR32F;
|
||
|
|
||
|
grcTextureFactory::CreateParams paramsNormalTexture;
|
||
|
paramsNormalTexture.HasParent = true;
|
||
|
paramsNormalTexture.Parent = NULL;
|
||
|
paramsNormalTexture.Format = MR_SSAO_USE_PACKED_NORMALS ? grctfR32F : grctfA8R8G8B8;
|
||
|
|
||
|
const unsigned screenWidth = width;
|
||
|
const unsigned screenHeight = height;
|
||
|
|
||
|
for(int i=0; i<MRSSAO_NUM_RESOLUTIONS; i++)
|
||
|
{
|
||
|
char DepthName[256];
|
||
|
char NormalName[256];
|
||
|
char AOName[256];
|
||
|
char BlurredAOName[256];
|
||
|
char PosXName[256];
|
||
|
char PosYName[256];
|
||
|
|
||
|
sprintf(DepthName, "SSAO Viewspace positions LOD %d", i);
|
||
|
sprintf(NormalName, "SSAO Normal LOD %d", i);
|
||
|
sprintf(AOName, "SSAO AO LOD %d", i);
|
||
|
sprintf(BlurredAOName, "Blurred SSAO AO LOD %d", i);
|
||
|
sprintf(PosXName, "SSAO Position X LOD %d", i);
|
||
|
sprintf(PosYName, "SSAO Position Y LOD %d", i);
|
||
|
|
||
|
if(i==0)
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
params.Format = grctfR32F;
|
||
|
|
||
|
if(i!=1)
|
||
|
{
|
||
|
CreateRenderTarget(DepthName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Use the console half-size depth buffer.
|
||
|
}
|
||
|
|
||
|
CreateRenderTarget(NormalName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶msNormalTexture);
|
||
|
|
||
|
CreateRenderTarget(PosXName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
|
||
|
CreateRenderTarget(PosYName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
}
|
||
|
|
||
|
#ifdef MR_SSAO_USE_FULL_COLOUR_TARGETS
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
#else
|
||
|
params.Format = grctfL8;
|
||
|
#endif
|
||
|
|
||
|
if(i==0)
|
||
|
{
|
||
|
#define MR_SSAO_FORCE_MAX_LOD1 0
|
||
|
#if MR_SSAO_FORCE_MAX_LOD1
|
||
|
m_AOs[i] = NULL;
|
||
|
m_BlurredAOs[i] = NULL;
|
||
|
#else //MR_SSAO_FORCE_MAX_LOD1
|
||
|
|
||
|
CreateRenderTarget(AOName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
|
||
|
#define MR_SSAO_BLUR_TO_TARGET 1
|
||
|
#if !MR_SSAO_BLUR_TO_TARGET || MR_SSAO_CONFIGURE_FOR_GET_SSAO_TEXTURE
|
||
|
CreateRenderTarget(BlurredAOName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
#endif // !MR_SSAO_BLUR_TO_TARGET || MR_SSAO_CONFIGURE_FOR_GET_SSAO_TEXTURE
|
||
|
|
||
|
#endif //MR_SSAO_FORCE_MAX_LOD1
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CreateRenderTarget(AOName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
|
||
|
CreateRenderTarget(BlurredAOName, grcrtPermanent, screenWidth >> i, screenHeight >> i, 32, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif //SUPPORT_MRSSAO
|
||
|
|
||
|
|
||
|
if (__DEV)
|
||
|
{
|
||
|
int HDAOwidth = width >> 1;
|
||
|
int HDAOheight = height >> 1;
|
||
|
int bpp = 32;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
params.Format = grctfR11G11B10F;
|
||
|
CreateRenderTarget( "HDAO2_Normal", grcrtPermanent, HDAOwidth, HDAOheight, bpp, ¶ms);
|
||
|
params.Format = SSAO_OUTPUT_DEPTH ? grctfD24S8 : grctfR32F;
|
||
|
CreateRenderTarget( "HDAO2_Depth", SSAO_OUTPUT_DEPTH ? grcrtDepthBuffer : grcrtPermanent, HDAOwidth, HDAOheight, bpp, ¶ms);
|
||
|
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
if (settings.m_graphics.m_MSAA > 1) CreateRenderTarget( "HDAO2_GBuffer1_Resolved", grcrtPermanent, width, height, bpp, ¶ms);
|
||
|
|
||
|
if (settings.m_graphics.m_MSAA>1 && HDAO2_MULTISAMPLE_FILTER)
|
||
|
{
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
bpp = 32;
|
||
|
}else
|
||
|
{
|
||
|
params.Format = grctfL8;
|
||
|
bpp = 8;
|
||
|
}
|
||
|
|
||
|
params.UseAsUAV = true;
|
||
|
CreateRenderTarget( "HDAO2_Result", grcrtPermanent, HDAOwidth, HDAOheight, bpp, ¶ms);
|
||
|
CreateRenderTarget( "HDAO2_Temp1", grcrtPermanent, width, height, bpp, ¶ms);
|
||
|
CreateRenderTarget( "HDAO2_Temp2", grcrtPermanent, width, height, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
#if SUPPORT_HBAO
|
||
|
if (SSAO::UseNextGeneration(settings))
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.HasParent = true;
|
||
|
// params.Parent = GBuffer::GetTarget(GBUFFER_RT_3);
|
||
|
params.AllocateFromPoolOnCreate = false;
|
||
|
params.Format = grctfL8;
|
||
|
CreateRenderTarget( "SSAO Continuity mask", grcrtPermanent, width/2, height/2, 8, ¶ms);
|
||
|
CreateRenderTarget( "SSAO Continuity mask Dilated", grcrtPermanent, width/2, height/2, 8, ¶ms);
|
||
|
params.Format = grctfG16R16F;
|
||
|
|
||
|
if (((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount() == 1)
|
||
|
{
|
||
|
CreateRenderTarget( "SSAO History", grcrtPermanent, width/2, height/2, 32, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int GetMirrorResolutionSetting(Settings &settings) {
|
||
|
// #define MIRROR_REFLECTION_RES_BASELINE 128
|
||
|
// return MIRROR_REFLECTION_RES_BASELINE << CSettingsManager::GetInstance().GetSettings().m_graphics.m_ReflectionQuality;
|
||
|
/*int reflectionQuality = settings.m_graphics.m_ReflectionQuality;
|
||
|
|
||
|
int reflectionSizeX = Max(32, settings.m_video.m_ScreenWidth / (1 << (3 - Min(3, reflectionQuality))));
|
||
|
int reflectionSizeY = Max(32, settings.m_video.m_ScreenHeight / (1 << (3 - Min(3, reflectionQuality))));
|
||
|
u32 dimension = (u32) rage::Sqrtf((float)(reflectionSizeX * reflectionSizeY));
|
||
|
u32 iMipLevels = 0;
|
||
|
while (dimension)
|
||
|
{
|
||
|
dimension >>= 1;
|
||
|
iMipLevels++;
|
||
|
}
|
||
|
iMipLevels--;
|
||
|
|
||
|
return 1 << iMipLevels;
|
||
|
*/
|
||
|
bool s_requirePowerOf2 = false;
|
||
|
|
||
|
int reflectionQuality = settings.m_graphics.m_ReflectionQuality;
|
||
|
int reflectionSize = Max(32, (settings.m_video.m_ScreenWidth+settings.m_video.m_ScreenHeight) >> (4 - Min(3, reflectionQuality)));
|
||
|
|
||
|
if (s_requirePowerOf2)
|
||
|
{
|
||
|
u32 closestPow2Size = 32;
|
||
|
while (reflectionSize > 3*closestPow2Size/2)
|
||
|
closestPow2Size <<= 1;
|
||
|
return closestPow2Size;
|
||
|
}else
|
||
|
{
|
||
|
return reflectionSize & ~0xF;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void calculateMirrorRenderTargetSizes(Settings &settings)
|
||
|
{
|
||
|
#define MIRROR_RT_NAME "MIRROR_RT"
|
||
|
#define MIRROR_DT_NAME "MIRROR_DT"
|
||
|
#define MIRROR_DT_NAME_RO "MIRROR_DT_READ_ONLY"
|
||
|
#define MIRROR_DT_NAME_COPY "MIRROR_DT_COPY"
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
|
||
|
const int mirrorResX = GetMirrorResolutionSetting(settings);
|
||
|
const int mirrorResY = mirrorResX / 2;
|
||
|
|
||
|
int tbpp = 64;
|
||
|
if (!PARAM_highColorPrecision.Get())
|
||
|
{
|
||
|
tbpp = 32;
|
||
|
}
|
||
|
|
||
|
CreateRenderTarget(MIRROR_RT_NAME, grcrtPermanent, mirrorResX, mirrorResY, tbpp, ¶ms);
|
||
|
|
||
|
int depthBpp = 40;
|
||
|
|
||
|
CreateRenderTarget(MIRROR_DT_NAME, grcrtDepthBuffer, mirrorResX, mirrorResY, depthBpp, ¶ms);
|
||
|
|
||
|
if (GRCDEVICE.IsReadOnlyDepthAllowed())
|
||
|
{
|
||
|
// CreateRenderTarget(MIRROR_DT_NAME_RO, ms_pDepthTarget->GetTexturePtr(), params.Format, DepthStencilReadOnly);
|
||
|
}
|
||
|
else
|
||
|
CreateRenderTarget(MIRROR_DT_NAME_COPY, grcrtDepthBuffer, mirrorResX, mirrorResY, depthBpp, NULL);
|
||
|
}
|
||
|
|
||
|
void calculateWaterRenderTargetsSizes(Settings &settings)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams createParams;
|
||
|
createParams.StereoRTMode = grcDevice::STEREO;
|
||
|
|
||
|
//Changing the resolution of these targets breaks the fog shadows.
|
||
|
//Not sure if we want them at lower resolutions so disabling for now.
|
||
|
bool m_EnableWaterLighting = settings.m_graphics.m_WaterQuality != (CSettings::eSettingsLevel) (0);
|
||
|
|
||
|
u32 resWidth = settings.m_video.m_ScreenWidth / 2;
|
||
|
u32 resHeight = settings.m_video.m_ScreenHeight / 2;
|
||
|
|
||
|
if (m_EnableWaterLighting)
|
||
|
{
|
||
|
CreateRenderTarget("Water Fog+Shadow", grcrtPermanent, resWidth, resHeight, 32, &createParams);
|
||
|
CreateRenderTarget("Water Fog+Shadow 1/4", grcrtPermanent, resWidth/2, resHeight/2, 32, &createParams);
|
||
|
CreateRenderTarget("Water Fog+Shadow 1/16 Temp", grcrtPermanent, resWidth/4, resHeight/4, 32, &createParams);
|
||
|
CreateRenderTarget("Water Fog+Shadow 1/16", grcrtPermanent, resWidth/4, resHeight/4, 32, &createParams);\
|
||
|
CreateRenderTarget("Water Params", grcrtPermanent, resWidth, resHeight, 32, &createParams);
|
||
|
|
||
|
CreateRenderTarget("Water Refraction Mask", grcrtPermanent, resWidth/2, resHeight/2, 32, &createParams);
|
||
|
|
||
|
CreateRenderTarget("Water Refraction Depth", grcrtDepthBuffer, resWidth, resHeight, 32, &createParams);
|
||
|
}
|
||
|
|
||
|
CreateRenderTarget("Water Refraction", grcrtPermanent, resWidth, resHeight, 32, &createParams);
|
||
|
|
||
|
#if 1 //WATER_TILED_LIGHTING
|
||
|
grcTextureFactory::CreateParams classificationParams;
|
||
|
classificationParams.Format = grctfA8R8G8B8;
|
||
|
|
||
|
u32 tileSize = settings.m_graphics.m_MSAA > 4 ? 8 : 16;
|
||
|
u32 numTilesX = (settings.m_video.m_ScreenWidth + tileSize - 1) / tileSize;
|
||
|
u32 numTilesY = (settings.m_video.m_ScreenHeight + tileSize - 1) / tileSize;
|
||
|
|
||
|
CreateRenderTarget("Water Classification", grcrtPermanent, numTilesX, numTilesY, 32, &classificationParams);
|
||
|
#endif //WATER_TILED_LIGHTING
|
||
|
|
||
|
}
|
||
|
|
||
|
void calculatePedDamageRenderTargetSizes(Settings &settings)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Multisample = 0;
|
||
|
int bpp = 32;
|
||
|
|
||
|
int iTargetSizeW, iTargetSizeH;
|
||
|
|
||
|
u32 dimension = (u32) rage::Sqrtf((float)(settings.m_video.m_ScreenWidth * settings.m_video.m_ScreenHeight));
|
||
|
|
||
|
s32 iMipLevels = 0;
|
||
|
while (dimension)
|
||
|
{
|
||
|
dimension >>= 1;
|
||
|
iMipLevels++;
|
||
|
}
|
||
|
iMipLevels = Max(1, (iMipLevels - 8));
|
||
|
iTargetSizeW = Min((int)(CPedDamageSetBase::kTargetSizeW / 4) * iMipLevels, (int)CPedDamageSetBase::kTargetSizeW);
|
||
|
iTargetSizeH = Min((int)(CPedDamageSetBase::kTargetSizeH / 4) * iMipLevels, (int)CPedDamageSetBase::kTargetSizeH);
|
||
|
|
||
|
int vSize = iTargetSizeW*2; // swap the width and height to take advantage of the ps3 Stride
|
||
|
int hSize = iTargetSizeH*2;
|
||
|
|
||
|
char targetName[256] = "\0";
|
||
|
|
||
|
// allocate high resolution render targets for the player only damage and decorations
|
||
|
for (int i=0;i<kMaxHiResBloodRenderTargets;i++)
|
||
|
{
|
||
|
formatf(targetName,sizeof(targetName),"BloodTargetHiRes%d",i);
|
||
|
CreateRenderTarget(targetName, grcrtPermanent, hSize, vSize, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
hSize = iTargetSizeH; // Side ways makes it more like the ps3 targets (except the last 2)
|
||
|
vSize = iTargetSizeW;
|
||
|
|
||
|
// allocate medium resolution render targets
|
||
|
for (int i=0;i<kMaxMedResBloodRenderTargets;i++)
|
||
|
{
|
||
|
formatf(targetName,sizeof(targetName),"BloodTargetMedRes%d",i);
|
||
|
CreateRenderTarget(targetName, grcrtPermanent, hSize, vSize, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
// allocate low resolution render targets (these overlap with the medium res targets...)
|
||
|
hSize = iTargetSizeH/2;
|
||
|
vSize = iTargetSizeW/2;
|
||
|
|
||
|
for (int i=0;i<kMaxLowResBloodRenderTargets;i++)
|
||
|
{
|
||
|
formatf(targetName,sizeof(targetName),"BloodTargetLowRes%d",i);
|
||
|
CreateRenderTarget(targetName, grcrtPermanent, hSize, vSize, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
hSize = iTargetSizeH/2; // side ways small, so 2 can fit side by side
|
||
|
vSize = iTargetSizeW/2;
|
||
|
|
||
|
CreateRenderTarget("PedMirrorDepth", grcrtDepthBuffer, hSize*2, vSize, 32, ¶ms);
|
||
|
|
||
|
CreateRenderTarget("Mirror Ped Decoration Target", grcrtPermanent, hSize*2, vSize, bpp, ¶ms);
|
||
|
|
||
|
int rotatedDepthTargetWidth = iTargetSizeH;
|
||
|
int rotatedDepthTargetHeight = iTargetSizeW;
|
||
|
|
||
|
CreateRenderTarget("PedDamageLowResDepth", grcrtDepthBuffer, rotatedDepthTargetWidth/2, rotatedDepthTargetHeight/2, 32, ¶ms);
|
||
|
CreateRenderTarget("PedDamageMedResDepth", grcrtDepthBuffer, rotatedDepthTargetWidth, rotatedDepthTargetHeight, 32, ¶ms);
|
||
|
CreateRenderTarget("PedDamageHiResDepth", grcrtDepthBuffer, iTargetSizeH*2, iTargetSizeW*2, 32, ¶ms);
|
||
|
|
||
|
{
|
||
|
bool m_bEnableHiresCompressedDecorations = true;//PEDDECORATIONBUILDER.IsUsingHiResCompressedMPDecorations();
|
||
|
|
||
|
/* u32 dimension = (u32) rage::Sqrtf((float)(settings.m_video.m_ScreenWidth * settings.m_video.m_ScreenHeight));
|
||
|
float dimensionResolution = 0;
|
||
|
if (dimension < 900)
|
||
|
{
|
||
|
dimensionResolution = ((float)(m_bEnableHiresCompressedDecorations?2:1))/4;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32 iMipLevels = 0;
|
||
|
while (dimension)
|
||
|
{
|
||
|
dimension >>= 1;
|
||
|
iMipLevels++;
|
||
|
}
|
||
|
iMipLevels -= 10;
|
||
|
|
||
|
if (iMipLevels == 0)
|
||
|
{
|
||
|
dimensionResolution = ((float)(m_bEnableHiresCompressedDecorations?2:1))/2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dimensionResolution = ((float)(m_bEnableHiresCompressedDecorations?2:1))*iMipLevels;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 compWidth = (u32)(CompressedDecorationBuilder::kDecorationTargetWidth * dimensionResolution);
|
||
|
u32 compHeight = (u32)(CompressedDecorationBuilder::kDecorationTargetHeight * dimensionResolution);
|
||
|
*/
|
||
|
|
||
|
u32 compHeight = (m_bEnableHiresCompressedDecorations?CompressedDecorationBuilder::kDecorationHiResTargetRatio:1)*CompressedDecorationBuilder::kDecorationTargetHeight;
|
||
|
if (settings.m_graphics.m_TextureQuality == 0) compHeight = compHeight >> 1;
|
||
|
else if (settings.m_graphics.m_TextureQuality >1) compHeight = compHeight << 1;
|
||
|
|
||
|
u32 compWidth = (m_bEnableHiresCompressedDecorations?CompressedDecorationBuilder::kDecorationHiResTargetRatio:1)*CompressedDecorationBuilder::kDecorationTargetWidth;
|
||
|
if (settings.m_graphics.m_TextureQuality == 0) compWidth = compWidth >> 1;
|
||
|
else if (settings.m_graphics.m_TextureQuality >1) compWidth = compWidth << 1;
|
||
|
|
||
|
|
||
|
// u32 compWidth = (u32)(m_bEnableHiresCompressedDecorations?2:1)*CompressedDecorationBuilder::kDecorationTargetWidth;
|
||
|
// u32 compHeight = (u32)(m_bEnableHiresCompressedDecorations?2:1)*CompressedDecorationBuilder::kDecorationTargetHeight;
|
||
|
|
||
|
CreateRenderTarget("PedDamagedCompressedDepth", grcrtDepthBuffer, compWidth, compHeight, 32, ¶ms);
|
||
|
|
||
|
/*
|
||
|
These don't get re-created
|
||
|
if (!CompressedDecorationBuilder::IsUsingUncompressedMPDecorations())
|
||
|
{
|
||
|
CreateRenderTarget("CompressedDecorationBuilder", grcrtPermanent, compWidth, compHeight, CompressedDecorationBuilder::kDecorationTargetBpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
if (m_bEnableHiresCompressedDecorations)
|
||
|
{
|
||
|
for (int i = 0; i < kMaxCompressedTextures; i++)
|
||
|
{
|
||
|
char name[RAGE_MAX_PATH];
|
||
|
formatf(name,RAGE_MAX_PATH,"tat_rt_%03d_a_uni_hires", i);
|
||
|
CreateRenderTarget(name, grcrtDepthBuffer, compWidth, compHeight, 32, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void calculatePhoneMgrRenderTargetSizes(Settings &settings)
|
||
|
{
|
||
|
#define PHOTO_X_SIZE 256
|
||
|
#define PHOTO_Y_SIZE 256
|
||
|
#define PHONE_SCREEN_RES 256
|
||
|
#define SCREEN_RT_NAME "PHONE_SCREEN"
|
||
|
#define PHOTO_RT_NAME "PHOTO"
|
||
|
|
||
|
const s32 resX = PHONE_SCREEN_RES;
|
||
|
const s32 resY = PHONE_SCREEN_RES;
|
||
|
const s32 rtWidth = (s32)(((float)resX/1280.0) * settings.m_video.m_ScreenWidth);
|
||
|
const s32 rtHeight = (s32)(((float)resY/720.0) * settings.m_video.m_ScreenHeight);
|
||
|
CreateRenderTarget(SCREEN_RT_NAME, grcrtPermanent, rtWidth, rtHeight, 32);
|
||
|
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Multisample = 0;
|
||
|
|
||
|
CreateRenderTarget(PHOTO_RT_NAME, grcrtPermanent, PHOTO_X_SIZE, PHOTO_Y_SIZE, 32, ¶ms);
|
||
|
}
|
||
|
|
||
|
void calculateViewportManagerRenderTargetSizes(Settings &settings)
|
||
|
{
|
||
|
#if __BANK
|
||
|
for(int i=0; i<ENTITYSELECT_NO_OF_PLANES; i++)
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.UseFloat = true;
|
||
|
params.Multisample = 0;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
params.IsResolvable = false;
|
||
|
params.IsRenderable = true;
|
||
|
params.UseHierZ = true;
|
||
|
params.Format = grctfNone;
|
||
|
|
||
|
static const int sBPP = 32;
|
||
|
|
||
|
#if ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
//Create EDRAM depth target
|
||
|
bool createFullsizeDepth = true;
|
||
|
if(createFullsizeDepth)
|
||
|
CreateRenderTarget("Entity Select Depth Target", grcrtDepthBuffer, settings.m_video.m_ScreenWidth, settings.m_video.m_ScreenHeight, sBPP, ¶ms);
|
||
|
#else // ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
CreateRenderTarget("Entity Select Depth Target", grcrtDepthBuffer, settings.m_video.m_ScreenWidth, settings.m_video.m_ScreenHeight, sBPP, ¶ms);
|
||
|
#endif // ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
|
||
|
#if ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
//Create EDRAM RGB target
|
||
|
bool createFullsizeRt = true;
|
||
|
if(createFullsizeRt)
|
||
|
CreateRenderTarget("Entity Select EDRAM target", grcrtPermanent, settings.m_video.m_ScreenWidth, settings.m_video.m_ScreenHeight, sBPP, ¶ms);
|
||
|
#else // ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
CreateRenderTarget("Entity Select target", grcrtPermanent, settings.m_video.m_ScreenWidth, settings.m_video.m_ScreenHeight, sBPP, ¶ms);
|
||
|
#endif // ENTITYSELECT_NO_OF_PLANES == 1
|
||
|
|
||
|
params.HasParent = false;
|
||
|
params.Parent = NULL;
|
||
|
params.IsResolvable = true;
|
||
|
params.IsRenderable = false;
|
||
|
PS3_ONLY(params.InLocalMemory = false); //We need to read this texture from the CPU, so don't create it in VRAM.
|
||
|
|
||
|
#if RSG_PC || RSG_ORBIS || RSG_DURANGO
|
||
|
params.Lockable = true;
|
||
|
#endif
|
||
|
#if RSG_ORBIS
|
||
|
params.ForceNoTiling = true;
|
||
|
#endif // RSG_ORBIS
|
||
|
|
||
|
#define ENTITYSELECT_TARGET_SIZE 64 //Must be at least 32 because of 32-pixel alignment requirement. (on Xenon, for resolve)
|
||
|
|
||
|
//Create resolve target.
|
||
|
CreateRenderTarget("Entity Select Resolve Target 0", grcrtPermanent, ENTITYSELECT_TARGET_SIZE, ENTITYSELECT_TARGET_SIZE, sBPP, ¶ms);
|
||
|
CreateRenderTarget("Entity Select Resolve Target 1", grcrtPermanent, ENTITYSELECT_TARGET_SIZE, ENTITYSELECT_TARGET_SIZE, sBPP, ¶ms);
|
||
|
}
|
||
|
#endif //__BANK
|
||
|
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
int reflectionResolution = REFLECTION_TARGET_HEIGHT;
|
||
|
|
||
|
#if !__FINAL
|
||
|
int BPP = 0;
|
||
|
#if !RSG_ORBIS
|
||
|
if( PARAM_DX11Use8BitTargets.Get() )
|
||
|
{
|
||
|
BPP = 32;
|
||
|
}
|
||
|
else
|
||
|
#endif // !RSG_ORBIS
|
||
|
{
|
||
|
BPP = 32;
|
||
|
}
|
||
|
const int tbpp = BPP;
|
||
|
#else //!__FINAL
|
||
|
const int tbpp=32;
|
||
|
#endif //!__FINAL
|
||
|
|
||
|
params.Multisample = grcDevice::MSAA_None;
|
||
|
params.MipLevels = 4;
|
||
|
|
||
|
if ( !PARAM_UseDefaultResReflection.Get())
|
||
|
{
|
||
|
int reflectionSizeX = (((int)settings.m_graphics.m_ReflectionQuality > 0) ? Max(1, (int)settings.m_video.m_ScreenWidth / (1 << (3 - Min(3, (int)settings.m_graphics.m_ReflectionQuality)))) : 32);
|
||
|
int reflectionSizeY = (((int)settings.m_graphics.m_ReflectionQuality > 0) ? Max(1, (int)settings.m_video.m_ScreenHeight / (1 << (3 - Min(3, (int)settings.m_graphics.m_ReflectionQuality)))) : 32);
|
||
|
u32 dimension = (u32) rage::Sqrtf((float)(reflectionSizeX * reflectionSizeY));
|
||
|
u32 iMipLevels = 0;
|
||
|
while (dimension)
|
||
|
{
|
||
|
dimension >>= 1;
|
||
|
iMipLevels++;
|
||
|
}
|
||
|
iMipLevels--;
|
||
|
|
||
|
reflectionResolution = 1 << iMipLevels;
|
||
|
|
||
|
//We still need to mip down to the same resolution as console so adjust increase the number of mip levels depending on our resolution.
|
||
|
u32 mipResolution = reflectionResolution;
|
||
|
while( mipResolution > REFLECTION_TARGET_HEIGHT)
|
||
|
{
|
||
|
mipResolution = mipResolution >>1;
|
||
|
params.MipLevels++;
|
||
|
}
|
||
|
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR", grcrtPermanent, reflectionResolution * 2, reflectionResolution, tbpp, ¶ms);
|
||
|
// CreateRenderTarget("REFLECTION_MAP_DEPTH", grcrtDepthBuffer, reflectionResolution * 2, reflectionResolution, 32);
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR COPY", grcrtPermanent, reflectionResolution * 2, reflectionResolution, tbpp, ¶ms);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR", grcrtPermanent, REFLECTION_TARGET_WIDTH, REFLECTION_TARGET_HEIGHT, tbpp, ¶ms);
|
||
|
// this corrupts gbuf0 when reflection phase is placed after cascade shadow
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR COPY", grcrtPermanent, REFLECTION_TARGET_WIDTH, REFLECTION_TARGET_HEIGHT, tbpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
|
||
|
#define CUBEMAPREF_MIP 4
|
||
|
params.Format = grctfR11G11B10F;
|
||
|
params.MipLevels = CUBEMAPREF_MIP;
|
||
|
params.ArraySize = 6;
|
||
|
|
||
|
const int bpp = 32;//grcTextureFactory::GetInstance().GetBitsPerPixel(params.Format);
|
||
|
|
||
|
//REFLECTION CUBE MAPS
|
||
|
#if REFLECTION_CUBEMAP_SAMPLING
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR_CUBE", grcrtCubeMap, reflectionResolution, reflectionResolution, bpp, ¶ms);
|
||
|
#else
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR_CUBE", grcrtCubeMap, reflectionResolution, reflectionResolution, bpp, ¶ms);
|
||
|
#endif
|
||
|
|
||
|
#if GS_INSTANCED_CUBEMAP
|
||
|
params.Format = grctfD24S8;
|
||
|
params.MipLevels = 1;
|
||
|
params.ArraySize = 6;
|
||
|
CreateRenderTarget("REFLECTION_MAP_COLOUR_CUBE_DEPTH", grcrtDepthBuffer, reflectionResolution, reflectionResolution, 32, ¶ms);
|
||
|
#else
|
||
|
|
||
|
params.ArraySize = 1;
|
||
|
params.MipLevels = 1;
|
||
|
params.PerArraySliceRTV = 1;
|
||
|
params.HasParent = true;
|
||
|
params.Parent = NULL;
|
||
|
params.IsResolvable = true;
|
||
|
params.IsRenderable = true;
|
||
|
params.Lockable = 0;
|
||
|
params.Multisample = grcDevice::MSAAMode(settings.m_graphics.m_ReflectionMSAA);
|
||
|
|
||
|
#if 0//DOUBLE_BUFFER_COLOR
|
||
|
const int numColorTargets = 2;
|
||
|
#else
|
||
|
const int numColorTargets = 1;
|
||
|
#endif
|
||
|
for (int i = 0; i < numColorTargets; i++)
|
||
|
{
|
||
|
char targetFacetName[256];
|
||
|
formatf(targetFacetName, 254, "REFLECTION_MAP_COLOUR_FACET %d", i);
|
||
|
|
||
|
CreateRenderTarget(targetFacetName, grcrtPermanent, reflectionResolution, reflectionResolution, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
params.Format = grctfD24S8;
|
||
|
params.UseHierZ = true;
|
||
|
params.IsResolvable = false;
|
||
|
params.Lockable = 0;
|
||
|
|
||
|
#if 0//DOUBLE_BUFFER_DEPTH
|
||
|
const int numDepthTargets = 2;
|
||
|
#else
|
||
|
const int numDepthTargets = 1;
|
||
|
#endif
|
||
|
for (int i = 0; i < numDepthTargets; i++)
|
||
|
{
|
||
|
CreateRenderTarget("REFLECTION_MAP_DEPTH", grcrtDepthBuffer, reflectionResolution, reflectionResolution, 32, ¶ms);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// R A I N H E I G H T M A P / H E I G H T M A P
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
// CreateRenderTarget("HEIGHT_MAP_COLOR", grcrtPermanent, HGHT_TARGET_SIZE, HGHT_TARGET_SIZE, 32);
|
||
|
|
||
|
params.Multisample = grcDevice::MSAA_None;
|
||
|
CreateRenderTarget("HEIGHT_MAP_DEPTH", RSG_ORBIS ? grcrtShadowMap : grcrtPermanent, HGHT_TARGET_SIZE, HGHT_TARGET_SIZE, 32, ¶ms);
|
||
|
}
|
||
|
|
||
|
|
||
|
//WATER REFLECTION
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Multisample = grcDevice::MSAA_None;
|
||
|
int tbpp=32;
|
||
|
params.Format = grctfR11G11B10F;
|
||
|
|
||
|
const int resX = GetMirrorResolutionSetting(settings);
|
||
|
const int resY = resX / 2;
|
||
|
|
||
|
CreateRenderTarget("WATER_REFLECTION_COLOUR", grcrtPermanent, resX, resY, tbpp, ¶ms);
|
||
|
|
||
|
if((settings.m_graphics.m_ReflectionMSAA > 1) && GRCDEVICE.GetDxFeatureLevel() >= 1010)
|
||
|
{
|
||
|
// create a MSAA rendertarget and keep MSAA for depth
|
||
|
params.Multisample = settings.m_graphics.m_ReflectionMSAA;
|
||
|
params.MipLevels = 1;
|
||
|
|
||
|
CViewportManager::ComputeVendorMSAA(params);
|
||
|
|
||
|
CreateRenderTarget("WATER_REFLECTION_COLOUR_MSAA", grcrtPermanent, resX, resY, 32, ¶ms);
|
||
|
}
|
||
|
|
||
|
tbpp = 40;
|
||
|
params.Format = grctfD32FS8;
|
||
|
|
||
|
CreateRenderTarget("WATER_REFLECTION_DEPTH", grcrtDepthBuffer, resX, resY, tbpp, ¶ms);
|
||
|
|
||
|
if(GRCDEVICE.IsReadOnlyDepthAllowed())
|
||
|
{
|
||
|
// CreateRenderTarget("WATER_REFLECTION_DEPTH", pDepthTarget->GetTexturePtr(), params.Format, DepthStencilReadOnly);
|
||
|
}
|
||
|
else
|
||
|
CreateRenderTarget("WATER_REFLECTION_DEPTH_COPY", grcrtDepthBuffer, resX, resY, 32);
|
||
|
}
|
||
|
|
||
|
// SeeThrough FX
|
||
|
{
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Multisample = grcDevice::MSAA_None;
|
||
|
params.Format = grctfA8R8G8B8;
|
||
|
|
||
|
CreateRenderTarget("FX_SEETHROUGH_COLOR", grcrtPermanent, SEETHROUGH_LAYER_WIDTH, SEETHROUGH_LAYER_HEIGHT, 32, ¶ms);
|
||
|
CreateRenderTarget("FX_SEETHROUGH_BLUR", grcrtPermanent, SEETHROUGH_LAYER_WIDTH, SEETHROUGH_LAYER_HEIGHT, 32, ¶ms);
|
||
|
CreateRenderTarget("FX_SEETHROUGH_DEPTH", grcrtDepthBuffer, SEETHROUGH_LAYER_WIDTH, SEETHROUGH_LAYER_HEIGHT, 32);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void calculatePostFXRenderTargetsSize(Settings &settings)
|
||
|
{
|
||
|
//Create render targets.
|
||
|
int iWidth = settings.m_video.m_ScreenWidth;
|
||
|
int iHeight = settings.m_video.m_ScreenHeight;
|
||
|
#if RSG_PC
|
||
|
applySceneScale(settings.m_graphics.m_SamplingMode, iWidth, iHeight);
|
||
|
#endif
|
||
|
|
||
|
grcTextureFactory::CreateParams params;
|
||
|
params.Multisample = 0;
|
||
|
int bpp = 64;
|
||
|
|
||
|
#if __BANK
|
||
|
if (PARAM_postfxusesFP16.Get())
|
||
|
{
|
||
|
bpp = 64;
|
||
|
params.Format = grctfA16B16G16R16F;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
bpp = 32;
|
||
|
params.Format = grctfR11G11B10F;
|
||
|
}
|
||
|
|
||
|
#if RSG_PC
|
||
|
params.StereoRTMode = grcDevice::STEREO;
|
||
|
#endif // RSG_PC
|
||
|
|
||
|
CreateRenderTarget("Half Screen 0", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);
|
||
|
|
||
|
if (settings.m_graphics.m_PostFX >= CSettings::Medium)
|
||
|
{
|
||
|
CreateRenderTarget("Bloom Buffer", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Unfiltered", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);
|
||
|
}
|
||
|
|
||
|
u32 dofTargetWidth = iWidth/4;
|
||
|
u32 dofTargetHeight = iHeight/4;
|
||
|
#if DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
||
|
if( (settings.m_graphics.m_PostFX >= CSettings::High) && (GRCDEVICE.IsStereoEnabled() == false))
|
||
|
{
|
||
|
dofTargetWidth = iWidth;
|
||
|
dofTargetHeight = iHeight;
|
||
|
}
|
||
|
#endif //DOF_COMPUTE_GAUSSIAN || DOF_DIFFUSION
|
||
|
|
||
|
CreateRenderTarget("DOF 1", grcrtPermanent, dofTargetWidth, dofTargetHeight, bpp, ¶ms);
|
||
|
CreateRenderTarget("DOF 2", grcrtPermanent, dofTargetWidth, dofTargetHeight, bpp, ¶ms);
|
||
|
|
||
|
DURANGO_ONLY(CreateRenderTarget("Bloom Buffer Half 0", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);)
|
||
|
CreateRenderTarget("Bloom Buffer Half 1", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Quarter 0", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Quarter 1", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Eighth 0", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Eighth 1", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Sixteenth 0", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms);
|
||
|
CreateRenderTarget("Bloom Buffer Sixteenth 1", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms);
|
||
|
|
||
|
if (settings.m_graphics.m_PostFX >= CSettings::High)
|
||
|
{
|
||
|
CreateRenderTarget("Lens Artefact Final Buffer", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);
|
||
|
#if 1 || __DEV
|
||
|
CreateRenderTarget("Lens Artefact 4x Buffer 0", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
CreateRenderTarget("Lens Artefact 4x Buffer 1", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
CreateRenderTarget("Lens Artefact 8x Buffer 0", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
CreateRenderTarget("Lens Artefact 8x Buffer 1", grcrtPermanent, iWidth/8, iHeight/8, bpp, ¶ms);
|
||
|
CreateRenderTarget("Lens Artefact 16x Buffer 0", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms);
|
||
|
CreateRenderTarget("Lens Artefact 16x Buffer 1", grcrtPermanent, iWidth/16, iHeight/16, bpp, ¶ms);
|
||
|
#endif // __DEV
|
||
|
}
|
||
|
#if RSG_PC
|
||
|
if (PostFX::g_EnableFilmEffect)
|
||
|
#endif // RSG_PC
|
||
|
CreateRenderTarget("LensDistortion", grcrtPermanent, iWidth, iHeight, bpp, ¶ms);
|
||
|
|
||
|
#if BOKEH_SUPPORT
|
||
|
bool BokehEnable = (GRCDEVICE.GetDxFeatureLevel() >= 1100) NOTFINAL_ONLY(&& !PARAM_disableBokeh.Get());
|
||
|
BokehEnable &= (settings.m_graphics.m_PostFX >= CSettings::High) ? true : false;
|
||
|
|
||
|
if( BokehEnable )
|
||
|
{
|
||
|
CreateRenderTarget("Bokeh Points", grcrtPermanent, iWidth, iHeight, 64, ¶ms);
|
||
|
// Shared with BloomBuffer now
|
||
|
DURANGO_ONLY(CreateRenderTarget("Bokeh Points Temp", grcrtPermanent, iWidth/2, iHeight/2, bpp, ¶ms);)
|
||
|
|
||
|
CreateRenderTarget("BokehDepthBlur", grcrtPermanent, iWidth, iHeight, bpp, ¶ms);
|
||
|
|
||
|
CreateRenderTarget("BokehDepthBlurHalfRes", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
|
||
|
#if COC_SPREAD
|
||
|
if( true /*CurrentDOFTechnique == dof_computeGaussian || CurrentDOFTechnique == dof_diffusion*/)
|
||
|
{
|
||
|
CreateRenderTarget("BokehDepthBlurHalfResTemp", grcrtPermanent, iWidth/4, iHeight/4, bpp, ¶ms);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
CreateRenderTarget("HeatHaze 1", grcrtPermanent, iWidth/8, iHeight/8, 8, ¶ms);
|
||
|
CreateRenderTarget("HeatHaze 2", grcrtPermanent, iWidth/8, iHeight/8, 8, ¶ms);
|
||
|
|
||
|
if (settings.m_graphics.m_ShaderQuality > 0)
|
||
|
{
|
||
|
CreateRenderTarget("Global FogRay", grcrtPermanent, iWidth/2, iHeight/2, 32, ¶ms);
|
||
|
CreateRenderTarget("Global FogRay 2", grcrtPermanent, iWidth/2, iHeight/2, 32, ¶ms);
|
||
|
}
|
||
|
|
||
|
#if RSG_PC
|
||
|
params.StereoRTMode = grcDevice::STEREO;
|
||
|
#endif
|
||
|
|
||
|
CreateRenderTarget("SSLR Cutout", grcrtPermanent, 256, 256, 8, ¶ms);
|
||
|
CreateRenderTarget("SSLR Intensity", grcrtPermanent, iWidth/4, iHeight/4, 8, ¶ms);
|
||
|
CreateRenderTarget("SSLR Intensity2", grcrtPermanent, iWidth/4, iHeight/4, 8, ¶ms);
|
||
|
|
||
|
params.StereoRTMode = grcDevice::AUTO;
|
||
|
|
||
|
CreateRenderTarget("Fog of War 0", grcrtPermanent, 64, 64, 32, ¶ms);
|
||
|
CreateRenderTarget("Fog of War 1", grcrtPermanent, 16, 16, 32, ¶ms);
|
||
|
CreateRenderTarget("Fog of War 2", grcrtPermanent, 4, 4, 32, ¶ms);
|
||
|
|
||
|
// Depending on the device resolution, we need a different number of passes and filter sizes
|
||
|
// to correctly downsample the luminance; the code below can only handle 1080, 900 and 720.
|
||
|
// Any other resolution defaults to the 720 behaviour.
|
||
|
|
||
|
int deviceHeight = iHeight;
|
||
|
|
||
|
if (deviceHeight > 1080)
|
||
|
{
|
||
|
deviceHeight = 1080;
|
||
|
}
|
||
|
else if (deviceHeight > 900)
|
||
|
{
|
||
|
deviceHeight = 900;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
deviceHeight = 720;
|
||
|
}
|
||
|
|
||
|
int LumDownsampleRTWidth[5];
|
||
|
int LumDownsampleRTHeight[5];
|
||
|
int LumDownsampleRTCount;
|
||
|
|
||
|
switch (deviceHeight)
|
||
|
{
|
||
|
case 1080:
|
||
|
{
|
||
|
LumDownsampleRTWidth[0] = 120; LumDownsampleRTHeight[0] = 90; LumDownsampleRTWidth[1] = 30; LumDownsampleRTHeight[1] = 30; LumDownsampleRTWidth[2] = 10; LumDownsampleRTHeight[2] = 10; LumDownsampleRTWidth[3] = 5; LumDownsampleRTHeight[3] = 5; LumDownsampleRTWidth[4] = 1; LumDownsampleRTHeight[4] = 1;
|
||
|
LumDownsampleRTCount = 5;
|
||
|
break;
|
||
|
}
|
||
|
case 900:
|
||
|
{
|
||
|
LumDownsampleRTWidth[0] = 100; LumDownsampleRTHeight[0] = 75; LumDownsampleRTWidth[1] = 25; LumDownsampleRTHeight[1] = 25; LumDownsampleRTWidth[2] = 5; LumDownsampleRTHeight[2] = 5; LumDownsampleRTWidth[3] = 1; LumDownsampleRTHeight[3] = 1;
|
||
|
LumDownsampleRTCount = 4;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 720:
|
||
|
default:
|
||
|
{
|
||
|
LumDownsampleRTWidth[0] = 80; LumDownsampleRTHeight[0] = 60; LumDownsampleRTWidth[1] = 20; LumDownsampleRTHeight[1] = 20; LumDownsampleRTWidth[2] = 10; LumDownsampleRTHeight[2] = 10; LumDownsampleRTWidth[3] = 5; LumDownsampleRTHeight[3] = 5; LumDownsampleRTWidth[4] = 1; LumDownsampleRTHeight[4] = 1;
|
||
|
LumDownsampleRTCount = 5;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if AVG_LUMINANCE_COMPUTE
|
||
|
if (settings.m_graphics.m_DX_Version >= 2)
|
||
|
{
|
||
|
float fdeviceWidth = (float)(iWidth/4);
|
||
|
float fdeviceHeight = (float)(iHeight/4);
|
||
|
|
||
|
float maxSize = rage::Max(fdeviceWidth, fdeviceHeight);
|
||
|
|
||
|
int LumCSDownsampleUAVCount = 0;
|
||
|
|
||
|
params.UseAsUAV = true;
|
||
|
while ( maxSize > 16.0f )
|
||
|
{
|
||
|
maxSize = ceilf(maxSize / 16.0f);
|
||
|
|
||
|
fdeviceWidth = ceilf(fdeviceWidth / 16.0f);
|
||
|
fdeviceHeight = ceilf(fdeviceHeight / 16.0f);
|
||
|
|
||
|
char szLumDownName[256];
|
||
|
formatf(szLumDownName, 254, "LumDownsampleUAV %d", LumCSDownsampleUAVCount);
|
||
|
|
||
|
CreateRenderTarget(szLumDownName, grcrtPermanent, (int)fdeviceWidth, (int)fdeviceHeight, 32, ¶ms);
|
||
|
|
||
|
LumCSDownsampleUAVCount++;
|
||
|
}
|
||
|
|
||
|
//1x1
|
||
|
params.UseFloat = true;
|
||
|
CreateRenderTarget("LumDownsampleUAV Final", grcrtPermanent, 1, 1, 32, ¶ms);
|
||
|
|
||
|
params.UseAsUAV = false;
|
||
|
}
|
||
|
else
|
||
|
#endif //AVG_LUMINANCE_COMPUTE
|
||
|
{
|
||
|
int iWidth4 = iWidth/4;
|
||
|
int iHeight4 = iHeight/4;
|
||
|
|
||
|
int lumWidth = LumDownsampleRTWidth[0];
|
||
|
int lumHeight = LumDownsampleRTHeight[0];
|
||
|
|
||
|
int ImLumDownsampleRTCount = 0;
|
||
|
|
||
|
params.Format = grctfR11G11B10F;
|
||
|
|
||
|
while (iWidth4/4 > lumWidth || iHeight4/4 > lumHeight)
|
||
|
{
|
||
|
iWidth4 /= 4;
|
||
|
iHeight4 /= 4;
|
||
|
|
||
|
int imLumRTWidth = rage::Max(lumWidth*4, iWidth4);
|
||
|
int imLumRTHeight = rage::Max(lumHeight*3, iHeight4);
|
||
|
|
||
|
char szLumDownName[256];
|
||
|
formatf(szLumDownName, 254, "ImLumDownsample %d", ImLumDownsampleRTCount);
|
||
|
|
||
|
|
||
|
CreateRenderTarget(szLumDownName, grcrtPermanent, imLumRTWidth, imLumRTHeight, bpp, ¶ms);
|
||
|
ImLumDownsampleRTCount++;
|
||
|
}
|
||
|
|
||
|
|
||
|
for (int i = 0; i < LumDownsampleRTCount; i++)
|
||
|
{
|
||
|
if (i == LumDownsampleRTCount - 1)
|
||
|
{
|
||
|
params.UseFloat = true;
|
||
|
#if RSG_DURANGO
|
||
|
params.ESRAMPhase = 0; // final buffer is tiny and hangs around too long
|
||
|
#endif
|
||
|
}
|
||
|
char szLumDownName[256];
|
||
|
formatf(szLumDownName, 254, "LumDownsample %d", i);
|
||
|
CreateRenderTarget(szLumDownName, grcrtPermanent, LumDownsampleRTWidth[i], LumDownsampleRTHeight[i], 32, ¶ms);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
params.Format = grctfR32F;
|
||
|
CreateRenderTarget("Center Reticule Dist", grcrtPermanent, 1, 1, 32, ¶ms);
|
||
|
|
||
|
#if ADAPTIVE_DOF
|
||
|
#if ADAPTIVE_DOF_GPU
|
||
|
params.StereoRTMode = grcDevice::AUTO;
|
||
|
grcTextureFactory::TextureCreateParams TextureParams(grcTextureFactory::TextureCreateParams::SYSTEM,
|
||
|
grcTextureFactory::TextureCreateParams::LINEAR, grcsRead|grcsWrite, NULL,
|
||
|
grcTextureFactory::TextureCreateParams::RENDERTARGET,
|
||
|
grcTextureFactory::TextureCreateParams::MSAA_NONE);
|
||
|
|
||
|
CreateRenderTarget("depth reduc 0", grcrtPermanent, 1024, 1024, 32, ¶ms);
|
||
|
CreateRenderTarget("depth reduc 1", grcrtPermanent, 32, 32, 32, ¶ms);
|
||
|
CreateRenderTarget("depth reduc 2", grcrtPermanent, 1, 1, 32, ¶ms);
|
||
|
|
||
|
// grcTextureFactory::GetInstance().Create( ADAPTIVE_DOF_GPU_HISTORY_SIZE, 1, params.Format, NULL, 1, &TextureParams );
|
||
|
// grcTextureFactory::GetInstance().CreateRenderTarget( "adaptiveDofParams", adaptiveDofParamsTexture->GetTexturePtr());
|
||
|
#endif // ADAPTIVE_DOF_GPU
|
||
|
#endif
|
||
|
|
||
|
grcTextureFactory::CreateParams mb_params;
|
||
|
mb_params.Multisample = 0;
|
||
|
mb_params.HasParent = true;
|
||
|
mb_params.Parent = NULL;
|
||
|
mb_params.Format = grctfA8R8G8B8;
|
||
|
#if RSG_DURANGO
|
||
|
params.ESRAMPhase = grcTextureFactory::TextureCreateParams::ESRPHASE_LIGHTING;
|
||
|
#endif
|
||
|
|
||
|
if (settings.m_graphics.m_PostFX >= CSettings::Medium)
|
||
|
{
|
||
|
for (int i = 0; i < 2; i++)
|
||
|
{
|
||
|
CreateRenderTarget("FPV Motion Blur Targets", grcrtPermanent, iWidth / 2, iHeight / 2, 32, &mb_params);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* SettingsDefaults implementation */
|
||
|
float SettingsDefaults::CalcFinalLodRootScale(const Settings &settings)
|
||
|
{
|
||
|
return Lerp(settings.m_graphics.m_MaxLodScale, sm_fMaxLodScaleMinRange, sm_fMaxLodScaleMaxRange);
|
||
|
}
|
||
|
|
||
|
s64 SettingsDefaults::renderTargetMemSizeFor(Settings settings) {
|
||
|
totalTextureSize = 0;
|
||
|
|
||
|
renderTargetStereoMode = settings.m_video.m_Stereo != 0;
|
||
|
|
||
|
calculateRenderTargetsSize(settings);
|
||
|
|
||
|
calculateGBufferRenderTargetSize(settings);
|
||
|
|
||
|
calculateCascadeShadowsRenderTargetSize(settings);
|
||
|
|
||
|
calculateParaboloidShadowRenderTargetsSize(settings);
|
||
|
|
||
|
calculateSSAORenderTargetsSize(settings);
|
||
|
|
||
|
calculateMirrorRenderTargetSizes(settings);
|
||
|
|
||
|
calculateWaterRenderTargetsSizes(settings);
|
||
|
|
||
|
calculatePedDamageRenderTargetSizes(settings);
|
||
|
|
||
|
calculatePhoneMgrRenderTargetSizes(settings);
|
||
|
|
||
|
calculateViewportManagerRenderTargetSizes(settings);
|
||
|
|
||
|
calculatePostFXRenderTargetsSize(settings);
|
||
|
|
||
|
calcualteUIRenderTargetSize(settings);
|
||
|
|
||
|
return totalTextureSize;
|
||
|
}
|
||
|
|
||
|
|
||
|
s64 SettingsDefaults::totalVideoMemory() {return GRCDEVICE.GetAvailableVideoMemory();}
|
||
|
|
||
|
|
||
|
s64 SettingsDefaults::videoMemoryUsage(CSettings::eSettingsLevel textureQuality, const Settings &settings)
|
||
|
{
|
||
|
// Calculated from max memory used with min/max lod scale factors at -5.5,-1399,29.3
|
||
|
const float fLodRange[2] = { 1.0f, 2.5f }; // Range used for calculating these numbers
|
||
|
|
||
|
const s64 baseRenderTargetValue = 100; // 147 - Uses alignment in settings calculation now
|
||
|
const s64 misc = (settings.m_graphics.m_DX_Version == 2 ? 11 + 47 : 0); // Indirect / Inorder - DX11 Only - Grass
|
||
|
|
||
|
// Index and Vertex Buffer LOD 1.0 - Low Variety, LOD 1.0 - High Variety, LOD 2.5 - Low Variety, LOD 2.5 High Variety
|
||
|
const s64 aIndexAndVertexBuffers[4] = { 60 + 298, 86 + 447, 126 + 548, 152 + 697}; // LOD 1.0, LOD 2.5
|
||
|
|
||
|
s64 aTextureSpace[4]; // LOD 1.0 - Low Variety, LOD 1.0 - High Variety, LOD 2.5 - Low Variety, LOD 2.5 High Variety
|
||
|
if (textureQuality == CSettings::High)
|
||
|
{
|
||
|
aTextureSpace[0] = 1105;
|
||
|
aTextureSpace[1] = 1249; // HD Pack 1628
|
||
|
aTextureSpace[2] = 1700;
|
||
|
aTextureSpace[3] = 1846; // HD Pack 2523
|
||
|
}
|
||
|
else if (textureQuality == CSettings::Medium)
|
||
|
{
|
||
|
aTextureSpace[0] = 967;
|
||
|
aTextureSpace[1] = 1156;
|
||
|
aTextureSpace[2] = 1387;
|
||
|
aTextureSpace[3] = 1576;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
aTextureSpace[0] = 305;
|
||
|
aTextureSpace[1] = 360;
|
||
|
aTextureSpace[2] = 425;
|
||
|
aTextureSpace[3] = 480;
|
||
|
}
|
||
|
const float fLODRange = (fLodRange[1] - fLodRange[0]);
|
||
|
Assertf((CalcFinalLodRootScale(settings) >= fLodRange[0]), "LOD Max Range %f must be greater than Min LOD Range %f", settings.m_graphics.m_MaxLodScale, fLodRange[0]);
|
||
|
const float fMaxLOD = Max(CalcFinalLodRootScale(settings), fLodRange[0]);
|
||
|
const float fLODScale = (fMaxLOD - fLodRange[0]) / fLODRange; // 0 - 2.5 or higher
|
||
|
|
||
|
const s64 aIbBbRequirements[2] = { (s64)Lerp(settings.m_graphics.m_VehicleVarietyMultiplier, (float)aIndexAndVertexBuffers[0], (float)aIndexAndVertexBuffers[1]),
|
||
|
(s64)Lerp(settings.m_graphics.m_VehicleVarietyMultiplier, (float)aIndexAndVertexBuffers[2], (float)aIndexAndVertexBuffers[3]) };
|
||
|
const s64 ibvbRequirements = (s64)Lerp(fLODScale, aIbBbRequirements[0], aIbBbRequirements[1]);
|
||
|
|
||
|
const s64 aTexRequirements[2] = { (s64)Lerp(settings.m_graphics.m_VehicleVarietyMultiplier, (float)aTextureSpace[0], (float)aTextureSpace[1]),
|
||
|
(s64)Lerp(settings.m_graphics.m_VehicleVarietyMultiplier, (float)aTextureSpace[2], (float)aTextureSpace[3]) };
|
||
|
const s64 texRequirements = (s64)Lerp(fLODScale, aTexRequirements[0], aTexRequirements[1]);
|
||
|
|
||
|
// Not really accounting for Ped separate from vehicles yet. I don't image we need two settings for this
|
||
|
Assert(settings.m_graphics.m_VehicleVarietyMultiplier == settings.m_graphics.m_PedVarietyMultiplier);
|
||
|
|
||
|
// LOD scale probably won't account
|
||
|
return (baseRenderTargetValue + misc + ibvbRequirements + texRequirements) * 1024 * 1024;
|
||
|
}
|
||
|
|
||
|
s64 SettingsDefaults::videoMemSizeFor(Settings settings) {
|
||
|
return renderTargetMemSizeFor(settings) + videoMemoryUsage(settings.m_graphics.m_TextureQuality, settings);
|
||
|
}
|
||
|
|
||
|
bool SettingsDefaults::testSettingsForVideoMemorySpace(Settings settings) {
|
||
|
return totalVideoMemory() > renderTargetMemSizeFor(settings);
|
||
|
}
|
||
|
|
||
|
SettingsDefaults& SettingsDefaults::GetInstance()
|
||
|
{
|
||
|
static SettingsDefaults oSettingsDefaults;
|
||
|
return oSettingsDefaults;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
struct IntelDeviceInfoHeader
|
||
|
{
|
||
|
DWORD Size;
|
||
|
DWORD Version;
|
||
|
};
|
||
|
|
||
|
// New device dependent structure
|
||
|
struct IntelDeviceInfoV1
|
||
|
{
|
||
|
DWORD GPUMaxFreq;
|
||
|
DWORD GPUMinFreq;
|
||
|
};
|
||
|
|
||
|
struct IntelDeviceInfoV2
|
||
|
{
|
||
|
DWORD GPUMaxFreq;
|
||
|
DWORD GPUMinFreq;
|
||
|
DWORD GTGeneration;
|
||
|
DWORD EUCount;
|
||
|
DWORD PackageTDP;
|
||
|
DWORD MaxFillRate;
|
||
|
};
|
||
|
|
||
|
#define INTEL_VENDOR_ID 0x8086
|
||
|
|
||
|
// The new device dependent counter
|
||
|
#define INTEL_DEVICE_INFO_COUNTERS "Intel Device Information"
|
||
|
|
||
|
|
||
|
#define GGF_SUCCESS 0
|
||
|
#define GGF_ERROR -1
|
||
|
#define GGF_E_UNSUPPORTED_HARDWARE -2
|
||
|
#define GGF_E_UNSUPPORTED_DRIVER -3
|
||
|
#define GGF_E_D3D_ERROR -4
|
||
|
long SettingsDefaults::getIntelDeviceInfo( unsigned int VendorId, IntelDeviceInfoHeader *pIntelDeviceInfoHeader, void *pIntelDeviceInfoBuffer )
|
||
|
{
|
||
|
// The device information is stored in a D3D counter.
|
||
|
// We must create a D3D device, find the Intel counter
|
||
|
// and query the counter info
|
||
|
ID3D11Device *pDevice = NULL;
|
||
|
ID3D11DeviceContext *pImmediateContext = NULL;
|
||
|
D3D_FEATURE_LEVEL featureLevel;
|
||
|
HRESULT hr = NULL;
|
||
|
|
||
|
if ( pIntelDeviceInfoBuffer == NULL )
|
||
|
return GGF_ERROR;
|
||
|
|
||
|
if ( VendorId != INTEL_VENDOR_ID )
|
||
|
return GGF_E_UNSUPPORTED_HARDWARE;
|
||
|
|
||
|
ZeroMemory( &featureLevel, sizeof(D3D_FEATURE_LEVEL) );
|
||
|
|
||
|
HMODULE hD3D11 = ::LoadLibrary("D3D11.DLL");
|
||
|
if (!hD3D11) return GGF_ERROR;
|
||
|
|
||
|
HRESULT (WINAPI *l_D3D11CreateDevice)(
|
||
|
IDXGIAdapter* pAdapter,D3D_DRIVER_TYPE DriverType,HMODULE Software,
|
||
|
UINT Flags,CONST D3D_FEATURE_LEVEL* pFeatureLevels,UINT FeatureLevels,
|
||
|
UINT SDKVersion,ID3D11Device** ppDevice,D3D_FEATURE_LEVEL* pFeatureLevel,
|
||
|
ID3D11DeviceContext** ppImmediateContext );
|
||
|
|
||
|
l_D3D11CreateDevice = (HRESULT (WINAPI *)(
|
||
|
IDXGIAdapter* pAdapter,D3D_DRIVER_TYPE DriverType,HMODULE Software,
|
||
|
UINT Flags,CONST D3D_FEATURE_LEVEL* pFeatureLevels,UINT FeatureLevels,
|
||
|
UINT SDKVersion,ID3D11Device** ppDevice,D3D_FEATURE_LEVEL* pFeatureLevel,
|
||
|
ID3D11DeviceContext** ppImmediateContext ))::GetProcAddress(hD3D11,"D3D11CreateDevice");
|
||
|
|
||
|
// First create the Device, must be SandyBridge or later to create D3D11 device
|
||
|
hr = l_D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
|
||
|
D3D11_SDK_VERSION, &pDevice, &featureLevel, &pImmediateContext);
|
||
|
|
||
|
if ( FAILED(hr) )
|
||
|
{
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("D3D11CreateDevice failed\n");
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// The counter is in a device dependent counter
|
||
|
D3D11_COUNTER_INFO counterInfo;
|
||
|
D3D11_COUNTER_DESC pIntelCounterDesc;
|
||
|
|
||
|
int numDependentCounters;
|
||
|
UINT uiSlotsRequired, uiNameLength, uiUnitsLength, uiDescLength;
|
||
|
LPSTR sName, sUnits, sDesc;
|
||
|
|
||
|
ZeroMemory( &counterInfo, sizeof(D3D11_COUNTER_INFO) );
|
||
|
ZeroMemory( &pIntelCounterDesc, sizeof(D3D11_COUNTER_DESC) );
|
||
|
|
||
|
// Query the device to find the number of device dependent counters.
|
||
|
pDevice->CheckCounterInfo( &counterInfo );
|
||
|
|
||
|
if ( counterInfo.LastDeviceDependentCounter == 0 )
|
||
|
{
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("No device dependent counters\n");
|
||
|
|
||
|
// The driver does not support the Device Info Counter.
|
||
|
return GGF_E_UNSUPPORTED_DRIVER;
|
||
|
}
|
||
|
|
||
|
numDependentCounters = counterInfo.LastDeviceDependentCounter - D3D11_COUNTER_DEVICE_DEPENDENT_0 + 1;
|
||
|
|
||
|
// Search for the apporpriate counter - INTEL_DEVICE_INFO_COUNTERS
|
||
|
for ( int i = 0; i < numDependentCounters; ++i )
|
||
|
{
|
||
|
D3D11_COUNTER_DESC counterDescription;
|
||
|
D3D11_COUNTER_TYPE counterType;
|
||
|
|
||
|
counterDescription.Counter = static_cast<D3D11_COUNTER>(i+D3D11_COUNTER_DEVICE_DEPENDENT_0);
|
||
|
counterDescription.MiscFlags = 0;
|
||
|
counterType = static_cast<D3D11_COUNTER_TYPE>(0);
|
||
|
uiSlotsRequired = uiNameLength = uiUnitsLength = uiDescLength = 0;
|
||
|
sName = sUnits = sDesc = NULL;
|
||
|
|
||
|
if( SUCCEEDED( hr = pDevice->CheckCounter( &counterDescription, &counterType, &uiSlotsRequired, NULL, &uiNameLength, NULL, &uiUnitsLength, NULL, &uiDescLength ) ) )
|
||
|
{
|
||
|
LPSTR sName = rage_new char[uiNameLength];
|
||
|
LPSTR sUnits = rage_new char[uiUnitsLength];
|
||
|
LPSTR sDesc = rage_new char[uiDescLength];
|
||
|
|
||
|
if( SUCCEEDED( hr = pDevice->CheckCounter( &counterDescription, &counterType, &uiSlotsRequired, sName, &uiNameLength, sUnits, &uiUnitsLength, sDesc, &uiDescLength ) ) )
|
||
|
{
|
||
|
if ( strcmp( sName, INTEL_DEVICE_INFO_COUNTERS ) == 0 )
|
||
|
{
|
||
|
int IntelCounterMajorVersion;
|
||
|
int IntelCounterSize;
|
||
|
int argsFilled = 0;
|
||
|
|
||
|
pIntelCounterDesc.Counter = counterDescription.Counter;
|
||
|
|
||
|
argsFilled = sscanf_s( sDesc, "Version %d", &IntelCounterMajorVersion);
|
||
|
|
||
|
if ( argsFilled == 1 )
|
||
|
{
|
||
|
sscanf_s( sUnits, "Size %d", &IntelCounterSize);
|
||
|
}
|
||
|
else // Fall back to version 1.0
|
||
|
{
|
||
|
IntelCounterMajorVersion = 1;
|
||
|
IntelCounterSize = sizeof( IntelDeviceInfoV1 );
|
||
|
}
|
||
|
|
||
|
pIntelDeviceInfoHeader->Version = IntelCounterMajorVersion;
|
||
|
pIntelDeviceInfoHeader->Size = IntelCounterSize;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SAFE_DELETE_ARRAY( sName );
|
||
|
SAFE_DELETE_ARRAY( sUnits );
|
||
|
SAFE_DELETE_ARRAY( sDesc );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check if device info counter was found
|
||
|
if ( pIntelCounterDesc.Counter == NULL )
|
||
|
{
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("Could not find counter\n");
|
||
|
|
||
|
// The driver does not support the Device Info Counter.
|
||
|
return GGF_E_UNSUPPORTED_DRIVER;
|
||
|
}
|
||
|
|
||
|
// Intel Device Counter //
|
||
|
ID3D11Counter *pIntelCounter = NULL;
|
||
|
|
||
|
// Create the appropriate counter
|
||
|
hr = pDevice->CreateCounter(&pIntelCounterDesc, &pIntelCounter);
|
||
|
if ( FAILED(hr) )
|
||
|
{
|
||
|
SAFE_RELEASE( pIntelCounter );
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("CreateCounter failed\n");
|
||
|
|
||
|
return GGF_E_D3D_ERROR;
|
||
|
}
|
||
|
|
||
|
// Begin and end counter capture
|
||
|
pImmediateContext->Begin(pIntelCounter);
|
||
|
pImmediateContext->End(pIntelCounter);
|
||
|
|
||
|
// Check for available data
|
||
|
hr = pImmediateContext->GetData( pIntelCounter, NULL, NULL, NULL );
|
||
|
if ( FAILED(hr) || hr == S_FALSE )
|
||
|
{
|
||
|
SAFE_RELEASE( pIntelCounter );
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("Getdata failed \n");
|
||
|
return GGF_E_D3D_ERROR;
|
||
|
}
|
||
|
|
||
|
DWORD pData[2] = {0};
|
||
|
// Get pointer to structure
|
||
|
hr = pImmediateContext->GetData(pIntelCounter, pData, 2*sizeof(DWORD), NULL);
|
||
|
|
||
|
if ( FAILED(hr) || hr == S_FALSE )
|
||
|
{
|
||
|
SAFE_RELEASE( pIntelCounter );
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
printf("Getdata failed \n");
|
||
|
return GGF_E_D3D_ERROR;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Prepare data to be returned //
|
||
|
//
|
||
|
// Copy data to passed in parameter
|
||
|
void *pDeviceInfoBuffer = *(void**)pData;
|
||
|
|
||
|
memcpy( pIntelDeviceInfoBuffer, pDeviceInfoBuffer, pIntelDeviceInfoHeader->Size );
|
||
|
|
||
|
//
|
||
|
// Clean up //
|
||
|
//
|
||
|
SAFE_RELEASE( pIntelCounter );
|
||
|
SAFE_RELEASE( pImmediateContext );
|
||
|
SAFE_RELEASE( pDevice );
|
||
|
|
||
|
return GGF_SUCCESS;
|
||
|
}
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
IGFX_UNKNOWN = 0x0,
|
||
|
IGFX_SANDYBRIDGE = 0xC,
|
||
|
IGFX_IVYBRIDGE,
|
||
|
IGFX_HASWELL,
|
||
|
} PRODUCT_FAMILY;
|
||
|
|
||
|
void SettingsDefaults::GetIntelDisplayInfo()
|
||
|
{
|
||
|
|
||
|
const s64 oneMillion = 1000000;
|
||
|
|
||
|
IntelDeviceInfoHeader intelDeviceInfoHeader = { 0 };
|
||
|
byte intelDeviceInfoBuffer[1024];
|
||
|
|
||
|
long getStatus = getIntelDeviceInfo(m_oAdapterDesc.VendorId, &intelDeviceInfoHeader, intelDeviceInfoBuffer);
|
||
|
|
||
|
IntelDeviceInfoV2 intelDeviceInfo;
|
||
|
memcpy( &intelDeviceInfo, intelDeviceInfoBuffer, intelDeviceInfoHeader.Size );
|
||
|
|
||
|
if ( getStatus == GGF_SUCCESS && intelDeviceInfoHeader.Version >= 2 )
|
||
|
{
|
||
|
if (intelDeviceInfo.GTGeneration > IGFX_HASWELL)
|
||
|
{
|
||
|
m_processingPower = 41 * oneMillion;
|
||
|
m_memBandwidth = 41 * oneMillion;
|
||
|
Displayf("Better than Haswell Generation");
|
||
|
}
|
||
|
else if (intelDeviceInfo.GTGeneration == IGFX_HASWELL)
|
||
|
{
|
||
|
m_processingPower = 21 * oneMillion;
|
||
|
m_memBandwidth = 21 * oneMillion;
|
||
|
Displayf("Haswell Generation");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_processingPower = 1 * oneMillion;
|
||
|
m_memBandwidth = 1 * oneMillion;
|
||
|
Displayf("Lower than Haswell");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Assert((m_oAdapterDesc.VendorId == 0x8086) || (m_oAdapterDesc.VendorId == 0x8087));
|
||
|
const u32 cuHaswelLowestChipset = 0x402;
|
||
|
if (m_oAdapterDesc.DeviceId < cuHaswelLowestChipset)
|
||
|
{
|
||
|
m_processingPower = 1 * oneMillion;
|
||
|
m_memBandwidth = 1 * oneMillion;
|
||
|
Displayf("Lower than Haswell");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_processingPower = 21 * oneMillion;
|
||
|
m_memBandwidth = 21 * oneMillion;
|
||
|
Displayf("Haswell or Higher");
|
||
|
}
|
||
|
}
|
||
|
//Displayf("Cores %d GPU Clock %d Processing Power %d Mem Bandwidth %d", (s32)numOfCores, (s32)gpuClockMax, (s32)m_processingPower, (s32)m_memBandwidth);
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::initAdapter()
|
||
|
{
|
||
|
if (grcAdapterManager::GetInstance() == NULL)
|
||
|
{
|
||
|
m_hDXGI = LoadLibrary("dxgi.dll");
|
||
|
grcAdapterManager::InitClass(DXGI_FORMAT_R8G8B8A8_UNORM, 1100);
|
||
|
m_bcreatedAdapter = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::shutdownAdapter()
|
||
|
{
|
||
|
if (!m_bcreatedAdapter) return;
|
||
|
|
||
|
if (!m_osVersion)
|
||
|
{
|
||
|
((IDirect3D9*)m_pD3D9)->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
grcAdapterManager::ShutdownClass();
|
||
|
FreeLibrary((HINSTANCE)m_hDXGI);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::initCardManufacturer()
|
||
|
{
|
||
|
if (iTargetAdapter >= grcAdapterManager::GetInstance()->GetAdapterCount())
|
||
|
iTargetAdapter = 0;
|
||
|
|
||
|
IDXGIAdapter* pDeviceAdapter = ((const grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetDeviceAdapter();
|
||
|
AssertMsg(pDeviceAdapter, "Could not get the current device adapter");
|
||
|
|
||
|
pDeviceAdapter->GetDesc(&m_oAdapterDesc);
|
||
|
|
||
|
if (wcsstr(((const wchar_t*)&m_oAdapterDesc.Description), L"NVIDIA") || m_oAdapterDesc.VendorId == 0x10DE)
|
||
|
{
|
||
|
m_cardManufacturer = NVIDIA;
|
||
|
}
|
||
|
else if (wcsstr(((const wchar_t*)&m_oAdapterDesc.Description), L"ATI") || wcsstr(((const wchar_t*)&m_oAdapterDesc.Description), L"AMD") || m_oAdapterDesc.VendorId == 0x1002 || m_oAdapterDesc.VendorId == 0x1022)
|
||
|
{
|
||
|
m_cardManufacturer = ATI;
|
||
|
}
|
||
|
else if (wcsstr(((const wchar_t*)&m_oAdapterDesc.Description), L"Intel") || m_oAdapterDesc.VendorId == 0x8086 || m_oAdapterDesc.VendorId == 0x8087)
|
||
|
{
|
||
|
m_cardManufacturer = INTEL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_cardManufacturer = UNKNOWN_DEVICE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::initResolutionToMax()
|
||
|
{
|
||
|
if (iTargetAdapter >= grcAdapterManager::GetInstance()->GetAdapterCount())
|
||
|
iTargetAdapter = 0;
|
||
|
|
||
|
const grcAdapterD3D11* pAdapter = (const grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter);//(s64)sm_AdapterOrdinal);
|
||
|
AssertMsg(pAdapter, "Could not get the current adapter");
|
||
|
|
||
|
int iDisplayModes = pAdapter->GetModeCount();
|
||
|
grcDisplayWindow oDisplayWindow;
|
||
|
for (int mode = 0; mode < iDisplayModes; mode++)
|
||
|
{
|
||
|
pAdapter->GetMode(&oDisplayWindow, mode);
|
||
|
m_defaultDisplayWindow.uWidth = max(oDisplayWindow.uWidth, m_defaultDisplayWindow.uWidth);
|
||
|
m_defaultDisplayWindow.uHeight = max(oDisplayWindow.uHeight, m_defaultDisplayWindow.uHeight);
|
||
|
m_defaultDisplayWindow.uRefreshRate = max(oDisplayWindow.uRefreshRate, m_defaultDisplayWindow.uRefreshRate);
|
||
|
}
|
||
|
pAdapter->GetWidestMode (&m_defaultDisplayWindow);
|
||
|
m_defaultAspectRatio = (float)m_defaultDisplayWindow.uWidth / (float)m_defaultDisplayWindow.uHeight;
|
||
|
}
|
||
|
|
||
|
|
||
|
void SettingsDefaults::SetResolutionToClosestMode()
|
||
|
{
|
||
|
grcAdapterManager::GetInstance()->InitClass(D3DFMT_X8R8G8B8);
|
||
|
const grcAdapterD3D11* pAdapter = (const grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter);//(s64)sm_AdapterOrdinal);
|
||
|
AssertMsg(pAdapter, "Could not get the current adapter");
|
||
|
|
||
|
pAdapter->GetClosestModeMatchingAspect (&m_defaultDisplayWindow, m_defaultAspectRatio);
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::GetResolutionToClosestMode(grcDisplayWindow& currentSettings)
|
||
|
{
|
||
|
grcAdapterManager::GetInstance()->InitClass(D3DFMT_X8R8G8B8);
|
||
|
const grcAdapterD3D11* pAdapter = (const grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter);//(s64)sm_AdapterOrdinal);
|
||
|
AssertMsg(pAdapter, "Could not get the current adapter");
|
||
|
|
||
|
pAdapter->GetClosestMode (¤tSettings);
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::SetDXVersion()
|
||
|
{
|
||
|
int directXVersion = 1100;
|
||
|
switch (directXVersion)
|
||
|
{
|
||
|
case 900:
|
||
|
{
|
||
|
m_defaultDirectXVersion = 900;
|
||
|
return;
|
||
|
}
|
||
|
case 1000:
|
||
|
case 1100:
|
||
|
{
|
||
|
HMODULE hD3D11 = ::LoadLibrary("D3D11.DLL");
|
||
|
|
||
|
HMODULE hD3D10 = ::LoadLibrary("D3D10_1.DLL");
|
||
|
|
||
|
if (hD3D11)
|
||
|
{
|
||
|
HRESULT (WINAPI *l_D3D11CreateDevice)(
|
||
|
IDXGIAdapter* pAdapter,D3D_DRIVER_TYPE DriverType,HMODULE Software,
|
||
|
UINT Flags,CONST D3D_FEATURE_LEVEL* pFeatureLevels,UINT FeatureLevels,
|
||
|
UINT SDKVersion,ID3D11Device** ppDevice,D3D_FEATURE_LEVEL* pFeatureLevel,
|
||
|
ID3D11DeviceContext** ppImmediateContext );
|
||
|
|
||
|
l_D3D11CreateDevice = (HRESULT (WINAPI *)(
|
||
|
IDXGIAdapter* pAdapter,D3D_DRIVER_TYPE DriverType,HMODULE Software,
|
||
|
UINT Flags,CONST D3D_FEATURE_LEVEL* pFeatureLevels,UINT FeatureLevels,
|
||
|
UINT SDKVersion,ID3D11Device** ppDevice,D3D_FEATURE_LEVEL* pFeatureLevel,
|
||
|
ID3D11DeviceContext** ppImmediateContext ))::GetProcAddress(hD3D11,"D3D11CreateDevice");
|
||
|
|
||
|
D3D_FEATURE_LEVEL chosenFeatureLevel;
|
||
|
HRESULT hr;
|
||
|
hr = l_D3D11CreateDevice( NULL,
|
||
|
D3D_DRIVER_TYPE_HARDWARE,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
0,
|
||
|
D3D11_SDK_VERSION,
|
||
|
NULL,
|
||
|
&chosenFeatureLevel,
|
||
|
NULL );
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
m_defaultDirectXVersion = 900;
|
||
|
return;
|
||
|
}
|
||
|
switch(chosenFeatureLevel)
|
||
|
{
|
||
|
case D3D_FEATURE_LEVEL_10_0:
|
||
|
m_defaultDirectXVersion = 1000;
|
||
|
break;
|
||
|
case D3D_FEATURE_LEVEL_10_1:
|
||
|
m_defaultDirectXVersion = 1010;
|
||
|
break;
|
||
|
case D3D_FEATURE_LEVEL_11_0:
|
||
|
m_defaultDirectXVersion = 1100;
|
||
|
break;
|
||
|
default:
|
||
|
m_defaultDirectXVersion = 0;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (hD3D10) { //TODO: figure out how to determine dxversion of card if using DX10/DX10.1 runtime
|
||
|
m_defaultDirectXVersion = 1000;
|
||
|
return;
|
||
|
}
|
||
|
m_defaultDirectXVersion = 900;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::GetDisplayInfo()
|
||
|
{
|
||
|
m_setMinTextureQuality = false;
|
||
|
|
||
|
SetDXVersion();
|
||
|
|
||
|
#if USE_RESOURCE_CACHE
|
||
|
m_osVersion = grcResourceCache::GetOSVersion();
|
||
|
#endif
|
||
|
|
||
|
m_bcreatedAdapter = false;
|
||
|
|
||
|
initAdapter();
|
||
|
initCardManufacturer();
|
||
|
initResolutionToMax();
|
||
|
|
||
|
rage::grcDisplayInfo info;
|
||
|
info.oAdapterDesc = &m_oAdapterDesc;
|
||
|
info.iTargetAdapter = iTargetAdapter;
|
||
|
info.numOfCores = 100;
|
||
|
info.gpuClockMax = 1000;
|
||
|
info.memClockMax = 1000;
|
||
|
info.videoMemSize = info.sharedMemSize = 512<<20;
|
||
|
info.memBandwidth = 20<<20;
|
||
|
|
||
|
u32 uVidMem = 0;
|
||
|
PARAM_availablevidmem.Get(uVidMem);
|
||
|
|
||
|
bool initDone = false;
|
||
|
|
||
|
if (GRCDEVICE.IsUsingVendorAPI())
|
||
|
{
|
||
|
#if NV_SUPPORT
|
||
|
if(m_cardManufacturer == NVIDIA)
|
||
|
{
|
||
|
GRCDEVICE.InitNVIDIA();
|
||
|
}
|
||
|
|
||
|
if(GRCDEVICE.IsUsingNVidiaAPI() && m_cardManufacturer == NVIDIA)
|
||
|
{
|
||
|
info.videoMemSize = -1;
|
||
|
grcAdapterD3D11::GetNvidiaDisplayInfo(info);
|
||
|
|
||
|
if (info.videoMemSize == -1)
|
||
|
{
|
||
|
info.videoMemSize = m_oAdapterDesc.DedicatedVideoMemory;
|
||
|
info.sharedMemSize = m_oAdapterDesc.SharedSystemMemory;
|
||
|
}
|
||
|
|
||
|
m_numOfCores = info.numOfCores;
|
||
|
m_gpuClockMax = info.gpuClockMax;
|
||
|
m_memClockMax = info.memClockMax;
|
||
|
m_videoMemSize = info.videoMemSize;
|
||
|
m_sharedMemSize = info.sharedMemSize;
|
||
|
m_memBandwidth = info.memBandwidth;
|
||
|
|
||
|
m_memBandwidth = 16 * info.memClockMax;
|
||
|
m_processingPower = info.numOfCores * info.gpuClockMax;// * numGPUs; I think numGPUs is taken into account in numOfCores
|
||
|
|
||
|
const float fNVidiaScalingOnAdditionalGPUs = 1.0f;
|
||
|
m_memBandwidth = m_memBandwidth + (s64)((float)m_memBandwidth * (((float)((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount() - 1) * fNVidiaScalingOnAdditionalGPUs));
|
||
|
|
||
|
Displayf("GPU Count %d Cores %" I64FMT "d GPU Clock %" I64FMT "d Processing Power %" I64FMT "d Mem Bandwidth %" I64FMT "d",
|
||
|
((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount(), m_numOfCores, m_gpuClockMax, m_processingPower, m_memBandwidth);
|
||
|
|
||
|
|
||
|
m_videoMemSize = (uVidMem) ? (s64)uVidMem * (s64)1024 * (s64)1024 : m_videoMemSize;
|
||
|
getNVidiaDefaults();
|
||
|
|
||
|
initDone = true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if ATI_SUPPORT
|
||
|
if(m_cardManufacturer == ATI)
|
||
|
{
|
||
|
info.videoMemSize = -1;
|
||
|
grcAdapterD3D11::GetATIDisplayInfo(info);
|
||
|
|
||
|
if (info.videoMemSize == -1)
|
||
|
{
|
||
|
info.videoMemSize = m_oAdapterDesc.DedicatedVideoMemory;
|
||
|
info.sharedMemSize = m_oAdapterDesc.SharedSystemMemory;
|
||
|
}
|
||
|
|
||
|
m_numOfCores = info.numOfCores;
|
||
|
m_gpuClockMax = info.gpuClockMax;
|
||
|
m_memClockMax = info.memClockMax;
|
||
|
m_videoMemSize = info.videoMemSize;
|
||
|
m_sharedMemSize = info.sharedMemSize;
|
||
|
m_memBandwidth = info.memBandwidth;
|
||
|
|
||
|
const SIZE_T uMinVideoMemory = 900 * 1024 * 1024;
|
||
|
m_videoMemSize = (s64)(( m_videoMemSize < uMinVideoMemory ) ? ((m_sharedMemSize < uMinVideoMemory) ? (2048ULL * 1024ULL * 1024ULL) : m_sharedMemSize) : m_videoMemSize);
|
||
|
|
||
|
m_numOfCores = 240;
|
||
|
m_processingPower = m_numOfCores * m_gpuClockMax;
|
||
|
|
||
|
const float fCrossfireScalingOnAdditionalGPUs = 1.0f;
|
||
|
m_memBandwidth = m_memBandwidth + (s64)((float)m_memBandwidth * (((float)((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount() - 1) * fCrossfireScalingOnAdditionalGPUs));
|
||
|
|
||
|
Displayf("GPU Count %d Cores %" I64FMT "d GPU Clock %" I64FMT "d Processing Power %" I64FMT "d Mem Bandwidth %" I64FMT "d",
|
||
|
((grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(iTargetAdapter))->GetGPUCount(), m_numOfCores, m_gpuClockMax, m_processingPower, m_memBandwidth);
|
||
|
|
||
|
m_videoMemSize = (uVidMem) ? (s64)uVidMem * (s64)1024 * (s64)1024 : m_videoMemSize;
|
||
|
getATIDefaults();
|
||
|
|
||
|
initDone = true;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* if(m_cardManufacturer == INTEL)
|
||
|
{
|
||
|
GetIntelDisplayInfo();
|
||
|
|
||
|
m_videoMemSize = (s64)GRCDEVICE.RetrieveVideoMemory();
|
||
|
m_videoMemSize = (uVidMem) ? (s64)uVidMem * (s64)1024 * (s64)1024 : m_videoMemSize;
|
||
|
getIntelDefaults();
|
||
|
|
||
|
initDone = true;
|
||
|
}*/
|
||
|
}
|
||
|
|
||
|
if(!initDone)
|
||
|
{
|
||
|
m_videoMemSize = (s64)GRCDEVICE.RetrieveVideoMemory();
|
||
|
m_videoMemSize = (uVidMem) ? (s64)uVidMem * (s64)1024 * (s64)1024 : m_videoMemSize;
|
||
|
minimumSpecNoCheapShaders();
|
||
|
|
||
|
initDone = true;
|
||
|
}
|
||
|
|
||
|
if (IsLowQualitySystem(m_Defaults))
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::Low;
|
||
|
}
|
||
|
|
||
|
DetermineTextureDefaults();
|
||
|
LimitDefaultsForWeakCpu();
|
||
|
|
||
|
shutdownAdapter();
|
||
|
}
|
||
|
|
||
|
|
||
|
SettingsDefaults::SettingsDefaults()
|
||
|
{
|
||
|
m_Defaults = CSettingsManager::GetInstance().GetSafeModeSettings();
|
||
|
#if !RSG_PC
|
||
|
m_Defaults.m_video.m_ScreenWidth = 1920;
|
||
|
m_Defaults.m_video.m_ScreenHeight = 1080;
|
||
|
#endif // !RSG_PC
|
||
|
|
||
|
GRCDEVICE.InitAdapterOrdinal();
|
||
|
iTargetAdapter = GRCDEVICE.GetAdapterOrdinal();
|
||
|
// if (PARAM_adapter.Get())
|
||
|
// PARAM_adapter.Get(iTargetAdapter);
|
||
|
// s64 videoMemory = GRCDEVICE.GetAvailableVideoMemory();
|
||
|
GetDisplayInfo();
|
||
|
|
||
|
switch (m_defaultDirectXVersion)
|
||
|
{
|
||
|
case 900:
|
||
|
case 1000:
|
||
|
m_Defaults.m_graphics.m_DX_Version = 0;
|
||
|
break;
|
||
|
case 1010:
|
||
|
m_Defaults.m_graphics.m_DX_Version = 1;
|
||
|
break;
|
||
|
case 1100:
|
||
|
m_Defaults.m_graphics.m_DX_Version = 2;
|
||
|
break;
|
||
|
default:
|
||
|
m_Defaults.m_graphics.m_DX_Version = 0;
|
||
|
break;
|
||
|
}
|
||
|
// m_Defaults.m_graphics.UpdateFromSliders();
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::DetermineTextureDefaults()
|
||
|
{
|
||
|
m_defaultVSync = 1;
|
||
|
|
||
|
s64 renderTargetSize = renderTargetMemSizeFor(m_Defaults);
|
||
|
s64 fragmentationVideoMemSize = (s64)(m_videoMemSize * g_fPercentForStreamer);
|
||
|
|
||
|
if (m_setMinTextureQuality) {
|
||
|
m_Defaults.m_graphics.m_TextureQuality = CSettings::Low;
|
||
|
}
|
||
|
else if (fragmentationVideoMemSize > (videoMemoryUsage(CSettings::High, m_Defaults) + renderTargetSize))
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_TextureQuality = CSettings::High;
|
||
|
|
||
|
s64 slushMemory = fragmentationVideoMemSize - (videoMemoryUsage(CSettings::High, m_Defaults) + renderTargetSize);
|
||
|
const u64 maxSpace = 200 * 1024 * 1024;
|
||
|
if (slushMemory > maxSpace)
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_PedVarietyMultiplier = 1.0f;
|
||
|
m_Defaults.m_graphics.m_VehicleVarietyMultiplier = 1.0f;
|
||
|
}
|
||
|
}
|
||
|
else if (fragmentationVideoMemSize > (videoMemoryUsage(CSettings::Medium, m_Defaults) + renderTargetSize))
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_TextureQuality = CSettings::Medium;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((fragmentationVideoMemSize < (videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetSize)))
|
||
|
{
|
||
|
Warningf("Insufficient fragmented memory for your settings %dMB requires %dMB - Lowering Vehicle Variety", (u32)(fragmentationVideoMemSize / (1024 * 1024)), ((videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetSize) / (1024 * 1024)));
|
||
|
|
||
|
while(m_Defaults.m_graphics.m_PedVarietyMultiplier > 0.0)
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_PedVarietyMultiplier -= 0.1f;
|
||
|
m_Defaults.m_graphics.m_VehicleVarietyMultiplier -= 0.1f;
|
||
|
|
||
|
if (fragmentationVideoMemSize > (videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetSize))
|
||
|
break;
|
||
|
}
|
||
|
m_Defaults.m_graphics.m_PedVarietyMultiplier = Clamp(m_Defaults.m_graphics.m_PedVarietyMultiplier, 0.0f, 1.0f);
|
||
|
m_Defaults.m_graphics.m_VehicleVarietyMultiplier = Clamp(m_Defaults.m_graphics.m_VehicleVarietyMultiplier, 0.0f, 1.0f);
|
||
|
}
|
||
|
|
||
|
// TODO - Lower render targets until we fit
|
||
|
while (m_currentDefaultSettingsLevel > 0 && fragmentationVideoMemSize < videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetMemSizeFor(m_Defaults))
|
||
|
{
|
||
|
switch (m_currentDefaultSettingsLevel)
|
||
|
{
|
||
|
case 0:
|
||
|
downgradeToLevel0Settings();
|
||
|
break;
|
||
|
case 1:
|
||
|
downgradeToLevel0Settings();
|
||
|
break;
|
||
|
case 2:
|
||
|
downgradeToLevel1Settings();
|
||
|
break;
|
||
|
case 3:
|
||
|
downgradeToLevel2Settings();
|
||
|
break;
|
||
|
case 4:
|
||
|
downgradeToLevel3Settings();
|
||
|
break;
|
||
|
case 5:
|
||
|
downgradeToLevel4Settings();
|
||
|
break;
|
||
|
default:
|
||
|
downgradeToLevel0Settings();
|
||
|
break;
|
||
|
}
|
||
|
renderTargetSize = renderTargetMemSizeFor(m_Defaults);
|
||
|
}
|
||
|
|
||
|
Assertf((m_videoMemSize > (videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetSize)), "Insufficient memory for your settings %dMB requires %dMB", (u32)(m_videoMemSize / (1024 * 1024)), ((videoMemoryUsage(CSettings::Low, m_Defaults) + renderTargetSize) / (1024 * 1024)));
|
||
|
m_Defaults.m_graphics.m_TextureQuality = CSettings::Low;
|
||
|
}
|
||
|
|
||
|
m_defaultStereo3DConvergence = 7.0f;
|
||
|
m_defaultStereo3DSeparation = 10.0f;
|
||
|
Displayf("Default Selected Level %d for GPU", m_currentDefaultSettingsLevel);
|
||
|
|
||
|
/*
|
||
|
water-1 3%
|
||
|
water-2 5%
|
||
|
shadow-3 120%
|
||
|
shadow-2 60%
|
||
|
shadow-1 50%
|
||
|
fxaa-4/3/2 10%
|
||
|
fxaa-1 5%
|
||
|
ssao 20%
|
||
|
reflection-3 10%
|
||
|
reflection-2 5%
|
||
|
reflection-1 3%
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
void SettingsDefaults::getNVidiaDefaults() {
|
||
|
// defaultStereo3DEnabled = grcDevice::StereoIsPossible() ? 1 : 0;
|
||
|
s64 oneMillion = 1000000;
|
||
|
s64 resolution = m_defaultDisplayWindow.uWidth * m_defaultDisplayWindow.uHeight;
|
||
|
float baseResolution = 1024 * 1600;
|
||
|
float resFactor = resolution / baseResolution; // * (defaultStereo3DEnabled + 1);
|
||
|
|
||
|
InitializeToMaximumDefaultSettings();
|
||
|
|
||
|
if ((m_processingPower < 30 * oneMillion) || (m_videoMemSize < 1024 * 1024 * 900)) { //Also use lowest settings if less than a gig of video memory
|
||
|
downgradeToLevel0Settings();
|
||
|
return;
|
||
|
} //minimum specs
|
||
|
|
||
|
static int minResSetting = 100;
|
||
|
static int maxResSetting = 500;
|
||
|
static int superMax = 2000;
|
||
|
static int iMinWidth = 1024;
|
||
|
static int iMinHeight = 768;
|
||
|
|
||
|
PARAM_MinPower.Get(minResSetting);
|
||
|
PARAM_MaxPower.Get(maxResSetting);
|
||
|
PARAM_SuperMaxPower.Get(superMax);
|
||
|
PARAM_MinWidth.Get(iMinWidth);
|
||
|
PARAM_MinHeight.Get(iMinHeight);
|
||
|
|
||
|
if (m_processingPower < minResSetting * oneMillion) {
|
||
|
downgradeToLevel1Settings();
|
||
|
return;
|
||
|
} //minimum resolution console settings
|
||
|
|
||
|
if (m_processingPower < maxResSetting * oneMillion * resFactor) {
|
||
|
downgradeToLevel3Settings();
|
||
|
|
||
|
s64 powerOverMin = m_processingPower - minResSetting * oneMillion;
|
||
|
float percentageOfMaxRes = powerOverMin / float((maxResSetting - minResSetting) * oneMillion * resFactor);
|
||
|
m_defaultDisplayWindow.uWidth = iMinWidth + (s64)((m_defaultDisplayWindow.uWidth - iMinWidth) * percentageOfMaxRes);
|
||
|
m_defaultDisplayWindow.uHeight = iMinHeight + (s64)((m_defaultDisplayWindow.uHeight - iMinHeight) * percentageOfMaxRes);
|
||
|
|
||
|
SetResolutionToClosestMode ();
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = m_defaultDisplayWindow.uWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = m_defaultDisplayWindow.uHeight;
|
||
|
m_Defaults.m_video.m_RefreshRate = m_defaultDisplayWindow.uRefreshRate;
|
||
|
|
||
|
return;
|
||
|
} //maximum resolution console settings
|
||
|
|
||
|
if (m_processingPower < (s64)((s64)superMax * oneMillion * resFactor)) {
|
||
|
downgradeToLevel4Settings();
|
||
|
return;
|
||
|
} //maximum resolution high settings
|
||
|
|
||
|
return; //maximum resolution max settings
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::getIntelDefaults()
|
||
|
{
|
||
|
const s64 oneMillion = 1000000;
|
||
|
/*
|
||
|
s64 resolution = m_defaultDisplayWindow.uWidth * m_defaultDisplayWindow.uHeight;
|
||
|
float baseResolution = 1024 * 1600;
|
||
|
float resFactor = resolution / baseResolution;// * (defaultStereo3DEnabled + 1);
|
||
|
*/
|
||
|
|
||
|
InitializeToMaximumDefaultSettings();
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 1;
|
||
|
|
||
|
if (m_memBandwidth < 20 * oneMillion) {
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 0;
|
||
|
m_Defaults.m_graphics.m_LodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 0.0f;
|
||
|
m_Defaults.m_graphics.m_PedLodBias = 0.0f;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = false;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Low;
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = 800;
|
||
|
m_Defaults.m_video.m_ScreenHeight = 600;
|
||
|
//m_setMinTextureQuality = true;
|
||
|
|
||
|
return;
|
||
|
} //minimum specs
|
||
|
|
||
|
if (m_memBandwidth < 40 * oneMillion)
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 0;
|
||
|
m_Defaults.m_graphics.m_LodScale = 1.0f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 1.0f;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = true;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_MotionBlurStrength = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Medium;
|
||
|
|
||
|
m_defaultDisplayWindow.uWidth = 1280;
|
||
|
m_defaultDisplayWindow.uHeight = 720;
|
||
|
|
||
|
SetResolutionToClosestMode ();
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = m_defaultDisplayWindow.uWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = m_defaultDisplayWindow.uHeight;
|
||
|
m_Defaults.m_video.m_RefreshRate = m_defaultDisplayWindow.uRefreshRate;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 0;
|
||
|
m_Defaults.m_graphics.m_LodScale = 1.0f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 1.0f;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = true;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_MotionBlurStrength = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Medium;
|
||
|
|
||
|
m_defaultDisplayWindow.uWidth = 1280;
|
||
|
m_defaultDisplayWindow.uHeight = 720;
|
||
|
|
||
|
SetResolutionToClosestMode ();
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = m_defaultDisplayWindow.uWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = m_defaultDisplayWindow.uHeight;
|
||
|
m_Defaults.m_video.m_RefreshRate = m_defaultDisplayWindow.uRefreshRate;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::getATIDefaults() {
|
||
|
// defaultStereo3DEnabled = 0;
|
||
|
|
||
|
s64 oneMillion = 1000000;
|
||
|
s64 resolution = m_defaultDisplayWindow.uWidth * m_defaultDisplayWindow.uHeight;
|
||
|
float baseResolution = 1024 * 1600;
|
||
|
float resFactor = resolution / baseResolution;// * (defaultStereo3DEnabled + 1);
|
||
|
|
||
|
InitializeToMaximumDefaultSettings();
|
||
|
|
||
|
if ((m_memBandwidth < 30 * oneMillion) || (m_videoMemSize < 1024 * 1024 * 900)) { //Also use lowest settings if less than a gig of video memory
|
||
|
downgradeToLevel0Settings();
|
||
|
return;
|
||
|
} //minimum specs
|
||
|
|
||
|
int minResSetting = 80;
|
||
|
int maxResSetting = 200;
|
||
|
static int iMinWidth = 1024;
|
||
|
static int iMinHeight = 768;
|
||
|
PARAM_MinWidth.Get(iMinWidth);
|
||
|
PARAM_MinHeight.Get(iMinHeight);
|
||
|
|
||
|
if (m_memBandwidth < minResSetting * oneMillion) {
|
||
|
downgradeToLevel1Settings();
|
||
|
return;
|
||
|
} //minimum resolution console settings
|
||
|
|
||
|
if (m_memBandwidth < maxResSetting * oneMillion * resFactor) {
|
||
|
downgradeToLevel3Settings();
|
||
|
|
||
|
s64 powerOverMin = m_memBandwidth - minResSetting * oneMillion;
|
||
|
float percentageOfMaxRes = powerOverMin / float((maxResSetting - minResSetting) * oneMillion * resFactor);
|
||
|
m_defaultDisplayWindow.uWidth = iMinWidth + (s64)((m_defaultDisplayWindow.uWidth - iMinWidth) * percentageOfMaxRes);
|
||
|
m_defaultDisplayWindow.uHeight = iMinHeight + (s64)((m_defaultDisplayWindow.uHeight - iMinHeight) * percentageOfMaxRes);
|
||
|
|
||
|
SetResolutionToClosestMode ();
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = m_defaultDisplayWindow.uWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = m_defaultDisplayWindow.uHeight;
|
||
|
m_Defaults.m_video.m_RefreshRate = m_defaultDisplayWindow.uRefreshRate;
|
||
|
|
||
|
return;
|
||
|
} //maximum resolution console settings
|
||
|
|
||
|
if (m_memBandwidth < 300 * oneMillion * resFactor) {
|
||
|
downgradeToLevel4Settings();
|
||
|
return;
|
||
|
} //maximum resolution high settings
|
||
|
|
||
|
return; //maximum resolution max settings
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::downgradeToLevel0Settings()
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 0;
|
||
|
m_Defaults.m_graphics.m_LodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 0.0f;
|
||
|
m_Defaults.m_graphics.m_PedLodBias = 0.0f;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = false;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_MotionBlurStrength = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Low;
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = 800;
|
||
|
m_Defaults.m_video.m_ScreenHeight = 600;
|
||
|
m_Defaults.m_video.m_VSync = 2;
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 0;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::downgradeToLevel1Settings()
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 4;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_LodScale = 0.7f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 0.5f;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = false;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_MotionBlurStrength = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Low;
|
||
|
|
||
|
static int iMinWidth = 1024;
|
||
|
static int iMinHeight = 768;
|
||
|
PARAM_MinWidth.Get(iMinWidth);
|
||
|
PARAM_MinHeight.Get(iMinHeight);
|
||
|
m_Defaults.m_video.m_ScreenWidth = iMinWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = iMinHeight;
|
||
|
m_Defaults.m_video.m_VSync = 2;
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 1;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::downgradeToLevel2Settings()
|
||
|
{
|
||
|
static int iMinWidth = 1024;
|
||
|
static int iMinHeight = 768;
|
||
|
PARAM_MinWidth.Get(iMinWidth);
|
||
|
PARAM_MinHeight.Get(iMinHeight);
|
||
|
m_Defaults.m_video.m_ScreenWidth = iMinWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = iMinHeight;
|
||
|
m_Defaults.m_video.m_VSync = 2;
|
||
|
m_currentDefaultSettingsLevel = 2;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::downgradeToLevel3Settings()
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Low;
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 3;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::downgradeToLevel4Settings()
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Medium;
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 4;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::InitializeToMaximumDefaultSettings()
|
||
|
{
|
||
|
m_Defaults.m_video.m_ScreenWidth = m_defaultDisplayWindow.uWidth;
|
||
|
m_Defaults.m_video.m_ScreenHeight = m_defaultDisplayWindow.uHeight;
|
||
|
m_Defaults.m_video.m_Windowed = 0;
|
||
|
m_Defaults.m_video.m_VSync = 1;
|
||
|
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Ultra;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 4;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_LodScale = 1.0f;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 1.0f;
|
||
|
m_Defaults.m_graphics.m_PedVarietyMultiplier = 0.8f;
|
||
|
m_Defaults.m_graphics.m_VehicleVarietyMultiplier = 0.8f;
|
||
|
m_Defaults.m_graphics.m_PedLodBias = 0.2f;
|
||
|
m_Defaults.m_graphics.m_VehicleLodBias = 0.0f;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 16;
|
||
|
m_Defaults.m_graphics.m_MSAA = 0;
|
||
|
m_Defaults.m_graphics.m_MSAAFragments = 0;
|
||
|
m_Defaults.m_graphics.m_MSAAQuality = 0;
|
||
|
m_Defaults.m_graphics.m_SamplingMode = 0;
|
||
|
m_Defaults.m_graphics.m_FXAA_Enabled = true;
|
||
|
m_Defaults.m_graphics.m_Shadow_SoftShadows = CSettings::Ultra;
|
||
|
m_Defaults.m_graphics.m_HdStreamingInFlight = false;
|
||
|
m_Defaults.m_graphics.m_MaxLodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_MotionBlurStrength = 0.0f;
|
||
|
m_Defaults.m_graphics.m_DoF = true;
|
||
|
|
||
|
// Allow shadow angle past 5pm to cast really long shadows
|
||
|
m_Defaults.m_graphics.m_Shadow_LongShadows = false; // No GUI/Command line control - Could hook this up to ultra shadows
|
||
|
// Allow casting distance to increase.
|
||
|
m_Defaults.m_graphics.m_Shadow_Distance = 1.0f; // // No GUI/Command line control - Could hook this up to ultra shadows
|
||
|
// Can turn off reflection blur
|
||
|
m_Defaults.m_graphics.m_Reflection_MipBlur = true;
|
||
|
// Fog Light Volumes
|
||
|
m_Defaults.m_graphics.m_Lighting_FogVolumes = true;
|
||
|
|
||
|
m_Defaults.m_graphics.m_Shadow_ParticleShadows = true; // No GUI/Command line control - Shadow overrides it
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::High;
|
||
|
m_Defaults.m_graphics.m_Shader_SSA = true; // No GUI/Command line control - MSAA has the ability to disable it
|
||
|
|
||
|
m_currentDefaultSettingsLevel = 5;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::LimitDefaultsForWeakCpu()
|
||
|
{
|
||
|
char vendorStr[12];
|
||
|
u32 cpuInfo[4];
|
||
|
__cpuid((int*)cpuInfo, 0);
|
||
|
|
||
|
*(u32*)(&vendorStr[0]) = cpuInfo[1];
|
||
|
*(u32*)(&vendorStr[4]) = cpuInfo[3];
|
||
|
*(u32*)(&vendorStr[8]) = cpuInfo[2];
|
||
|
|
||
|
LARGE_INTEGER cpuFrequency;
|
||
|
QueryPerformanceFrequency(&cpuFrequency);
|
||
|
|
||
|
// Lower settings for older CPUs if they have a low clock frequency.
|
||
|
if ((!strncmp(vendorStr, "GenuineIntel", sizeof(vendorStr)) && (cpuFrequency.QuadPart < MINREQ_INTEL_CPU_FREQUENCY)) ||
|
||
|
(!strncmp(vendorStr, "AuthenticAMD", sizeof(vendorStr)) && (cpuFrequency.QuadPart < MINREQ_AMD_CPU_FREQUENCY)))
|
||
|
{
|
||
|
__cpuid((int*)cpuInfo, 1);
|
||
|
bool isAvxSupported = (cpuInfo[2] & (1 << 28)) != 0;
|
||
|
|
||
|
// If AVX instructions aren't supported, this is likely a pre-2011 CPU. AMD introduced
|
||
|
// AVX support with Bulldozer and Intel with Sandy Bridge.
|
||
|
if (!isAvxSupported)
|
||
|
{
|
||
|
m_Defaults.m_graphics.m_LodScale = 0.0f;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_CityDensity = 0.0f;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Low;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::minimumSpecNoCheapShaders() {
|
||
|
// defaultStereo3DEnabled = 0;
|
||
|
|
||
|
m_Defaults.m_graphics.m_Tessellation = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShadowQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_ReflectionMSAA = 0;
|
||
|
m_Defaults.m_graphics.m_ParticleQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_WaterQuality = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_ShaderQuality = CSettings::Medium;
|
||
|
m_Defaults.m_graphics.m_AnisotropicFiltering = 0;
|
||
|
m_Defaults.m_graphics.m_SSAO = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_PostFX = CSettings::Low;
|
||
|
m_Defaults.m_graphics.m_DoF = false;
|
||
|
m_Defaults.m_graphics.m_GrassQuality = CSettings::Medium;
|
||
|
|
||
|
m_Defaults.m_video.m_ScreenWidth = 800;
|
||
|
m_Defaults.m_video.m_ScreenHeight = 600;
|
||
|
|
||
|
// m_setMinTextureQuality = true;
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::PerformMinSpecTests()
|
||
|
{
|
||
|
// Check if the PC meets minimum requirements
|
||
|
if (sysMemTotalMemory() < MINREQ_PHYSICAL_MEMORY)
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_MEM);
|
||
|
}
|
||
|
|
||
|
VerifyCpuSpecs();
|
||
|
|
||
|
DXGI_ADAPTER_DESC oAdapterDesc;
|
||
|
|
||
|
IDXGIAdapter* pDXGIAdapter = ((const grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(GRCDEVICE.GetAdapterOrdinal()))->GetDeviceAdapter();
|
||
|
AssertMsg(pDXGIAdapter, "Could not get the current device adapter");
|
||
|
|
||
|
if( SUCCEEDED( pDXGIAdapter->GetDesc(&oAdapterDesc) ) )
|
||
|
{
|
||
|
const SIZE_T uMinVideoMemory = 900 * 1024 * 1024;
|
||
|
const s64 dedicatedVideoMemory = (s64)(( oAdapterDesc.DedicatedVideoMemory < uMinVideoMemory ) ? ((oAdapterDesc.SharedSystemMemory < uMinVideoMemory) ? (2048ULL * 1024ULL * 1024ULL) : oAdapterDesc.SharedSystemMemory) : oAdapterDesc.DedicatedVideoMemory);
|
||
|
if ( dedicatedVideoMemory < MINREQ_VIDEO_MEMORY)
|
||
|
{
|
||
|
if (dedicatedVideoMemory > 0 &&
|
||
|
wcsstr((const wchar_t*)&oAdapterDesc.Description, L"Intel"))
|
||
|
{
|
||
|
// For now assume that any Intel solutions with dedicated video memory are Iris or newer.
|
||
|
// If any older solutions pass our min spec rating, we can explicitly check for them via description or ID.
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_VID_MEM);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::VerifyCpuSpecs()
|
||
|
{
|
||
|
char vendorStr[12];
|
||
|
u32 cpuInfo[4];
|
||
|
__cpuid((int*)cpuInfo, 0);
|
||
|
|
||
|
*(u32*)(&vendorStr[0]) = cpuInfo[1];
|
||
|
*(u32*)(&vendorStr[4]) = cpuInfo[3];
|
||
|
*(u32*)(&vendorStr[8]) = cpuInfo[2];
|
||
|
|
||
|
if (!strncmp(vendorStr, "GenuineIntel", sizeof(vendorStr)))
|
||
|
{
|
||
|
__cpuid((int*)cpuInfo, 1);
|
||
|
|
||
|
if (sysIpcGetProcessorCount() < MINREQ_CPU_CORE_COUNT)
|
||
|
{
|
||
|
bool isHyperThreaded = (cpuInfo[3] & (1 << 28)) != 0;
|
||
|
if ((sysIpcGetProcessorCount() * 2) >= MINREQ_CPU_CORE_COUNT && isHyperThreaded)
|
||
|
{
|
||
|
// Dual core with Hyper-threading is okay
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_CPU_CORE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LARGE_INTEGER cpuFrequency;
|
||
|
QueryPerformanceFrequency(&cpuFrequency);
|
||
|
|
||
|
if (cpuFrequency.QuadPart < MINREQ_INTEL_CPU_FREQUENCY)
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_CPU_FREQ);
|
||
|
}
|
||
|
|
||
|
// TODO: We may need to let lower clocked but newer CPUs through.
|
||
|
// Use __cpuid to check for supported extensions like AVX2.
|
||
|
}
|
||
|
else if (!strncmp(vendorStr, "AuthenticAMD", sizeof(vendorStr)))
|
||
|
{
|
||
|
if (sysIpcGetProcessorCount() < MINREQ_CPU_CORE_COUNT)
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_CPU_CORE);
|
||
|
}
|
||
|
|
||
|
LARGE_INTEGER cpuFrequency;
|
||
|
QueryPerformanceFrequency(&cpuFrequency);
|
||
|
|
||
|
if (cpuFrequency.QuadPart < MINREQ_AMD_CPU_FREQUENCY)
|
||
|
{
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_CPU_FREQ);
|
||
|
}
|
||
|
|
||
|
// TODO: We may need to let lower clocked but newer CPUs through.
|
||
|
// Use __cpuid to check for supported extensions like ABM.
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Unknown CPU Vendor. Might not be able to run the game.
|
||
|
DisplayMinReqMsgBox(ERR_SYS_MINREQ_CPU);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SettingsDefaults::DisplayMinReqMsgBox(int errorCode)
|
||
|
{
|
||
|
#if !__FINAL
|
||
|
const char* pSmokeTestName = NULL;
|
||
|
if(SmokeTests::PARAM_smoketest.Get(pSmokeTestName))
|
||
|
return;
|
||
|
|
||
|
const char* pScriptName = NULL;
|
||
|
PARAM_runscript.Get(pScriptName);
|
||
|
if(pScriptName && !stricmp(pScriptName,"fps_test"))
|
||
|
return;
|
||
|
#endif
|
||
|
|
||
|
int msgBoxResult = MessageBoxW(NULL, rage::diagErrorCodes::GetErrorMessageString(static_cast<rage::FatalErrorCode>(errorCode)), rage::diagErrorCodes::GetErrorMessageString(ERR_SYS_MINREQ_TITLE), MB_OKCANCEL | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
|
||
|
if (msgBoxResult == IDCANCEL)
|
||
|
{
|
||
|
ShellExecuteW(NULL, L"open", rage::diagErrorCodes::GetErrorMessageString(ERR_SYS_MINREQ_URL), NULL, NULL, SW_SHOWMAXIMIZED);
|
||
|
ExitProcess(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool SettingsDefaults::IsLowQualitySystem(const Settings &settings)
|
||
|
{
|
||
|
const grcAdapterD3D11* adapterTest = (grcAdapterD3D11*)grcAdapterManager::GetInstance()->GetAdapter(settings.m_video.m_AdapterIndex);
|
||
|
|
||
|
IDXGIAdapter* pDeviceAdapter = adapterTest->GetDeviceAdapter();
|
||
|
AssertMsg(pDeviceAdapter, "Could not get the current device adapter");
|
||
|
|
||
|
DXGI_ADAPTER_DESC oAdapterDesc;
|
||
|
pDeviceAdapter->GetDesc(&oAdapterDesc);
|
||
|
|
||
|
|
||
|
if (oAdapterDesc.VendorId == 0x1002 || oAdapterDesc.VendorId == 0x1022)
|
||
|
{
|
||
|
if ((oAdapterDesc.DeviceId == 0x9440 || //AMD Radeon HD 4870
|
||
|
oAdapterDesc.DeviceId == 0x9441 || //AMD Radeon HD 4870 X2
|
||
|
oAdapterDesc.DeviceId == 0x9442 || //AMD Radeon HD 4850
|
||
|
oAdapterDesc.DeviceId == 0x9443 || //AMD Radeon HD 4850 X2
|
||
|
oAdapterDesc.DeviceId == 0x9460 || //AMD Radeon HD 4890
|
||
|
oAdapterDesc.DeviceId == 0x68c8 //ATI FirePro V4800 (FireGL) Graphics Adapter
|
||
|
) &&
|
||
|
(sysIpcGetProcessorCount() <= 4)
|
||
|
)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
#endif //__WIN32PC
|