You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/RenderDll/XRenderD3D9/DriverD3D.h

2399 lines
93 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include "Cry_XOptimise.h"
#include "IWindowMessageHandler.h"
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define DRIVERD3D_H_SECTION_2 2
#define DRIVERD3D_H_SECTION_3 3
#define DRIVERD3D_H_SECTION_4 4
#define DRIVERD3D_H_SECTION_5 5
#define DRIVERD3D_H_SECTION_6 6
#define DRIVERD3D_H_SECTION_7 7
#define DRIVERD3D_H_SECTION_8 8
#define DRIVERD3D_H_SECTION_9 9
#define DRIVERD3D_H_SECTION_10 10
#define DRIVERD3D_H_SECTION_11 11
#define DRIVERD3D_H_SECTION_12 12
#endif
# if !defined(_RELEASE)
# define ENABLE_CONTEXT_THREAD_CHECKING 0
# endif
# if !defined(ENABLE_CONTEXT_THREAD_CHECKING)
# define ENABLE_CONTEXT_THREAD_CHECKING 0
# endif
/*
===========================================
The DXRenderer interface Class
===========================================
*/
_inline int _VertBufferSize(D3DBuffer* pVB)
{
if (!pVB)
{
return 0;
}
D3D11_BUFFER_DESC Desc;
pVB->GetDesc(&Desc);
return Desc.ByteWidth;
}
_inline int _IndexBufferSize(D3DBuffer* pIB)
{
if (!pIB)
{
return 0;
}
D3D11_BUFFER_DESC Desc;
pIB->GetDesc(&Desc);
return Desc.ByteWidth;
}
#define VERSION_D3D 2.0
struct SPixFormat;
struct SGraphicsPiplinePassContext;
#include "D3DRenderAuxGeom.h"
#include "D3DColorGradingController.h"
#include "D3DStereo.h"
#include "GraphicsPipeline/StandardGraphicsPipeline.h"
#include <RenderDll/Common/PerInstanceConstantBufferPool.h>
#include "D3DDeferredShading.h"
#include "D3DTiledShading.h"
#include "D3DVolumetricFog.h"
#include "GPUTimer.h"
#include "PipelineProfiler.h"
#include "D3DDebug.h"
#include "DeviceInfo.h"
//=======================================================================
#include <memory> // std::unique_ptr
#include <utility> // std::forward
template<typename T, typename ... TArgs>
inline std::unique_ptr<T> CryMakeUnique(TArgs&& ... args)
{
return std::make_unique<T>(std::forward<TArgs>(args) ...);
}
struct SD3DContext
{
HWND m_hWnd;
int m_X;
int m_Y;
// Real offscreen target width for rendering
int m_Width;
// Real offscreen target height for rendering
int m_Height;
IDXGISwapChain* m_pSwapChain;
std::vector<D3DSurface*> m_pBackBuffers;
D3DSurface* m_pBackBuffer;
unsigned int m_pCurrentBackBufferIndex;
// Width of viewport on screen to display rendered content in
int m_nViewportWidth;
// Height of viewport on screen to display rendered content in
int m_nViewportHeight;
// Pixel resolution scale in X, includes scale from r_SuperSampling and any operating system screen or viewport scale
float m_fPixelScaleX;
// Pixel resolution scale in Y, includes scale from r_SuperSampling and any operating system screen or viewport scale
float m_fPixelScaleY;
// Denotes if context refers to main viewport
bool m_bMainViewport;
};
// Texture coordinate rectangle
struct CoordRect
{
float fLeftU, fTopV;
float fRightU, fBottomV;
};
bool DrawFullScreenQuad(float fLeftU, float fTopV, float fRightU, float fBottomV, bool bClampToScreenRes = true);
bool DrawFullScreenQuad(CoordRect c, bool bClampToScreenRes = true);
struct SStateBlend
{
UnINT64 nHashVal;
D3D11_BLEND_DESC Desc;
ID3D11BlendState* pState;
SStateBlend() { memset(this, 0, sizeof(*this)); }
static uint64 GetHash(const D3D11_BLEND_DESC& InDesc)
{
UnINT64 nHash;
nHash.i.Low = InDesc.AlphaToCoverageEnable |
(InDesc.RenderTarget[0].BlendEnable << 1) | (InDesc.RenderTarget[1].BlendEnable << 2) | (InDesc.RenderTarget[2].BlendEnable << 3) | (InDesc.RenderTarget[3].BlendEnable << 4) |
(InDesc.RenderTarget[0].SrcBlend << 5) | (InDesc.RenderTarget[0].DestBlend << 10) |
(InDesc.RenderTarget[0].SrcBlendAlpha << 15) | (InDesc.RenderTarget[0].DestBlendAlpha << 20) |
(InDesc.RenderTarget[0].BlendOp << 25) | (InDesc.RenderTarget[0].BlendOpAlpha << 28);
nHash.i.High = InDesc.RenderTarget[0].RenderTargetWriteMask |
(InDesc.RenderTarget[1].RenderTargetWriteMask << 4) |
(InDesc.RenderTarget[2].RenderTargetWriteMask << 8) |
(InDesc.RenderTarget[3].RenderTargetWriteMask << 12) |
InDesc.IndependentBlendEnable << 16;
return nHash.SortVal;
}
} _ALIGN(16);
struct SStateRaster
{
uint64 nValuesHash;
uint32 nHashVal;
ID3D11RasterizerState* pState;
D3D11_RASTERIZER_DESC Desc;
SStateRaster()
{
memset(this, 0, sizeof(*this));
Desc.DepthClipEnable = true;
Desc.FillMode = D3D11_FILL_SOLID;
Desc.FrontCounterClockwise = TRUE;
}
static uint32 GetHash(const D3D11_RASTERIZER_DESC& InDesc)
{
uint32 nHash;
nHash = InDesc.FillMode | (InDesc.CullMode << 2) |
(InDesc.DepthClipEnable << 4) | (InDesc.FrontCounterClockwise << 5) |
(InDesc.ScissorEnable << 6) | (InDesc.MultisampleEnable << 7) | (InDesc.AntialiasedLineEnable << 8) |
(InDesc.DepthBias << 9);
return nHash;
}
static uint64 GetValuesHash(const D3D11_RASTERIZER_DESC& InDesc)
{
uint64 nHash;
//avoid breaking strict alising rules
union f32_u
{
float floatVal;
unsigned int uintVal;
};
f32_u uDepthBiasClamp;
uDepthBiasClamp.floatVal = InDesc.DepthBiasClamp;
f32_u uSlopeScaledDepthBias;
uSlopeScaledDepthBias.floatVal = InDesc.SlopeScaledDepthBias;
nHash = (((uint64)uDepthBiasClamp.uintVal) |
((uint64)uSlopeScaledDepthBias.uintVal) << 32);
return nHash;
}
} _ALIGN(16);
_inline uint32 sStencilState(const D3D11_DEPTH_STENCILOP_DESC& Desc)
{
uint32 nST = (Desc.StencilFailOp << 0) |
(Desc.StencilDepthFailOp << 4) |
(Desc.StencilPassOp << 8) |
(Desc.StencilFunc << 12);
return nST;
}
struct SStateDepth
{
uint64 nHashVal;
D3D11_DEPTH_STENCIL_DESC Desc;
ID3D11DepthStencilState* pState;
SStateDepth()
: nHashVal()
, pState()
{
Desc.DepthEnable = TRUE;
Desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
Desc.DepthFunc = D3D11_COMPARISON_LESS;
Desc.StencilEnable = FALSE;
Desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
Desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
Desc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
Desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
Desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
Desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
Desc.BackFace = Desc.FrontFace;
}
static uint64 GetHash(const D3D11_DEPTH_STENCIL_DESC& InDesc)
{
uint64 nHash;
nHash = (InDesc.DepthEnable << 0) |
(InDesc.DepthWriteMask << 1) |
(InDesc.DepthFunc << 2) |
(InDesc.StencilEnable << 6) |
(InDesc.StencilReadMask << 7) |
(InDesc.StencilWriteMask << 15) |
(((uint64)sStencilState(InDesc.FrontFace)) << 23) |
(((uint64)sStencilState(InDesc.BackFace)) << 39);
return nHash;
}
} _ALIGN(16); \
#if defined(AZ_PLATFORM_ANDROID)
#define MAX_OCCL_QUERIES 256
#else
#define MAX_OCCL_QUERIES 4096
#endif
#define MAXFRAMECAPTURECALLBACK 1
//======================================================================
// Options for clearing
#define CLEAR_ZBUFFER 0x00000001 /* Clear target z buffer, equals D3D11_CLEAR_DEPTH */
#define CLEAR_STENCIL 0x00000002 /* Clear stencil planes, equals D3D11_CLEAR_STENCIL */
#define CLEAR_RTARGET 0x00000004 /* Clear target surface */
//======================================================================
//======================================================================
/// Forward declared classes
class CHWShader_D3D;
//======================================================================
/// Direct3D Render driver class
#ifdef SHADER_ASYNC_COMPILATION
class CAsyncShaderTask;
#endif
AZStd::vector<D3D11_INPUT_ELEMENT_DESC> GetD3D11Declaration(const AZ::Vertex::Format& vertexFormat);
class CD3D9Renderer
: public CRenderer
, public IWindowMessageHandler
, AZ::RenderNotificationsBus::Handler
, AZ::RenderScreenshotRequestBus::Handler
{
friend struct SPixFormat;
friend class CD3DStereoRenderer;
friend class CTexture;
friend class CSceneGBufferPass;
public:
CD3D9Renderer();
~CD3D9Renderer();
virtual SRenderPipeline* GetRenderPipeline() override { return &m_RP; }
static void StaticCleanup();
// Remove pointer indirection.
ILINE CD3D9Renderer* operator->()
{
return this;
}
ILINE const bool operator !() const
{
return false;
}
ILINE operator bool() const
{
return true;
}
ILINE operator CD3D9Renderer*()
{
return this;
}
virtual void InitRenderer();
virtual void Release();
virtual const SRenderTileInfo* GetRenderTileInfo() const override { return &m_RenderTileInfo; }
// CRY DX12
static unsigned int GetCurrentBackBufferIndex(IDXGISwapChain* pSwapChain);
struct SCharInstCB
{
AzRHI::ConstantBuffer* m_buffer;
SSkinningData* m_pSD;
util::list<SCharInstCB> list;
bool updated;
SCharInstCB()
: m_buffer()
, m_pSD()
, list()
, updated()
{
}
~SCharInstCB() { SAFE_RELEASE(m_buffer); list.erase(); }
};
protected:
// Invalidates temporal data generated by the renderer that is used by the coverage buffer system.
// This should be called whenever a level load happens, a camera teleport occurs, etc.
void InvalidateCoverageBufferData();
// Windows context
char m_WinTitle[80];
HINSTANCE m_hInst;
HWND m_hWnd; // The main app window
HWND m_hWndDesktop; // The desktop window
#ifdef WIN32
HICON m_hIconBig; // Icon currently being used on the taskbar
HICON m_hIconSmall; // Icon currently being used on the window
string m_iconPath; // Path to the icon currently loaded
#endif
//stereo mode
HWND m_hWnd2;
int m_bDraw2dImageStretchMode;
uint32 m_uLastBlendFlagsPassGroup;
int m_numOcclusionDownsampleStages;
// Cached size of the depth target previously used for generating the depth downsample chain
uint16 m_occlusionSourceSizeX;
uint16 m_occlusionSourceSizeY;
// Data to be populated by the render thread and read by the coverage buffer occlusion thread
struct OcclusionReadbackData
{
~OcclusionReadbackData();
void Destroy();
void Reset(bool reverseDepth);
// Matrix used to generate the data in the occlusion readback buffer
Matrix44A m_occlusionReadbackViewProj;
// Contains modified depth data from m_zTargetReadback. Buffer to only be used by the Coverage Buffer system.
float* m_occlusionReadbackBuffer = nullptr;
};
// Packet of data used by the renderer in order to generate occlusion data for the Coverage Buffer system.
struct CPUOcclusionData
{
enum class OcclusionDataState : AZ::u8
{
OcclusionDataInvalid = 0,
// Occlusion data is ready for use on the GPU
OcclusionDataOnGPU,
// Occlusion data has been read back on the CPU and is ready for use
OcclusionDataOnCPU
};
void SetupOcclusionData(const char* textureName);
void Destroy();
// Matrix used to render the Z-buffer that is downsampled into m_zTargetReadback
Matrix44A m_occlusionViewProj;
// Buffer containing downsampled depth buffer information to be read back by the CPU
CTexture* m_zTargetReadback = nullptr;
// Data to be read by the occlusion thread
OcclusionReadbackData m_occlusionReadbackData;
// Contains whether or not the occlusion data is valid. Occlusion data should be invalidated on level loads, camera teleports, etc.
OcclusionDataState m_occlusionDataState = OcclusionDataState::OcclusionDataInvalid;
};
// Triple buffer our downsampled texture that is used for CPU readbacks to prevent CPU/GPU resource contention
static const unsigned int s_numOcclusionReadbackTextures = 3;
// Set of data generated by FX_ZTargetReadBackOnCPU to be used by the Coverage Buffer system.
// Data is triple buffered by default to prevent CPU/GPU synchronization
CPUOcclusionData m_occlusionData[s_numOcclusionReadbackTextures];
// Index into m_occlusionData for which CPU data set PrepareOcclusion should read from.
// Will be set from the render thread and read from the occlusion thread
AZStd::atomic_uchar m_cpuOcclusionReadIndex;
// Current GPU write index into the occlusion data array
AZ::u8 m_occlusionBufferIndex = 0;
// The Coverage Buffer system in CCullRenderer is templated based on resolution, so this will not change at runtime
static const uint16 s_occlusionBufferWidth = CULL_SIZEX;
static const uint16 s_occlusionBufferHeight = CULL_SIZEY;
static const uint32 s_occlusionBufferNumElements = CULL_SIZEX * CULL_SIZEY;
CStandardGraphicsPipeline* m_GraphicsPipeline;
CTiledShading* m_pTiledShading;
CD3DStereoRenderer* m_pStereoRenderer;
CVolumetricFog m_volumetricFog;
std::vector<D3DSurface*> m_pBackBuffers;
D3DSurface* m_pBackBuffer;
unsigned int m_pCurrentBackBufferIndex;
ID3D11RenderTargetView* m_pSecondBackBuffer;
D3DDepthSurface* m_pZBuffer;
D3DDepthSurface* m_pNativeZBuffer;
D3DTexture* m_pZTexture;
D3DTexture* m_pNativeZTexture;
PerInstanceConstantBufferPool m_PerInstanceConstantBufferPool;
volatile int m_lockCharCB;
// CharCB can have different sizes depending on bone type.
// Therefore we need to keep a list per bone type for re-usability
util::list<SCharInstCB> m_CharCBFreeList[eBoneType_Count];
util::list<SCharInstCB> m_CharCBActiveList[eBoneType_Count][3];
volatile int m_CharCBFrameRequired[3];
volatile int m_CharCBAllocated;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_2
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
IDXGISwapChain* m_pSwapChain;
#endif
enum PresentStatus
{
epsOccluded = 1 << 0,
epsNonExclusive = 1 << 1,
};
DWORD m_dwPresentStatus; // Indicate present status
DWORD m_dwWindowStyle; // Saved window style for mode switches
int m_SceneRecurseCount;
SRenderTileInfo m_RenderTileInfo;
struct C2dImage
{
CTexture* pTex;
CTexture* pTarget;
float xpos, ypos, w, h, s0, t0, s1, t1, angle, z, stereoDepth;
DWORD col;
C2dImage(float _xpos, float _ypos, float _w, float _h, CTexture* _pTex, float _s0, float _t0, float _s1, float _t1, float _angle, DWORD _col, float _z, float _stereoDepth, CTexture* _pTarget = NULL)
: pTex(_pTex)
, xpos(_xpos)
, ypos(_ypos)
, w(_w)
, h(_h)
, s0(_s0)
, t0(_t0)
, s1(_s1)
, t1(_t1)
, angle(_angle)
, z(_z)
, col(_col)
, stereoDepth(_stereoDepth)
, pTarget(_pTarget) {}
};
TArray<C2dImage> m_2dImages;
// CRY DX12
TArray<C2dImage> m_uiImages;
//==================================================================
public:
enum
{
MAX_FRAME_QUERIES = 2
};
D3DQuery* m_pQuery[MAX_FRAME_QUERIES];
#if !defined(_RELEASE)
// sprite cells referenced this frame (particular sprite in particular atlas)
std::set<uint32> m_SpriteCellsUsed;
// sprite atlases referenced this frame
std::set<CTexture*> m_SpriteAtlasesUsed;
#endif
TArray<COcclusionQuery> m_OcclQueries;
uint32 m_OcclQueriesUsed;
enum EDefShadows_Passes
{
DS_STENCIL_PASS = 0,
DS_HISTENCIL_REFRESH = 1,
DS_SHADOW_PASS = 2,
DS_SHADOW_CULL_PASS = 3,
DS_SHADOW_FRUSTUM_CULL_PASS = 4,
DS_STENCIL_VOLUME_CLIP = 5,
DS_CLOUDS_SEPARATE = 6,
DS_VOLUME_SHADOW_PASS = 7,
// DS_GMEM_STENCIL_CULL_NON_CONVEX used by CD3D9Renderer::FX_StencilCullNonConvex(...)
// in D3DDeferredShading.cpp when using GMEM render path.
DS_GMEM_STENCIL_CULL_NON_CONVEX = 8,
// DS_STENCIL_CULL_NON_CONVEX_RESOLVE used by CD3D9Renderer::FX_StencilCullNonConvex(...)
// in D3DDeferredShading.cpp when stencil texture is not supported.
DS_STENCIL_CULL_NON_CONVEX_RESOLVE = 9,
DS_SHADOW_CULL_PASS_FRONTFACING = 10,
DS_SHADOW_FRUSTUM_CULL_PASS_FRONTFACING = 11,
DS_STENCIL_VOLUME_CLIP_FRONTFACING = 12,
DS_PASS_MAX
};
#if defined(SUPPORT_D3D_DEBUG_RUNTIME)
CD3DDebug m_d3dDebug;
bool m_bUpdateD3DDebug;
#endif
DWORD m_DeviceOwningthreadID; // thread if of thread who is allows to access the D3D Context
ID3D11InputLayout* m_pLastVDeclaration;
DXGI_SURFACE_DESC m_d3dsdBackBuffer; // Surface desc of the BackBuffer
DXGI_FORMAT m_ZFormat;
D3D11_PRIMITIVE_TOPOLOGY m_CurTopology;
TArray<SStateBlend> m_StatesBL;
TArray<SStateRaster> m_StatesRS;
TArray<SStateDepth> m_StatesDP;
uint32 m_nCurStateBL;
uint32 m_nCurStateRS;
uint32 m_nCurStateDP;
uint8 m_nCurStencRef;
inline uint32 GetOrCreateBlendState(const D3D11_BLEND_DESC& desc)
{
uint32 i;
HRESULT hr = S_OK;
uint64 nHash = SStateBlend::GetHash(desc);
for (i = 0; i < m_StatesBL.Num(); i++)
{
if (m_StatesBL[i].nHashVal.SortVal == nHash)
{
break;
}
}
if (i == m_StatesBL.Num())
{
SStateBlend* pState = m_StatesBL.AddIndex(1);
pState->Desc = desc;
pState->nHashVal.SortVal = nHash;
hr = GetDevice().CreateBlendState(&pState->Desc, &pState->pState);
assert(SUCCEEDED(hr));
}
return SUCCEEDED(hr) ? i : uint32(-1);
}
bool SetBlendState(const SStateBlend* pNewState)
{
uint32 bsIndex = GetOrCreateBlendState(pNewState->Desc);
if (bsIndex == uint32(-1))
{
return false;
}
if (bsIndex != m_nCurStateBL)
{
m_nCurStateBL = bsIndex;
m_DevMan.SetBlendState(m_StatesBL[bsIndex].pState, 0, 0xffffffff);
}
return true;
}
inline uint32 GetOrCreateRasterState(const D3D11_RASTERIZER_DESC& rasterizerDec, const bool bAllowMSAA = true)
{
uint32 i;
HRESULT hr = S_OK;
D3D11_RASTERIZER_DESC desc = rasterizerDec;
BOOL bMSAA = bAllowMSAA && m_RP.m_MSAAData.Type > 1;
if (bMSAA != desc.MultisampleEnable)
{
desc.MultisampleEnable = bMSAA;
}
uint32 nHash = SStateRaster::GetHash(desc);
uint64 nValuesHash = SStateRaster::GetValuesHash(desc);
for (i = 0; i < m_StatesRS.Num(); i++)
{
if (m_StatesRS[i].nHashVal == nHash && m_StatesRS[i].nValuesHash == nValuesHash)
{
break;
}
}
if (i == m_StatesRS.Num())
{
SStateRaster* pState = m_StatesRS.AddIndex(1);
pState->Desc = desc;
pState->nHashVal = nHash;
pState->nValuesHash = nValuesHash;
hr = GetDevice().CreateRasterizerState(&pState->Desc, &pState->pState);
assert(SUCCEEDED(hr));
}
return SUCCEEDED(hr) ? i : uint32(-1);
}
bool SetRasterState(const SStateRaster* pNewState, const bool bAllowMSAA = true)
{
uint32 rsIndex = GetOrCreateRasterState(pNewState->Desc, bAllowMSAA);
if (rsIndex == uint32(-1))
{
return false;
}
if (rsIndex != m_nCurStateRS)
{
m_nCurStateRS = rsIndex;
m_DevMan.SetRasterState(m_StatesRS[rsIndex].pState);
}
return true;
}
inline uint32 GetOrCreateDepthState(const D3D11_DEPTH_STENCIL_DESC& desc)
{
uint32 i;
HRESULT hr = S_OK;
uint64 nHash = SStateDepth::GetHash(desc);
const int kNumStates = m_StatesDP.Num();
for (i = 0; i < kNumStates; i++)
{
if (m_StatesDP[i].nHashVal == nHash)
{
break;
}
}
if (i == kNumStates)
{
SStateDepth* pState = m_StatesDP.AddIndex(1);
pState->Desc = desc;
pState->nHashVal = nHash;
hr = GetDevice().CreateDepthStencilState(&pState->Desc, &pState->pState);
assert(SUCCEEDED(hr));
}
return SUCCEEDED(hr) ? i : uint32(-1);
}
bool SetDepthState(const SStateDepth* pNewState, uint8 newStencRef)
{
uint32 dsIndex = GetOrCreateDepthState(pNewState->Desc);
if (dsIndex == uint32(-1))
{
return false;
}
if (dsIndex != m_nCurStateDP || m_nCurStencRef != newStencRef)
{
m_nCurStateDP = dsIndex;
m_nCurStencRef = newStencRef;
m_DevMan.SetDepthStencilState(m_StatesDP[dsIndex].pState, newStencRef);
}
return true;
}
void SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY topType)
{
if (m_CurTopology != topType)
{
m_CurTopology = topType;
m_DevMan.BindTopology(m_CurTopology);
}
}
virtual void LockParticleVideoMemory(uint32 nId);
virtual void UnLockParticleVideoMemory(uint32 nId);
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_3
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
SDepthTexture m_DepthBufferOrig;
SDepthTexture m_DepthBufferOrigMSAA;
SDepthTexture m_DepthBufferNative;
// Bindable depthstencil buffer view and shader resource view. Ideally would be unified into regular texture creation - requires big refactoring
D3DDepthSurface* m_pZBufferReadOnlyDSV;
D3DShaderResourceView* m_pZBufferDepthReadOnlySRV;
D3DShaderResourceView* m_pZBufferStencilReadOnlySRV;
int m_MaxAnisotropyLevel;
int m_nMaterialAnisoHighSampler;
int m_nMaterialAnisoLowSampler;
int m_nMaterialAnisoSamplerBorder;
//===============================================================================
//////////////////////////////////////////////////////////////////////////
enum
{
kUnitObjectIndexSizeof = 2
};
D3DBuffer* m_pUnitFrustumVB[SHAPE_MAX];
D3DBuffer* m_pUnitFrustumIB[SHAPE_MAX];
int m_UnitFrustVBSize[SHAPE_MAX];
int m_UnitFrustIBSize[SHAPE_MAX];
D3DBuffer* m_pQuadVB;
int16 m_nQuadVBSize;
//////////////////////////////////////////////////////////////////////////
#ifdef CRY_USE_METAL
SPixFormat m_FormatPVRTC2; //ETC2 compressed RGB for mobile
SPixFormat m_FormatPVRTC4; //ETC2a compressed RGBA for mobile
#endif
#if defined(ANDROID) || defined(CRY_USE_METAL)
SPixFormat m_FormatASTC_4x4;
SPixFormat m_FormatASTC_5x4;
SPixFormat m_FormatASTC_5x5;
SPixFormat m_FormatASTC_6x5;
SPixFormat m_FormatASTC_6x6;
SPixFormat m_FormatASTC_8x5;
SPixFormat m_FormatASTC_8x6;
SPixFormat m_FormatASTC_8x8;
SPixFormat m_FormatASTC_10x5;
SPixFormat m_FormatASTC_10x6;
SPixFormat m_FormatASTC_10x8;
SPixFormat m_FormatASTC_10x10;
SPixFormat m_FormatASTC_12x10;
SPixFormat m_FormatASTC_12x12;
#endif
SPixFormatSupport m_hwTexFormatSupport;
int m_fontBlendMode;
CCryNameTSCRC m_LevelShaderCacheMissIcon;
CColorGradingControllerD3D* m_pColorGradingControllerD3D;
CRenderPipelineProfiler* m_pPipelineProfiler;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_4
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
private:
D3DDevice* m_Device;
D3DDeviceContext* m_DeviceContext;
// Used for shadow casting for transparents.
CCryNameTSCRC m_techShadowGen;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_5
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
t_arrDeferredMeshIndBuff m_arrDeferredInds;
t_arrDeferredMeshVertBuff m_arrDeferredVerts;
public:
#ifdef SHADER_ASYNC_COMPILATION
DynArray<CAsyncShaderTask*> m_AsyncShaderTasks;
public:
#endif
void SetDefaultTexParams(bool bUseMips, bool bRepeat, bool bLoad);
public:
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_6
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
/////////////////////////////////////////////////////////////////////////////
// Functions to access the device and associated objects
const D3DDevice& GetDevice() const;
D3DDevice& GetDevice();
D3DDeviceContext& GetDeviceContext();
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_7
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
bool IsDeviceContextValid() { return m_DeviceContext != nullptr; }
/////////////////////////////////////////////////////////////////////////////
// Debug Functions to check that the D3D DeviceContext is only accessed
// by its owning thread
void BindContextToThread(DWORD threadID);
DWORD GetBoundThreadID() const;
void CheckContextThreadAccess() const;
bool FX_PrepareDepthMapsForLight(const SRenderLight& rLight, int nLightID, bool bClearPool = false);
void EF_PrepareShadowGenRenderList();
bool EF_PrepareShadowGenForLight(SRenderLight* pLight, int nLightID);
bool PrepareShadowGenForFrustum(ShadowMapFrustum* pCurFrustum, SRenderLight* pLight, int nLightFrustumID = 0, int nLOD = 0);
void PrepareShadowGenForFrustumNonJobs(const int nFlags);
virtual void EF_InvokeShadowMapRenderJobs(int nFlags);
void InvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo);
void StartInvokeShadowMapRenderJobs(ShadowMapFrustum* pCurFrustum, const SRenderingPassInfo& passInfo);
void UpdatePreviousFrameMatrices();
void GetReprojectionMatrix(Matrix44A& matReproj, const Matrix44A& matView, const Matrix44A& matProj, const Matrix44A& matPrevView, const Matrix44A& matPrevProj, float fFarPlane) const;
bool m_bDepthBoundsEnabled;
float m_fDepthBoundsMin, m_fDepthBoundsMax;
void SetDepthBoundTest(float fMin, float fMax, bool bEnable);
void CreateDeferredUnitBox(t_arrDeferredMeshIndBuff& indBuff, t_arrDeferredMeshVertBuff& vertBuff);
const t_arrDeferredMeshIndBuff& GetDeferredUnitBoxIndexBuffer() const;
const t_arrDeferredMeshVertBuff& GetDeferredUnitBoxVertexBuffer() const;
bool PrepareDepthMap(ShadowMapFrustum* SMSource, int nLightFrustumID = 0, bool bClearPool = false);
void ConfigShadowTexgen(int Num, ShadowMapFrustum* pFr, int nFrustNum = -1, bool bScreenToLocalBasis = false, bool bUseComparisonSampling = true);
void DrawAllShadowsOnTheScreen();
void DrawAllDynTextures(const char* szFilter, const bool bLogNames, const bool bOnlyIfUsedThisFrame);
void OnEntityDeleted(IRenderNode* pRenderNode);
void RT_ResetGlass();
void RT_PostLevelLoading() override;
//=============================================================
void SetCull(ECull eCull, bool bSkipMirrorCull = false) override { D3DSetCull(eCull, bSkipMirrorCull); }
void D3DSetCull(ECull eCull, bool bSkipMirrorCull = false);
struct gammaramp_t;
void GetDeviceGamma();
void SetDeviceGamma(gammaramp_t*);
HRESULT AdjustWindowForChange();
bool IsFullscreen() { return m_bFullScreen; }
bool IsSuperSamplingEnabled() { return m_numSSAASamples > 1; }
bool IsNativeScalingEnabled() { return m_width != m_nativeWidth || m_height != m_nativeHeight; }
int GetNativeWidth() const { return m_nativeWidth; }
int GetNativeHeight() const { return m_nativeHeight; }
D3DSurface* GetBackBuffer() { return m_pBackBuffer; }
static HWND CreateWindowCallback();
#if defined(SUPPORT_DEVICE_INFO)
DeviceInfo& DevInfo() { return m_devInfo; }
private:
DeviceInfo m_devInfo;
#endif
private:
void DebugShowRenderTarget();
bool SetWindow(int width, int height, bool fullscreen, WIN_HWND hWnd);
bool SetRes();
void UnSetRes();
void DisplaySplash(); //!< Load a bitmap from a file, blit it to the windowdc and free it
void DestroyWindow(void);
virtual void RestoreGamma(void);
void SetGamma(float fGamma, float fBrigtness, float fContrast, bool bForce);
int FindTextureInRegistry(const char* filename, int* tex_type);
int RegisterTextureInRegistry(const char* filename, int tex_type, int tid, int low_tid);
unsigned int MakeTextureREAL(const char* filename, int* tex_type, unsigned int load_low_res);
unsigned int CheckTexturePlus(const char* filename, const char* postfix);
static HRESULT CALLBACK OnD3D11CreateDevice(D3DDevice* pd3dDevice);
void PostDeviceReset();
void ForceUpdateGlobalShaderParameters() override;
public:
static HRESULT CALLBACK OnD3D11PostCreateDevice(D3DDevice* pd3dDevice);
// CRY DX12
Matrix44 m_matPsmWarp;
Matrix44 m_matViewInv;
int m_MatDepth;
static int CV_d3d11_CBUpdateStats;
static ICVar* CV_d3d11_forcedFeatureLevel;
static int CV_r_AlphaBlendLayerCount;
#if defined(SUPPORT_D3D_DEBUG_RUNTIME)
static int CV_d3d11_debugruntime;
static ICVar* CV_d3d11_debugMuteSeverity;
static ICVar* CV_d3d11_debugMuteMsgID;
static ICVar* CV_d3d11_debugBreakOnMsgID;
static int CV_d3d11_debugBreakOnce;
#endif
//============================================================
// Renderer interface
bool m_bFullScreen;
TArray<SD3DContext*> m_RContexts;
SD3DContext* m_CurrContext;
TArray<CTexture*> m_RTargets;
public:
void RT_PresentFast();
// Multithreading support
virtual void RT_BeginFrame();
virtual void RT_EndFrame();
virtual void RT_EndFrame(bool isLoading);
virtual void RT_ForceSwapBuffers();
virtual void RT_SwitchToNativeResolutionBackbuffer(bool resolveBackBuffer);
virtual void RT_Init();
virtual bool RT_CreateDevice();
virtual void RT_Reset();
virtual void RT_RenderScene(int nFlags, SThreadInfo& TI, RenderFunc pRenderFunc);
virtual void RT_SetCull(int nMode);
virtual void RT_SetScissor(bool bEnable, int x, int y, int width, int height);
virtual void RT_SetCameraInfo();
virtual void RT_SetStereoCamera();
virtual void RT_CreateResource(SResourceAsync* Res);
virtual void RT_ReleaseResource(SResourceAsync* pRes);
virtual void RT_ReleaseRenderResources();
virtual void RT_UnbindResources();
virtual void RT_UnbindTMUs();
virtual void RT_CreateRenderResources();
virtual void RT_PrecacheDefaultShaders();
virtual void RT_ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX, int nScaledY);
// CRY DX12
virtual void RT_ClearTarget(ITexture* pTex, const ColorF& color);
virtual void RT_ReleaseVBStream(void* pVB, int nStream);
virtual void RT_ReleaseCB(void* pCB);
virtual void RT_DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType);
virtual void RT_DrawDynVBUI(SVF_P2F_C4B_T2F_F4B* pBuf, uint16* pInds, uint32 nVerts, uint32 nInds, const PublicRenderPrimitiveType nPrimType);
virtual void RT_DrawStringU(IFFont_RenderProxy* pFont, float x, float y, float z, const char* pStr, bool asciiMultiLine, const STextDrawContext& ctx) const;
virtual void RT_DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround);
virtual void RT_Draw2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z);
virtual void RT_Draw2dImageStretchMode(bool bStretch);
virtual void RT_Push2dImage(float xpos, float ypos, float w, float h, CTexture* pTexture, float s0, float t0, float s1, float t1, float angle, DWORD col, float z, float stereoDepth);
virtual void RT_Draw2dImageList();
virtual void RT_DrawImageWithUV(float xpos, float ypos, float z, float w, float h, int texture_id, float* s, float* t, DWORD col, bool filtered = true);
virtual void RT_PushRenderTarget(int nTarget, CTexture* pTex, SDepthTexture* pDepth, int nS);
virtual void RT_PopRenderTarget(int nTarget);
virtual void RT_SetViewport(int x, int y, int width, int height, int id = -1) override;
virtual void RT_RenderDebug(bool bRenderStats = true);
virtual void RT_SetRendererCVar(ICVar* pCVar, const char* pArgText, const bool bSilentMode = false);
//===============================================================================
void RT_DrawImageWithUVInternal(float xpos, float ypos, float z, float w, float h, int texture_id, float s[4], float t[4], DWORD col, bool filtered = true);
void RT_Draw2dImageInternal(C2dImage* images, uint32 numImages, bool stereoLeftEye = true);
//===============================================================================
virtual WIN_HWND Init(int x, int y, int width, int height, unsigned int cbpp, int zbpp, int sbits, bool fullscreen, bool isEditor, WIN_HINSTANCE hinst, WIN_HWND Glhwnd = 0, bool bReInit = false, const SCustomRenderInitArgs* pCustomArgs = 0, bool bShaderCacheGen = false);
virtual void GetVideoMemoryUsageStats(size_t& vidMemUsedThisFrame, size_t& vidMemUsedRecently, bool bGetPoolsSizes = false);
/////////////////////////////////////////////////////////////////////////////////
// Render-context management
/////////////////////////////////////////////////////////////////////////////////
virtual bool SetCurrentContext(WIN_HWND hWnd);
virtual bool CreateContext(WIN_HWND hWnd, bool bAllowMSAA = false, int SSX = 1, int SSY = 1);
virtual bool DeleteContext(WIN_HWND hWnd);
virtual void MakeMainContextActive();
virtual WIN_HWND GetCurrentContextHWND() { return m_CurrContext ? m_CurrContext->m_hWnd : m_hWnd; }
virtual bool IsCurrentContextMainVP() { return m_CurrContext ? m_CurrContext->m_bMainViewport : true; }
virtual int GetCurrentContextViewportWidth() const { return (m_bDeviceLost ? -1 : m_CurrContext->m_nViewportWidth); }
virtual int GetCurrentContextViewportHeight() const { return (m_bDeviceLost ? -1 : m_CurrContext->m_nViewportHeight); }
/////////////////////////////////////////////////////////////////////////////////
virtual int CreateRenderTarget(const char* name, int nWidth, int nHeight, const ColorF& clearColor, ETEX_Format eTF = eTF_R8G8B8A8);
virtual bool DestroyRenderTarget(int nHandle);
virtual bool ResizeRenderTarget(int nHandle, int nWidth, int nHeight);
virtual bool SetRenderTarget(int nHandle, SDepthTexture* pDepthSurf = nullptr);
virtual SDepthTexture* CreateDepthSurface(int nWidth, int nHeight, bool shaderResourceView = false);
virtual void DestroyDepthSurface(SDepthTexture* pDepthSurf);
virtual bool ChangeDisplay(unsigned int width, unsigned int height, unsigned int cbpp);
virtual void ChangeViewport(unsigned int x, unsigned int y, unsigned int width, unsigned int height, bool bMainViewport = false, float scaleWidth = 1.0f, float scaleHeight = 1.0f);
virtual int EnumDisplayFormats(SDispFormat* formats);
//! Return all supported by video card video AA formats
virtual int EnumAAFormats(SAAFormat* formats);
//! Changes resolution of the window/device (doen't require to reload the level
virtual bool ChangeResolution(int nNewWidth, int nNewHeight, int nNewColDepth, int nNewRefreshHZ, bool bFullScreen, bool bForceReset);
virtual void Reset(void);
virtual void SwitchToNativeResolutionBackbuffer();
void CalculateResolutions(int width, int height, bool bUseNativeResolution, int* pRenderWidth, int* pRenderHeight, int* pNativeWidth, int* pNativeHeight, int* pBackbufferWidth, int* pBackbufferHeight);
virtual void BeginFrame();
virtual void ShutDown(bool bReInit = false);
virtual void ShutDownFast();
virtual void RenderDebug(bool bRenderStats = true);
virtual void RT_ShutDown(uint32 nFlags);
void DebugPrintShader(class CHWShader_D3D* pSH, void* pInst, int nX, int nY, ColorF colSH);
void DebugPerfBars(int nX, int nY);
void DebugVidResourcesBars(int nX, int nY);
void DebugDrawStats1();
void DebugDrawStats2();
void DebugDrawStats8();
void DebugDrawStats();
void DebugDrawRect(float x1, float y1, float x2, float y2, float* fColor);
void VidMemLog();
virtual void EndFrame();
virtual void LimitFramerate(const int maxFPS, const bool bUseSleep);
virtual void GetMemoryUsage(ICrySizer* Sizer);
void GetLogVBuffers();
virtual void TryFlush();
virtual void Draw2dImage(float xpos, float ypos, float w, float h, int textureid, float s0, float t0, float s1, float t1, float angle, const ColorF& col, float z = 1);
virtual void Draw2dImage(float xpos, float ypos, float w, float h, int textureid, float s0 = 0, float t0 = 0, float s1 = 1, float t1 = 1, float angle = 0, float r = 1, float g = 1, float b = 1, float a = 1, float z = 1);
virtual void Push2dImage(float xpos, float ypos, float w, float h, int textureid, float s0 = 0, float t0 = 0, float s1 = 1, float t1 = 1, float angle = 0,
float r = 1, float g = 1, float b = 1, float a = 1, float z = 1, float stereoDepth = 0);
virtual void Draw2dImageStretchMode(bool bStretch);
virtual void Draw2dImageList();
virtual void DrawImage(float xpos, float ypos, float w, float h, int texture_id, float s0, float t0, float s1, float t1, float r, float g, float b, float a, bool filtered = true);
virtual void DrawImageWithUV(float xpos, float ypos, float z, float w, float h, int texture_id, float* s, float* t, float r, float g, float b, float a, bool filtered = true);
virtual void SetCullMode(int mode = R_CULL_BACK);
virtual void PushProfileMarker(const char* label);
virtual void PopProfileMarker(const char* label);
virtual bool EnableFog(bool enable);
virtual void SetFogColor(const ColorF& color);
virtual void CreateResourceAsync(SResourceAsync* pResource);
virtual void ReleaseResourceAsync(SResourceAsync* pResource);
virtual void ReleaseResourceAsync(AZStd::unique_ptr<SResourceAsync> pResource) override;
virtual unsigned int DownLoadToVideoMemory(const byte* data, int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false);
virtual unsigned int DownLoadToVideoMemory(const byte* data, int w, int h, int d, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, ETEX_Type eTT, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false);
virtual unsigned int DownLoadToVideoMemoryCube(const byte* data, int w, int h, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false);
virtual unsigned int DownLoadToVideoMemory3D(const byte* data, int w, int h, int d, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nummipmap, bool repeat = true, int filter = FILTER_BILINEAR, int Id = 0, const char* szCacheName = NULL, int flags = 0, EEndian eEndian = eLittleEndian, RectI* pRegion = NULL, bool bAsynDevTexCreation = false);
virtual void UpdateTextureInVideoMemory(uint32 tnum, const byte* newdata, int posx, int posy, int w, int h, ETEX_Format eTF = eTF_R8G8B8A8, int posz = 0, int sizez = 1);
virtual bool EF_PrecacheResource(SShaderItem* pSI, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter);
virtual bool EF_PrecacheResource(ITexture* pTP, float fMipFactor, float fTimeToReady, int Flags, int nUpdateId, int nCounter);
virtual void RemoveTexture(unsigned int TextureId);
virtual void DeleteFont(IFFont* font);
virtual ITexture* EF_CreateCompositeTexture(int type, const char* szName, int nWidth, int nHeight, int nDepth, int nMips, int nFlags, ETEX_Format eTF, const STexComposition* pCompositions, size_t nCompositions, int8 nPriority = -1);
virtual void PostLevelLoading();
virtual void PostLevelUnload();
virtual void ApplyViewParameters(const CameraViewParameters& viewParameters) override;
virtual void SetCamera(const CCamera& cam);
virtual void SetViewport(int x, int y, int width, int height, int id = 0);
virtual void GetViewport(int* x, int* y, int* width, int* height) const;
virtual void SetScissor(int x = 0, int y = 0, int width = 0, int height = 0);
virtual void SetRenderTile(f32 nTilesPosX, f32 nTilesPosY, f32 nTilesGridSizeX, f32 nTilesGridSizeY);
void DrawLines(Vec3 v[], int nump, ColorF& col, int flags, float fGround);
virtual void Graph(byte* g, int x, int y, int wdt, int hgt, int nC, int type, const char* text, ColorF& color, float fScale);
virtual void DrawDynVB(SVF_P3F_C4B_T2F* pBuf, uint16* pInds, int nVerts, int nInds, PublicRenderPrimitiveType nPrimType);
virtual void DrawDynUiPrimitiveList(DynUiPrimitiveList& primitives, int totalNumVertices, int totalNumIndices);
virtual void PrintResourcesLeaks();
virtual void FX_PushWireframeMode(int mode);
virtual void FX_PopWireframeMode();
void FX_SetWireframeMode(int nMode);
virtual void PushMatrix();
virtual void PopMatrix();
virtual void EnableVSync(bool enable);
virtual void DrawPrimitivesInternal(CVertexBuffer* src, int vert_num, const eRenderPrimitiveType prim_type);
virtual void ResetToDefault();
// Sets default Blend, DepthStencil and Raster states.
virtual void SetDefaultRenderStates();
virtual void SetMaterialColor(float r, float g, float b, float a);
virtual bool ProjectToScreen(float ptx, float pty, float ptz, float* sx, float* sy, float* sz);
virtual int UnProject(float sx, float sy, float sz, float* px, float* py, float* pz, const float modelMatrix[16], const float projMatrix[16], const int viewport[4]);
virtual int UnProjectFromScreen(float sx, float sy, float sz, float* px, float* py, float* pz);
virtual void GetModelViewMatrix(float* mat);
virtual void GetProjectionMatrix(float* mat);
virtual void SetMatrices(float* pProjMat, float* pViewMat);
void DrawQuad(float x0, float y0, float x1, float y1, const ColorF& color, float z = 1.0f, float s0 = 0.0f, float t0 = 0.0f, float s1 = 1.0f, float t1 = 1.0f) override;
void DrawQuad3D(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const ColorF& color,
float ftx0 = 0, float fty0 = 0, float ftx1 = 1, float fty1 = 1);
void DrawFullScreenQuad(CShader* pSH, const CCryNameTSCRC& TechName, float s0, float t0, float s1, float t1, uint32 nState = GS_NODEPTHTEST);
// NOTE: deprecated
virtual void ClearTargetsImmediately(uint32 nFlags);
virtual void ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors, float fDepth);
virtual void ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors);
virtual void ClearTargetsImmediately(uint32 nFlags, float fDepth);
virtual void ClearTargetsLater(uint32 nFlags);
virtual void ClearTargetsLater(uint32 nFlags, const ColorF& Colors, float fDepth);
virtual void ClearTargetsLater(uint32 nFlags, const ColorF& Colors);
virtual void ClearTargetsLater(uint32 nFlags, float fDepth);
virtual void ReadFrameBuffer(unsigned char* pRGB, int nImageX, int nSizeX, int nSizeY, ERB_Type eRBType, bool bRGBA, int nScaledX = -1, int nScaledY = -1);
virtual void ReadFrameBufferFast(uint32* pDstARGBA8, int dstWidth, int dstHeight, bool BGRA = true);
virtual void SetRendererCVar(ICVar* pCVar, const char* pArgText, bool bSilentMode = false);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routines uses 2 destination surfaces. It triggers a backbuffer copy to one of its surfaces,
// and then copies the other surface to system memory. This hopefully will remove any
// CPU stalls due to the rect lock call since the buffer will already be in system
// memory when it is called
// Inputs :
// pDstARGBA8 : Pointer to a buffer that will hold the captured frame (should be at least 4*dstWidth*dstHieght for RGBA surface)
// destinationWidth : Width of the frame to copy
// destinationHeight : Height of the frame to copy
//
// Note : If dstWidth or dstHeight is larger than the current surface dimensions, the dimensions
// of the surface are used for the copy
//
bool CaptureFrameBufferFast(unsigned char* pDstRGBA8, int destinationWidth, int destinationHeight);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy a captured surface to a buffer
//
// Inputs :
// pDstARGBA8 : Pointer to a buffer that will hold the captured frame (should be at least 4*dstWidth*dstHieght for RGBA surface)
// destinationWidth : Width of the frame to copy
// destinationHeight : Height of the frame to copy
//
// Note : If dstWidth or dstHeight is larger than the current surface dimensions, the dimensions
// of the surface are used for the copy
//
bool CopyFrameBufferFast(unsigned char* pDstRGBA8, int destinationWidth, int destinationHeight);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine registers a callback address that is called when a new frame is available
// Inputs :
// pCapture : Address of the ICaptureFrameListener object
//
// Outputs : returns true if successful, otherwise false
//
bool RegisterCaptureFrame(ICaptureFrameListener* pCapture);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine unregisters a callback address that was previously registered
// Inputs :
// pCapture : Address of the ICaptureFrameListener object to unregister
//
// Outputs : returns true if successful, otherwise false
//
bool UnRegisterCaptureFrame(ICaptureFrameListener* pCapture);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine initializes 2 destination surfaces for use by the CaptureFrameBufferFast routine
// It also, captures the current backbuffer into one of the created surfaces
//
// Inputs :
// bufferWidth : Width of capture buffer, on consoles the scaling is done on the GPU. Pass in 0 (the default) to use backbuffer dimensions
// bufferHeight : Height of capture buffer.
//
// Outputs : returns true if surfaces were created otherwise returns false
//
bool InitCaptureFrameBufferFast(uint32 bufferWidth, uint32 bufferHeight);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine releases the 2 surfaces used for frame capture by the CaptureFrameBufferFast routine
//
// Inputs : None
//
// Returns : None
//
void CloseCaptureFrameBufferFast(void);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine checks for any frame buffer callbacks that are needed and calls them
//
// Inputs : None
//
// Outputs : None
//
void CaptureFrameBufferCallBack(void);
/////////////////////////////////////////////////////////////////////////////////////////////////////
// This routine checks for any frame buffer callbacks that are needed and checks their flags, calling preparation functions if required
//
// Inputs : None
//
// Outputs : None
//
void CaptureFrameBufferPrepare(void);
//////////////////////////////////////////////////////////////////////
// RenderScreenshot request bus
virtual void WriteScreenshotToFile(const char* filepath) override;
virtual void WriteScreenshotToBuffer() override;
virtual bool CopyScreenshotToBuffer(unsigned char* imageBuffer, unsigned int width, unsigned int height) override;
//misc
bool ScreenShotInternal(const char* filename = nullptr, int width = 0);
virtual bool ScreenShot(const char* filename, int width = 0);
virtual bool ScreenShot();
virtual void UnloadOldTextures(){};
virtual void Set2DMode(uint32 orthoX, uint32 orthoY, TransformationMatrices& backupMatrices, float znear = -1e10f, float zfar = 1e10f);
virtual void Unset2DMode(const TransformationMatrices& restoringMatrices);
virtual void Set2DModeNonZeroTopLeft(float orthoLeft, float orthoTop, float orthoWidth, float orthoHeight, TransformationMatrices& backupMatrices, float znear = -1e10f, float zfar = 1e10f);
virtual int ScreenToTexture(int nTexID);
virtual bool SetGammaDelta(float fGamma);
//////////////////////////////////////////////////////////////////////
// Replacement functions for the Font engine
virtual bool FontUploadTexture(class CFBitmap*, ETEX_Format eTF = eTF_R8G8B8A8);
virtual int FontCreateTexture(int Width, int Height, byte* pData, ETEX_Format eTF = eTF_R8G8B8A8, bool genMips = IRenderer::FontCreateTextureGenMipsDefaultValue, const char* textureName = nullptr);
virtual bool FontUpdateTexture(int nTexId, int X, int Y, int USize, int VSize, byte* pData);
virtual void FontReleaseTexture(class CFBitmap* pBmp);
virtual void FontSetTexture(class CFBitmap*, int nFilterMode);
virtual void FontSetTexture(int nTexId, int nFilterMode);
virtual void FontSetRenderingState(bool overrideViewProjMatrices, TransformationMatrices& backupMatrices);
virtual void FontSetBlending(int src, int dst, int baseState);
virtual void FontRestoreRenderingState(bool overrideViewProjMatrices, const TransformationMatrices& backupMatrices);
void FontSetState(bool bRestore, int baseState);
virtual void SetProfileMarker(const char* label, ESPM mode) const;
//////////////////////////////////////////////////////////////////////
void FX_ApplyThreadState(SThreadInfo& TI, SThreadInfo* OldTI);
void EF_RenderScene(int nFlags, SViewport& VP, const SRenderingPassInfo& passInfo);
void EF_Scene3D(SViewport& VP, int nFlags, const SRenderingPassInfo& passInfo);
bool CheckMSAAChange();
bool CheckSSAAChange();
// FX Shaders pipeline
void FX_DrawInstances(CShader* ef, SShaderPass* slw, int nRE, uint32 nCurInst, uint32 nLastInst, uint32 nUsedAttr, byte* nInstanceData, int nInstAttrMask, byte Attributes[], short dwCBufSlot);
void FX_DrawShader_InstancedHW(CShader* ef, SShaderPass* slw);
void FX_DrawShader_General(CShader* ef, SShaderTechnique* pTech);
void FX_SetupForwardShadows(bool bUseShaderPermutations = false);
void FX_SetupShadowsForTransp();
void FX_SetupShadowsForFog();
bool FX_DrawToRenderTarget(CShader* pShader, CShaderResources* pRes, CRenderObject* pObj, SShaderTechnique* pTech, SHRenderTarget* pTarg, int nPreprType, IRenderElement* pRE);
void FX_DrawShader_Fur(CShader* ef, SShaderTechnique* pTech);
// hdr src texture is optional, if not specified uses default hdr destination target
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_8
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
void CopyFramebufferDX11(CTexture* pDst, ID3D11Resource* pSrcResource, D3DFormat srcFormat);
#endif
void FX_ScreenStretchRect(CTexture* pDst, CTexture* pHDRSrc = NULL);
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_9
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
virtual bool BakeMesh(const SMeshBakingInputParams* pInputParams, SMeshBakingOutput* pReturnValues);
#endif
virtual int GetOcclusionBuffer(uint16* pOutOcclBuffer, Matrix44* pmCamBuffer);
virtual void WaitForParticleBuffer(threadID nThreadId);
void InsertParticleVideoMemoryFence(int nThreadId);
void FX_StencilTestCurRef(bool bEnable, bool bNoStencilClear = true, bool bStFuncEqual = true);
void EF_PrepareCustomShadowMaps();
void EF_PrepareAllDepthMaps();
void SetFrontFacingStencillState(int nStencilID);
void SetBackFacingStencillState(int nStencilID);
//These two overridden functions allow for control over which pass to use during the stencil pass.
void FX_StencilCullPass(int nStencilID, int nNumVers, int nNumInds, CShader* pShader, int frontFacePass);
void FX_StencilCullPass(int nStencilID, int nNumVers, int nNumInds, CShader* pShader, int frontFacePass, int backFacePass);
void FX_StencilFrustumCull(int nStencilID, const SRenderLight* pLight, ShadowMapFrustum* pFrustum, int nAxis);
void FX_StencilCullNonConvex(int nStencilID, IRenderMesh* pWaterTightMesh, const Matrix34& mWorldTM);
// Prepare the GPU-targets for next frame's CPU depth readback
void FX_ZTargetReadBack();
void UpdateOcclusionDataForCPU();
// Perform the CPU-side readback of the GPU target prepared in FX_ZTargetReadBack
void FX_ZTargetReadBackOnCPU();
void FX_UpdateCharCBs();
void* FX_AllocateCharInstCB(SSkinningData*, uint32);
void FX_ClearCharInstCB(uint32);
void UpdatePerFrameParameters();
bool CreateAuxiliaryMeshes();
bool ReleaseAuxiliaryMeshes();
bool CreateUnitVolumeMesh(t_arrDeferredMeshIndBuff& arrDeferredInds, t_arrDeferredMeshVertBuff& arrDeferredVerts, D3DBuffer*& pUnitFrustumIB, D3DBuffer*& pUnitFrustumVB);
void FX_DeferredShadowPass(const SRenderLight* pLight, ShadowMapFrustum* pShadowFrustum, bool bShadowPass, bool bCloudShadowPass, bool bStencilPrepass, int nLod);
bool FX_DeferredShadowPassSetup(const Matrix44& mShadowTexGen, ShadowMapFrustum* pShadowFrustum, float maskRTWidth, float maskRTHeight, Matrix44& mScreenToShadow, bool bNearest);
bool FX_DeferredShadowPassSetupBlend(const Matrix44& mShadowTexGen, int nFrustumNum, float maskRTWidth, float maskRTHeight);
bool FX_DeferredShadows(SRenderLight* pLight, int maskRTWidth, int maskRTHeight);
void FX_DeferredShadowMaskGen(const TArray<uint32>& shadowPoolLights);
void FX_MergeShadowMaps(ShadowMapFrustum* pDst, const ShadowMapFrustum* pSrc);
void FX_ClearShadowMaskTexture();
void FX_DrawDebugPasses();
void FX_DrawMultiLayers();
void FX_DrawTechnique(CShader* ef, SShaderTechnique* pTech);
void FX_RefractionPartialResolve();
bool FX_HDRScene(bool bEnable, bool bClear = true);
void FX_RenderForwardOpaque(void (* RenderFunc)(), const bool bLighting, const bool bAllowDeferred);
void FX_RenderWater(void (* RenderFunc)());
void FX_RenderFog();
bool FX_ZScene(bool bEnable, bool bClearZBuffer, bool bRenderNormalsOnly = false, bool bZPrePass = false);
// GMEM Related /////////////////////////////////////////////////////
enum EGmemTransitions
{
eGT_PRE_Z,
eGT_POST_GBUFFER,
eGT_POST_Z_PRE_DEFERRED,
eGT_POST_DEFERRED_PRE_FORWARD,
eGT_POST_AW_TRANS_PRE_POSTFX
};
enum EGmemDepthStencilMode
{
eGDSM_RenderTarget, // Values are written/read to/from a RT during the ZPass. Values are linearized when written to the RT.
eGDSM_DepthStencilBuffer, // Values are written to the depth/stencil buffer and read using an extension. Values are linearized in the shader when fetching them.
eGDSM_Texture, // Values are resolved (and linearized) from the depth/stencil buffer to a texture with an extra pass.
eGDSM_Invalid
};
// Binds appropriate GMEM RTs depending on which section of the rendering pipeline we're in
void FX_GmemTransition(const EGmemTransitions transition);
EGmemDepthStencilMode FX_GmemGetDepthStencilMode() const;
// Values of this enum must match the intended values for cvar r_EnableGMEMPath
enum EGmemPath
{
eGT_REGULAR_PATH = 0, // No GMEM path is enabled. Using regular render path.
eGT_256bpp_PATH,
eGT_128bpp_PATH,
eGT_PathCount // Must be last
};
enum EGmemPathState
{
eGT_OK, // Nothing to report
eGT_DEV_UNSUPPORTED, // GMEM path not supported due to device limitations
eGT_FEATURES_UNSUPPORTED // Some rendering features are no supported with the GMEM path defined in .cfg file (r_EnableGMEMPath)
};
enum EGmemRendertargetType
{
eGT_Diffuse,
eGT_Specular,
eGT_Normals,
eGT_DepthStencil,
eGT_DiffuseLight,
eGT_SpecularLight,
eGT_VelocityBuffer,
eGT_RenderTargetCount // Must be last
};
static const int s_gmemRendertargetSlots[eGT_PathCount][eGT_RenderTargetCount];
// Checks if GMEM path is enabled.
EGmemPath FX_GetEnabledGmemPath(EGmemPathState* const gmemPathStateOut) const;
static const int s_gmemLargeRTCount = 5;
/////////////////////////////////////////////////////////////////////
bool FX_FogScene();
bool FX_DeferredCaustics();
bool FX_DeferredWaterVolumeCaustics(const N3DEngineCommon::SCausticInfo& causticInfo);
bool FX_DeferredRainOcclusionMap(const N3DEngineCommon::ArrOccluders& arrOccluders, const SRainParams& rainVolParams);
bool FX_DeferredRainOcclusion();
bool FX_DeferredRainPreprocess();
bool FX_DeferredRainGBuffer();
bool FX_DeferredSnowLayer();
bool FX_DeferredSnowDisplacement();
bool FX_MotionVectorGeneration(bool bEnable);
bool FX_CustomRenderScene(bool bEnable);
bool FX_PostProcessScene(bool bEnable);
bool FX_DeferredRendering(bool bDebugPass = false, bool bUpdateRTOnly = false);
bool FX_DeferredDecals();
bool FX_DeferredDecalsEmissive();
bool FX_SkinRendering(bool bEnable);
void FX_DepthFixupPrepare();
void FX_DepthFixupMerge();
void FX_SRGBConversion();
// Linearize Depth
void SetupLinearizeDepthParams(CShader* shader);
void FX_LinearizeDepth(CTexture* ptexZ);
// Performance queries
//=======================================================================
virtual float GetGPUFrameTime();
virtual void GetRenderTimes(SRenderTimes& outTimes);
// Shaders pipeline
//=======================================================================
virtual void FX_PipelineShutdown(bool bFastShutdown = false);
virtual void EF_ClearTargetsImmediately(uint32 nFlags);
virtual void EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil);
virtual void EF_ClearTargetsImmediately(uint32 nFlags, const ColorF& Colors);
virtual void EF_ClearTargetsImmediately(uint32 nFlags, float fDepth, uint8 nStencil);
virtual void EF_ClearTargetsLater(uint32 nFlags);
virtual void EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors, float fDepth, uint8 nStencil);
virtual void EF_ClearTargetsLater(uint32 nFlags, const ColorF& Colors);
virtual void EF_ClearTargetsLater(uint32 nFlags, float fDepth, uint8 nStencil);
void FX_Invalidate();
void EF_Restore();
virtual void FX_SetState(int st, int AlphaRef = -1, int RestoreState = 0) override;
void FX_StateRestore(int prevState);
void ChangeLog();
void SetCurDownscaleFactor(Vec2 sf);
// sets fullscreen viewport regardless of current scaling -
// should only be used for final upscale (in Post AA)
void SetFullscreenViewport();
bool CreateMSAADepthBuffer();
void FlushHardware(bool bIssueBeforeSync);
void PostMeasureOverdraw();
void DrawTexelsPerMeterInfo();
virtual bool CheckDeviceLost();
short m_nPrepareShadowFrame;
_inline void EF_DirtyMatrix()
{
int nThreadID = m_pRT->GetThreadList();
m_RP.m_TI[nThreadID].m_PersFlags |= RBPF_FP_MATRIXDIRTY | RBPF_FP_DIRTY;
}
void FX_ResetPipe() override;
_inline void EF_SetGlobalColor(float r, float g, float b, float a)
{
assert(m_pRT->IsRenderThread());
EF_SetColorOp(255, 255, eCA_Texture | (eCA_Constant << 3), eCA_Texture | (eCA_Constant << 3));
EF_SetSrgbWrite(false);
if (m_RP.m_CurGlobalColor[0] != r || m_RP.m_CurGlobalColor[1] != g || m_RP.m_CurGlobalColor[2] != b || m_RP.m_CurGlobalColor[3] != a)
{
m_RP.m_CurGlobalColor[0] = r;
m_RP.m_CurGlobalColor[1] = g;
m_RP.m_CurGlobalColor[2] = b;
m_RP.m_CurGlobalColor[3] = a;
m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_FP_DIRTY;
}
}
_inline void EF_SetVertColor()
{
// Only used from FontSetState, we do not want to call SetSrgbWrite - use whatever is set
EF_SetColorOp(255, 255, eCA_Texture | (eCA_Diffuse << 3), eCA_Texture | (eCA_Diffuse << 3));
}
_inline void EF_DisableTextureAndColor()
{
assert(m_pRT->IsRenderThread());
if ((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg & 7) == eCA_Texture || (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg & 7) == eCA_Diffuse)
{
m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg & ~7) | eCA_Constant;
m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_FP_DIRTY;
}
if (((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg >> 3) & 7) == eCA_Texture || ((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg >> 3) & 7) == eCA_Diffuse)
{
m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurColorArg & ~0x38) | (eCA_Constant << 3);
m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_FP_DIRTY;
}
if ((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg & 7) == eCA_Texture || (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg & 7) == eCA_Diffuse)
{
m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg & ~7) | eCA_Constant;
m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_FP_DIRTY;
}
if (((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg >> 3) & 7) == eCA_Texture || ((m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg >> 3) & 7) == eCA_Diffuse)
{
m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg = (m_RP.m_TI[m_RP.m_nProcessThreadID].m_eCurAlphaArg & ~0x38) | (eCA_Constant << 3);
m_RP.m_TI[m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_FP_DIRTY;
}
}
//================================================================================
virtual long FX_SetVertexDeclaration(int StreamMask, const AZ::Vertex::Format& vertexFormat) override;
inline bool FX_SetStreamFlags([[maybe_unused]] SShaderPass* pPass)
{
if (CV_r_usehwskinning && m_RP.m_pRE && (m_RP.m_pRE->mfGetFlags() & FCEF_SKINNED))
{
m_RP.m_FlagsStreams_Decl |= VSM_HWSKIN;
m_RP.m_FlagsStreams_Stream |= VSM_HWSKIN;
return true;
}
return false;
}
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_10
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
void FX_DrawBatches(CShader* pSh, SShaderPass* pPass);
void FX_DrawBatchesSkinned(CShader* pSh, SShaderPass* pPass, SSkinningData* pSkinningData);
//========================================================================================
void FX_SetActiveRenderTargets(bool bAllowDIP = false) override;
void FX_SetViewport();
void FX_ClearTargets();
/* NOTES:
* - passing D3DSurface/D3DDepthSurface are the close-to-metal calls and might not be
* implemented for a specific device
* - using rectangles and passing optional=true will use the most close-to-metal call
* possible, even if it clears more than the given rect - otherwise a
* shader-implementation will do the exact rect clear
*
* - if there is a fallback, then the RT-stack is utilized to clear, which comes with
* moderate CPU-overhead (relative to the cost of the close-to-metal call)
*/
void FX_ClearTarget(D3DSurface* pView, const ColorF& cClear, const uint numRects = 0, const RECT* pRects = nullptr);
void FX_ClearTarget(ITexture* pTex, const ColorF& cClear, const uint numRects, const RECT* pRects, const bool bOptional);
void FX_ClearTarget(ITexture* pTex, const ColorF& cClear);
void FX_ClearTarget(ITexture* pTex);
void FX_ClearTarget(D3DDepthSurface* pView, const int nFlags, const float cDepth, const uint8 cStencil, const uint numRects = 0, const RECT* pRects = nullptr);
void FX_ClearTarget(SDepthTexture* pTex, const int nFlags, const float cDepth, const uint8 cStencil, const uint numRects, const RECT* pRects, const bool bOptional);
void FX_ClearTarget(SDepthTexture* pTex, const int nFlags, const float cDepth, const uint8 cStencil);
void FX_ClearTarget(SDepthTexture* pTex, const int nFlags);
void FX_ClearTarget(SDepthTexture* pTex);
// shader-implementation of clear
void FX_ClearTargetRegion(const uint32 nAdditionalStates = 0);
#define MAX_RT_STACK 8
#if defined(WIN32) || defined(OPENGL)
#define RT_STACK_WIDTH D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
#else
#define RT_STACK_WIDTH 4
#endif
struct SRTStack
{
D3DSurface* m_pTarget;
D3DDepthSurface* m_pDepth;
CTexture* m_pTex;
SDepthTexture* m_pSurfDepth;
int m_Width;
int m_Height;
uint32 m_bNeedReleaseRT : 1;
uint32 m_bWasSetRT : 1;
uint32 m_bWasSetD : 1;
uint32 m_bScreenVP : 1;
uint32 m_ClearFlags;
ColorF m_ReqColor;
float m_fReqDepth;
uint8 m_nReqStencil;
};
int m_nRTStackLevel[RT_STACK_WIDTH];
SRTStack m_RTStack[RT_STACK_WIDTH][MAX_RT_STACK];
int m_nMaxRT2Commit;
SRTStack* m_pNewTarget[RT_STACK_WIDTH];
CTexture* m_pCurTarget[RT_STACK_WIDTH];
TArray<SDepthTexture*> m_TempDepths;
enum
{
MAX_WIREFRAME_STACK = 10
};
int m_arrWireFrameStack[MAX_WIREFRAME_STACK];
int m_nWireFrameStack;
bool FX_GetTargetSurfaces(CTexture* pTarget, D3DSurface*& pTargSurf, SRTStack* pCur, int nCMSide = -1, int nTarget = 0, uint32 nTileCount = 1);
virtual bool FX_SetRenderTarget(int nTarget, void* pTargetSurf, SDepthTexture* pDepthTarget, uint32 nTileCount = 1) override;
virtual bool FX_PushRenderTarget(int nTarget, void* pTargetSurf, SDepthTexture* pDepthTarget, uint32 nTileCount = 1) override;
virtual bool FX_SetRenderTarget(int nTarget, CTexture* pTarget, SDepthTexture* pDepthTarget, bool bPush = false, int nCMSide = -1, bool bScreenVP = false, uint32 nTileCount = 1) override;
virtual bool FX_PushRenderTarget(int nTarget, CTexture* pTarget, SDepthTexture* pDepthTarget, int nCMSide = -1, bool bScreenVP = false, uint32 nTileCount = 1) override;
virtual bool FX_RestoreRenderTarget(int nTarget) override;
virtual bool FX_PopRenderTarget(int nTarget) override;
virtual SDepthTexture* FX_GetDepthSurface(int nWidth, int nHeight, bool bAA, bool shaderResourceView = false) override;
virtual SDepthTexture* GetDepthBufferOrig() override { return &m_DepthBufferOrig; }
virtual uint32 GetBackBufferWidth() override { return m_backbufferWidth; }
virtual uint32 GetBackBufferHeight() override { return m_backbufferHeight; }
CTexture* FX_GetCurrentRenderTarget(int target);
D3DSurface* FX_GetCurrentRenderTargetSurface(int target) const;
// CONFETTI BEGIN: David Srour
// Following is used to assign load/store actions for the nTarget render target.
// This function should be used AFTER using FX_PushRenderTarget.
// Currently, these will only do something meaningful for devices running Metal & GL-ES.
void FX_SetColorDontCareActions(int const nTarget,
bool const loadDontCare = false,
bool const storeDontCare = false);
void FX_SetDepthDontCareActions(int const nTarget,
bool const loadDontCare = false,
bool const storeDontCare = false);
void FX_SetStencilDontCareActions(int const nTarget,
bool const loadDontCare = false,
bool const storeDontCare = false);
// Following is used to toggle GL-ES "Pixel Local Storage" extension
// Will only do something meaningful for devices running GL-ES with the PLS extension enabled.
void FX_TogglePLS(bool const enable);
// CONFETTI END
//========================================================================================
virtual void FX_Commit(bool bAllowDIP = false) override;
void FX_ZState(uint32& nState);
void FX_HairState(uint32& nState, const SShaderPass* pPass);
bool FX_SetFPMode();
bool FX_SetUIMode();
ILINE uint32 PackBlendModeAndPassGroup()
{
return ((m_RP.m_nPassGroupID << 24) | (m_RP.m_CurState & GS_BLEND_MASK));
}
ILINE bool ShouldApplyFogCorrection()
{
return PackBlendModeAndPassGroup() != m_uLastBlendFlagsPassGroup;
}
void FX_CommitStates(const SShaderTechnique* pTech, const SShaderPass* pPass, bool bUseMaterialState);
_inline void FX_DrawRE(CShader* sh, SShaderPass* sl)
{
int bFogOverrided = 0;
// Unlock all VB (if needed) and set current streams
FX_CommitStreams(sl);
if (ShouldApplyFogCorrection())
{
FX_FogCorrection();
}
if (m_RP.m_pRE)
{
m_RP.m_pRE->mfDraw(sh, sl);
}
else
{
FX_DrawIndexedMesh(eptTriangleList);
}
}
ILINE long FX_SetVStream(int nID, const void* pB, uint32 nOffs, uint32 nStride, [[maybe_unused]] uint32 nFreq = 1)
{
FUNCTION_PROFILER_RENDER_FLAT
D3DBuffer* pVB = (D3DBuffer*)pB;
HRESULT h = S_OK;
SStreamInfo& sinfo = m_RP.m_VertexStreams[nID];
if (sinfo.pStream != pVB || sinfo.nOffset != nOffs || sinfo.nStride != nStride)
{
sinfo.pStream = pVB;
sinfo.nOffset = nOffs;
sinfo.nStride = nStride;
m_DevMan.BindVB(nID, 1, &pVB, &nOffs, &nStride);
}
//assert(h == S_OK);
return h;
}
virtual long FX_SetIStream(const void* pB, uint32 nOffs, RenderIndexType idxType) override
{
#if !defined(_RELEASE) && !defined(SUPPORT_FLEXIBLE_INDEXBUFFER)
IF (idxType == Index32 || idxType == Index16 && (nOffs & 1), 0)
{
__debugbreak();
}
#endif
D3DBuffer* pIB = (D3DBuffer*)pB;
HRESULT h = S_OK;
#if !defined(SUPPORT_FLEXIBLE_INDEXBUFFER)
if (m_RP.m_pIndexStream != pIB)
{
m_RP.m_pIndexStream = pIB;
m_DevMan.BindIB(pIB, 0, DXGI_FORMAT_R16_UINT);
}
m_RP.m_IndexStreamOffset = nOffs;
m_RP.m_IndexStreamType = idxType;
#else
if (m_RP.m_pIndexStream != pIB || m_RP.m_IndexStreamOffset != nOffs || m_RP.m_IndexStreamType != idxType)
{
m_RP.m_pIndexStream = pIB;
m_RP.m_IndexStreamOffset = nOffs;
m_RP.m_IndexStreamType = idxType;
m_DevMan.BindIB(pIB, nOffs, (DXGI_FORMAT) idxType);
}
#endif
assert(h == S_OK);
return h;
}
ILINE uint32 ApplyIndexBufferBindOffset(uint32 firstIndex)
{
#if !defined(SUPPORT_FLEXIBLE_INDEXBUFFER)
return firstIndex + (m_RP.m_IndexStreamOffset >> 1);
#else
return firstIndex;
#endif
}
ILINE long FX_ResetVertexDeclaration()
{
GetDeviceContext().IASetInputLayout(NULL);
m_pLastVDeclaration = NULL;
return S_OK;
}
ILINE D3DPrimitiveType FX_ConvertPrimitiveType(const eRenderPrimitiveType eType) const
{
assert(eType != eptHWSkinGroups);
return (D3DPrimitiveType) eType;
}
virtual void FX_DrawIndexedPrimitive(const eRenderPrimitiveType eType, const int nVBOffset, [[maybe_unused]] const int nMinVertexIndex, const int nVerticesCount, const int nStartIndex, const int nNumIndices, bool bInstanced = false) override
{
int nPrimitives = 0;
if (eType == eptTriangleList)
{
nPrimitives = nNumIndices / 3;
assert(nNumIndices % 3 == 0);
}
else
{
switch (eType)
{
case ept4ControlPointPatchList:
nPrimitives = nNumIndices >> 2;
assert(nNumIndices % 4 == 0);
break;
case ept3ControlPointPatchList:
nPrimitives = nNumIndices / 3;
assert(nNumIndices % 3 == 0);
break;
case eptTriangleStrip:
nPrimitives = nNumIndices - 2;
assert(nNumIndices > 2);
break;
case eptLineList:
nPrimitives = nNumIndices >> 1;
assert(nNumIndices % 2 == 0);
break;
#ifdef _DEBUG
default:
assert(0); // not supported
return;
#endif
}
}
const D3DPrimitiveType eNativePType = FX_ConvertPrimitiveType(eType);
SetPrimitiveTopology(eNativePType);
if (bInstanced)
{
m_DevMan.DrawIndexedInstanced(nNumIndices, nVerticesCount, ApplyIndexBufferBindOffset(nStartIndex), nVBOffset, nVBOffset);
}
else
{
m_DevMan.DrawIndexed(nNumIndices, ApplyIndexBufferBindOffset(nStartIndex), nVBOffset);
}
#if defined(ENABLE_PROFILING_CODE)
m_RP.m_PS[m_RP.m_nProcessThreadID].m_nPolygons[m_RP.m_nPassGroupDIP] += nPrimitives;
m_RP.m_PS[m_RP.m_nProcessThreadID].m_nDIPs[m_RP.m_nPassGroupDIP]++;
#endif
}
// This is a cross-platform low-level function for DIP call
ILINE void FX_DrawPrimitive(eRenderPrimitiveType eType, int nStartVertex, int nVerticesCount, int nInstanceVertices = 0)
{
int nPrimitives;
if (nInstanceVertices)
{
nPrimitives = nVerticesCount;
}
else
{
switch (eType)
{
case eptTriangleList:
nPrimitives = nVerticesCount / 3;
assert(nVerticesCount % 3 == 0);
break;
case eptTriangleStrip:
nPrimitives = nVerticesCount - 2;
assert(nVerticesCount > 2);
break;
case eptLineList:
nPrimitives = nVerticesCount / 2;
assert(nVerticesCount % 2 == 0);
break;
case eptLineStrip:
nPrimitives = nVerticesCount - 1;
assert(nVerticesCount > 1);
break;
case eptPointList:
case ept1ControlPointPatchList:
nPrimitives = nVerticesCount;
assert(nVerticesCount > 0);
break;
#ifndef _RELEASE
default:
assert(0); // not supported
return;
#endif
}
}
const D3DPrimitiveType eNativePType = FX_ConvertPrimitiveType(eType);
SetPrimitiveTopology(eNativePType);
if (nInstanceVertices)
{
m_DevMan.DrawInstanced(nInstanceVertices, nVerticesCount, 0, nStartVertex);
}
else
{
m_DevMan.Draw(nVerticesCount, nStartVertex);
}
#if defined(ENABLE_PROFILING_CODE)
m_RP.m_PS[m_RP.m_nProcessThreadID].m_nPolygons[m_RP.m_nPassGroupDIP] += nPrimitives;
m_RP.m_PS[m_RP.m_nProcessThreadID].m_nDIPs[m_RP.m_nPassGroupDIP]++;
#endif
}
bool FX_CommitStreams(SShaderPass* sl, bool bSetVertexDecl = true);
// get the anti aliasing formats available for current width, height and BPP
int GetAAFormat(TArray<SAAFormat>& Formats);
virtual void EF_SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa);
virtual void EF_SetSrgbWrite(bool sRGBWrite);
void FX_HDRPostProcessing();
void FX_FinalComposite();
void FX_PreRender(int Stage);
void FX_PostRender();
void EF_Init();
void EF_InitWaveTables();
void EF_OnDemandVertexDeclaration(SOnDemandD3DVertexDeclaration& out, const int nStreamMask, const AZ::Vertex::Format& vertexformat, const bool bMorph, const bool bInstanced);
void EF_InitD3DVertexDeclarations();
void EF_SetCameraInfo();
void FX_SetObjectTransform(CRenderObject* obj, CShader* pSH, int nTransFlags);
bool FX_ObjectChange(CShader* Shader, CShaderResources* pRes, CRenderObject* pObject, IRenderElement* pRE);
private:
void UpdateNearestChange(int flags); //Helper method for FX_ObjectChange to avoid I-cache misses
void HandleDefaultObject(); //Helper method for FX_ObjectChange to avoid I-cache misses
bool IsVelocityPassEnabled() const; //Helper method to detect if we should enable the velocity pass. Its needed to MB and TAA
// Get pointers to current D3D11 shaders, set tessellation related RT flags and return true if tessellation is enabled for current object
inline bool FX_SetTessellationShaders(CHWShader_D3D*& pCurHS, CHWShader_D3D*& pCurDS, const SShaderPass* pPass);
#ifdef TESSELLATION_RENDERER
inline void FX_SetAdjacencyOffsetBuffer();
#endif
bool InternalSaveToTIFF(ID3D11Texture2D* backBuffer, const char* filePath);
// The cached screenshot path for screenshot request bus.
char m_screenshotFilepathCache[AZ_MAX_PATH_LEN];
public:
void EF_DrawDebugTools(SViewport& VP, const SRenderingPassInfo& passInfo);
static void FX_DrawWire();
static void FX_DrawNormals();
static void FX_DrawTangents();
static void FX_DrawFurBending();
static void FX_FlushShader_ShadowGen();
static void FX_FlushShader_General();
static void FX_FlushShader_ZPass();
static void FX_SelectTechnique(CShader* pShader, SShaderTechnique* pTech);
// Unbind a buffer if it is bound to a Vertex or Index buffer slot
void FX_UnbindStreamSource(D3DBuffer* buffer);
int m_sPrevX, m_sPrevY, m_sPrevWdt, m_sPrevHgt;
bool m_bsPrev;
void EF_Scissor(bool bEnable, int sX, int sY, int sWdt, int sHgt);
bool EF_GetScissorState(int& sX, int& sY, int& sWdt, int& sHgt);
void EF_SetFogColor(const ColorF& Color);
void FX_FogCorrection();
byte FX_StartQuery(SRendItem* pRI);
void FX_EndQuery(SRendItem* pRI, byte bStartQ);
#if defined(DO_RENDERSTATS)
ILINE bool FX_ShouldTrackStats()
{
bool bShouldTrackStats = (CV_r_stats == 6 || m_pDebugRenderNode || m_bCollectDrawCallsInfo || m_bCollectDrawCallsInfoPerNode);
return bShouldTrackStats;
}
void FX_TrackStats(CRenderObject* pObj, IRenderMesh* pRenderMesh);
#endif
void FX_DrawIndexedMesh (const eRenderPrimitiveType nPrimType);
bool FX_SetResourcesState();
int EF_Preprocess(SRendItem* ri, uint32 nums, uint32 nume, RenderFunc pRenderFunc, const SRenderingPassInfo& passInfo);
void EF_SortRenderLists(SRenderListDesc* pRLD, int nThreadID, bool bUseDist = false, bool bUseJobSystem = false);
void EF_SortRenderList(int nList, int nAW, SRenderListDesc* pRLD, int nThread, bool bUseDist = false);
void FX_StartBatching();
void FX_ProcessBatchesList(int nums, int nume, uint32 nBatchFilter, uint32 nBatchExcludeFilter = 0);
// Only do expensive DX12 resource set building for PC DX12
#if defined(CRY_USE_DX12)
void PerFrameValidateResourceSets();
#endif
void FX_ProcessZPassRenderLists();
void FX_ProcessZPassRender_List(ERenderListID list, uint32 filter);
void FX_ProcessThicknessRenderLists();
void FX_ProcessSoftAlphaTestRenderLists();
void FX_ProcessSkinRenderLists(int nList, void (* RenderFunc)(), bool bLighting);
void FX_ProcessEyeOverlayRenderLists(int nList, void (* RenderFunc)(), bool bLightin);
void FX_ProcessHalfResParticlesRenderList(int nList, void (* RenderFunc)(), bool bLighting);
void FX_WaterVolumesPreprocess();
void FX_ProcessPostRenderLists(uint32 nBatchFilter);
void FX_ProcessRenderList(int nList, uint32 nBatchFilter, bool bSetRenderFunc = true);
void FX_ProcessRenderList(int nums, int nume, int nList, int nAfterWater, void (* RenderFunc)(), bool bLighting, uint32 nBatchFilter = FB_GENERAL, uint32 nBatchExcludeFilter = 0);
_inline void FX_ProcessRenderList(int nList, int nAfterWater, void (* RenderFunc)(), bool bLighting, uint32 nBatchFilter = FB_GENERAL, uint32 nBatchExcludeFilter = 0)
{
FX_ProcessRenderList(m_RP.m_pRLD->m_nStartRI[nAfterWater][nList], m_RP.m_pRLD->m_nEndRI[nAfterWater][nList], nList, nAfterWater, RenderFunc, bLighting, nBatchFilter, nBatchExcludeFilter);
}
void FX_WaterVolumesCaustics();
void FX_WaterVolumesCausticsPreprocess(N3DEngineCommon::SCausticInfo& causticInfo);
bool FX_WaterVolumesCausticsUpdateGrid(N3DEngineCommon::SCausticInfo& causticInfo);
void EF_ProcessRenderLists(void (* RenderFunc)(), int nFlags, SViewport& VP, const SRenderingPassInfo& passInfo, bool bSync3DEngineJobs);
void FX_ProcessPostGroups(int nums, int nume);
void EF_PrintProfileInfo();
virtual void EF_EndEf3D (int nFlags, int nPrecacheUpdateId, int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo);
virtual void EF_EndEf2D(bool bSort); // 2d only
virtual WIN_HWND GetHWND() { return m_hWnd; }
virtual bool SetWindowIcon(const char* path);
virtual void SetColorOp(byte eCo, byte eAo, byte eCa, byte eAa);
virtual void SetSrgbWrite(bool srgbWrite);
//////////////////////////////////////////////////////////////////////////
public:
bool IsDeviceLost() { return(m_bDeviceLost != 0); }
#if defined(FEATURE_SVO_GI)
virtual ISvoRenderer* GetISvoRenderer();
#endif
virtual IRenderAuxGeom* GetIRenderAuxGeom([[maybe_unused]] void* jobID = 0)
{
#if defined(ENABLE_RENDER_AUX_GEOM)
if (m_pRenderAuxGeomD3D)
{
return m_pRenderAuxGeomD3D->GetRenderAuxGeom(jobID);
}
#endif
return &m_renderAuxGeomNull;
}
virtual IColorGradingController* GetIColorGradingController()
{
return m_pColorGradingControllerD3D;
}
virtual IStereoRenderer* GetIStereoRenderer()
{
return m_pStereoRenderer;
}
virtual ITexture* Create2DTexture(const char* name, int width, int height, int numMips, int flags, unsigned char* data, ETEX_Format format)
{
return CTexture::Create2DTexture(name, width, height, numMips, flags, data, format, format);
}
CTiledShading& GetTiledShading()
{
return *m_pTiledShading;
}
CStandardGraphicsPipeline& GetGraphicsPipeline()
{
return *m_GraphicsPipeline;
}
CVolumetricFog& GetVolumetricFog()
{
return m_volumetricFog;
}
PerInstanceConstantBufferPool& GetPerInstanceConstantBufferPool()
{
return m_PerInstanceConstantBufferPool;
}
PerInstanceConstantBufferPool* GetPerInstanceConstantBufferPoolPointer()
{
return &m_PerInstanceConstantBufferPool;
}
virtual void PushFogVolume(class CREFogVolume* pFogVolume, const SRenderingPassInfo& passInfo)
{
GetVolumetricFog().PushFogVolume(pFogVolume, passInfo);
}
CD3DStereoRenderer& GetS3DRend() const { return *m_pStereoRenderer; }
bool IsStereoEnabled() const;
void RT_PrepareStereo(int mode, int output);
void RT_CopyToStereoTex(int channel);
void RT_UpdateTrackingStates();
void RT_DisplayStereo();
void RT_DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) final;
virtual void EnableGPUTimers2(bool bEnabled)
{
if (bEnabled)
{
CD3DProfilingGPUTimer::EnableTiming();
}
else
{
CD3DProfilingGPUTimer::DisableTiming();
}
}
virtual void AllowGPUTimers2(bool bAllow)
{
if (bAllow)
{
CD3DProfilingGPUTimer::AllowTiming();
}
else
{
CD3DProfilingGPUTimer::DisallowTiming();
}
}
virtual const RPProfilerStats* GetRPPStats(ERenderPipelineProfilerStats eStat, bool bCalledFromMainThread = true) const { return m_pPipelineProfiler ? &m_pPipelineProfiler->GetBasicStats(eStat, bCalledFromMainThread ? m_RP.m_nFillThreadID : m_RP.m_nProcessThreadID) : nullptr; }
virtual const RPProfilerStats* GetRPPStatsArray(bool bCalledFromMainThread = true) const { return m_pPipelineProfiler ? m_pPipelineProfiler->GetBasicStatsArray(bCalledFromMainThread ? m_RP.m_nFillThreadID : m_RP.m_nProcessThreadID) : nullptr; }
virtual int GetPolygonCountByType([[maybe_unused]] uint32 EFSList, [[maybe_unused]] EVertexCostTypes vct, [[maybe_unused]] uint32 z, [[maybe_unused]] bool bCalledFromMainThread = true)
{
#if defined(ENABLE_PROFILING_CODE)
return m_RP.m_PS[bCalledFromMainThread ? m_RP.m_nFillThreadID : m_RP.m_nProcessThreadID].m_nPolygonsByTypes[EFSList][vct][z];
#else
return 0;
#endif
}
#ifdef SUPPORT_HW_MOUSE_CURSOR
virtual IHWMouseCursor* GetIHWMouseCursor();
#endif
virtual void StartLoadtimePlayback(ILoadtimeCallback* pCallback);
virtual void StopLoadtimePlayback();
// macros to implement the platform differences for pushing GPU Markers
#if defined(ENABLE_FRAME_PROFILER_LABELS)
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_11
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(OPENGL)
#define PROFILE_LABEL_GPU(_NAME) DXGLProfileLabel(_NAME);
#define PROFILE_LABEL_PUSH_GPU(_NAME) DXGLProfileLabelPush(_NAME);
#define PROFILE_LABEL_POP_GPU(_NAME) DXGLProfileLabelPop(_NAME);
#elif defined(CRY_USE_DX12)
#define PROFILE_LABEL_GPU(_NAME) do { } while (0)
#define PROFILE_LABEL_PUSH_GPU(_NAME) do { GetDeviceContext().PushMarker(_NAME); } while (0)
#define PROFILE_LABEL_POP_GPU(_NAME) do { GetDeviceContext().PopMarker(); } while (0)
#else
#define PROFILE_LABEL_GPU(X) do { wchar_t buf[256]; Unicode::Convert(buf, X); D3DPERF_SetMarker(0xffffffff, buf); } while (0)
#define PROFILE_LABEL_PUSH_GPU(X) do { wchar_t buf[128]; Unicode::Convert(buf, X); D3DPERF_BeginEvent(0xff00ff00, buf); } while (0)
#define PROFILE_LABEL_POP_GPU(X) do { D3DPERF_EndEvent(); } while (0)
#endif
#else
#define PROFILE_LABEL_GPU(_NAME)
#define PROFILE_LABEL_PUSH_GPU(_NAME)
#define PROFILE_LABEL_POP_GPU(_NAME)
#endif
void AddProfilerLabel([[maybe_unused]] const char* name) override { PROFILE_LABEL_GPU(name); }
void BeginProfilerSection(const char* name, [[maybe_unused]] uint32 eProfileLabelFlags = 0) override { PROFILE_LABEL_PUSH_GPU(name); if (m_pPipelineProfiler) { m_pPipelineProfiler->BeginSection(name); } }
void EndProfilerSection(const char* name) override { PROFILE_LABEL_POP_GPU(name); if (m_pPipelineProfiler) { m_pPipelineProfiler->EndSection(name); } }
private:
void OnRendererFreeResources(int flags) override;
void HandleDisplayPropertyChanges();
void FX_SetAlphaTestState(float alphaRef);
#if defined(ENABLE_PROFILING_CODE)
#if DRIVERD3D_H_TRAIT_DEFSAVETEXTURE || defined(OPENGL)
ID3D11Texture2D* m_pSaveTexture[2];
#endif
// Surfaces used to capture the current screen
unsigned int m_captureFlipFlop;
// Variables used for frame buffer capture and callback
ICaptureFrameListener* m_pCaptureCallBack[MAXFRAMECAPTURECALLBACK];
unsigned int m_frameCaptureRegisterNum;
int m_nScreenCaptureRequestFrame[RT_COMMAND_BUF_COUNT];
int m_screenCapTexHandle[RT_COMMAND_BUF_COUNT];
#endif
class FrameBufferDescription
{
public:
~FrameBufferDescription();
byte* pDest = nullptr;
ID3D11Texture2D* pBackBufferTex = nullptr;
ID3D11Texture2D* pTmpTexture = nullptr;
ID3D11Texture2D* tempZtex = nullptr;
float* depthData = nullptr;
D3D11_TEXTURE2D_DESC backBufferDesc;
D3D11_MAPPED_SUBRESOURCE resource;
bool includeAlpha = false;
//size information
int outputBytesPerPixel;
int texSize;
const static int inputBytesPerPixel = 4;
};
FrameBufferDescription* m_frameBufDesc = nullptr;
bool PrepFrameCapture(FrameBufferDescription& frameBufDesc, CTexture* pRenderTarget = 0);
void FillFrameBuffer(FrameBufferDescription& frameBufDesc, bool redBlueSwap);
bool CaptureFrameBufferToFile(const char* pFilePath, CTexture* pRenderTarget = 0);
// Store local pointers to CVars used for capturing
void CacheCaptureCVars();
void CaptureFrameBuffer();
// Resolve supersampled back buffer
void ResolveSupersampledBackbuffer();
// Scale back buffer contents to match viewport
void ScaleBackbufferToViewport();
ICVar* CV_capture_frames;
ICVar* CV_capture_folder;
ICVar* CV_capture_buffer;
ICVar* CV_capture_frame_once;
ICVar* CV_capture_file_name;
ICVar* CV_capture_file_prefix;
#if defined(WIN32) || defined(WIN64)
ICVar* CV_r_FullscreenWindow;
ICVar* CV_r_FullscreenNativeRes;
bool m_fullscreenWindow;
#endif
#if DRIVERD3D_H_TRAIT_DEFREGISTEREDWINDOWHANDLER
bool m_registeredWindoWHandler = false;
#endif
virtual void EnablePipelineProfiler(bool bEnable);
#if defined(ENABLE_RENDER_AUX_GEOM)
CRenderAuxGeomD3D* m_pRenderAuxGeomD3D;
#endif
CAuxGeomCB_Null m_renderAuxGeomNull;
static TArray<CRenderObject*> s_tempObjects[2];
static TArray<SRendItem*> s_tempRIs;
// For matching calls between EF_Init and FX_PipelineShutdown
bool m_shaderPipelineInitialized = false;
bool m_clearShadowMaskTexture = false;
#if defined(WIN32)
public:
// Called to inspect window messages sent to this renderer's windows
virtual bool HandleMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
private:
uint m_nConnectedMonitors; // The number of monitors currently connected to the system
bool m_bDisplayChanged; // Dirty-flag set when the number of monitors in the system changes
#endif
// Gmem variables
private:
mutable EGmemDepthStencilMode m_gmemDepthStencilMode;
};
enum
{
SPCBI_NUMBER_OF_BUFFERS = 64
};
struct SPersistentConstBufferInfo
{
uint64 m_crc[SPCBI_NUMBER_OF_BUFFERS];
AzRHI::ConstantBuffer* m_pStaticInstCB[SPCBI_NUMBER_OF_BUFFERS];
int m_frameID;
int m_buffer;
};
///////////////////////////////////////////////////////////////////////////////
inline void CD3D9Renderer::BindContextToThread([[maybe_unused]] DWORD threadID)
{
#if ENABLE_CONTEXT_THREAD_CHECKING
m_DeviceOwningthreadID = threadID;
#endif
}
///////////////////////////////////////////////////////////////////////////////
inline void CD3D9Renderer::CheckContextThreadAccess() const
{
#if ENABLE_CONTEXT_THREAD_CHECKING
if (m_DeviceOwningthreadID != CryGetCurrentThreadId())
{
CryFatalError("accessing d3d11 immediate context from unbound thread!");
}
#endif
}
///////////////////////////////////////////////////////////////////////////////
inline DWORD CD3D9Renderer::GetBoundThreadID() const
{
return m_DeviceOwningthreadID;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
inline D3DDevice& CD3D9Renderer::GetDevice()
{
AZ_Assert(m_Device, "Device is null");
return *m_Device;
}
inline const D3DDevice& CD3D9Renderer::GetDevice() const
{
AZ_Assert(m_Device, "Device is null");
return *m_Device;
}
///////////////////////////////////////////////////////////////////////////////
inline D3DDeviceContext& CD3D9Renderer::GetDeviceContext()
{
CheckContextThreadAccess();
AZ_Assert(m_DeviceContext, "Device context is null");
return *m_DeviceContext;
}
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DRIVERD3D_H_SECTION_12
#include AZ_RESTRICTED_FILE(DriverD3D_h)
#endif
#if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES)
void UserOverrideDisplayProperties(DXGI_MODE_DESC& desc);
#endif
extern StaticInstance<CD3D9Renderer> gcpRendD3D;
//=========================================================================================
#include "D3DHWShader.h"
#include <RenderDll/Common/FencedIB.h>
#include <RenderDll/Common/FencedVB.h>
#include "DeviceManager/TempDynBuffer.h"
//=========================================================================================
#define STREAMED_TEXTURE_USAGE (CDeviceManager::USAGE_STREAMING)
void EnableCloseButton(void* hWnd, bool enabled);