/* * 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 "../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 // std::unique_ptr #include // std::forward template inline std::unique_ptr CryMakeUnique(TArgs&& ... args) { return std::make_unique(std::forward(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 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 struct IStatoscopeDataGroup; class CHWShader_D3D; //====================================================================== /// Direct3D Render driver class #ifdef SHADER_ASYNC_COMPILATION class CAsyncShaderTask; #endif AZStd::vector 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 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 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 m_CharCBFreeList[eBoneType_Count]; util::list 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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 m_2dImages; // CRY DX12 TArray m_uiImages; //================================================================== public: enum { MAX_FRAME_QUERIES = 2 }; D3DQuery* m_pQuery[MAX_FRAME_QUERIES]; #if !defined(_RELEASE) || defined(ENABLE_STATOSCOPE_RELEASE) // sprite cells referenced this frame (particular sprite in particular atlas) std::set m_SpriteCellsUsed; // sprite atlases referenced this frame std::set m_SpriteAtlasesUsed; #endif #if ENABLE_STATOSCOPE IStatoscopeDataGroup* m_pGPUTimersDG; IStatoscopeDataGroup* m_pGraphicsDG; IStatoscopeDataGroup* m_pPerformanceOverviewDG; #endif TArray 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 m_StatesBL; TArray m_StatesRS; TArray 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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #endif t_arrDeferredMeshIndBuff m_arrDeferredInds; t_arrDeferredMeshVertBuff m_arrDeferredVerts; public: #ifdef SHADER_ASYNC_COMPILATION DynArray 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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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(const 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; } #if defined(SUPPORT_DEVICE_INFO) static HWND CreateWindowCallback(); 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 m_RContexts; SD3DContext* m_CurrContext; TArray 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, const 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 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, const 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, const 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(const 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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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& 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(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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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 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, 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, 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(const eRenderPrimitiveType eType, const int nStartVertex, const int nVerticesCount, const 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& 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 (const int nFlags, const int nPrecacheUpdateId, const int nNearPrecacheUpdateId, const SRenderingPassInfo& passInfo); virtual void EF_EndEf2D(const 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); } void InitNVAPI(); void InitAMDAPI(); #if defined(FEATURE_SVO_GI) virtual ISvoRenderer* GetISvoRenderer(); #endif virtual IRenderAuxGeom* GetIRenderAuxGeom(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(uint32 EFSList, EVertexCostTypes vct, uint32 z, 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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #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(const char* name) override { PROFILE_LABEL_GPU(name); } void BeginProfilerSection(const char* name, 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_file_format; 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 s_tempObjects[2]; static TArray 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(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 #if defined(AZ_PLATFORM_XENIA) #include "Xenia/DriverD3D_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/DriverD3D_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/DriverD3D_h_salem.inl" #endif #endif #if defined(SUPPORT_DEVICE_INFO_USER_DISPLAY_OVERRIDES) void UserOverrideDisplayProperties(DXGI_MODE_DESC& desc); #endif extern StaticInstance gcpRendD3D; //========================================================================================= #include "D3DHWShader.h" #include "../Common/FencedIB.h" #include "../Common/FencedVB.h" #include "DeviceManager/TempDynBuffer.h" //========================================================================================= #define STREAMED_TEXTURE_USAGE (CDeviceManager::USAGE_STREAMING) void EnableCloseButton(void* hWnd, bool enabled);