1 // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
3 /*=============================================================================
4 Texture.cpp : Common texture manager implementation.
7 * Created by Honich Andrey
9 =============================================================================*/
12 #include <Cry3DEngine/ImageExtensionHelper.h>
13 #include "Image/CImage.h"
14 #include "Image/DDSImage.h"
15 #include "TextureManager.h"
16 #include <CrySystem/Scaleform/IFlashUI.h>
17 #include <CrySystem/File/IResourceManager.h>
18 #include <Cry3DEngine/I3DEngine.h>
19 #include <CryString/StringUtils.h> // stristr()
20 #include "TextureStreamPool.h"
21 #include "TextureHelpers.h"
22 #include <CrySystem/Scaleform/IUIFramework.h>
23 #include <CrySystem/Scaleform/IScaleformHelper.h>
25 // class CMipmapGenPass;
26 #include "../../XRenderD3D9/GraphicsPipeline/Common/UtilityPasses.h"
28 #define TEXTURE_LEVEL_CACHE_PAK "dds0.pak"
30 SSamplerState
SSamplerState::s_sDefState
;
32 STexStageInfo
CTexture::s_TexStages
[MAX_TMU
];
33 SamplerStateHandle
CTexture::s_TexStateIDs
[eHWSC_Num
][MAX_TMU
];
34 int CTexture::s_nStreamingMode
;
35 int CTexture::s_nStreamingUpdateMode
;
36 bool CTexture::s_bPrecachePhase
;
37 bool CTexture::s_bInLevelPhase
= false;
38 bool CTexture::s_bPrestreamPhase
;
39 int CTexture::s_nStreamingThroughput
= 0;
40 float CTexture::s_nStreamingTotalTime
= 0;
41 CTextureStreamPoolMgr
* CTexture::s_pPoolMgr
;
42 std::set
<string
> CTexture::s_vTexReloadRequests
;
43 CryCriticalSection
CTexture::s_xTexReloadLock
;
44 CryCriticalSectionNonRecursive
CTexture::s_invalidationLock
;
45 #ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT
46 CTexture::LowResSystemCopyType
CTexture::s_LowResSystemCopy
;
49 bool CTexture::m_bLoadedSystem
;
51 // ==============================================================================
52 CTexture
* CTexture::s_ptexNoTexture
;
53 CTexture
* CTexture::s_ptexNoTextureCM
;
54 CTexture
* CTexture::s_ptexWhite
;
55 CTexture
* CTexture::s_ptexGray
;
56 CTexture
* CTexture::s_ptexBlack
;
57 CTexture
* CTexture::s_ptexBlackAlpha
;
58 CTexture
* CTexture::s_ptexBlackCM
;
59 CTexture
* CTexture::s_ptexDefaultProbeCM
;
60 CTexture
* CTexture::s_ptexDefaultMergedDetail
;
61 CTexture
* CTexture::s_ptexFlatBump
;
62 #if !defined(_RELEASE)
63 CTexture
* CTexture::s_ptexMipMapDebug
;
64 CTexture
* CTexture::s_ptexColorBlue
;
65 CTexture
* CTexture::s_ptexColorCyan
;
66 CTexture
* CTexture::s_ptexColorGreen
;
67 CTexture
* CTexture::s_ptexColorPurple
;
68 CTexture
* CTexture::s_ptexColorRed
;
69 CTexture
* CTexture::s_ptexColorWhite
;
70 CTexture
* CTexture::s_ptexColorYellow
;
71 CTexture
* CTexture::s_ptexColorOrange
;
72 CTexture
* CTexture::s_ptexColorMagenta
;
74 CTexture
* CTexture::s_ptexPaletteDebug
;
75 CTexture
* CTexture::s_ptexPaletteTexelsPerMeter
;
76 CTexture
* CTexture::s_ptexIconShaderCompiling
;
77 CTexture
* CTexture::s_ptexIconStreaming
;
78 CTexture
* CTexture::s_ptexIconStreamingTerrainTexture
;
79 CTexture
* CTexture::s_ptexIconNavigationProcessing
;
80 CTexture
* CTexture::s_ptexMipColors_Diffuse
;
81 CTexture
* CTexture::s_ptexMipColors_Bump
;
82 CTexture
* CTexture::s_ptexShadowJitterMap
;
83 CTexture
* CTexture::s_ptexEnvironmentBRDF
;
84 CTexture
* CTexture::s_ptexScreenNoiseMap
;
85 CTexture
* CTexture::s_ptexDissolveNoiseMap
;
86 CTexture
* CTexture::s_ptexNoise3D
;
87 CTexture
* CTexture::s_ptexGrainFilterMap
;
88 CTexture
* CTexture::s_ptexFilmGrainMap
;
89 CTexture
* CTexture::s_ptexVignettingMap
;
90 CTexture
* CTexture::s_ptexAOJitter
;
91 CTexture
* CTexture::s_ptexAOVOJitter
;
92 CTexture
* CTexture::s_ptexFromRE
[8];
93 CTexture
* CTexture::s_ptexShadowID
[8];
94 CTexture
* CTexture::s_ptexShadowMask
;
95 CTexture
* CTexture::s_ptexCachedShadowMap
[MAX_GSM_LODS_NUM
];
96 CTexture
* CTexture::s_ptexNearestShadowMap
;
97 CTexture
* CTexture::s_ptexHeightMapAO
[2];
98 CTexture
* CTexture::s_ptexHeightMapAODepth
[2];
99 CTexture
* CTexture::s_ptexFromRE_FromContainer
[2];
100 CTexture
* CTexture::s_ptexFromObj
;
101 CTexture
* CTexture::s_ptexSvoTree
;
102 CTexture
* CTexture::s_ptexSvoTris
;
103 CTexture
* CTexture::s_ptexSvoGlobalCM
;
104 CTexture
* CTexture::s_ptexSvoRgbs
;
105 CTexture
* CTexture::s_ptexSvoNorm
;
106 CTexture
* CTexture::s_ptexSvoOpac
;
107 CTexture
* CTexture::s_ptexRT_2D
;
108 CTexture
* CTexture::s_ptexNormalsFitting
;
109 CTexture
* CTexture::s_ptexPerlinNoiseMap
;
111 CTexture
* CTexture::s_ptexSceneNormalsMap
;
112 CTexture
* CTexture::s_ptexSceneNormalsMapMS
;
113 CTexture
* CTexture::s_ptexSceneNormalsBent
;
114 CTexture
* CTexture::s_ptexAOColorBleed
;
115 CTexture
* CTexture::s_ptexSceneDiffuse
;
116 CTexture
* CTexture::s_ptexSceneSpecular
;
118 CTexture
* CTexture::s_ptexSceneSelectionIDs
;
119 CTexture
* CTexture::s_ptexSceneHalfDepthStencil
;
121 CTexture
* CTexture::s_ptexWindGrid
;
123 #if defined(DURANGO_USE_ESRAM)
124 CTexture
* CTexture::s_ptexSceneSpecularESRAM
;
127 // Post-process related textures
128 CTexture
* CTexture::s_ptexBackBuffer
= NULL
;
129 CTexture
* CTexture::s_ptexModelHudBuffer
;
130 CTexture
* CTexture::s_ptexPrevBackBuffer
[2][2] = {
133 CTexture
* CTexture::s_ptexCached3DHud
;
134 CTexture
* CTexture::s_ptexCached3DHudScaled
;
135 CTexture
* CTexture::s_ptexBackBufferScaled
[3];
136 CTexture
* CTexture::s_ptexBackBufferScaledTemp
[2];
137 CTexture
* CTexture::s_ptexPrevFrameScaled
;
139 CTexture
* CTexture::s_ptexDepthBufferQuarter
;
140 CTexture
* CTexture::s_ptexDepthBufferHalfQuarter
;
142 CTexture
* CTexture::s_ptexWaterOcean
;
143 CTexture
* CTexture::s_ptexWaterVolumeTemp
[2];
144 CTexture
* CTexture::s_ptexWaterVolumeDDN
;
145 CTexture
* CTexture::s_ptexWaterVolumeRefl
[2] = { NULL
};
146 CTexture
* CTexture::s_ptexWaterCaustics
[2] = { NULL
};
147 CTexture
* CTexture::s_ptexRainOcclusion
;
148 CTexture
* CTexture::s_ptexRainSSOcclusion
[2];
150 CTexture
* CTexture::s_ptexRainDropsRT
[2];
152 CTexture
* CTexture::s_ptexRT_ShadowPool
;
153 CTexture
* CTexture::s_ptexFarPlane
;
154 CTexture
* CTexture::s_ptexCloudsLM
;
156 CTexture
* CTexture::s_ptexSceneTarget
= NULL
;
157 CTexture
* CTexture::s_ptexSceneTargetR11G11B10F
[2] = { NULL
};
158 CTexture
* CTexture::s_ptexSceneTargetScaledR11G11B10F
[4] = { NULL
};
159 CTexture
* CTexture::s_ptexCurrSceneTarget
;
160 CTexture
* CTexture::s_ptexCurrentSceneDiffuseAccMap
;
161 CTexture
* CTexture::s_ptexSceneDiffuseAccMap
;
162 CTexture
* CTexture::s_ptexSceneSpecularAccMap
;
163 CTexture
* CTexture::s_ptexSceneDiffuseAccMapMS
;
164 CTexture
* CTexture::s_ptexSceneSpecularAccMapMS
;
165 CTexture
* CTexture::s_ptexZTarget
;
166 CTexture
* CTexture::s_ptexZOcclusion
[2];
167 CTexture
* CTexture::s_ptexZTargetReadBack
[4];
168 CTexture
* CTexture::s_ptexZTargetDownSample
[4];
169 CTexture
* CTexture::s_ptexZTargetScaled
;
170 CTexture
* CTexture::s_ptexZTargetScaled2
;
171 CTexture
* CTexture::s_ptexZTargetScaled3
;
172 CTexture
* CTexture::s_ptexHDRTarget
;
173 CTexture
* CTexture::s_ptexVelocity
;
174 CTexture
* CTexture::s_ptexVelocityTiles
[3] = { NULL
};
175 CTexture
* CTexture::s_ptexVelocityObjects
[2] = { NULL
};
176 CTexture
* CTexture::s_ptexHDRTargetPrev
= NULL
;
177 CTexture
* CTexture::s_ptexHDRTargetScaled
[4];
178 CTexture
* CTexture::s_ptexHDRTargetScaledTmp
[4];
179 CTexture
* CTexture::s_ptexHDRTargetScaledTempRT
[4];
180 CTexture
* CTexture::s_ptexHDRDofLayers
[2];
181 CTexture
* CTexture::s_ptexSceneCoC
[MIN_DOF_COC_K
] = { NULL
};
182 CTexture
* CTexture::s_ptexSceneCoCTemp
= NULL
;
183 CTexture
* CTexture::s_ptexHDRTempBloom
[2];
184 CTexture
* CTexture::s_ptexHDRFinalBloom
;
185 CTexture
* CTexture::s_ptexHDRAdaptedLuminanceCur
[8];
186 int CTexture::s_nCurLumTextureIndex
;
187 CTexture
* CTexture::s_ptexCurLumTexture
;
188 CTexture
* CTexture::s_ptexHDRToneMaps
[NUM_HDR_TONEMAP_TEXTURES
];
189 CTexture
* CTexture::s_ptexHDRMeasuredLuminance
[MAX_GPU_NUM
];
190 CTexture
* CTexture::s_ptexHDRMeasuredLuminanceDummy
;
191 CTexture
* CTexture::s_ptexSkyDomeMie
;
192 CTexture
* CTexture::s_ptexSkyDomeRayleigh
;
193 CTexture
* CTexture::s_ptexSkyDomeMoon
;
194 CTexture
* CTexture::s_ptexColorChart
;
195 CTexture
* CTexture::s_ptexSceneTargetScaled
;
196 CTexture
* CTexture::s_ptexSceneTargetScaledBlurred
;
197 CTexture
* CTexture::s_ptexStereoL
= NULL
;
198 CTexture
* CTexture::s_ptexStereoR
= NULL
;
199 CTexture
* CTexture::s_ptexQuadLayers
[2] = { NULL
};
201 CTexture
* CTexture::s_ptexFlaresOcclusionRing
[MAX_OCCLUSION_READBACK_TEXTURES
] = { NULL
};
202 CTexture
* CTexture::s_ptexFlaresGather
= NULL
;
204 SEnvTexture
CTexture::s_EnvTexts
[MAX_ENVTEXTURES
];
206 TArray
<SEnvTexture
> CTexture::s_CustomRT_2D
;
208 TArray
<CTexture
> CTexture::s_ShaderTemplates(EFTT_MAX
);
209 bool CTexture::s_ShaderTemplatesInitialized
= false;
211 CTexture
* CTexture::s_pTexNULL
= 0;
213 CTexture
* CTexture::s_pBackBuffer
;
214 CTexture
* CTexture::s_FrontBufferTextures
[2] = { NULL
};
216 CTexture
* CTexture::s_ptexVolumetricFog
= NULL
;
217 CTexture
* CTexture::s_ptexVolumetricClipVolumeStencil
= NULL
;
219 CTexture
* CTexture::s_ptexVolCloudShadow
= NULL
;
221 #if defined(TEXSTRM_DEFERRED_UPLOAD)
222 ID3D11DeviceContext
* CTexture::s_pStreamDeferredCtx
= nullptr;
225 #if defined(VOLUMETRIC_FOG_SHADOWS)
226 CTexture
* CTexture::s_ptexVolFogShadowBuf
[2] = { 0 };
229 ETEX_Format
CTexture::s_eTFZ
= eTF_R32F
;
231 //============================================================
233 SResourceView
SResourceView::ShaderResourceView(DXGI_FORMAT nFormat
, int nFirstSlice
, int nSliceCount
, int nMostDetailedMip
, int nMipCount
, bool bSrgbRead
, bool bMultisample
, int nFlags
)
235 SResourceView
result(0);
237 result
.m_Desc
.eViewType
= eShaderResourceView
;
238 result
.m_Desc
.nFormat
= nFormat
;
239 result
.m_Desc
.nFirstSlice
= nFirstSlice
;
240 result
.m_Desc
.nSliceCount
= nSliceCount
;
241 result
.m_Desc
.nMostDetailedMip
= nMostDetailedMip
;
242 result
.m_Desc
.nMipCount
= nMipCount
;
243 result
.m_Desc
.bSrgbRead
= bSrgbRead
? 1 : 0;
244 result
.m_Desc
.nFlags
= nFlags
;
245 result
.m_Desc
.bMultisample
= bMultisample
? 1 : 0;
250 SResourceView
SResourceView::RenderTargetView(DXGI_FORMAT nFormat
, int nFirstSlice
, int nSliceCount
, int nMipLevel
, bool bMultisample
)
252 SResourceView
result(0);
254 result
.m_Desc
.eViewType
= eRenderTargetView
;
255 result
.m_Desc
.nFormat
= nFormat
;
256 result
.m_Desc
.nFirstSlice
= nFirstSlice
;
257 result
.m_Desc
.nSliceCount
= nSliceCount
;
258 result
.m_Desc
.nMostDetailedMip
= nMipLevel
;
259 result
.m_Desc
.nMipCount
= 1;
260 result
.m_Desc
.bMultisample
= bMultisample
? 1 : 0;
265 SResourceView
SResourceView::DepthStencilView(DXGI_FORMAT nFormat
, int nFirstSlice
, int nSliceCount
, int nMipLevel
, bool bMultisample
, int nFlags
)
267 SResourceView
result(0);
269 result
.m_Desc
.eViewType
= eDepthStencilView
;
270 result
.m_Desc
.nFormat
= nFormat
;
271 result
.m_Desc
.nFirstSlice
= nFirstSlice
;
272 result
.m_Desc
.nSliceCount
= nSliceCount
;
273 result
.m_Desc
.nMostDetailedMip
= nMipLevel
;
274 result
.m_Desc
.nMipCount
= 1;
275 result
.m_Desc
.nFlags
= nFlags
;
276 result
.m_Desc
.bMultisample
= bMultisample
? 1 : 0;
281 SResourceView
SResourceView::UnorderedAccessView(DXGI_FORMAT nFormat
, int nFirstSlice
, int nSliceCount
, int nMipLevel
, int nFlags
)
283 SResourceView
result(0);
285 result
.m_Desc
.eViewType
= eUnorderedAccessView
;
286 result
.m_Desc
.nFormat
= nFormat
;
287 result
.m_Desc
.nFirstSlice
= nFirstSlice
;
288 result
.m_Desc
.nSliceCount
= nSliceCount
;
289 result
.m_Desc
.nMostDetailedMip
= nMipLevel
;
290 result
.m_Desc
.nMipCount
= 1;
291 result
.m_Desc
.nFlags
= nFlags
;
296 //============================================================
299 static inline uint32
ConvertFromTextureFlags(ETextureFlags eFlags
)
301 // NOTE Currently without correspondence:
306 // FT_USAGE_ALLOWREADSRGB
310 (!(eFlags
& FT_DONT_READ
) ? CDeviceObjectFactory::BIND_SHADER_RESOURCE
: 0) |
311 ( (eFlags
& FT_USAGE_RENDERTARGET
) ? CDeviceObjectFactory::BIND_RENDER_TARGET
: 0) |
312 ( (eFlags
& FT_USAGE_DEPTHSTENCIL
) ? CDeviceObjectFactory::BIND_DEPTH_STENCIL
: 0) |
313 ( (eFlags
& FT_USAGE_UNORDERED_ACCESS
) ? CDeviceObjectFactory::BIND_UNORDERED_ACCESS
: 0) |
314 ( (eFlags
& FT_USAGE_DYNAMIC
) ? CDeviceObjectFactory::USAGE_CPU_WRITE
: 0) |
315 (!(eFlags
& FT_DONT_STREAM
) ? CDeviceObjectFactory::USAGE_STREAMING
: 0) |
316 ( (eFlags
& FT_STAGE_READBACK
) ? (CDeviceObjectFactory::USAGE_STAGE_ACCESS
| CDeviceObjectFactory::USAGE_CPU_READ
) : 0) |
317 ( (eFlags
& FT_STAGE_UPLOAD
) ? (CDeviceObjectFactory::USAGE_STAGE_ACCESS
| CDeviceObjectFactory::USAGE_CPU_WRITE
) : 0) |
318 ( (eFlags
& FT_FORCE_MIPS
) ? CDeviceObjectFactory::USAGE_AUTOGENMIPS
: 0) |
319 ( (eFlags
& FT_USAGE_UAV_RWTEXTURE
) ? CDeviceObjectFactory::USAGE_UAV_READWRITE
: 0);
324 static inline ETextureFlags
ConvertToTextureFlags(uint32 eFlags
)
326 // NOTE Currently without correspondence:
331 // FT_USAGE_ALLOWREADSRGB
334 return ETextureFlags(
335 (!(eFlags
& CDeviceObjectFactory::BIND_SHADER_RESOURCE
) ? FT_DONT_READ
: 0) |
336 ( (eFlags
& CDeviceObjectFactory::BIND_RENDER_TARGET
) ? FT_USAGE_RENDERTARGET
: 0) |
337 ( (eFlags
& CDeviceObjectFactory::BIND_DEPTH_STENCIL
) ? FT_USAGE_DEPTHSTENCIL
: 0) |
338 ( (eFlags
& CDeviceObjectFactory::BIND_UNORDERED_ACCESS
) ? FT_USAGE_UNORDERED_ACCESS
: 0) |
339 (((eFlags
& (CDeviceObjectFactory::USAGE_STAGE_ACCESS
| CDeviceObjectFactory::USAGE_CPU_WRITE
))
340 == CDeviceObjectFactory::USAGE_CPU_WRITE
) ? FT_USAGE_DYNAMIC
: 0) |
341 (!(eFlags
& CDeviceObjectFactory::USAGE_STREAMING
) ? FT_DONT_STREAM
: 0) |
342 ( (eFlags
& (CDeviceObjectFactory::USAGE_STAGE_ACCESS
| CDeviceObjectFactory::USAGE_CPU_READ
)) ? FT_STAGE_READBACK
: 0) |
343 ( (eFlags
& (CDeviceObjectFactory::USAGE_STAGE_ACCESS
| CDeviceObjectFactory::USAGE_CPU_WRITE
)) ? FT_STAGE_UPLOAD
: 0) |
344 ( (eFlags
& CDeviceObjectFactory::USAGE_AUTOGENMIPS
) ? FT_FORCE_MIPS
: 0) |
345 ( (eFlags
& CDeviceObjectFactory::USAGE_UAV_READWRITE
) ? FT_USAGE_UAV_RWTEXTURE
: 0));
349 //============================================================
350 CTexture::CTexture(const uint32 nFlags
, const ColorF
& clearColor
/*= ColorF(Clr_Empty)*/, CDeviceTexture
* devTexToOwn
/*= nullptr*/)
353 m_eDstFormat
= eTF_Unknown
;
354 m_eSrcFormat
= eTF_Unknown
;
361 m_nDevTextureSize
= 0;
362 m_fAvgBrightness
= 1.0f
;
365 m_cClearColor
= clearColor
;
366 m_nPersistentSize
= 0;
367 m_fAvgBrightness
= 0.0f
;
369 #if CRY_PLATFORM_DURANGO && (CRY_RENDERER_DIRECT3D >= 110) && (CRY_RENDERER_DIRECT3D < 120)
370 m_nDeviceAddressInvalidated
= 0;
372 #if CRY_PLATFORM_DURANGO && DURANGO_USE_ESRAM
373 m_nESRAMOffset
= SKIP_ESRAM
;
376 m_nUpdateFrameID
= -1;
377 m_nAccessFrameID
= -1;
379 m_pPixelFormat
= NULL
;
380 m_pDevTexture
= NULL
;
382 m_bAsyncDevTexCreation
= false;
385 m_bNeedRestoring
= false;
386 m_bNoTexture
= false;
388 m_bUseMultisampledRTV
= true;
389 m_bHighQualityFiltering
= false;
390 m_bCustomFormat
= false;
391 m_eSrcTileMode
= eTM_Unspecified
;
393 m_bPostponed
= false;
394 m_bForceStreamHighRes
= false;
395 m_bWasUnloaded
= false;
397 m_bStreamPrepared
= false;
398 m_bStreamRequested
= false;
399 m_bVertexTexture
= false;
400 m_bUseDecalBorderCol
= false;
402 m_bNoDevTexture
= false;
403 m_bInDistanceSortedList
= false;
404 m_bCreatedInLevel
= gRenDev
->m_bInLevel
;
407 m_bStreamHighPriority
= 0;
408 m_nStreamingPriority
= 0;
409 m_nMinMipVidUploaded
= MAX_MIP_LEVELS
;
410 m_nMinMipVidActive
= MAX_MIP_LEVELS
;
411 m_nStreamSlot
= InvalidStreamSlot
;
412 m_fpMinMipCur
= MAX_MIP_LEVELS
<< 8;
413 m_nStreamFormatCode
= 0;
415 m_nDefState
= EDefaultSamplerStates::PointClamp
;
416 m_pFileTexMips
= NULL
;
417 m_fCurrentMipBias
= 0.f
;
419 static_assert(MaxStreamTasks
< 32767, "Too many stream tasks!");
423 OwnDevTexture(devTexToOwn
);
427 //============================================================
429 CTexture::~CTexture()
431 InvalidateDeviceResource(eResourceDestroyed
);
433 // sizes of these structures should NOT exceed L2 cache line!
434 #if CRY_PLATFORM_64BIT
435 static_assert((offsetof(CTexture
, m_composition
) - offsetof(CTexture
, m_pFileTexMips
)) <= 64, "Invalid offset!");
436 //static_assert((offsetof(CTexture, m_pFileTexMips) % 64) == 0, "Invalid offset!");
440 if (!gRenDev
->m_pRT
->IsRenderThread() || gRenDev
->m_pRT
->IsRenderLoadingThread())
449 if (gRenDev
&& gRenDev
->m_pRT
)
450 gRenDev
->m_pRT
->RC_ReleaseDeviceTexture(this);
455 StreamState_ReleaseInfo(this, m_pFileTexMips
);
456 m_pFileTexMips
= NULL
;
459 #ifdef ENABLE_TEXTURE_STREAM_LISTENER
460 if (s_pStreamListener
)
461 s_pStreamListener
->OnDestroyedStreamedTexture(this);
465 if (m_bInDistanceSortedList
)
469 #ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT
470 s_LowResSystemCopy
.erase(this);
473 CRY_ASSERT_MESSAGE(m_invalidateCallbacks
.empty(), "Make sure any clients (e.g. Renderpasses, resource sets, etc..) are released before destroying this resource");
476 void CTexture::RT_ReleaseDevice()
478 ReleaseDeviceTexture(false);
481 const CCryNameTSCRC
& CTexture::mfGetClassName()
486 CCryNameTSCRC
CTexture::GenName(const char* name
, uint32 nFlags
)
488 stack_string strName
= name
;
491 //'\\' in texture names causing duplication
492 PathUtil::ToUnixPath(strName
);
494 if (nFlags
& FT_ALPHA
)
497 return CCryNameTSCRC(strName
.c_str());
503 bool operator()(const char* s1
, const char* s2
) const { return strcmp(s1
, s2
) < 0; }
506 CTexture
* CTexture::GetByID(int nID
)
508 CTexture
* pTex
= s_ptexNoTexture
;
510 const CCryNameTSCRC
& className
= mfGetClassName();
511 CBaseResource
* pBR
= CBaseResource::GetResource(className
, nID
, false);
513 pTex
= (CTexture
*)pBR
;
517 CTexture
* CTexture::GetByName(const char* szName
, uint32 flags
)
519 CTexture
* pTex
= nullptr;
521 CCryNameTSCRC Name
= GenName(szName
, flags
);
522 CBaseResource
* pBR
= CBaseResource::GetResource(mfGetClassName(), Name
, false);
524 pTex
= (CTexture
*)pBR
;
528 CTexture
* CTexture::GetByNameCRC(CCryNameTSCRC Name
)
530 CTexture
* pTex
= nullptr;
532 CBaseResource
* pBR
= CBaseResource::GetResource(mfGetClassName(), Name
, false);
534 pTex
= (CTexture
*)pBR
;
538 CTexture
* CTexture::FindOrRegisterTextureObject(const char* name
, uint32 nFlags
, ETEX_Format eTFDst
, bool& bFound
)
540 CTexture
* pTex
= nullptr;
542 CCryNameTSCRC Name
= GenName(name
, nFlags
);
543 CBaseResource
* pBR
= CBaseResource::GetResource(mfGetClassName(), Name
, false);
546 pTex
= new CTexture(nFlags
);
547 pTex
->Register(mfGetClassName(), Name
);
548 pTex
->m_eFlags
= nFlags
;
549 pTex
->m_eDstFormat
= eTFDst
;
550 pTex
->m_SrcName
= name
;
555 pTex
= (CTexture
*)pBR
;
563 void CTexture::SetDevTexture(CDeviceTexture
* pDeviceTex
)
566 m_pDevTexture
->SetOwner(NULL
);
567 SAFE_RELEASE(m_pDevTexture
);
569 m_pDevTexture
= pDeviceTex
;
572 m_pDevTexture
->SetNoDelete(!!(m_eFlags
& FT_DONT_RELEASE
));
573 m_pDevTexture
->SetOwner(this);
576 InvalidateDeviceResource(eDeviceResourceDirty
);
579 void CTexture::OwnDevTexture(CDeviceTexture
* pDeviceTex
)
581 SAFE_RELEASE(m_pDevTexture
);
583 m_pDevTexture
= pDeviceTex
;
586 const STextureLayout Layput
= m_pDevTexture
->GetLayout();
588 m_nWidth
= Layput
.m_nWidth
;
589 m_nHeight
= Layput
.m_nHeight
;
590 m_nDepth
= Layput
.m_nDepth
;
591 m_nArraySize
= Layput
.m_nArraySize
;
592 m_nMips
= Layput
.m_nMips
;
593 m_eSrcFormat
= Layput
.m_eSrcFormat
;
594 m_eDstFormat
= Layput
.m_eDstFormat
;
595 m_pPixelFormat
= Layput
.m_pPixelFormat
;
596 m_eTT
= Layput
.m_eTT
;
597 m_eFlags
= Layput
.m_eFlags
; /* TODO: change FT_... to CDeviceObjectFactory::... */
598 m_bIsSRGB
= Layput
.m_bIsSRGB
;
600 m_nDevTextureSize
= m_nPersistentSize
= m_pDevTexture
->GetDeviceSize();
601 CryInterlockedAdd(&CTexture::s_nStatsCurManagedNonStreamedTexMem
, m_nDevTextureSize
);
604 InvalidateDeviceResource(eDeviceResourceDirty
);
607 void CTexture::PostCreate()
609 m_nUpdateFrameID
= gRenDev
->GetFrameID(false);
610 m_bPostponed
= false;
613 void CTexture::GetMemoryUsage(ICrySizer
* pSizer
) const
616 pSizer
->AddObject(m_SrcName
);
618 #ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT
619 const LowResSystemCopyType::iterator
& it
= s_LowResSystemCopy
.find(this);
620 if (it
!= CTexture::s_LowResSystemCopy
.end())
621 pSizer
->AddObject((*it
).second
.m_lowResSystemCopy
);
625 m_pFileTexMips
->GetMemoryUsage(pSizer
, m_nMips
, m_CacheFileHeader
.m_nSides
);
628 //=======================================================
629 // Low-level functions calling CreateDeviceTexture()
631 bool CTexture::CreateRenderTarget(ETEX_Format eFormat
, const ColorF
& cClear
)
633 if (m_eSrcFormat
== eTF_Unknown
)
634 m_eSrcFormat
= eFormat
;
635 if (m_eSrcFormat
== eTF_Unknown
)
637 const void** pData
= nullptr;
639 SetClosestFormatSupported();
640 m_eFlags
|= FT_USAGE_RENDERTARGET
;
641 m_cClearColor
= cClear
;
642 m_nMips
= m_eFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(m_nWidth
, m_nHeight
) : m_nMips
;
643 bool bRes
= CreateDeviceTexture(pData
);
649 bool CTexture::CreateDepthStencil(ETEX_Format eFormat
, const ColorF
& cClear
)
651 if (m_eSrcFormat
== eTF_Unknown
)
652 m_eSrcFormat
= eFormat
;
653 if (m_eSrcFormat
== eTF_Unknown
)
655 const void** pData
= nullptr;
657 SetClosestFormatSupported();
658 m_eFlags
|= FT_USAGE_DEPTHSTENCIL
;
659 m_cClearColor
= cClear
;
660 m_nMips
= m_eFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(m_nWidth
, m_nHeight
) : m_nMips
;
661 bool bRes
= CreateDeviceTexture(pData
);
667 bool CTexture::CreateShaderResource(STexData
& td
)
669 m_nWidth
= td
.m_nWidth
;
670 m_nHeight
= td
.m_nHeight
;
671 m_nDepth
= td
.m_nDepth
;
672 m_eSrcFormat
= td
.m_eFormat
;
673 m_nMips
= td
.m_nMips
;
674 m_fAvgBrightness
= td
.m_fAvgBrightness
;
675 m_cMinColor
= td
.m_cMinColor
;
676 m_cMaxColor
= td
.m_cMaxColor
;
677 m_cClearColor
= ColorF(0.0f
, 0.0f
, 0.0f
, 1.0f
);
678 m_bUseDecalBorderCol
= (td
.m_nFlags
& FIM_DECAL
) != 0;
679 m_bIsSRGB
= (td
.m_nFlags
& FIM_SRGB_READ
) != 0;
681 assert((m_nDepth
== 1) || (m_eTT
== eTT_3D
));
682 assert((m_nArraySize
== 1) || (m_eTT
== eTT_Cube
|| m_eTT
== eTT_CubeArray
|| m_eTT
== eTT_2DArray
));
683 assert((m_nArraySize
% 6) || (m_eTT
== eTT_Cube
|| m_eTT
== eTT_CubeArray
));
684 assert(!td
.m_pData
[1] || !(m_eFlags
& FT_REPLICATE_TO_ALL_SIDES
) || (m_eTT
== eTT_Cube
|| m_eTT
== eTT_CubeArray
));
685 assert(m_nWidth
&& m_nHeight
&& m_nMips
);
687 SetClosestFormatSupported();
688 if (!ImagePreprocessing(td
))
691 assert(m_nWidth
&& m_nHeight
&& m_nMips
);
693 const int nMaxTextureSize
= gRenDev
->GetMaxTextureSize();
694 if (nMaxTextureSize
> 0)
696 if (m_nWidth
> nMaxTextureSize
|| m_nHeight
> nMaxTextureSize
)
700 // Semi-consecutive data: {{slice,0},{slice,0},{0,0}}
701 const void* pData
[6 * 2 + 2];
702 pData
[6 * 2 + 0] = nullptr;
703 pData
[6 * 2 + 1] = nullptr;
704 for (uint32 i
= 0; i
< 6; i
++)
705 pData
[i
* 2 + 0] = td
.m_pData
[i
],
706 pData
[i
* 2 + 1] = nullptr;
708 bool bRes
= CreateDeviceTexture(pData
);
713 //=======================================================
714 // Mid-level functions calling Create...()
716 bool CTexture::Create2DTexture(int nWidth
, int nHeight
, int nMips
, int nFlags
, byte
* pSrcData
, ETEX_Format eSrcFormat
)
719 nMips
= CTexture::CalcNumMips(nWidth
, nHeight
);
720 m_eSrcTileMode
= pSrcData
? eTM_None
: eTM_Unspecified
;
721 m_eSrcFormat
= eSrcFormat
;
725 td
.m_eFormat
= eSrcFormat
;
726 td
.m_nWidth
= nWidth
;
727 td
.m_nHeight
= nHeight
;
730 td
.m_pData
[0] = pSrcData
;
732 bool bRes
= CreateShaderResource(td
);
734 m_eFlags
|= FT_FAILED
;
741 bool CTexture::Create3DTexture(int nWidth
, int nHeight
, int nDepth
, int nMips
, int nFlags
, byte
* pSrcData
, ETEX_Format eSrcFormat
)
744 // nMips = CTexture::CalcNumMips(nWidth, nHeight);
745 m_eSrcTileMode
= pSrcData
? eTM_None
: eTM_Unspecified
;
746 m_eSrcFormat
= eSrcFormat
;
750 td
.m_eFormat
= eSrcFormat
;
751 td
.m_nWidth
= nWidth
;
752 td
.m_nHeight
= nHeight
;
753 td
.m_nDepth
= nDepth
;
755 td
.m_pData
[0] = pSrcData
;
757 bool bRes
= CreateShaderResource(td
);
759 m_eFlags
|= FT_FAILED
;
766 //=======================================================
767 // High-level functions calling Create...()
769 CTexture
* CTexture::GetOrCreateTextureObject(const char* name
, uint32 nWidth
, uint32 nHeight
, int nDepth
, ETEX_Type eTT
, uint32 nFlags
, ETEX_Format eFormat
, int nCustomID
)
771 SYNCHRONOUS_LOADING_TICK();
775 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Texture
, 0, "%s", name
);
777 CTexture
* pTex
= FindOrRegisterTextureObject(name
, nFlags
, eFormat
, bFound
);
780 if (pTex
->m_nWidth
== 0)
781 pTex
->SetWidth(nWidth
);
782 if (pTex
->m_nHeight
== 0)
783 pTex
->SetHeight(nHeight
);
785 pTex
->m_nMips
= nFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(pTex
->m_nWidth
, pTex
->m_nHeight
) : pTex
->m_nMips
;
786 pTex
->m_eFlags
|= nFlags
& (FT_DONT_RELEASE
| FT_USAGE_RENDERTARGET
| FT_USAGE_DEPTHSTENCIL
);
791 pTex
->m_nDepth
= nDepth
;
792 pTex
->SetWidth(nWidth
);
793 pTex
->SetHeight(nHeight
);
794 pTex
->m_nMips
= nFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(pTex
->m_nWidth
, pTex
->m_nHeight
) : pTex
->m_nMips
;
796 pTex
->m_eSrcFormat
= eFormat
;
797 pTex
->m_nCustomID
= nCustomID
;
798 pTex
->m_SrcName
= name
;
799 pTex
->SetClosestFormatSupported();
804 _smart_ptr
<CTexture
> CTexture::GetOrCreateTextureObjectPtr(const char* name
, uint32 nWidth
, uint32 nHeight
, int nDepth
, ETEX_Type eTT
, uint32 nFlags
, ETEX_Format eFormat
, int nCustomID
)
806 CTexture
* pTex
= GetOrCreateTextureObject(name
, nWidth
, nHeight
, nDepth
, eTT
, nFlags
, eFormat
, nCustomID
);
807 _smart_ptr
<CTexture
> result
;
808 result
.Assign_NoAddRef(pTex
);
813 CTexture
* CTexture::GetOrCreateTextureArray(const char* name
, uint32 nWidth
, uint32 nHeight
, uint32 nArraySize
, int nMips
, ETEX_Type eType
, uint32 nFlags
, ETEX_Format eFormat
, int nCustomID
)
815 assert(eType
== eTT_2DArray
|| eType
== eTT_CubeArray
);
817 if (nArraySize
> 2048 /*D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION*/)
824 nMips
= CTexture::CalcNumMips(nWidth
, nHeight
);
826 bool sRGB
= (nFlags
& FT_USAGE_ALLOWREADSRGB
) != 0;
827 nFlags
&= ~FT_USAGE_ALLOWREADSRGB
;
829 CTexture
* pTex
= GetOrCreateTextureObject(name
, nWidth
, nHeight
, 1, eType
, nFlags
, eFormat
, nCustomID
);
830 pTex
->SetWidth(nWidth
);
831 pTex
->SetHeight(nHeight
);
832 pTex
->m_nMips
= nFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(pTex
->m_nWidth
, pTex
->m_nHeight
) : pTex
->m_nMips
;
833 pTex
->m_nArraySize
= nArraySize
; assert((eType
!= eTT_CubeArray
) || !(nArraySize
% 6));
837 if (nFlags
& FT_USAGE_RENDERTARGET
)
839 bRes
= pTex
->CreateRenderTarget(eFormat
, Clr_Unknown
);
841 else if (nFlags
& FT_USAGE_DEPTHSTENCIL
)
843 bRes
= pTex
->CreateDepthStencil(eFormat
, Clr_Unknown
);
849 td
.m_eFormat
= eFormat
;
851 td
.m_nWidth
= nWidth
;
852 td
.m_nHeight
= nHeight
;
854 td
.m_nFlags
= sRGB
? FIM_SRGB_READ
: 0;
856 bRes
= pTex
->CreateShaderResource(td
);
860 pTex
->m_eFlags
|= FT_FAILED
;
866 CTexture
* CTexture::GetOrCreateRenderTarget(const char* name
, uint32 nWidth
, uint32 nHeight
, const ColorF
& cClear
, ETEX_Type eTT
, uint32 nFlags
, ETEX_Format eFormat
, int nCustomID
)
868 CTexture
* pTex
= GetOrCreateTextureObject(name
, nWidth
, nHeight
, 1, eTT
, nFlags
| FT_USAGE_RENDERTARGET
, eFormat
, nCustomID
);
869 pTex
->SetWidth(nWidth
);
870 pTex
->SetHeight(nHeight
);
871 pTex
->m_nMips
= nFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(pTex
->m_nWidth
, pTex
->m_nHeight
) : pTex
->m_nMips
;
872 pTex
->m_eFlags
|= nFlags
;
874 bool bRes
= pTex
->CreateRenderTarget(eFormat
, cClear
);
876 pTex
->m_eFlags
|= FT_FAILED
;
882 CTexture
* CTexture::GetOrCreateDepthStencil(const char* name
, uint32 nWidth
, uint32 nHeight
, const ColorF
& cClear
, ETEX_Type eTT
, uint32 nFlags
, ETEX_Format eFormat
, int nCustomID
)
884 CTexture
* pTex
= GetOrCreateTextureObject(name
, nWidth
, nHeight
, 1, eTT
, nFlags
| FT_USAGE_DEPTHSTENCIL
, eFormat
, nCustomID
);
885 pTex
->SetWidth(nWidth
);
886 pTex
->SetHeight(nHeight
);
887 pTex
->m_nMips
= nFlags
& FT_FORCE_MIPS
? CTexture::CalcNumMips(pTex
->m_nWidth
, pTex
->m_nHeight
) : pTex
->m_nMips
;
888 pTex
->m_eFlags
|= nFlags
;
890 bool bRes
= pTex
->CreateDepthStencil(eFormat
, cClear
);
892 pTex
->m_eFlags
|= FT_FAILED
;
898 CTexture
* CTexture::GetOrCreate2DTexture(const char* szName
, int nWidth
, int nHeight
, int nMips
, int nFlags
, byte
* pSrcData
, ETEX_Format eSrcFormat
, bool bAsyncDevTexCreation
)
900 FUNCTION_PROFILER(GetISystem(), PROFILE_RENDERER
);
902 CTexture
* pTex
= GetOrCreateTextureObject(szName
, nWidth
, nHeight
, 1, eTT_2D
, nFlags
, eSrcFormat
, -1);
903 pTex
->m_bAsyncDevTexCreation
= bAsyncDevTexCreation
;
906 pTex
->Create2DTexture(nWidth
, nHeight
, nMips
, nFlags
, pSrcData
, eSrcFormat
);
911 CTexture
* CTexture::GetOrCreate3DTexture(const char* szName
, int nWidth
, int nHeight
, int nDepth
, int nMips
, int nFlags
, byte
* pSrcData
, ETEX_Format eSrcFormat
)
913 CTexture
* pTex
= GetOrCreateTextureObject(szName
, nWidth
, nHeight
, nDepth
, eTT_3D
, nFlags
, eSrcFormat
, -1);
916 pTex
->Create3DTexture(nWidth
, nHeight
, nDepth
, nMips
, nFlags
, pSrcData
, eSrcFormat
);
921 CTexture
* CTexture::GetOrCreate2DCompositeTexture(const char* szName
, int nWidth
, int nHeight
, int nMips
, int nFlags
, ETEX_Format eFormat
, const STexComposition
* pCompositions
, size_t nCompositions
)
923 nFlags
|= FT_COMPOSITE
;
924 nFlags
&= ~FT_DONT_STREAM
;
927 nMips
= CTexture::CalcNumMips(nWidth
, nHeight
);
930 CTexture
* pTex
= FindOrRegisterTextureObject(szName
, nFlags
, eFormat
, bFound
);
933 pTex
->SetWidth(nWidth
);
934 pTex
->SetHeight(nHeight
);
935 pTex
->m_nMips
= nMips
;
936 pTex
->m_composition
.assign(pCompositions
, pCompositions
+ nCompositions
);
938 // Strip all invalid textures from the composition
941 for (int r
= 0, c
= pTex
->m_composition
.size(); r
!= c
; ++r
)
943 if (!pTex
->m_composition
[r
].pTexture
)
945 CryWarning(VALIDATOR_MODULE_RENDERER
, VALIDATOR_WARNING
, "Composition %i for '%s' is missing", r
, szName
);
950 pTex
->m_composition
[w
] = pTex
->m_composition
[r
];
953 pTex
->m_composition
.resize(w
);
955 if (CTexture::s_bPrecachePhase
)
957 pTex
->m_bPostponed
= true;
958 pTex
->m_bWasUnloaded
= true;
962 pTex
->StreamPrepareComposition();
969 //=======================================================
971 bool CTexture::Reload()
975 // If the texture is flagged to not be released, we skip the reloading
976 if (m_eFlags
& FT_DONT_RELEASE
)
981 ReleaseDeviceTexture(false);
982 return ToggleStreaming(true);
985 if (m_eFlags
& FT_FROMIMAGE
)
987 assert(!(m_eFlags
& (FT_USAGE_RENDERTARGET
| FT_USAGE_DEPTHSTENCIL
| FT_USAGE_DYNAMIC
)));
988 bOK
= LoadFromImage(m_SrcName
.c_str()); // true=reloading
990 SetNoTexture(m_eTT
== eTT_Cube
? s_ptexNoTextureCM
: s_ptexNoTexture
);
992 else if (m_eFlags
& (FT_USAGE_RENDERTARGET
| FT_USAGE_DEPTHSTENCIL
| FT_USAGE_DYNAMIC
))
994 const void** pData
= nullptr;
995 bOK
= CreateDeviceTexture(pData
);
1004 CTexture
* CTexture::ForName(const char* name
, uint32 nFlags
, ETEX_Format eFormat
)
1008 bool bFound
= false;
1010 MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other
, 0, "Textures");
1011 MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Texture
, 0, "%s", name
);
1013 CRY_DEFINE_ASSET_SCOPE("Texture", name
);
1015 CTexture
* pTex
= FindOrRegisterTextureObject(name
, nFlags
, eFormat
, bFound
);
1016 if (bFound
|| name
[0] == '$')
1020 pTex
->m_SrcName
= name
;
1024 // switch off streaming for the same texture with the same flags except DONT_STREAM
1025 if ((nFlags
& FT_DONT_STREAM
) != 0 && (pTex
->GetFlags() & FT_DONT_STREAM
) == 0)
1027 if (!pTex
->m_bPostponed
)
1028 pTex
->ReleaseDeviceTexture(false);
1029 pTex
->m_eFlags
|= FT_DONT_STREAM
;
1030 if (!pTex
->m_bPostponed
)
1037 pTex
->m_SrcName
= name
;
1040 pTex
->m_sAssetScopeName
= gEnv
->pLog
->GetAssetScopeString();
1043 if (CTexture::s_bPrecachePhase
|| (pTex
->m_eFlags
& FT_ASYNC_PREPARE
))
1045 // NOTE: attached alpha isn't detectable by flags before the header is loaded, so we do it by file-suffix
1046 if (/*(nFlags & FT_TEX_NORMAL_MAP) &&*/ TextureHelpers::VerifyTexSuffix(EFTT_NORMALS
, name
) && TextureHelpers::VerifyTexSuffix(EFTT_SMOOTHNESS
, name
))
1047 nFlags
|= FT_HAS_ATTACHED_ALPHA
;
1049 pTex
->m_eDstFormat
= eFormat
;
1050 pTex
->m_eFlags
= nFlags
;
1051 pTex
->m_bPostponed
= true;
1052 pTex
->m_bWasUnloaded
= true;
1055 if (!CTexture::s_bPrecachePhase
)
1056 pTex
->Load(eFormat
);
1061 _smart_ptr
<CTexture
> CTexture::ForNamePtr(const char* name
, uint32 nFlags
, ETEX_Format eFormat
)
1063 CTexture
* pTex
= ForName(name
, nFlags
, eFormat
);
1064 _smart_ptr
<CTexture
> result
;
1065 result
.Assign_NoAddRef(pTex
);
1071 struct CompareTextures
1073 bool operator()(const CTexture
* a
, const CTexture
* b
)
1075 return (stricmp(a
->GetSourceName(), b
->GetSourceName()) < 0);
1079 void CTexture::Precache()
1081 LOADING_TIME_PROFILE_SECTION(iSystem
);
1083 if (!s_bPrecachePhase
)
1088 gEnv
->pLog
->UpdateLoadingScreen("Requesting textures precache ...");
1090 gRenDev
->m_pRT
->RC_PreloadTextures();
1092 gEnv
->pLog
->UpdateLoadingScreen("Textures precache done.");
1095 void CTexture::RT_Precache()
1097 if (gRenDev
->CheckDeviceLost())
1100 LOADING_TIME_PROFILE_SECTION(iSystem
);
1102 // Disable invalid file access logging if texture streaming is disabled
1103 // If texture streaming is turned off, we will hit this on the renderthread
1104 // and stall due to the invalid file access stalls
1105 ICVar
* sysPakLogInvalidAccess
= NULL
;
1106 int pakLogFileAccess
= 0;
1107 if (!CRenderer::CV_r_texturesstreaming
)
1109 if (sysPakLogInvalidAccess
= gEnv
->pConsole
->GetCVar("sys_PakLogInvalidFileAccess"))
1111 pakLogFileAccess
= sysPakLogInvalidAccess
->GetIVal();
1115 CTimeValue t0
= gEnv
->pTimer
->GetAsyncTime();
1116 CryLog("-- Precaching textures...");
1117 iLog
->UpdateLoadingScreen(0);
1119 std::vector
<CTexture
*> TexturesForPrecaching
;
1120 std::vector
<CTexture
*> TexturesForComposition
;
1122 bool bTextureCacheExists
= false;
1125 AUTO_LOCK(CBaseResource::s_cResLock
);
1127 SResourceContainer
* pRL
= CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
1130 TexturesForPrecaching
.reserve(pRL
->m_RMap
.size());
1132 ResourcesMapItor itor
;
1133 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
1135 CTexture
* tp
= (CTexture
*)itor
->second
;
1138 if (tp
->CTexture::IsPostponed())
1140 if (tp
->CTexture::GetFlags() & FT_COMPOSITE
)
1141 TexturesForComposition
.push_back(tp
);
1143 TexturesForPrecaching
.push_back(tp
);
1149 // Preload all the post poned textures
1151 if (!gEnv
->IsEditor())
1152 CryLog("=============================== Loading textures ================================");
1154 std::vector
<CTexture
*>& Textures
= TexturesForPrecaching
;
1155 std::sort(Textures
.begin(), Textures
.end(), CompareTextures());
1157 gEnv
->pSystem
->GetStreamEngine()->PauseStreaming(false, 1 << eStreamTaskTypeTexture
);
1159 int numTextures
= Textures
.size();
1160 int prevProgress
= 0;
1162 for (uint32 i
= 0; i
< Textures
.size(); i
++)
1164 CTexture
* tp
= Textures
[i
];
1166 if (!CRenderer::CV_r_texturesstreaming
|| !tp
->m_bStreamPrepared
)
1168 tp
->m_bPostponed
= false;
1169 tp
->Load(tp
->m_eDstFormat
);
1171 int progress
= (i
* 10) / numTextures
;
1172 if (progress
!= prevProgress
)
1174 prevProgress
= progress
;
1175 gEnv
->pLog
->UpdateLoadingScreen("Precaching progress: %d", progress
);
1179 while (s_StreamPrepTasks
.GetNumLive())
1181 if (gRenDev
->m_pRT
->IsRenderThread() && !gRenDev
->m_pRT
->IsRenderLoadingThread())
1183 StreamState_Update();
1184 StreamState_UpdatePrep();
1186 else if (gRenDev
->m_pRT
->IsRenderLoadingThread())
1188 StreamState_UpdatePrep();
1194 for (uint32 i
= 0; i
< Textures
.size(); i
++)
1196 CTexture
* tp
= Textures
[i
];
1198 if (tp
->m_bStreamed
&& tp
->m_bForceStreamHighRes
)
1200 tp
->m_bStreamHighPriority
|= 1;
1201 tp
->m_fpMinMipCur
= 0;
1202 s_pTextureStreamer
->Precache(tp
);
1206 if (!gEnv
->IsEditor())
1207 CryLog("========================== Finished loading textures ============================");
1211 std::vector
<CTexture
*>& Textures
= TexturesForComposition
;
1213 for (uint32 i
= 0; i
< Textures
.size(); i
++)
1215 CTexture
* tp
= Textures
[i
];
1217 if (!CRenderer::CV_r_texturesstreaming
|| !tp
->m_bStreamPrepared
)
1219 tp
->m_bPostponed
= false;
1220 tp
->StreamPrepareComposition();
1224 for (uint32 i
= 0; i
< Textures
.size(); i
++)
1226 CTexture
* tp
= Textures
[i
];
1228 if (tp
->m_bStreamed
&& tp
->m_bForceStreamHighRes
)
1230 tp
->m_bStreamHighPriority
|= 1;
1231 tp
->m_fpMinMipCur
= 0;
1232 s_pTextureStreamer
->Precache(tp
);
1237 if (bTextureCacheExists
)
1239 //GetISystem()->GetIResourceManager()->UnloadLevelCachePak( TEXTURE_LEVEL_CACHE_PAK );
1242 CTimeValue t1
= gEnv
->pTimer
->GetAsyncTime();
1243 float dt
= (t1
- t0
).GetSeconds();
1244 CryLog("Precaching textures done in %.2f seconds", dt
);
1246 s_bPrecachePhase
= false;
1248 // Restore pakLogFileAccess if it was disabled during precaching
1249 // because texture precaching was disabled
1250 if (pakLogFileAccess
)
1252 sysPakLogInvalidAccess
->Set(pakLogFileAccess
);
1256 bool CTexture::Load(ETEX_Format eFormat
)
1258 LOADING_TIME_PROFILE_SECTION_NAMED_ARGS("CTexture::Load(ETEX_Format eTFDst)", m_SrcName
);
1259 m_bWasUnloaded
= false;
1260 m_bStreamed
= false;
1262 bool bFound
= LoadFromImage(m_SrcName
.c_str(), eFormat
); // false=not reloading
1265 SetNoTexture(m_eTT
== eTT_Cube
? s_ptexNoTextureCM
: s_ptexNoTexture
);
1267 m_eFlags
|= FT_FROMIMAGE
;
1273 bool CTexture::ToggleStreaming(const bool bEnable
)
1275 if (!(m_eFlags
& (FT_FROMIMAGE
| FT_DONT_RELEASE
)) || (m_eFlags
& FT_DONT_STREAM
))
1277 AbortStreamingTasks(this);
1282 ReleaseDeviceTexture(false);
1284 if (StreamPrepare(true))
1289 StreamState_ReleaseInfo(this, m_pFileTexMips
);
1290 m_pFileTexMips
= NULL
;
1292 m_bStreamed
= false;
1296 ReleaseDeviceTexture(false);
1300 bool CTexture::LoadFromImage(const char* name
, ETEX_Format eFormat
)
1302 LOADING_TIME_PROFILE_SECTION_ARGS(name
);
1304 if (CRenderer::CV_r_texnoload
)
1310 string
sFileName(name
);
1311 sFileName
.MakeLower();
1313 m_eDstFormat
= eFormat
;
1315 // try to stream-in the texture
1316 if (CRenderer::CV_r_texturesstreaming
&& !(m_eFlags
& FT_DONT_STREAM
) && (m_eTT
== eTT_2D
|| m_eTT
== eTT_Cube
))
1319 if (StreamPrepare(true))
1321 assert(m_pDevTexture
);
1324 m_eFlags
|= FT_DONT_STREAM
;
1325 m_bStreamed
= false;
1326 m_bForceStreamHighRes
= false;
1332 StreamState_ReleaseInfo(this, m_pFileTexMips
);
1333 m_pFileTexMips
= NULL
;
1334 m_bStreamed
= false;
1341 CRY_DEFINE_ASSET_SCOPE("Texture", m_sAssetScopeName
);
1346 if (s_pTextureStreamer
->BeginPrepare(this, sFileName
, (m_eFlags
& FT_ALPHA
) ? FIM_ALPHA
: 0))
1350 uint32 nImageFlags
=
1351 ((m_eFlags
& FT_ALPHA
) ? FIM_ALPHA
: 0) |
1352 ((m_eFlags
& FT_STREAMED_PREPARE
) ? FIM_READ_VIA_STREAMS
: 0);
1354 _smart_ptr
<CImageFile
> pImage
= CImageFile::mfLoad_file(sFileName
, nImageFlags
);
1355 return Load(pImage
);
1358 bool CTexture::Load(CImageFile
* pImage
)
1360 if (!pImage
|| pImage
->mfGetFormat() == eTF_Unknown
)
1363 LOADING_TIME_PROFILE_SECTION_NAMED_ARGS("CTexture::Load(CImageFile* pImage)", pImage
->mfGet_filename().c_str());
1365 if ((m_eFlags
& FT_ALPHA
) && !pImage
->mfIs_image(0))
1367 SetNoTexture(s_ptexWhite
);
1370 const char* name
= pImage
->mfGet_filename().c_str();
1371 if (pImage
->mfGet_Flags() & FIM_SPLITTED
) // propagate splitted file flag
1372 m_eFlags
|= FT_SPLITTED
;
1373 if (pImage
->mfGet_Flags() & FIM_X360_NOT_PRETILED
)
1374 m_eFlags
|= FT_TEX_WAS_NOT_PRE_TILED
;
1375 if (pImage
->mfGet_Flags() & FIM_FILESINGLE
) // propagate flag from image to texture
1376 m_eFlags
|= FT_FILESINGLE
;
1377 if (pImage
->mfGet_Flags() & FIM_NORMALMAP
)
1379 if (!(m_eFlags
& FT_TEX_NORMAL_MAP
) && !CryStringUtils::stristr(name
, "_ddn"))
1381 // becomes reported as editor error
1382 gEnv
->pSystem
->Warning(VALIDATOR_MODULE_RENDERER
, VALIDATOR_WARNING
, VALIDATOR_FLAG_FILE
| VALIDATOR_FLAG_TEXTURE
,
1383 name
, "Not a normal map texture attempted to be used as a normal map: %s", name
);
1387 if (!(m_eFlags
& FT_ALPHA
) && !(
1388 pImage
->mfGetFormat() == eTF_BC5U
|| pImage
->mfGetFormat() == eTF_BC5S
|| pImage
->mfGetFormat() == eTF_BC7
||
1389 pImage
->mfGetFormat() == eTF_EAC_RG11
|| pImage
->mfGetFormat() == eTF_EAC_RG11S
1390 ) && CryStringUtils::stristr(name
, "_ddn") != 0 && GetDevTexture()) // improvable code
1392 // becomes reported as editor error
1393 gEnv
->pSystem
->Warning(VALIDATOR_MODULE_RENDERER
, VALIDATOR_WARNING
, VALIDATOR_FLAG_FILE
| VALIDATOR_FLAG_TEXTURE
,
1394 name
, "Wrong format '%s' for normal map texture '%s'", CTexture::GetFormatName(), name
);
1397 if (pImage
->mfGet_Flags() & FIM_NOTSUPPORTS_MIPS
&& !(m_eFlags
& FT_NOMIPS
))
1398 m_eFlags
|= FT_FORCE_MIPS
;
1399 if (pImage
->mfGet_Flags() & FIM_HAS_ATTACHED_ALPHA
)
1400 m_eFlags
|= FT_HAS_ATTACHED_ALPHA
; // if the image has alpha attached we store this in the CTexture
1402 m_eSrcTileMode
= pImage
->mfGetTileMode();
1403 m_nArraySize
= pImage
->mfGet_NumSides();
1405 (pImage
->mfGet_depth () > 1) ? eTT_3D
:
1406 (pImage
->mfGet_NumSides() == 6) ? eTT_Cube
:
1407 !(pImage
->mfGet_NumSides() % 6) ? eTT_CubeArray
:
1408 (pImage
->mfGet_NumSides() == 1) ? eTT_2D
:
1412 td
.m_nFlags
= pImage
->mfGet_Flags();
1413 td
.m_pData
[0] = pImage
->mfGet_image(0);
1414 td
.m_nWidth
= pImage
->mfGet_width();
1415 td
.m_nHeight
= pImage
->mfGet_height();
1416 td
.m_nDepth
= pImage
->mfGet_depth();
1417 td
.m_eFormat
= pImage
->mfGetFormat();
1418 td
.m_nMips
= pImage
->mfGet_numMips();
1419 td
.m_fAvgBrightness
= pImage
->mfGet_avgBrightness();
1420 td
.m_cMinColor
= pImage
->mfGet_minColor();
1421 td
.m_cMaxColor
= pImage
->mfGet_maxColor();
1422 if ((m_eFlags
& FT_NOMIPS
) || td
.m_nMips
<= 0)
1424 td
.m_pFilePath
= pImage
->mfGet_filename();
1426 // base range after normalization, fe. [0,1] for 8bit images, or [0,2^15] for RGBE/HDR data
1427 if (CImageExtensionHelper::IsDynamicRange(td
.m_eFormat
))
1429 td
.m_cMinColor
/= td
.m_cMaxColor
.a
;
1430 td
.m_cMaxColor
/= td
.m_cMaxColor
.a
;
1433 // check if it's a cubemap
1434 if (pImage
->mfIs_image(1))
1436 for (int i
= 1; i
< 6; i
++)
1438 td
.m_pData
[i
] = pImage
->mfGet_image(i
);
1446 bRes
= CreateShaderResource(td
);
1449 for (int i
= 0; i
< 6; i
++)
1450 if (td
.m_pData
[i
] && td
.WasReallocated(i
))
1451 SAFE_DELETE_ARRAY(td
.m_pData
[i
]);
1456 void CTexture::UpdateData(STexData
&td
, int flags
)
1459 m_eDstFormat
= td
.m_eFormat
;
1460 CreateShaderResource(td
);
1463 ETEX_Format
CTexture::FormatFixup(ETEX_Format eFormat
)
1469 return eTF_R8G8B8A8S
;
1473 return eTF_R8G8B8A8
;
1475 // only available as hardware format under DX11.1 with DXGI 1.2
1480 //! Only available as hardware format under Vulkan or XBO.
1484 const SPixFormat
* pPF
;
1485 return GetClosestFormatSupported(eFormat
, pPF
);
1493 bool CTexture::FormatFixup(STexData
& td
)
1495 const ETEX_Format eSrcFormat
= td
.m_eFormat
;
1496 const ETEX_Format eDstFormat
= FormatFixup(td
.m_eFormat
);
1497 CRY_ASSERT(eDstFormat
!= eTF_Unknown
);
1499 if (m_eSrcTileMode
== eTM_None
)
1502 int nSourceSize
= CTexture::TextureDataSize(td
.m_nWidth
, td
.m_nHeight
, td
.m_nDepth
, td
.m_nMips
, 1, eSrcFormat
);
1503 int nTargetSize
= CTexture::TextureDataSize(td
.m_nWidth
, td
.m_nHeight
, td
.m_nDepth
, td
.m_nMips
, 1, eDstFormat
);
1505 for (int nImage
= 0; nImage
< sizeof(td
.m_pData
) / sizeof(td
.m_pData
[0]); ++nImage
)
1507 if (td
.m_pData
[nImage
])
1509 byte
* pNewImage
= new byte
[nTargetSize
];
1510 CTexture::ExpandMipFromFile(pNewImage
, nTargetSize
, td
.m_pData
[nImage
], nSourceSize
, eSrcFormat
, eDstFormat
);
1511 td
.AssignData(nImage
, pNewImage
);
1515 td
.m_eFormat
= eDstFormat
;
1520 if (eDstFormat
!= eSrcFormat
)
1528 bool CTexture::ImagePreprocessing(STexData
& td
)
1530 FUNCTION_PROFILER(GetISystem(), PROFILE_RENDERER
);
1532 const char* pTexFileName
= td
.m_pFilePath
? td
.m_pFilePath
: "$Unknown";
1534 if (m_eDstFormat
== eTF_Unknown
)
1536 td
.m_pData
[0] = td
.m_pData
[1] = td
.m_pData
[2] = td
.m_pData
[3] = td
.m_pData
[4] = td
.m_pData
[5] = 0;
1537 m_nWidth
= m_nHeight
= m_nDepth
= m_nMips
= 0;
1539 #if !defined(_RELEASE)
1540 TextureError(pTexFileName
, "Trying to create a texture with unsupported target format %s!", NameForTextureFormat(m_eSrcFormat
));
1545 const ETEX_Format eSrcFormat
= td
.m_eFormat
;
1546 const bool fmtConversionNeeded
= eSrcFormat
!= m_eDstFormat
;
1548 #if !CRY_PLATFORM_WINDOWS || CRY_RENDERER_OPENGL
1549 if (fmtConversionNeeded
)
1551 td
.m_pData
[0] = td
.m_pData
[1] = td
.m_pData
[2] = td
.m_pData
[3] = td
.m_pData
[4] = td
.m_pData
[5] = 0;
1552 m_nWidth
= m_nHeight
= m_nDepth
= m_nMips
= 0;
1554 #if !defined(_RELEASE)
1555 TextureError(pTexFileName
, "Trying an image format conversion from %s to %s. This is not supported on this platform!", NameForTextureFormat(eSrcFormat
), NameForTextureFormat(m_eDstFormat
));
1561 const bool doProcessing
= fmtConversionNeeded
&& (m_eFlags
& FT_TEX_FONT
) == 0; // we generate the font in native format
1564 const int nSrcWidth
= td
.m_nWidth
;
1565 const int nSrcHeight
= td
.m_nHeight
;
1567 for (int i
= 0; i
< 6; i
++)
1569 byte
* pSrcData
= td
.m_pData
[i
];
1573 byte
* pNewData
= Convert(pSrcData
, nSrcWidth
, nSrcHeight
, td
.m_nMips
, eSrcFormat
, m_eDstFormat
, td
.m_nMips
, nOutSize
, true);
1575 td
.AssignData(i
, pNewData
);
1581 #if defined(TEXTURE_GET_SYSTEM_COPY_SUPPORT)
1582 if (m_eFlags
& FT_KEEP_LOWRES_SYSCOPY
)
1583 PrepareLowResSystemCopy(td
.m_pData
[0], true);
1589 int CTexture::CalcNumMips(int nWidth
, int nHeight
)
1592 while (nWidth
|| nHeight
)
1594 if (!nWidth
) nWidth
= 1;
1595 if (!nHeight
) nHeight
= 1;
1603 uint32
CTexture::TextureDataSize(uint32 nWidth
, uint32 nHeight
, uint32 nDepth
, uint32 nMips
, uint32 nSlices
, const ETEX_Format eTF
, ETEX_TileMode eTM
)
1605 FUNCTION_PROFILER_RENDERER
;
1607 // Don't allow 0 dimensions, it's clearly wrong to reflect on "unspecified-yet" textures.
1608 CRY_ASSERT(eTF
!= eTF_Unknown
&& nWidth
&& nHeight
&& nDepth
);
1609 // Allow 0 mips and 0 slices to generate offsets with this function.
1610 if (!nMips
|| !nSlices
)
1613 const bool bIsBlockCompressed
= IsBlockCompressed(eTF
);
1614 nWidth
= max(1U, nWidth
);
1615 nHeight
= max(1U, nHeight
);
1616 nDepth
= max(1U, nDepth
);
1618 if (eTM
!= eTM_None
)
1620 // NOTE: Using this function to acquire strides of elements or rows (and even slices in arrays),
1621 // is not yielding any usable information. In the moment the clients need to be aware that
1622 // the internal layout for tiled modes can't be interpreted and stay away from it.
1623 // TODO: Create separate interfaces for sub-resource size queries and for layout-stride queries
1625 #if CRY_PLATFORM_ORBIS
1626 if (bIsBlockCompressed
)
1628 nWidth
= ((nWidth
+ 3) & (-4));
1629 nHeight
= ((nHeight
+ 3) & (-4));
1633 #if CRY_PLATFORM_CONSOLE
1634 return CDeviceTexture::TextureDataSize(nWidth
, nHeight
, nDepth
, nMips
, nSlices
, eTF
, eTM
, CDeviceObjectFactory::BIND_SHADER_RESOURCE
);
1642 const uint32 nBytesPerElement
= bIsBlockCompressed
? BytesPerBlock(eTF
) : BytesPerPixel(eTF
);
1645 while ((nWidth
|| nHeight
|| nDepth
) && nMips
)
1647 nWidth
= max(1U, nWidth
);
1648 nHeight
= max(1U, nHeight
);
1649 nDepth
= max(1U, nDepth
);
1652 uint32 nV
= nHeight
;
1655 if (bIsBlockCompressed
)
1657 // depth is not 4x4x4 compressed, but 4x4x1
1658 nU
= ((nWidth
+ 3) / (4));
1659 nV
= ((nHeight
+ 3) / (4));
1662 nSize
+= nU
* nV
* nW
* nBytesPerElement
;
1671 return nSize
* nSlices
;
1675 bool CTexture::IsInPlaceFormat(const ETEX_Format fmt
)
1696 case eTF_R11G11B10F
:
1697 case eTF_R10G10B10A2
:
1698 case eTF_R16G16B16A16
:
1699 case eTF_R16G16B16A16S
:
1700 case eTF_R16G16B16A16F
:
1701 case eTF_R32G32B32A32F
:
1710 #if defined(CRY_DDS_DX10_SUPPORT)
1723 case eTF_ASTC_LDR_4x4
:
1733 void CTexture::ExpandMipFromFile(byte
* pSrcData
, const int dstSize
, const byte
* src
, const int srcSize
, const ETEX_Format eSrcFormat
, const ETEX_Format eDstFormat
)
1735 if (IsInPlaceFormat(eSrcFormat
))
1737 assert(dstSize
== srcSize
);
1738 if (pSrcData
!= src
)
1740 cryMemcpy(pSrcData
, src
, srcSize
);
1746 // upload mip from file with conversions depending on format and platform specifics
1749 case eTF_B8G8R8
: // -> eTF_R8G8B8A8
1750 assert(eDstFormat
== eTF_R8G8B8A8
);
1752 for (int i
= srcSize
/ 3 - 1; i
>= 0; --i
)
1754 pSrcData
[i
* 4 + 0] = src
[i
* 3 + 2];
1755 pSrcData
[i
* 4 + 1] = src
[i
* 3 + 1];
1756 pSrcData
[i
* 4 + 2] = src
[i
* 3 + 0];
1757 pSrcData
[i
* 4 + 3] = 255;
1761 case eTF_L8V8U8X8
: // -> eTF_R8G8B8A8S
1762 assert(eDstFormat
== eTF_R8G8B8A8S
);
1764 for (int i
= srcSize
/ 4 - 1; i
>= 0; --i
)
1766 pSrcData
[i
* 4 + 0] = src
[i
* 3 + 0];
1767 pSrcData
[i
* 4 + 1] = src
[i
* 3 + 1];
1768 pSrcData
[i
* 4 + 2] = src
[i
* 3 + 2];
1769 pSrcData
[i
* 4 + 3] = src
[i
* 3 + 3];
1773 case eTF_L8V8U8
: // -> eTF_R8G8B8A8S
1774 assert(eDstFormat
== eTF_R8G8B8A8S
);
1776 for (int i
= srcSize
/ 3 - 1; i
>= 0; --i
)
1778 pSrcData
[i
* 4 + 0] = src
[i
* 3 + 0];
1779 pSrcData
[i
* 4 + 1] = src
[i
* 3 + 1];
1780 pSrcData
[i
* 4 + 2] = src
[i
* 3 + 2];
1781 pSrcData
[i
* 4 + 3] = 255;
1785 case eTF_L8
: // -> eTF_R8G8B8A8
1786 assert(eDstFormat
== eTF_R8G8B8A8
);
1788 for (int i
= srcSize
- 1; i
>= 0; --i
)
1790 const byte bSrc
= src
[i
];
1791 pSrcData
[i
* 4 + 0] = bSrc
;
1792 pSrcData
[i
* 4 + 1] = bSrc
;
1793 pSrcData
[i
* 4 + 2] = bSrc
;
1794 pSrcData
[i
* 4 + 3] = 255;
1798 case eTF_A8L8
: // -> eTF_R8G8B8A8
1799 assert(eDstFormat
== eTF_R8G8B8A8
);
1801 for (int i
= srcSize
- 1; i
>= 0; i
-= 2)
1803 const byte bSrcL
= src
[i
- 1];
1804 const byte bSrcA
= src
[i
- 0];
1805 pSrcData
[i
* 4 + 0] = bSrcL
;
1806 pSrcData
[i
* 4 + 1] = bSrcL
;
1807 pSrcData
[i
* 4 + 2] = bSrcL
;
1808 pSrcData
[i
* 4 + 3] = bSrcA
;
1813 case eTF_B5G5R5A1
: // -> eTF_B8G8R8A8
1814 assert(eDstFormat
== eTF_B8G8R8A8
);
1816 for (int i
= srcSize
/ 2 - 1; i
>= 0; --i
)
1818 const uint16 rgb5551
= uint16((src
[i
* 2 + 0] << 8) + src
[i
* 2 + 1]);
1819 pSrcData
[i
* 4 + 0] = ((rgb5551
>> 0) * 33) >> 2;
1820 pSrcData
[i
* 4 + 1] = ((rgb5551
>> 5) * 33) >> 2;
1821 pSrcData
[i
* 4 + 2] = ((rgb5551
>> 10) * 33) >> 2;
1822 pSrcData
[i
* 4 + 3] = ((rgb5551
>> 15) ? 255 : 0);
1826 case eTF_B5G6R5
: // -> eTF_B8G8R8X8
1827 assert(eDstFormat
== eTF_B8G8R8X8
);
1829 for (int i
= srcSize
/ 2 - 1; i
>= 0; --i
)
1831 const uint16 rgb565
= uint16((src
[i
* 2 + 0] << 8) + src
[i
* 2 + 1]);
1832 pSrcData
[i
* 4 + 0] = ((rgb565
>> 0) * 33) >> 2;
1833 pSrcData
[i
* 4 + 1] = ((rgb565
>> 5) * 65) >> 4;
1834 pSrcData
[i
* 4 + 2] = ((rgb565
>> 11) * 33) >> 2;
1835 pSrcData
[i
* 4 + 3] = 255;
1839 case eTF_B4G4R4A4
: // -> eTF_B8G8R8A8
1840 case eTF_R4G4B4A4
: // -> eTF_R8G8B8A8
1841 assert((eSrcFormat
== eTF_B4G4R4A4
&& eDstFormat
== eTF_B8G8R8A8
) ||
1842 (eSrcFormat
== eTF_R4G4B4A4
&& eDstFormat
== eTF_R8G8B8A8
));
1844 for (int i
= srcSize
/ 2 - 1; i
>= 0; --i
)
1846 const uint16 rgb4444
= uint16((src
[i
* 2 + 0] << 8) + src
[i
* 2 + 1]);
1847 pSrcData
[i
* 4 + 0] = (rgb4444
>> 0) * 17;
1848 pSrcData
[i
* 4 + 1] = (rgb4444
>> 4) * 17;
1849 pSrcData
[i
* 4 + 2] = (rgb4444
>> 8) * 17;
1850 pSrcData
[i
* 4 + 3] = (rgb4444
>> 12) * 17;
1854 case eTF_R4G4
: // -> eTF_R8G8|eTF_R8G8B8A8
1855 assert(eDstFormat
== eTF_R8G8
|| eDstFormat
== eTF_R8G8B8A8
);
1856 if (eDstFormat
== eTF_R8G8
)
1858 for (int i
= srcSize
/ 1 - 1; i
>= 0; --i
)
1860 const uint8 rgb44
= uint8(src
[i
* 1 + 0]);
1861 pSrcData
[i
* 2 + 0] = (rgb44
>> 0) * 17;
1862 pSrcData
[i
* 2 + 1] = (rgb44
>> 4) * 17;
1867 for (int i
= srcSize
/ 1 - 1; i
>= 0; --i
)
1869 const uint8 rgb44
= uint8(src
[i
* 1 + 0]);
1870 pSrcData
[i
* 4 + 0] = (rgb44
>> 0) * 17;
1871 pSrcData
[i
* 4 + 1] = (rgb44
>> 4) * 17;
1872 pSrcData
[i
* 4 + 2] = 0;
1873 pSrcData
[i
* 4 + 3] = 255;
1883 bool CTexture::Invalidate(int nNewWidth
, int nNewHeight
, ETEX_Format eNewFormat
)
1885 bool bRelease
= false;
1886 if (nNewWidth
> 0 && nNewWidth
!= m_nWidth
)
1888 m_nWidth
= nNewWidth
;
1891 if (nNewHeight
> 0 && nNewHeight
!= m_nHeight
)
1893 m_nHeight
= nNewHeight
;
1896 if (eNewFormat
!= eTF_Unknown
&& eNewFormat
!= m_eSrcFormat
)
1898 m_eSrcFormat
= eNewFormat
;
1899 SetClosestFormatSupported();
1909 if (m_eFlags
& FT_FORCE_MIPS
)
1912 ReleaseDeviceTexture(true);
1918 D3DBaseView
* CTexture::GetResourceView(const SResourceView
& rvDesc
)
1920 if (CDeviceTexture
* pDevTex
= GetDevTexture(rvDesc
.m_Desc
.bMultisample
))
1922 ResourceViewHandle hView
= pDevTex
->GetOrCreateResourceViewHandle(rvDesc
);
1923 return pDevTex
->LookupResourceView(hView
).second
;
1929 D3DBaseView
* CTexture::GetResourceView(const SResourceView
& rvDesc
) const
1931 if (CDeviceTexture
* pDevTex
= GetDevTexture(rvDesc
.m_Desc
.bMultisample
))
1933 ResourceViewHandle hView
= pDevTex
->GetResourceViewHandle(rvDesc
);
1934 if (hView
!= ResourceViewHandle::Unspecified
)
1935 return pDevTex
->LookupResourceView(hView
).second
;
1941 void CTexture::SetResourceView(const SResourceView
& rvDesc
, D3DBaseView
* pView
)
1943 if (CDeviceTexture
* pDevTex
= GetDevTexture(rvDesc
.m_Desc
.bMultisample
))
1945 ResourceViewHandle hView
= pDevTex
->GetResourceViewHandle(rvDesc
);
1946 if (hView
!= ResourceViewHandle::Unspecified
)
1948 SAFE_RELEASE(pDevTex
->LookupResourceView(hView
).second
);
1950 pDevTex
->LookupResourceView(hView
).second
= pView
;
1951 pDevTex
->LookupResourceView(hView
).second
->AddRef();
1956 void CTexture::SetDefaultShaderResourceView(D3DBaseView
* pDeviceShaderResource
, bool bMultisampled
/*= false*/)
1958 CDeviceTexture
* pDevTex
= GetDevTexture(bMultisampled
&& IsMSAA());
1960 SAFE_RELEASE(pDevTex
->LookupResourceView(EDefaultResourceViews::Default
).second
);
1962 pDevTex
->LookupResourceView(EDefaultResourceViews::Default
).second
= pDeviceShaderResource
;
1963 pDevTex
->LookupResourceView(EDefaultResourceViews::Default
).second
->AddRef();
1965 // Notify that resource is dirty
1966 if (!(m_eFlags
& FT_USAGE_RENDERTARGET
))
1968 InvalidateDeviceResource(eDeviceResourceViewDirty
);
1972 byte
* CTexture::GetData32(int nSide
, int nLevel
, byte
* pDstData
, ETEX_Format eDstFormat
)
1974 #if CRY_PLATFORM_WINDOWS
1975 // NOTE: the function will not maintain any dirty state and always download the data, don't use it in the render-loop
1976 CDeviceTexture
* pDevTexture
= GetDevTexture();
1977 pDevTexture
->DownloadToStagingResource(D3D11CalcSubresource(nLevel
, nSide
, m_nMips
), [&](void* pData
, uint32 rowPitch
, uint32 slicePitch
)
1979 if (m_eDstFormat
!= eTF_R8G8B8A8
)
1983 if (m_eSrcFormat
== eDstFormat
&& pDstData
)
1985 memcpy(pDstData
, pData
, GetDeviceDataSize());
1989 pDstData
= Convert((byte
*)pData
, m_nWidth
, m_nHeight
, 1, m_eSrcFormat
, eDstFormat
, 1, nOutSize
, true);
1996 pDstData
= new byte
[m_nWidth
* m_nHeight
* 4];
1999 memcpy(pDstData
, pData
, m_nWidth
* m_nHeight
* 4);
2011 const int CTexture::GetSize(bool bIncludePool
) const
2013 int nSize
= sizeof(CTexture
);
2014 nSize
+= m_SrcName
.capacity();
2016 // TODO: neccessary?
2017 // if (m_pRenderTargetData)
2019 // nSize += sizeof(*m_pRenderTargetData);
2020 // nSize += m_pRenderTargetData->m_DirtyRects.capacity() * sizeof(RECT);
2025 nSize
+= m_pFileTexMips
->GetSize(m_nMips
, m_CacheFileHeader
.m_nSides
);
2026 if (bIncludePool
&& m_pFileTexMips
->m_pPoolItem
)
2027 nSize
+= m_pFileTexMips
->m_pPoolItem
->GetSize();
2033 void CTexture::Init()
2035 SDynTexture::Init();
2039 SDynTexture2::Init(eTP_Clouds
);
2040 SDynTexture2::Init(eTP_Sprites
);
2041 SDynTexture2::Init(eTP_VoxTerrain
);
2042 SDynTexture2::Init(eTP_DynTexSources
);
2044 if (!gRenDev
->IsShaderCacheGenMode())
2045 LoadScaleformSystemTextures();
2048 void CTexture::PostInit()
2050 LOADING_TIME_PROFILE_SECTION
;
2051 if (!gRenDev
->IsShaderCacheGenMode())
2052 CTexture::LoadDefaultSystemTextures();
2055 int __cdecl
TexCallback(const VOID
* arg1
, const VOID
* arg2
)
2057 CTexture
** pi1
= (CTexture
**)arg1
;
2058 CTexture
** pi2
= (CTexture
**)arg2
;
2059 CTexture
* ti1
= *pi1
;
2060 CTexture
* ti2
= *pi2
;
2062 if (ti1
->GetDeviceDataSize() > ti2
->GetDeviceDataSize())
2064 if (ti1
->GetDeviceDataSize() < ti2
->GetDeviceDataSize())
2066 return stricmp(ti1
->GetSourceName(), ti2
->GetSourceName());
2069 int __cdecl
TexCallbackMips(const VOID
* arg1
, const VOID
* arg2
)
2071 CTexture
** pi1
= (CTexture
**)arg1
;
2072 CTexture
** pi2
= (CTexture
**)arg2
;
2073 CTexture
* ti1
= *pi1
;
2074 CTexture
* ti2
= *pi2
;
2078 nSize1
= ti1
->GetActualSize();
2079 nSize2
= ti2
->GetActualSize();
2081 if (nSize1
> nSize2
)
2083 if (nSize1
< nSize2
)
2085 return stricmp(ti1
->GetSourceName(), ti2
->GetSourceName());
2088 void CTexture::Update()
2090 FUNCTION_PROFILER_RENDERER
;
2092 CRenderer
* rd
= gRenDev
;
2095 // reload pending texture reload requests
2097 std::set
<string
> queue
;
2099 s_xTexReloadLock
.Lock();
2100 s_vTexReloadRequests
.swap(queue
);
2101 s_xTexReloadLock
.Unlock();
2103 for (std::set
<string
>::iterator i
= queue
.begin(); i
!= queue
.end(); ++i
)
2107 CTexture::s_bStreamingFromHDD
= gEnv
->pSystem
->GetStreamEngine()->IsStreamDataOnHDD();
2108 CTexture::s_nStatsStreamPoolInUseMem
= CTexture::s_pPoolMgr
->GetInUseSize();
2110 s_pTextureStreamer
->ApplySchedule(ITextureStreamer::eASF_Full
);
2111 s_pTextureStreamer
->BeginUpdateSchedule();
2113 #ifdef ENABLE_TEXTURE_STREAM_LISTENER
2114 StreamUpdateStats();
2117 SDynTexture::Tick();
2119 SResourceContainer
* pRL
= CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
2120 ResourcesMapItor itor
;
2122 if ((s_nStreamingMode
!= CRenderer::CV_r_texturesstreaming
) || (s_nStreamingUpdateMode
!= CRenderer::CV_r_texturesstreamingUpdateType
))
2129 #ifndef CONSOLE_CONST_CVAR_MODE
2131 if (CRenderer::CV_r_texlog
== 2 || CRenderer::CV_r_texlog
== 3 || CRenderer::CV_r_texlog
== 4)
2134 TArray
<CTexture
*> Texs
;
2137 if (CRenderer::CV_r_texlog
== 2 || CRenderer::CV_r_texlog
== 3)
2139 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2141 CTexture
* tp
= (CTexture
*)itor
->second
;
2142 if (CRenderer::CV_r_texlog
== 3 && tp
->IsNoTexture())
2146 else if (CRenderer::CV_r_texlog
== 2 && !tp
->IsNoTexture() && tp
->m_pFileTexMips
) // (tp->GetFlags() & FT_FROMIMAGE))
2151 if (CRenderer::CV_r_texlog
== 3)
2153 CryLogAlways("Logging to MissingTextures.txt...");
2154 fp
= fxopen("MissingTextures.txt", "w");
2158 CryLogAlways("Logging to UsedTextures.txt...");
2159 fp
= fxopen("UsedTextures.txt", "w");
2161 fprintf(fp
, "*** All textures: ***\n");
2164 qsort(&Texs
[0], Texs
.Num(), sizeof(CTexture
*), TexCallbackMips
);
2166 for (i
= 0; i
< Texs
.Num(); i
++)
2168 int w
= Texs
[i
]->GetWidth();
2169 int h
= Texs
[i
]->GetHeight();
2171 int nTSize
= Texs
[i
]->m_pFileTexMips
->GetSize(Texs
[i
]->GetNumMips(), Texs
[i
]->GetNumSides());
2173 fprintf(fp
, "%d\t\t%d x %d\t\tType: %s\t\tMips: %d\t\tFormat: %s\t\t(%s)\n", nTSize
, w
, h
, Texs
[i
]->NameForTextureType(Texs
[i
]->GetTextureType()), Texs
[i
]->GetNumMips(), Texs
[i
]->NameForTextureFormat(Texs
[i
]->GetDstFormat()), Texs
[i
]->GetName());
2174 //Size += Texs[i]->GetDataSize();
2177 PartSize
+= Texs
[i
]->GetDeviceDataSize();
2179 fprintf(fp
, "*** Total Size: %d\n\n", Size
/*, PartSize, PartSize */);
2183 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2185 CTexture
* tp
= (CTexture
*)itor
->second
;
2186 if (tp
->m_nAccessFrameID
== rd
->m_RP
.m_TI
[rd
->m_RP
.m_nProcessThreadID
].m_nFrameUpdateID
)
2198 fp
= fxopen("UsedTextures_Frame.txt", "w");
2201 fprintf(fp
, "\n\n*** Textures used in current frame: ***\n");
2203 IRenderAuxText::TextToScreenColor(4, 13, 1, 1, 0, 1, "*** Textures used in current frame: ***");
2207 qsort(&Texs
[0], Texs
.Num(), sizeof(CTexture
*), TexCallback
);
2210 for (i
= 0; i
< Texs
.Num(); i
++)
2213 fprintf(fp
, "%.3fKb\t\tType: %s\t\tFormat: %s\t\t(%s)\n", Texs
[i
]->GetDeviceDataSize() / 1024.0f
, CTexture::NameForTextureType(Texs
[i
]->GetTextureType()), CTexture::NameForTextureFormat(Texs
[i
]->GetDstFormat()), Texs
[i
]->GetName());
2216 cry_sprintf(buf
, "%.3fKb Type: %s Format: %s (%s)", Texs
[i
]->GetDeviceDataSize() / 1024.0f
, CTexture::NameForTextureType(Texs
[i
]->GetTextureType()), CTexture::NameForTextureFormat(Texs
[i
]->GetDstFormat()), Texs
[i
]->GetName());
2217 IRenderAuxText::TextToScreenColor(4, nY
, 0, 1, 0, 1, buf
);
2220 PartSize
+= Texs
[i
]->GetDeviceDataSize();
2221 Size
+= Texs
[i
]->GetDataSize();
2225 fprintf(fp
, "*** Total Size: %.3fMb, Device Size: %.3fMb\n\n", Size
/ (1024.0f
* 1024.0f
), PartSize
/ (1024.0f
* 1024.0f
));
2229 cry_sprintf(buf
, "*** Total Size: %.3fMb, Device Size: %.3fMb", Size
/ (1024.0f
* 1024.0f
), PartSize
/ (1024.0f
* 1024.0f
));
2230 IRenderAuxText::TextToScreenColor(4, nY
+ 1, 0, 1, 1, 1, buf
);
2234 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2236 CTexture
* tp
= (CTexture
*)itor
->second
;
2237 if (tp
&& !tp
->IsNoTexture())
2248 fp
= fxopen("UsedTextures_All.txt", "w");
2251 fprintf(fp
, "\n\n*** All Existing Textures: ***\n");
2253 IRenderAuxText::TextToScreenColor(4, 13, 1, 1, 0, 1, "*** Textures loaded: ***");
2256 qsort(&Texs
[0], Texs
.Num(), sizeof(CTexture
*), TexCallback
);
2259 for (i
= 0; i
< Texs
.Num(); i
++)
2263 int w
= Texs
[i
]->GetWidth();
2264 int h
= Texs
[i
]->GetHeight();
2265 fprintf(fp
, "%d\t\t%d x %d\t\t%d mips (%.3fKb)\t\tType: %s \t\tFormat: %s\t\t(%s)\n", Texs
[i
]->GetDataSize(), w
, h
, Texs
[i
]->GetNumMips(), Texs
[i
]->GetDeviceDataSize() / 1024.0f
, CTexture::NameForTextureType(Texs
[i
]->GetTextureType()), CTexture::NameForTextureFormat(Texs
[i
]->GetDstFormat()), Texs
[i
]->GetName());
2269 cry_sprintf(buf
, "%.3fKb Type: %s Format: %s (%s)", Texs
[i
]->GetDataSize() / 1024.0f
, CTexture::NameForTextureType(Texs
[i
]->GetTextureType()), CTexture::NameForTextureFormat(Texs
[i
]->GetDstFormat()), Texs
[i
]->GetName());
2270 IRenderAuxText::TextToScreenColor(4, nY
, 0, 1, 0, 1, buf
);
2273 Size
+= Texs
[i
]->GetDeviceDataSize();
2277 fprintf(fp
, "*** Total Size: %.3fMb\n\n", Size
/ (1024.0f
* 1024.0f
));
2281 cry_sprintf(buf
, "*** Total Size: %.3fMb", Size
/ (1024.0f
* 1024.0f
));
2282 IRenderAuxText::TextToScreenColor(4, nY
+ 1, 0, 1, 1, 1, buf
);
2286 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2288 CTexture
* tp
= (CTexture
*)itor
->second
;
2289 if (tp
&& !tp
->IsNoTexture() && !tp
->IsStreamed())
2301 if (CRenderer::CV_r_texlog
!= 4)
2302 CRenderer::CV_r_texlog
= 0;
2304 else if (CRenderer::CV_r_texlog
== 1)
2306 //char *str = GetTexturesStatusText();
2308 TArray
<CTexture
*> Texs
;
2309 //TArray<CTexture *> TexsNM;
2310 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2312 CTexture
* tp
= (CTexture
*)itor
->second
;
2313 if (tp
&& !tp
->IsNoTexture())
2316 //if (tp->GetFlags() & FT_TEX_NORMAL_MAP)
2317 // TexsNM.AddElem(tp);
2322 qsort(&Texs
[0], Texs
.Num(), sizeof(CTexture
*), TexCallback
);
2327 int64 NonStrSize
= 0;
2330 int64 SizeDynCom
= 0;
2331 int64 SizeDynAtl
= 0;
2332 int64 PartSizeNM
= 0;
2335 int nNumTexDynAtl
= 0;
2336 int nNumTexDynCom
= 0;
2337 for (i
= 0; i
< Texs
.Num(); i
++)
2339 CTexture
* tex
= Texs
[i
];
2340 const uint32 texFlags
= tex
->GetFlags();
2341 const int texDataSize
= tex
->GetDataSize();
2342 const int texDeviceDataSize
= tex
->GetDeviceDataSize();
2344 if (tex
->GetDevTexture() && !(texFlags
& (FT_USAGE_DYNAMIC
| FT_USAGE_RENDERTARGET
)))
2346 AllSize
+= texDataSize
;
2347 if (!Texs
[i
]->IsStreamed())
2349 NonStrSize
+= texDataSize
;
2354 if (texFlags
& (FT_USAGE_RENDERTARGET
| FT_USAGE_DYNAMIC
))
2356 if (texFlags
& FT_USAGE_ATLAS
)
2359 SizeDynAtl
+= texDataSize
;
2364 SizeDynCom
+= texDataSize
;
2367 else if (0 == (texFlags
& FT_TEX_NORMAL_MAP
))
2369 if (!Texs
[i
]->IsUnloaded())
2372 Size
+= texDataSize
;
2373 PartSize
+= texDeviceDataSize
;
2378 if (!Texs
[i
]->IsUnloaded())
2381 SizeNM
+= texDataSize
;
2382 PartSizeNM
+= texDeviceDataSize
;
2387 cry_sprintf(buf
, "All texture objects: %u (Size: %.3fMb), NonStreamed: %d (Size: %.3fMb)", Texs
.Num(), AllSize
/ (1024.0 * 1024.0), nNoStr
, NonStrSize
/ (1024.0 * 1024.0));
2388 IRenderAuxText::TextToScreenColor(4, 13, 1, 1, 0, 1, buf
);
2389 cry_sprintf(buf
, "All Loaded Texture Maps: %d (All MIPS: %.3fMb, Loaded MIPS: %.3fMb)", nNumTex
, Size
/ (1024.0f
* 1024.0f
), PartSize
/ (1024.0 * 1024.0));
2390 IRenderAuxText::TextToScreenColor(4, 16, 1, 1, 0, 1, buf
);
2391 cry_sprintf(buf
, "All Loaded Normal Maps: %d (All MIPS: %.3fMb, Loaded MIPS: %.3fMb)", nNumTexNM
, SizeNM
/ (1024.0 * 1024.0), PartSizeNM
/ (1024.0 * 1024.0));
2392 IRenderAuxText::TextToScreenColor(4, 19, 1, 1, 0, 1, buf
);
2393 cry_sprintf(buf
, "All Dynamic textures: %d (%.3fMb), %d Atlases (%.3fMb), %d Separared (%.3fMb)", nNumTexDynAtl
+ nNumTexDynCom
, (SizeDynAtl
+ SizeDynCom
) / (1024.0 * 1024.0), nNumTexDynAtl
, SizeDynAtl
/ (1024.0 * 1024.0), nNumTexDynCom
, SizeDynCom
/ (1024.0 * 1024.0));
2394 IRenderAuxText::TextToScreenColor(4, 22, 1, 1, 0, 1, buf
);
2397 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2399 CTexture
* tp
= (CTexture
*)itor
->second
;
2400 if (tp
&& !tp
->IsNoTexture() && tp
->m_nAccessFrameID
== rd
->m_RP
.m_TI
[rd
->m_RP
.m_nProcessThreadID
].m_nFrameUpdateID
)
2407 qsort(&Texs
[0], Texs
.Num(), sizeof(CTexture
*), TexCallback
);
2414 for (i
= 0; i
< Texs
.Num(); i
++)
2416 Size
+= Texs
[i
]->GetDataSize();
2417 if (Texs
[i
]->GetFlags() & (FT_USAGE_DYNAMIC
| FT_USAGE_RENDERTARGET
))
2419 if (Texs
[i
]->GetFlags() & FT_USAGE_ATLAS
)
2420 SizeDynAtl
+= Texs
[i
]->GetDataSize();
2422 SizeDynCom
+= Texs
[i
]->GetDataSize();
2425 PartSize
+= Texs
[i
]->GetDeviceDataSize();
2426 if (!Texs
[i
]->IsStreamed())
2427 NonStrSize
+= Texs
[i
]->GetDataSize();
2429 cry_sprintf(buf
, "Current tex. objects: %u (Size: %.3fMb, Dyn. Atlases: %.3f, Dyn. Separated: %.3f, Loaded: %.3f, NonStreamed: %.3f)", Texs
.Num(), Size
/ (1024.0f
* 1024.0f
), SizeDynAtl
/ (1024.0f
* 1024.0f
), SizeDynCom
/ (1024.0f
* 1024.0f
), PartSize
/ (1024.0f
* 1024.0f
), NonStrSize
/ (1024.0f
* 1024.0f
));
2430 IRenderAuxText::TextToScreenColor(4, 27, 1, 0, 0, 1, buf
);
2436 void CTexture::RT_LoadingUpdate()
2438 CTexture::s_bStreamingFromHDD
= gEnv
->pSystem
->GetStreamEngine()->IsStreamDataOnHDD();
2439 CTexture::s_nStatsStreamPoolInUseMem
= CTexture::s_pPoolMgr
->GetInUseSize();
2441 ITextureStreamer::EApplyScheduleFlags asf
= CTexture::s_bPrecachePhase
2442 ? ITextureStreamer::eASF_InOut
// Exclude the prep update, as it will be done by the RLT (and can be expensive)
2443 : ITextureStreamer::eASF_Full
;
2445 s_pTextureStreamer
->ApplySchedule(asf
);
2448 void CTexture::RLT_LoadingUpdate()
2450 s_pTextureStreamer
->BeginUpdateSchedule();
2453 //=========================================================================
2455 Ang3
sDeltAngles(Ang3
& Ang0
, Ang3
& Ang1
)
2458 for (int i
= 0; i
< 3; i
++)
2461 a0
= (float)((360.0 / 65536) * ((int)(a0
* (65536 / 360.0)) & 65535)); // angmod
2463 a1
= (float)((360.0 / 65536) * ((int)(a1
* (65536 / 360.0)) & 65535));
2469 SEnvTexture
* CTexture::FindSuitableEnvTex(Vec3
& Pos
, Ang3
& Angs
, bool bMustExist
, int RendFlags
, bool bUseExistingREs
, CShader
* pSH
, CShaderResources
* pRes
, CRenderObject
* pObj
, bool bReflect
, CRenderElement
* pRE
, bool* bMustUpdate
)
2471 SEnvTexture
* cm
= NULL
;
2472 float time0
= iTimer
->GetAsyncCurTime();
2475 float distO
= 999999;
2476 float adist
= 999999;
2477 int firstForUse
= -1;
2481 *bMustUpdate
= false;
2489 pRE
->mfGetPlane(pl
);
2490 objPos
= pl
.MirrorPosition(Vec3(0, 0, 0));
2493 pRE
->mfCenter(objPos
, pObj
);
2495 objPos
= pObj
->GetTranslation();
2497 float dist
= 999999;
2498 for (i
= 0; i
< MAX_ENVTEXTURES
; i
++)
2500 SEnvTexture
* cur
= &CTexture::s_EnvTexts
[i
];
2501 if (cur
->m_bReflected
!= bReflect
)
2503 float s
= (cur
->m_CamPos
- Pos
).GetLengthSquared();
2504 Ang3 angDelta
= sDeltAngles(Angs
, cur
->m_Angle
);
2505 float a
= angDelta
.x
* angDelta
.x
+ angDelta
.y
* angDelta
.y
+ angDelta
.z
* angDelta
.z
;
2508 so
= (cur
->m_ObjPos
- objPos
).GetLengthSquared();
2509 if (s
<= dist
&& a
<= adist
&& so
<= distO
)
2515 if (!so
&& !s
&& !a
)
2518 if (cur
->m_pTex
&& !cur
->m_pTex
->m_pTexture
&& firstFree
< 0)
2521 if (bMustExist
&& firstForUse
>= 0)
2522 return &CTexture::s_EnvTexts
[firstForUse
];
2526 float curTime
= iTimer
->GetCurrTime();
2528 float fTimeInterval
= dist
* CRenderer::CV_r_envtexupdateinterval
+ CRenderer::CV_r_envtexupdateinterval
* 0.5f
;
2529 float fDelta
= curTime
- CTexture::s_EnvTexts
[firstForUse
].m_TimeLastUpdated
;
2532 else if (dist
> MAX_ENVTEXSCANDIST
)
2535 nUpdate
= firstFree
;
2539 else if (fDelta
> fTimeInterval
)
2540 nUpdate
= firstForUse
;
2543 // No need to update (Up to date)
2544 return &CTexture::s_EnvTexts
[firstForUse
];
2546 if (!CTexture::s_EnvTexts
[nUpdate
].m_pTex
)
2550 if (!CTexture::s_EnvTexts
[nUpdate
].m_pTex
->m_pTexture
|| gRenDev
->m_RP
.m_PS
[gRenDev
->m_RP
.m_nProcessThreadID
].m_fEnvTextUpdateTime
< 0.1f
)
2553 CTexture::s_EnvTexts
[n
].m_TimeLastUpdated
= curTime
;
2554 CTexture::s_EnvTexts
[n
].m_CamPos
= Pos
;
2555 CTexture::s_EnvTexts
[n
].m_Angle
= Angs
;
2556 CTexture::s_EnvTexts
[n
].m_ObjPos
= objPos
;
2557 CTexture::s_EnvTexts
[n
].m_bReflected
= bReflect
;
2559 *bMustUpdate
= true;
2561 gRenDev
->m_RP
.m_PS
[gRenDev
->m_RP
.m_nProcessThreadID
].m_fEnvTextUpdateTime
+= iTimer
->GetAsyncCurTime() - time0
;
2562 return &CTexture::s_EnvTexts
[nUpdate
];
2567 for (i
= 0; i
< MAX_ENVTEXTURES
; i
++)
2569 SEnvTexture
* cur
= &CTexture::s_EnvTexts
[i
];
2570 if (dist
< curTime
- cur
->m_TimeLastUpdated
&& !cur
->m_bInprogress
)
2572 dist
= curTime
- cur
->m_TimeLastUpdated
;
2576 if (firstForUse
< 0)
2580 int n
= firstForUse
;
2581 CTexture::s_EnvTexts
[n
].m_TimeLastUpdated
= curTime
;
2582 CTexture::s_EnvTexts
[n
].m_CamPos
= Pos
;
2583 CTexture::s_EnvTexts
[n
].m_ObjPos
= objPos
;
2584 CTexture::s_EnvTexts
[n
].m_Angle
= Angs
;
2585 CTexture::s_EnvTexts
[n
].m_bReflected
= bReflect
;
2587 *bMustUpdate
= true;
2589 gRenDev
->m_RP
.m_PS
[gRenDev
->m_RP
.m_nProcessThreadID
].m_fEnvTextUpdateTime
+= iTimer
->GetAsyncCurTime() - time0
;
2590 return &CTexture::s_EnvTexts
[n
];
2594 //===========================================================================
2596 void CTexture::ShutDown()
2600 RT_FlushAllStreamingTasks(true);
2602 ReleaseSystemTextures(true);
2604 if (CRenderer::CV_r_releaseallresourcesonexit
)
2606 SResourceContainer
* pRL
= CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
2610 ResourcesMapItor itor
;
2611 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); )
2613 CTexture
* pTX
= (CTexture
*)itor
->second
;
2617 if (CRenderer::CV_r_printmemoryleaks
)
2618 iLog
->Log("Warning: CTexture::ShutDown: Texture %s was not deleted (%d)", pTX
->GetName(), pTX
->GetRefCounter());
2619 SAFE_RELEASE_FORCE(pTX
);
2623 // To avoid crash on ShutDown
2624 CTexture::s_ptexSceneNormalsMap
= NULL
;
2625 CTexture::s_ptexSceneDiffuse
= NULL
;
2626 CTexture::s_ptexSceneSpecular
= NULL
;
2627 CTexture::s_ptexSceneDiffuseAccMap
= NULL
;
2628 CTexture::s_ptexSceneSpecularAccMap
= NULL
;
2629 CTexture::s_ptexBackBuffer
= NULL
;
2630 CTexture::s_ptexPrevBackBuffer
[0][0] = NULL
;
2631 CTexture::s_ptexPrevBackBuffer
[1][0] = NULL
;
2632 CTexture::s_ptexPrevBackBuffer
[0][1] = NULL
;
2633 CTexture::s_ptexPrevBackBuffer
[1][1] = NULL
;
2634 CTexture::s_ptexSceneTarget
= NULL
;
2635 CTexture::s_ptexZTarget
= NULL
;
2636 CTexture::s_ptexHDRTarget
= NULL
;
2637 CTexture::s_ptexStereoL
= NULL
;
2638 CTexture::s_ptexStereoR
= NULL
;
2639 for (uint32 i
= 0; i
< 2; ++i
)
2640 CTexture::s_ptexQuadLayers
[i
] = NULL
;
2643 if (s_ShaderTemplatesInitialized
)
2645 for (i
= 0; i
< EFTT_MAX
; i
++)
2647 s_ShaderTemplates
[i
].~CTexture();
2650 s_ShaderTemplates
.Free();
2652 SAFE_DELETE(s_pTexNULL
);
2654 s_pPoolMgr
->Flush();
2657 bool CTexture::ReloadFile_Request(const char* szFileName
)
2659 s_xTexReloadLock
.Lock();
2660 s_vTexReloadRequests
.insert(szFileName
);
2661 s_xTexReloadLock
.Unlock();
2666 bool CTexture::ReloadFile(const char* szFileName
)
2668 char realNameBuffer
[256];
2669 fpConvertDOSToUnixName(realNameBuffer
, szFileName
);
2671 char gameFolderPath
[256];
2672 cry_strcpy(gameFolderPath
, PathUtil::GetGameFolder());
2673 PREFAST_SUPPRESS_WARNING(6054); // it is nullterminated
2674 int gameFolderPathLength
= strlen(gameFolderPath
);
2675 if (gameFolderPathLength
> 0 && gameFolderPath
[gameFolderPathLength
- 1] == '\\')
2677 gameFolderPath
[gameFolderPathLength
- 1] = '/';
2679 else if (gameFolderPathLength
> 0 && gameFolderPath
[gameFolderPathLength
- 1] != '/')
2681 gameFolderPath
[gameFolderPathLength
++] = '/';
2682 gameFolderPath
[gameFolderPathLength
] = 0;
2685 char* realName
= realNameBuffer
;
2686 if (strlen(realNameBuffer
) >= (uint32
)gameFolderPathLength
&& memcmp(realName
, gameFolderPath
, gameFolderPathLength
) == 0)
2687 realName
+= gameFolderPathLength
;
2689 bool bStatus
= true;
2691 SResourceContainer
* pRL
= CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
2694 AUTO_LOCK(CBaseResource::s_cResLock
);
2696 ResourcesMapItor itor
;
2697 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++)
2699 CTexture
* tp
= (CTexture
*)itor
->second
;
2703 if (!(tp
->m_eFlags
& FT_FROMIMAGE
))
2705 char srcNameBuffer
[MAX_PATH
+ 1];
2706 fpConvertDOSToUnixName(srcNameBuffer
, tp
->m_SrcName
.c_str());
2707 char* srcName
= srcNameBuffer
;
2708 if (strlen(srcName
) >= (uint32
)gameFolderPathLength
&& _strnicmp(srcName
, gameFolderPath
, gameFolderPathLength
) == 0)
2709 srcName
+= gameFolderPathLength
;
2710 //CryLogAlways("realName = %s srcName = %s gameFolderPath = %s szFileName = %s", realName, srcName, gameFolderPath, szFileName);
2711 if (!stricmp(realName
, srcName
))
2724 void CTexture::ReloadTextures()
2726 LOADING_TIME_PROFILE_SECTION
;
2728 // Flush any outstanding texture requests before reloading
2729 gEnv
->pRenderer
->FlushPendingTextureTasks();
2731 SResourceContainer
* pRL
= CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
2734 ResourcesMapItor itor
;
2736 for (itor
= pRL
->m_RMap
.begin(); itor
!= pRL
->m_RMap
.end(); itor
++, nID
++)
2738 CTexture
* tp
= (CTexture
*)itor
->second
;
2741 if (!(tp
->m_eFlags
& FT_FROMIMAGE
))
2748 bool CTexture::SetNoTexture(CTexture
* pDefaultTexture
/* = s_ptexNoTexture*/)
2750 if (pDefaultTexture
)
2752 m_pDevTexture
= pDefaultTexture
->m_pDevTexture
;
2753 m_eSrcFormat
= pDefaultTexture
->GetSrcFormat();
2754 m_eDstFormat
= pDefaultTexture
->GetDstFormat();
2755 m_nMips
= pDefaultTexture
->GetNumMips();
2756 m_nWidth
= pDefaultTexture
->GetWidth();
2757 m_nHeight
= pDefaultTexture
->GetHeight();
2759 m_nDefState
= pDefaultTexture
->m_nDefState
;
2760 m_fAvgBrightness
= 1.0f
;
2763 m_cClearColor
= ColorF(0.0f
, 0.0f
, 0.0f
, 1.0f
);
2765 #if CRY_PLATFORM_DURANGO && (CRY_RENDERER_DIRECT3D >= 110) && (CRY_RENDERER_DIRECT3D < 120)
2766 m_nDeviceAddressInvalidated
= m_pDevTexture
->GetBaseAddressInvalidated();
2768 #if CRY_PLATFORM_DURANGO && DURANGO_USE_ESRAM
2769 m_nESRAMOffset
= SKIP_ESRAM
;
2772 m_bNoTexture
= true;
2776 StreamState_ReleaseInfo(this, m_pFileTexMips
);
2777 m_pFileTexMips
= NULL
;
2779 m_bStreamed
= false;
2780 m_bPostponed
= false;
2781 m_eFlags
|= FT_FAILED
;
2782 m_nDevTextureSize
= 0;
2783 m_nPersistentSize
= 0;
2789 //===========================================================================
2791 void CTexture::ReleaseSystemTextures(bool bFinalRelease
)
2793 if (gRenDev
->m_pTextureManager
)
2794 gRenDev
->m_pTextureManager
->ReleaseDefaultTextures();
2796 if (s_pStatsTexWantedLists
)
2798 for (int i
= 0; i
< 2; ++i
)
2799 s_pStatsTexWantedLists
[i
].clear();
2802 // Keep these valid - if any textures failed to load and also leaked across the shutdown,
2803 // they'll be left with a dangling dev texture pointer otherwise.
2804 //SAFE_RELEASE_FORCE(s_ptexNoTexture);
2805 //SAFE_RELEASE_FORCE(s_ptexNoTextureCM);
2806 //SAFE_RELEASE_FORCE(s_ptexWhite);
2807 //SAFE_RELEASE_FORCE(s_ptexGray);
2808 //SAFE_RELEASE_FORCE(s_ptexBlack);
2809 //SAFE_RELEASE_FORCE(s_ptexBlackAlpha);
2810 //SAFE_RELEASE_FORCE(s_ptexBlackCM);
2811 //SAFE_RELEASE_FORCE(s_ptexFlatBump);
2812 #if !defined(_RELEASE)
2813 //SAFE_RELEASE_FORCE(s_ptexDefaultMergedDetail);
2814 //SAFE_RELEASE_FORCE(s_ptexMipMapDebug);
2815 //SAFE_RELEASE_FORCE(s_ptexColorBlue);
2816 //SAFE_RELEASE_FORCE(s_ptexColorCyan);
2817 //SAFE_RELEASE_FORCE(s_ptexColorGreen);
2818 //SAFE_RELEASE_FORCE(s_ptexColorPurple);
2819 //SAFE_RELEASE_FORCE(s_ptexColorRed);
2820 //SAFE_RELEASE_FORCE(s_ptexColorWhite);
2821 //SAFE_RELEASE_FORCE(s_ptexColorYellow);
2822 //SAFE_RELEASE_FORCE(s_ptexColorMagenta);
2823 //SAFE_RELEASE_FORCE(s_ptexColorOrange);
2825 //SAFE_RELEASE_FORCE(s_ptexPaletteDebug);
2826 //SAFE_RELEASE_FORCE(s_ptexShadowJitterMap);
2827 //SAFE_RELEASE_FORCE(s_ptexEnvironmentBRDF);
2828 //SAFE_RELEASE_FORCE(s_ptexScreenNoiseMap);
2829 //SAFE_RELEASE_FORCE(s_ptexDissolveNoiseMap);
2830 //SAFE_RELEASE_FORCE(s_ptexNoise3D);
2831 //SAFE_RELEASE_FORCE(s_ptexGrainFilterMap);
2832 //SAFE_RELEASE_FORCE(s_ptexFilmGrainMap);
2833 //SAFE_RELEASE_FORCE(s_ptexVignettingMap);
2834 //SAFE_RELEASE_FORCE(s_ptexAOJitter);
2835 //SAFE_RELEASE_FORCE(s_ptexAOVOJitter);
2836 SAFE_RELEASE_FORCE(s_ptexRT_2D
);
2837 SAFE_RELEASE_FORCE(s_ptexCloudsLM
);
2838 //SAFE_RELEASE_FORCE(s_ptexRainOcclusion);
2839 //SAFE_RELEASE_FORCE(s_ptexRainSSOcclusion[0]);
2840 //SAFE_RELEASE_FORCE(s_ptexRainSSOcclusion[1]);
2842 //SAFE_RELEASE_FORCE(s_ptexHitAreaRT[0]);
2843 //SAFE_RELEASE_FORCE(s_ptexHitAreaRT[1]);
2845 SAFE_RELEASE_FORCE(s_ptexVolumetricFog
);
2846 SAFE_RELEASE_FORCE(s_ptexVolumetricClipVolumeStencil
);
2848 SAFE_RELEASE_FORCE(s_ptexVolCloudShadow
);
2851 for (i
= 0; i
< 8; i
++)
2853 //SAFE_RELEASE_FORCE(s_ptexFromRE[i]);
2855 for (i
= 0; i
< 8; i
++)
2857 SAFE_RELEASE_FORCE(s_ptexShadowID
[i
]);
2860 for (i
= 0; i
< 2; i
++)
2862 //SAFE_RELEASE_FORCE(s_ptexFromRE_FromContainer[i]);
2865 SAFE_RELEASE_FORCE(s_ptexFromObj
);
2866 SAFE_RELEASE_FORCE(s_ptexSvoTree
);
2867 SAFE_RELEASE_FORCE(s_ptexSvoTris
);
2868 SAFE_RELEASE_FORCE(s_ptexSvoGlobalCM
);
2869 SAFE_RELEASE_FORCE(s_ptexSvoRgbs
);
2870 SAFE_RELEASE_FORCE(s_ptexSvoNorm
);
2871 SAFE_RELEASE_FORCE(s_ptexSvoOpac
);
2873 SAFE_RELEASE_FORCE(s_ptexColorChart
);
2875 SAFE_RELEASE_FORCE(s_ptexWindGrid
);
2877 for (i
= 0; i
< MAX_ENVTEXTURES
; i
++)
2879 s_EnvTexts
[i
].Release();
2881 //m_EnvTexTemp.Release();
2883 SAFE_RELEASE_FORCE(s_ptexMipColors_Diffuse
);
2884 SAFE_RELEASE_FORCE(s_ptexMipColors_Bump
);
2885 SAFE_RELEASE_FORCE(s_ptexSkyDomeMie
);
2886 SAFE_RELEASE_FORCE(s_ptexSkyDomeRayleigh
);
2887 SAFE_RELEASE_FORCE(s_ptexSkyDomeMoon
);
2888 SAFE_RELEASE_FORCE(s_ptexRT_ShadowPool
);
2889 SAFE_RELEASE_FORCE(s_ptexFarPlane
);
2891 SAFE_RELEASE_FORCE(s_ptexSceneNormalsMapMS
);
2892 SAFE_RELEASE_FORCE(s_ptexSceneDiffuseAccMapMS
);
2893 SAFE_RELEASE_FORCE(s_ptexSceneSpecularAccMapMS
);
2895 s_CustomRT_2D
.Free();
2896 //s_ShaderTemplates.Free();
2898 s_pPoolMgr
->Flush();
2900 // release targets pools
2901 //SDynTexture_Shadow::ShutDown();
2902 SDynTexture::ShutDown();
2903 SDynTexture2::ShutDown();
2905 //ReleaseSystemTargets();
2907 m_bLoadedSystem
= false;
2910 void CTexture::LoadScaleformSystemTextures()
2912 LOADING_TIME_PROFILE_SECTION
;
2915 void CTexture::LoadDefaultSystemTextures()
2917 LOADING_TIME_PROFILE_SECTION
;
2922 MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other
, 0, "Engine textures");
2924 if (!m_bLoadedSystem
)
2926 m_bLoadedSystem
= true;
2928 // Textures loaded directly from file
2931 CTexture
*& pTexture
;
2932 const char* szFileName
;
2935 texturesFromFile
[] =
2937 { s_ptexWhite
, "%ENGINE%/EngineAssets/Textures/White.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2938 { s_ptexBlack
, "%ENGINE%/EngineAssets/Textures/Black.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2939 { s_ptexBlackAlpha
, "%ENGINE%/EngineAssets/Textures/BlackAlpha.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2940 { s_ptexBlackCM
, "%ENGINE%/EngineAssets/Textures/BlackCM.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2941 { s_ptexGray
, "%ENGINE%/EngineAssets/Textures/Grey.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2942 { s_ptexDefaultMergedDetail
, "%ENGINE%/EngineAssets/Textures/GreyAlpha.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2943 { s_ptexDefaultProbeCM
, "%ENGINE%/EngineAssets/Shading/defaultProbe_cm.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2944 { s_ptexFlatBump
, "%ENGINE%/EngineAssets/Textures/White_ddn.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_TEX_NORMAL_MAP
},
2945 { s_ptexPaletteDebug
, "%ENGINE%/EngineAssets/Textures/palletteInst.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2946 { s_ptexPaletteTexelsPerMeter
, "%ENGINE%/EngineAssets/Textures/TexelsPerMeterGrad.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2947 { s_ptexIconShaderCompiling
, "%ENGINE%/EngineAssets/Icons/ShaderCompiling.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2948 { s_ptexIconStreaming
, "%ENGINE%/EngineAssets/Icons/Streaming.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2949 { s_ptexIconStreamingTerrainTexture
, "%ENGINE%/EngineAssets/Icons/StreamingTerrain.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2950 { s_ptexIconNavigationProcessing
, "%ENGINE%/EngineAssets/Icons/NavigationProcessing.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2951 { s_ptexShadowJitterMap
, "%ENGINE%/EngineAssets/Textures/rotrandom.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2952 { s_ptexEnvironmentBRDF
, "%ENGINE%/EngineAssets/Shading/environmentBRDF.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2953 { s_ptexScreenNoiseMap
, "%ENGINE%/EngineAssets/Textures/JumpNoiseHighFrequency_x27y19.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_NOMIPS
},
2954 { s_ptexDissolveNoiseMap
, "%ENGINE%/EngineAssets/Textures/noise.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2955 { s_ptexNoise3D
, "%ENGINE%/EngineAssets/Textures/noise3d.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2956 { s_ptexGrainFilterMap
, "%ENGINE%/EngineAssets/ScreenSpace/grain_bayer_mul.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_NOMIPS
},
2957 { s_ptexFilmGrainMap
, "%ENGINE%/EngineAssets/ScreenSpace/film_grain.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_NOMIPS
},
2958 { s_ptexVignettingMap
, "%ENGINE%/EngineAssets/Shading/vignetting.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2959 { s_ptexAOJitter
, "%ENGINE%/EngineAssets/ScreenSpace/PointsOnSphere4x4.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2960 { s_ptexAOVOJitter
, "%ENGINE%/EngineAssets/ScreenSpace/PointsOnSphereVO4x4.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2961 { s_ptexNormalsFitting
, "%ENGINE%/EngineAssets/ScreenSpace/NormalsFitting.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2962 { s_ptexPerlinNoiseMap
, "%ENGINE%/EngineAssets/Textures/perlinNoise2D.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2964 #if !defined(_RELEASE)
2965 { s_ptexNoTexture
, "%ENGINE%/EngineAssets/TextureMsg/ReplaceMe.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2966 { s_ptexNoTextureCM
, "%ENGINE%/EngineAssets/TextureMsg/ReplaceMeCM.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2967 { s_ptexMipMapDebug
, "%ENGINE%/EngineAssets/TextureMsg/MipMapDebug.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2968 { s_ptexColorBlue
, "%ENGINE%/EngineAssets/TextureMsg/color_Blue.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2969 { s_ptexColorCyan
, "%ENGINE%/EngineAssets/TextureMsg/color_Cyan.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2970 { s_ptexColorGreen
, "%ENGINE%/EngineAssets/TextureMsg/color_Green.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2971 { s_ptexColorPurple
, "%ENGINE%/EngineAssets/TextureMsg/color_Purple.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2972 { s_ptexColorRed
, "%ENGINE%/EngineAssets/TextureMsg/color_Red.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2973 { s_ptexColorWhite
, "%ENGINE%/EngineAssets/TextureMsg/color_White.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2974 { s_ptexColorYellow
, "%ENGINE%/EngineAssets/TextureMsg/color_Yellow.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2975 { s_ptexColorOrange
, "%ENGINE%/EngineAssets/TextureMsg/color_Orange.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2976 { s_ptexColorMagenta
, "%ENGINE%/EngineAssets/TextureMsg/color_Magenta.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2978 { s_ptexNoTexture
, "%ENGINE%/EngineAssets/Textures/Grey.dds", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2979 { s_ptexNoTextureCM
, "%ENGINE%/EngineAssets/Shading/defaultProbe_cm.tif", FT_DONT_RELEASE
| FT_DONT_STREAM
},
2983 for (int t
= 0; t
< CRY_ARRAY_COUNT(texturesFromFile
); ++t
)
2985 if (!texturesFromFile
[t
].pTexture
)
2986 texturesFromFile
[t
].pTexture
= CTexture::ForName(texturesFromFile
[t
].szFileName
, texturesFromFile
[t
].flags
, eTF_Unknown
);
2988 if (!texturesFromFile
[t
].pTexture
|| !texturesFromFile
[t
].pTexture
->IsLoaded() || !texturesFromFile
[t
].pTexture
->GetDevTexture())
2989 CryFatalError("Can't open %s texture file.", texturesFromFile
[t
].szFileName
);
2992 // Associate dummy NULL-resource with s_pTexNULL
2993 s_pTexNULL
= new CTexture(FT_DONT_RELEASE
| FT_DONT_STREAM
, Clr_Transparent
, CDeviceTexture::Associate(s_ptexBlackAlpha
->GetLayout(), nullptr));
2995 // Default Template textures
2996 int nRTFlags
= FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_STATE_CLAMP
| FT_USAGE_RENDERTARGET
;
2997 s_ptexMipColors_Diffuse
= CTexture::GetOrCreateTextureObject("$MipColors_Diffuse", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_MIPCOLORS_DIFFUSE
);
2998 s_ptexMipColors_Bump
= CTexture::GetOrCreateTextureObject("$MipColors_Bump", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_MIPCOLORS_BUMP
);
3000 s_ptexRT_2D
= CTexture::GetOrCreateTextureObject("$RT_2D", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_RT_2D
);
3002 s_ptexRainOcclusion
= CTexture::GetOrCreateTextureObject("$RainOcclusion", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3003 s_ptexRainSSOcclusion
[0] = CTexture::GetOrCreateTextureObject("$RainSSOcclusion0", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3004 s_ptexRainSSOcclusion
[1] = CTexture::GetOrCreateTextureObject("$RainSSOcclusion1", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3006 //s_ptexHitAreaRT[0] = CTexture::CreateTextureObject("$HitEffectAccumBuffRT_0", 128, 128, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown);
3007 //s_ptexHitAreaRT[1] = CTexture::CreateTextureObject("$HitEffectAccumBuffRT_1", 128, 128, 1, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_USAGE_RENDERTARGET, eTF_Unknown);
3009 s_ptexFromObj
= CTexture::GetOrCreateTextureObject("FromObj", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_FROMOBJ
);
3010 s_ptexSvoTree
= CTexture::GetOrCreateTextureObject("SvoTree", 0, 0, 1, eTT_3D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVOTREE
);
3011 s_ptexSvoTris
= CTexture::GetOrCreateTextureObject("SvoTris", 0, 0, 1, eTT_3D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVOTRIS
);
3012 s_ptexSvoGlobalCM
= CTexture::GetOrCreateTextureObject("SvoGlobalCM", 0, 0, 1, eTT_Cube
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVOGLCM
);
3013 s_ptexSvoRgbs
= CTexture::GetOrCreateTextureObject("SvoRgbs", 0, 0, 1, eTT_3D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVORGBS
);
3014 s_ptexSvoNorm
= CTexture::GetOrCreateTextureObject("SvoNorm", 0, 0, 1, eTT_3D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVONORM
);
3015 s_ptexSvoOpac
= CTexture::GetOrCreateTextureObject("SvoOpac", 0, 0, 1, eTT_3D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SVOOPAC
);
3017 s_ptexWindGrid
= CTexture::GetOrCreateTextureObject("WindGrid", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_STAGE_UPLOAD
, eTF_Unknown
, TO_WINDGRID
);
3018 if (!CTexture::IsTextureExist(CTexture::s_ptexWindGrid
))
3020 CTexture::s_ptexWindGrid
->Create2DTexture(256, 256, 1, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_STAGE_UPLOAD
, nullptr, eTF_R16G16F
);
3023 s_ptexZTargetReadBack
[0] = CTexture::GetOrCreateTextureObject("$ZTargetReadBack0", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3024 s_ptexZTargetReadBack
[1] = CTexture::GetOrCreateTextureObject("$ZTargetReadBack1", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3025 s_ptexZTargetReadBack
[2] = CTexture::GetOrCreateTextureObject("$ZTargetReadBack2", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3026 s_ptexZTargetReadBack
[3] = CTexture::GetOrCreateTextureObject("$ZTargetReadBack3", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3028 s_ptexZTargetDownSample
[0] = CTexture::GetOrCreateTextureObject("$ZTargetDownSample0", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3029 s_ptexZTargetDownSample
[1] = CTexture::GetOrCreateTextureObject("$ZTargetDownSample1", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3030 s_ptexZTargetDownSample
[2] = CTexture::GetOrCreateTextureObject("$ZTargetDownSample2", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3031 s_ptexZTargetDownSample
[3] = CTexture::GetOrCreateTextureObject("$ZTargetDownSample3", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
, eTF_Unknown
);
3033 s_ptexSceneNormalsMapMS
= CTexture::GetOrCreateTextureObject("$SceneNormalsMapMS", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SCENE_NORMALMAP_MS
);
3034 s_ptexSceneDiffuseAccMapMS
= CTexture::GetOrCreateTextureObject("$SceneDiffuseAccMS", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SCENE_DIFFUSE_ACC_MS
);
3035 s_ptexSceneSpecularAccMapMS
= CTexture::GetOrCreateTextureObject("$SceneSpecularAccMS", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SCENE_SPECULAR_ACC_MS
);
3037 s_ptexRT_ShadowPool
= CTexture::GetOrCreateTextureObject("$RT_ShadowPool", 0, 0, 1, eTT_2D
, FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
, eTF_Unknown
);
3038 s_ptexFarPlane
= CTexture::GetOrCreateTextureObject("$FarPlane", 8, 8, 1, eTT_2D
, FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
, eTF_Unknown
);
3040 #if CRY_PLATFORM_WINDOWS || CRY_PLATFORM_APPLE || CRY_PLATFORM_LINUX
3041 s_ptexDepthBufferQuarter
= CTexture::GetOrCreateTextureObject("$DepthBufferQuarter", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
, eTF_Unknown
);
3043 s_ptexDepthBufferQuarter
= NULL
;
3045 s_ptexDepthBufferHalfQuarter
= CTexture::GetOrCreateTextureObject("$DepthBufferHalfQuarter", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
, eTF_Unknown
);
3047 if (!s_ptexModelHudBuffer
)
3048 s_ptexModelHudBuffer
= CTexture::GetOrCreateTextureObject("$ModelHud", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_MODELHUD
);
3050 if (!s_ptexBackBuffer
)
3052 s_ptexSceneTarget
= CTexture::GetOrCreateTextureObject("$SceneTarget", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SCENE_TARGET
);
3053 s_ptexCurrSceneTarget
= s_ptexSceneTarget
;
3055 s_ptexSceneTargetR11G11B10F
[0] = CTexture::GetOrCreateTextureObject("$SceneTargetR11G11B10F_0", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3056 s_ptexSceneTargetR11G11B10F
[1] = CTexture::GetOrCreateTextureObject("$SceneTargetR11G11B10F_1", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3057 s_ptexSceneTargetScaledR11G11B10F
[0] = CTexture::GetOrCreateTextureObject("$SceneTargetScaled0R11G11B10F", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3058 s_ptexSceneTargetScaledR11G11B10F
[1] = CTexture::GetOrCreateTextureObject("$SceneTargetScaled1R11G11B10F", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3059 s_ptexSceneTargetScaledR11G11B10F
[2] = CTexture::GetOrCreateTextureObject("$SceneTargetScaled2R11G11B10F", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3060 s_ptexSceneTargetScaledR11G11B10F
[3] = CTexture::GetOrCreateTextureObject("$SceneTargetScaled3R11G11B10F", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3062 s_ptexVelocity
= CTexture::GetOrCreateTextureObject("$Velocity", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3063 s_ptexVelocityTiles
[0] = CTexture::GetOrCreateTextureObject("$VelocityTilesTmp0", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3064 s_ptexVelocityTiles
[1] = CTexture::GetOrCreateTextureObject("$VelocityTilesTmp1", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3065 s_ptexVelocityTiles
[2] = CTexture::GetOrCreateTextureObject("$VelocityTiles", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3066 s_ptexVelocityObjects
[0] = CTexture::GetOrCreateTextureObject("$VelocityObjects", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3067 // Only used for VR, but we need to support runtime switching
3068 s_ptexVelocityObjects
[1] = CTexture::GetOrCreateTextureObject("$VelocityObjects_R", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3070 s_ptexBackBuffer
= CTexture::GetOrCreateTextureObject("$BackBuffer", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_BACKBUFFERMAP
);
3072 s_ptexPrevFrameScaled
= CTexture::GetOrCreateTextureObject("$PrevFrameScale", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3074 s_ptexBackBufferScaled
[0] = CTexture::GetOrCreateTextureObject("$BackBufferScaled_d2", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_BACKBUFFERSCALED_D2
);
3075 s_ptexBackBufferScaled
[1] = CTexture::GetOrCreateTextureObject("$BackBufferScaled_d4", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_BACKBUFFERSCALED_D4
);
3076 s_ptexBackBufferScaled
[2] = CTexture::GetOrCreateTextureObject("$BackBufferScaled_d8", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_BACKBUFFERSCALED_D8
);
3078 s_ptexBackBufferScaledTemp
[0] = CTexture::GetOrCreateTextureObject("$BackBufferScaledTemp_d2", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3079 s_ptexBackBufferScaledTemp
[1] = CTexture::GetOrCreateTextureObject("$BackBufferScaledTemp_d4", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, -1);
3081 s_ptexSceneNormalsMap
= CTexture::GetOrCreateTextureObject("$SceneNormalsMap", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
, TO_SCENE_NORMALMAP
);
3082 s_ptexSceneNormalsBent
= CTexture::GetOrCreateTextureObject("$SceneNormalsBent", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3083 s_ptexSceneDiffuse
= CTexture::GetOrCreateTextureObject("$SceneDiffuse", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3084 s_ptexSceneSpecular
= CTexture::GetOrCreateTextureObject("$SceneSpecular", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3085 #if defined(DURANGO_USE_ESRAM)
3086 s_ptexSceneSpecularESRAM
= CTexture::GetOrCreateTextureObject("$SceneSpecularESRAM", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3088 s_ptexSceneDiffuseAccMap
= CTexture::GetOrCreateTextureObject("$SceneDiffuseAcc", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
, TO_SCENE_DIFFUSE_ACC
);
3089 s_ptexSceneSpecularAccMap
= CTexture::GetOrCreateTextureObject("$SceneSpecularAcc", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
, TO_SCENE_SPECULAR_ACC
);
3090 s_ptexShadowMask
= CTexture::GetOrCreateTextureObject("$ShadowMask", 0, 0, 1, eTT_2DArray
, nRTFlags
, eTF_R8
, TO_SHADOWMASK
);
3092 s_ptexFlaresGather
= CTexture::GetOrCreateTextureObject("$FlaresGather", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3093 for (i
= 0; i
< MAX_OCCLUSION_READBACK_TEXTURES
; i
++)
3095 cry_sprintf(str
, "$FlaresOcclusion_%d", i
);
3096 s_ptexFlaresOcclusionRing
[i
] = CTexture::GetOrCreateTextureObject(str
, 0, 0, 1, eTT_2D
, nRTFlags
, eTF_R8G8B8A8
);
3099 // fixme: get texture resolution from CREWaterOcean
3100 // TODO: make s_ptexWaterVolumeTemp an array texture
3101 s_ptexWaterOcean
= CTexture::GetOrCreateTextureObject("$WaterOceanMap", 64, 64, 1, eTT_2D
, FT_DONT_RELEASE
| FT_NOMIPS
| FT_STAGE_UPLOAD
| FT_DONT_STREAM
, eTF_Unknown
, TO_WATEROCEANMAP
);
3102 s_ptexWaterVolumeTemp
[0] = CTexture::GetOrCreateTextureObject("$WaterVolumeTemp_0", 64, 64, 1, eTT_2D
, /*FT_DONT_RELEASE |*/ FT_NOMIPS
| FT_STAGE_UPLOAD
| FT_DONT_STREAM
, eTF_Unknown
);
3103 s_ptexWaterVolumeTemp
[1] = CTexture::GetOrCreateTextureObject("$WaterVolumeTemp_1", 64, 64, 1, eTT_2D
, /*FT_DONT_RELEASE |*/ FT_NOMIPS
| FT_STAGE_UPLOAD
| FT_DONT_STREAM
, eTF_Unknown
);
3104 s_ptexWaterVolumeDDN
= CTexture::GetOrCreateTextureObject("$WaterVolumeDDN", 64, 64, 1, eTT_2D
, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
| FT_FORCE_MIPS
, eTF_Unknown
, TO_WATERVOLUMEMAP
);
3105 s_ptexWaterVolumeRefl
[0] = CTexture::GetOrCreateTextureObject("$WaterVolumeRefl", 64, 64, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
| FT_FORCE_MIPS
, eTF_Unknown
, TO_WATERVOLUMEREFLMAP
);
3106 s_ptexWaterVolumeRefl
[1] = CTexture::GetOrCreateTextureObject("$WaterVolumeReflPrev", 64, 64, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
| FT_FORCE_MIPS
, eTF_Unknown
, TO_WATERVOLUMEREFLMAPPREV
);
3107 s_ptexWaterCaustics
[0] = CTexture::GetOrCreateTextureObject("$WaterVolumeCaustics", 512, 512, 1, eTT_2D
, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_WATERVOLUMECAUSTICSMAP
);
3108 s_ptexWaterCaustics
[1] = CTexture::GetOrCreateTextureObject("$WaterVolumeCausticsTemp", 512, 512, 1, eTT_2D
, /*FT_DONT_RELEASE |*/ FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_WATERVOLUMECAUSTICSMAPTEMP
);
3110 s_ptexRainDropsRT
[0] = CTexture::GetOrCreateTextureObject("$RainDropsAccumRT_0", 512, 512, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3111 s_ptexRainDropsRT
[1] = CTexture::GetOrCreateTextureObject("$RainDropsAccumRT_1", 512, 512, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3115 //for d3d10 we cannot free it during level transition, therefore allocate once and keep it
3116 s_ptexZTarget
= CTexture::GetOrCreateTextureObject("$ZTarget", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3119 s_ptexZTargetScaled
= CTexture::GetOrCreateTextureObject("$ZTargetScaled", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_DOWNSCALED_ZTARGET_FOR_AO
);
3120 s_ptexZTargetScaled2
= CTexture::GetOrCreateTextureObject("$ZTargetScaled2", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_QUARTER_ZTARGET_FOR_AO
);
3121 s_ptexZTargetScaled3
= CTexture::GetOrCreateTextureObject("$ZTargetScaled3", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3124 s_ptexSceneSelectionIDs
= CTexture::GetOrCreateTextureObject("$SceneSelectionIDs", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_R32F
);
3125 s_ptexSceneHalfDepthStencil
= CTexture::GetOrCreateTextureObject("$SceneHalfDepthStencil", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
, eTF_D32F
);
3127 s_ptexHDRTarget
= CTexture::GetOrCreateTextureObject("$HDRTarget", 0, 0, 1, eTT_2D
, nRTFlags
, eTF_Unknown
);
3129 // Create dummy texture object for terrain and clouds lightmap
3130 s_ptexCloudsLM
= CTexture::GetOrCreateTextureObject("$CloudsLM", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_CLOUDS_LM
);
3132 for (i
= 0; i
< 8; i
++)
3134 cry_sprintf(str
, "$FromRE_%d", i
);
3135 if (!s_ptexFromRE
[i
])
3136 s_ptexFromRE
[i
] = CTexture::GetOrCreateTextureObject(str
, 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_FROMRE0
+ i
);
3139 for (i
= 0; i
< 8; i
++)
3141 cry_sprintf(str
, "$ShadowID_%d", i
);
3142 s_ptexShadowID
[i
] = CTexture::GetOrCreateTextureObject(str
, 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SHADOWID0
+ i
);
3145 for (i
= 0; i
< 2; i
++)
3147 cry_sprintf(str
, "$FromRE%d_FromContainer", i
);
3148 if (!s_ptexFromRE_FromContainer
[i
])
3149 s_ptexFromRE_FromContainer
[i
] = CTexture::GetOrCreateTextureObject(str
, 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_FROMRE0_FROM_CONTAINER
+ i
);
3152 s_ptexColorChart
= CTexture::GetOrCreateTextureObject("$ColorChart", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_COLORCHART
);
3154 s_ptexSkyDomeMie
= CTexture::GetOrCreateTextureObject("$SkyDomeMie", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SKYDOME_MIE
);
3155 s_ptexSkyDomeRayleigh
= CTexture::GetOrCreateTextureObject("$SkyDomeRayleigh", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SKYDOME_RAYLEIGH
);
3156 s_ptexSkyDomeMoon
= CTexture::GetOrCreateTextureObject("$SkyDomeMoon", 0, 0, 1, eTT_2D
, FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_RENDERTARGET
, eTF_Unknown
, TO_SKYDOME_MOON
);
3158 for (i
= 0; i
< EFTT_MAX
; i
++)
3160 new(&s_ShaderTemplates
[i
])CTexture(FT_DONT_RELEASE
);
3161 s_ShaderTemplates
[i
].SetCustomID(EFTT_DIFFUSE
+ i
);
3162 s_ShaderTemplates
[i
].SetFlags(FT_DONT_RELEASE
);
3164 s_ShaderTemplatesInitialized
= true;
3166 s_ptexVolumetricFog
= CTexture::GetOrCreateTextureObject("$VolFogInscattering", 0, 0, 0, eTT_3D
, FT_NOMIPS
| FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_UNORDERED_ACCESS
, eTF_Unknown
);
3167 s_ptexVolumetricClipVolumeStencil
= CTexture::GetOrCreateTextureObject("$ClipVolumeStencilVolume", 0, 0, 0, eTT_2D
, FT_NOMIPS
| FT_DONT_RELEASE
| FT_DONT_STREAM
| FT_USAGE_DEPTHSTENCIL
| FT_USAGE_RENDERTARGET
, eTF_Unknown
);
3169 s_ptexVolCloudShadow
= CTexture::GetOrCreateTextureObject("$VolCloudShadows", 0, 0, 0, eTT_3D
, FT_NOMIPS
| FT_USAGE_UNORDERED_ACCESS
, eTF_Unknown
);
3171 #if defined(DURANGO_USE_ESRAM)
3172 // Assign ESRAM offsets
3173 if (CRenderer::CV_r_useESRAM
)
3175 // Precomputed offsets, using xg library and aligned to 4k
3176 // 1600x900 RGBA16F: 11894784
3177 // 1600x900 RGBA8: 5955584
3179 if (gRenDev
->GetWidth() <= 1600 && gRenDev
->GetHeight() <= 900)
3181 s_ptexHDRTarget
->SetESRAMOffset(0);
3182 s_ptexSceneSpecularESRAM
->SetESRAMOffset(0);
3183 s_ptexSceneNormalsMap
->SetESRAMOffset(11894784 + 5955584 * 0);
3184 s_ptexSceneDiffuse
->SetESRAMOffset(11894784 + 5955584 * 1);
3185 // Depth target uses: 11894784 + 5955584 * 2
3189 iLog
->LogError("Disabling ESRAM since resolution is larger than 1600x900");
3195 if (gRenDev
->m_pTextureManager
)
3196 gRenDev
->m_pTextureManager
->PreloadDefaultTextures();
3201 //////////////////////////////////////////////////////////////////////////
3202 const char* CTexture::GetFormatName() const
3204 return NameForTextureFormat(GetDstFormat());
3207 //////////////////////////////////////////////////////////////////////////
3208 const char* CTexture::GetTypeName() const
3210 return NameForTextureType(GetTextureType());
3213 //////////////////////////////////////////////////////////////////////////
3214 CDynTextureSource::CDynTextureSource()
3218 , m_lastUpdateTime(0)
3219 , m_lastUpdateFrameID(0)
3224 CDynTextureSource::~CDynTextureSource()
3226 SAFE_DELETE(m_pDynTexture
);
3229 void CDynTextureSource::AddRef()
3231 CryInterlockedIncrement(&m_refCount
);
3234 void CDynTextureSource::Release()
3236 long refCnt
= CryInterlockedDecrement(&m_refCount
);
3241 void CDynTextureSource::CalcSize(uint32
& width
, uint32
& height
, float distToCamera
) const
3245 switch (CRenderer::CV_r_envtexresolution
)
3260 if (distToCamera
> 0)
3262 int x(0), y(0), vpwidth(1), vpheight(1);
3263 gRenDev
->GetViewport(&x
, &y
, &vpwidth
, &vpheight
);
3264 float lod
= logf(max(distToCamera
* 1024.0f
/ (float) max(vpwidth
, vpheight
), 1.0f
));
3265 uint32 lodFixed
= fastround_positive(lod
);
3266 size
= 1 << max(logSize
- lodFixed
, 5u);
3273 bool CDynTextureSource::Apply(int nTUnit
, SamplerStateHandle nTS
)
3275 assert(m_pDynTexture
);
3276 if (!m_pDynTexture
|| !m_pDynTexture
->IsValid())
3279 m_pDynTexture
->Apply(nTUnit
, nTS
);
3283 void CDynTextureSource::GetTexGenInfo(float& offsX
, float& offsY
, float& scaleX
, float& scaleY
) const
3285 assert(m_pDynTexture
);
3286 if (!m_pDynTexture
|| !m_pDynTexture
->IsValid())
3295 ITexture
* pSrcTex(m_pDynTexture
->GetTexture());
3296 float invSrcWidth(1.0f
/ (float) pSrcTex
->GetWidth());
3297 float invSrcHeight(1.0f
/ (float) pSrcTex
->GetHeight());
3298 offsX
= m_pDynTexture
->m_nX
* invSrcWidth
;
3299 offsY
= m_pDynTexture
->m_nY
* invSrcHeight
;
3300 assert(m_width
<= m_pDynTexture
->m_nWidth
&& m_height
<= m_pDynTexture
->m_nHeight
);
3301 scaleX
= m_width
* invSrcWidth
;
3302 scaleY
= m_height
* invSrcHeight
;
3305 void CDynTextureSource::InitDynTexture(ETexPool eTexPool
)
3307 CalcSize(m_width
, m_height
);
3308 m_pDynTexture
= new SDynTexture2(m_width
, m_height
, FT_USAGE_RENDERTARGET
| FT_STATE_CLAMP
| FT_NOMIPS
, "DynTextureSource", eTexPool
);
3311 struct FlashTextureSourceSharedRT_AutoUpdate
3314 static void Add(CFlashTextureSourceBase
* pSrc
)
3316 CryAutoCriticalSection
lock(ms_lock
);
3317 stl::push_back_unique(ms_sources
, pSrc
);
3320 static void AddToLightList(CFlashTextureSourceBase
* pSrc
)
3322 if (stl::find(ms_LightTextures
, pSrc
)) return;
3323 ms_LightTextures
.push_back(pSrc
);
3326 static void Remove(CFlashTextureSourceBase
* pSrc
)
3328 CryAutoCriticalSection
lock(ms_lock
);
3330 const size_t size
= ms_sources
.size();
3331 for (size_t i
= 0; i
< size
; ++i
)
3333 if (ms_sources
[i
] == pSrc
)
3335 ms_sources
[i
] = ms_sources
[size
- 1];
3336 ms_sources
.pop_back();
3337 if (ms_sources
.empty())
3339 stl::reconstruct(ms_sources
);
3344 stl::find_and_erase(ms_LightTextures
, pSrc
);
3349 SRenderThread
* pRT
= gRenDev
->m_pRT
;
3350 if (!pRT
|| (pRT
->IsMainThread() && pRT
->m_eVideoThreadMode
== SRenderThread::eVTM_Disabled
))
3352 CTimeValue curTime
= gEnv
->pTimer
->GetAsyncTime();
3353 const int frameID
= gRenDev
->GetFrameID(false);
3354 if (ms_lastTickFrameID
!= frameID
)
3356 CryAutoCriticalSection
lock(ms_lock
);
3358 const float deltaTime
= gEnv
->pTimer
->GetFrameTime();
3359 const bool isEditing
= gEnv
->IsEditing();
3360 const bool isPaused
= gEnv
->pSystem
->IsPaused();
3362 const size_t size
= ms_sources
.size();
3363 for (size_t i
= 0; i
< size
; ++i
)
3365 ms_sources
[i
]->AutoUpdate(curTime
, deltaTime
, isEditing
, isPaused
);
3368 ms_lastTickFrameID
= frameID
;
3373 static void TickRT()
3375 SRenderThread
* pRT
= gRenDev
->m_pRT
;
3376 if (!pRT
|| (pRT
->IsRenderThread() && pRT
->m_eVideoThreadMode
== SRenderThread::eVTM_Disabled
))
3378 const int frameID
= gRenDev
->GetFrameID(false);
3379 if (ms_lastTickRTFrameID
!= frameID
)
3381 CryAutoCriticalSection
lock(ms_lock
);
3383 const size_t size
= ms_sources
.size();
3384 for (size_t i
= 0; i
< size
; ++i
)
3386 ms_sources
[i
]->AutoUpdateRT(frameID
);
3389 ms_lastTickRTFrameID
= frameID
;
3394 static void RenderLightTextures()
3396 for (std::vector
<CFlashTextureSourceBase
*>::const_iterator it
= ms_LightTextures
.begin(); it
!= ms_LightTextures
.end(); ++it
)
3398 ms_LightTextures
.clear();
3402 static std::vector
<CFlashTextureSourceBase
*> ms_sources
;
3403 static std::vector
<CFlashTextureSourceBase
*> ms_LightTextures
;
3404 static CryCriticalSection ms_lock
;
3405 static int ms_lastTickFrameID
;
3406 static int ms_lastTickRTFrameID
;
3409 void CFlashTextureSourceBase::Tick()
3411 FlashTextureSourceSharedRT_AutoUpdate::Tick();
3414 void CFlashTextureSourceBase::TickRT()
3416 FlashTextureSourceSharedRT_AutoUpdate::TickRT();
3419 void CFlashTextureSourceBase::RenderLights()
3421 FlashTextureSourceSharedRT_AutoUpdate::RenderLightTextures();
3424 void CFlashTextureSourceBase::AddToLightRenderList(const IDynTextureSource
* pSrc
)
3426 FlashTextureSourceSharedRT_AutoUpdate::AddToLightList((CFlashTextureSourceBase
*)pSrc
);
3429 void CFlashTextureSourceBase::AutoUpdate(const CTimeValue
& curTime
, const float delta
, const bool isEditing
, const bool isPaused
)
3433 m_pFlashPlayer
->UpdatePlayer(this);
3434 #if CRY_PLATFORM_WINDOWS
3435 m_perFrameRendering
&= !isEditing
;
3438 if (m_perFrameRendering
|| (curTime
- m_lastVisible
).GetSeconds() < 1.0f
)
3440 Advance(delta
, isPaused
);
3445 void CFlashTextureSourceBase::AutoUpdateRT(const int frameID
)
3449 if (m_perFrameRendering
&& (frameID
!= m_lastVisibleFrameID
))
3456 std::vector
<CFlashTextureSourceBase
*> FlashTextureSourceSharedRT_AutoUpdate::ms_sources
;
3457 std::vector
<CFlashTextureSourceBase
*> FlashTextureSourceSharedRT_AutoUpdate::ms_LightTextures
;
3458 CryCriticalSection
FlashTextureSourceSharedRT_AutoUpdate::ms_lock
;
3459 int FlashTextureSourceSharedRT_AutoUpdate::ms_lastTickFrameID
= 0;
3460 int FlashTextureSourceSharedRT_AutoUpdate::ms_lastTickRTFrameID
= 0;
3462 CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::~CFlashPlayerInstanceWrapper()
3464 SAFE_RELEASE(m_pBootStrapper
);
3465 SAFE_RELEASE(m_pPlayer
);
3468 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::GetTempPtr() const
3470 CryAutoCriticalSection
lock(m_lock
);
3473 m_pPlayer
->AddRef();
3478 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::GetPermPtr(CFlashTextureSourceBase
* pSrc
)
3480 CryAutoCriticalSection
lock(m_lock
);
3482 m_canDeactivate
= false;
3483 CreateInstance(pSrc
);
3488 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::Activate(bool activate
, CFlashTextureSourceBase
* pSrc
)
3490 CryAutoCriticalSection
lock(m_lock
);
3494 CreateInstance(pSrc
);
3498 if (m_canDeactivate
)
3500 SAFE_RELEASE(m_pPlayer
);
3505 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::CreateInstance(CFlashTextureSourceBase
* pSrc
)
3507 if (!m_pPlayer
&& m_pBootStrapper
)
3509 m_pPlayer
= m_pBootStrapper
->CreatePlayerInstance(IFlashPlayer::DEFAULT_NO_MOUSE
);
3512 #if defined(ENABLE_DYNTEXSRC_PROFILING)
3513 m_pPlayer
->LinkDynTextureSource(pSrc
);
3515 m_pPlayer
->Advance(0.0f
);
3516 m_width
= m_pPlayer
->GetWidth();
3517 m_height
= m_pPlayer
->GetHeight();
3522 const char* CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::GetSourceFilePath() const
3524 return m_pBootStrapper
? m_pBootStrapper
->GetFilePath() : "UNDEFINED";
3527 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapper::Advance(float delta
)
3530 m_pPlayer
->Advance(delta
);
3533 CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::~CFlashPlayerInstanceWrapperLayoutElement()
3537 m_pUILayout
->Unload();
3543 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::GetTempPtr() const
3545 CryAutoCriticalSection
lock(m_lock
);
3548 m_pPlayer
->AddRef();
3553 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::GetPermPtr(CFlashTextureSourceBase
* pSrc
)
3555 CryAutoCriticalSection
lock(m_lock
);
3557 m_canDeactivate
= false;
3558 CreateInstance(pSrc
, m_layoutName
.c_str());
3563 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::Activate(bool activate
, CFlashTextureSourceBase
* pSrc
)
3565 CryAutoCriticalSection
lock(m_lock
);
3569 CreateInstance(pSrc
, m_layoutName
.c_str());
3573 if (m_canDeactivate
)
3575 SAFE_RELEASE(m_pPlayer
);
3580 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::CreateInstance(CFlashTextureSourceBase
* pSrc
, const char* layoutName
)
3582 UIFramework::IUIFramework
* pUIFramework
= gEnv
->pUIFramework
;
3585 char name
[_MAX_PATH
];
3586 cry_strcpy(name
, layoutName
);
3587 PathUtil::RemoveExtension(name
);
3588 const char* pExt
= fpGetExtension(layoutName
);
3589 if (!pExt
|| strcmpi(pExt
, ".layout") != 0)
3594 if (pUIFramework
->LoadLayout(name
) != INVALID_LAYOUT_ID
)
3596 m_layoutName
= name
;
3597 m_pUILayout
= pUIFramework
->GetLayoutBase(m_layoutName
);
3600 m_pPlayer
= m_pUILayout
->GetPlayer();
3604 pSrc
->m_autoUpdate
= !m_pPlayer
->HasMetadata("CE_NoAutoUpdate");
3606 #if defined(ENABLE_DYNTEXSRC_PROFILING)
3607 m_pPlayer
->LinkDynTextureSource(pSrc
);
3609 m_pPlayer
->Advance(0.0f
);
3610 m_width
= m_pPlayer
->GetWidth();
3611 m_height
= m_pPlayer
->GetHeight();
3618 const char* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::GetSourceFilePath() const
3620 return m_pPlayer
? m_pPlayer
->GetFilePath() : "UNDEFINED";
3623 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperLayoutElement::Advance(float delta
)
3626 m_pPlayer
->Advance(delta
);
3629 CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::~CFlashPlayerInstanceWrapperUIElement()
3631 SAFE_RELEASE(m_pUIElement
);
3632 SAFE_RELEASE(m_pPlayer
);
3635 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::SetUIElement(IUIElement
* p
)
3637 assert(!m_pUIElement
);
3639 m_pUIElement
->AddRef();
3642 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::GetTempPtr() const
3644 CryAutoCriticalSection
lock(m_lock
);
3647 m_pPlayer
->AddRef();
3652 IFlashPlayer
* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::GetPermPtr(CFlashTextureSourceBase
* pSrc
)
3654 CryAutoCriticalSection
lock(m_lock
);
3656 m_canDeactivate
= false;
3658 UpdateUIElementPlayer(pSrc
);
3663 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::Activate(bool activate
, CFlashTextureSourceBase
* pSrc
)
3665 CryAutoCriticalSection
lock(m_lock
);
3667 m_activated
= m_canDeactivate
? activate
: m_activated
;
3668 UpdateUIElementPlayer(pSrc
);
3671 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::Clear(CFlashTextureSourceBase
* pSrc
)
3673 CryAutoCriticalSection
lock(m_lock
);
3675 if (m_pUIElement
&& m_pPlayer
)
3676 m_pUIElement
->RemoveTexture(pSrc
);
3678 SAFE_RELEASE(m_pPlayer
);
3681 const char* CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::GetSourceFilePath() const
3683 return m_pUIElement
? m_pUIElement
->GetFlashFile() : "UNDEFINED";
3686 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::UpdatePlayer(CFlashTextureSourceBase
* pSrc
)
3688 CryAutoCriticalSection
lock(m_lock
);
3690 UpdateUIElementPlayer(pSrc
);
3693 void CFlashTextureSourceBase::CFlashPlayerInstanceWrapperUIElement::UpdateUIElementPlayer(CFlashTextureSourceBase
* pSrc
)
3699 const bool isVisible
= m_pUIElement
->IsVisible();
3700 IFlashPlayer
* pPlayer
= isVisible
? m_pUIElement
->GetFlashPlayer() : NULL
;
3701 if (pPlayer
!= m_pPlayer
)
3703 assert(gRenDev
->m_pRT
->IsMainThread());
3705 const bool addTex
= m_pPlayer
== NULL
;
3706 SAFE_RELEASE(m_pPlayer
);
3708 m_pPlayer
= pPlayer
;
3712 m_width
= m_pPlayer
->GetWidth();
3713 m_height
= m_pPlayer
->GetHeight();
3714 m_pPlayer
->AddRef();
3716 m_pUIElement
->AddTexture(pSrc
);
3719 m_pUIElement
->RemoveTexture(pSrc
);
3724 assert(gRenDev
->m_pRT
->IsMainThread());
3727 m_pUIElement
->RemoveTexture(pSrc
);
3728 SAFE_RELEASE(m_pPlayer
);
3733 CFlashTextureSourceBase::CFlashTextureSourceBase(const char* pFlashFileName
, const IRenderer::SLoadShaderItemArgs
* pArgs
)
3736 , m_lastVisibleFrameID(0)
3739 , m_aspectRatio(1.0f
)
3741 , m_autoUpdate(true)
3742 , m_pFlashFileName(pFlashFileName
)
3743 , m_perFrameRendering(false)
3744 , m_pFlashPlayer(CFlashPlayerInstanceWrapperNULL::Get())
3746 #if defined(ENABLE_DYNTEXSRC_PROFILING)
3747 , m_pMatSrc(pArgs
? pArgs
->m_pMtlSrc
: 0)
3748 , m_pMatSrcParent(pArgs
? pArgs
->m_pMtlSrcParent
: 0)
3755 if (IsFlashUIFile(pFlashFileName
))
3757 valid
= CreateTexFromFlashFile(pFlashFileName
);
3760 gEnv
->pFlashUI
->RegisterModule(this, pFlashFileName
);
3763 else if (IsFlashUILayoutFile(pFlashFileName
))
3766 m_pFlashPlayer
->Clear(this);
3768 SAFE_RELEASE(m_pFlashPlayer
);
3770 CFlashPlayerInstanceWrapperLayoutElement
* pInstanceWrapper
= new CFlashPlayerInstanceWrapperLayoutElement();
3771 pInstanceWrapper
->CreateInstance(this, pFlashFileName
);
3772 m_pFlashPlayer
= pInstanceWrapper
;
3777 IFlashPlayerBootStrapper
* pBootStrapper
= gEnv
->pScaleformHelper
? gEnv
->pScaleformHelper
->CreateFlashPlayerBootStrapper() : nullptr;
3780 if (pBootStrapper
->Load(pFlashFileName
))
3782 m_autoUpdate
= !pBootStrapper
->HasMetadata("CE_NoAutoUpdate");
3784 CFlashPlayerInstanceWrapper
* pInstanceWrapper
= new CFlashPlayerInstanceWrapper();
3785 pInstanceWrapper
->SetBootStrapper(pBootStrapper
);
3786 pInstanceWrapper
->CreateInstance(this);
3787 m_pFlashPlayer
= pInstanceWrapper
;
3792 SAFE_RELEASE(pBootStrapper
);
3798 for (size_t i
= 0; i
< NumCachedTexStateIDs
; ++i
)
3800 m_texStateIDs
[i
].original
= EDefaultSamplerStates::Unspecified
;
3801 m_texStateIDs
[i
].patched
= EDefaultSamplerStates::Unspecified
;
3804 if (valid
&& m_autoUpdate
)
3805 FlashTextureSourceSharedRT_AutoUpdate::Add(this);
3808 bool CFlashTextureSourceBase::IsFlashFile(const char* pFlashFileName
)
3812 const char* pExt
= fpGetExtension(pFlashFileName
);
3813 const bool bPath
= strchr(pFlashFileName
, '/') || strchr(pFlashFileName
, '\\');
3819 // Pseudo files (no path, looks up flow-node)
3820 return (!stricmp(pExt
, ".ui"));
3823 // Real files (looks up filesystem)
3824 return (!stricmp(pExt
, ".layout") || !stricmp(pExt
, ".gfx") || !stricmp(pExt
, ".swf") || !stricmp(pExt
, ".usm"));
3831 bool CFlashTextureSourceBase::IsFlashUIFile(const char* pFlashFileName
)
3835 const char* pExt
= fpGetExtension(pFlashFileName
);
3836 const bool bPath
= strchr(pFlashFileName
, '/') || strchr(pFlashFileName
, '\\');
3842 // Pseudo files (no path, looks up flow-node)
3843 return !stricmp(pExt
, ".ui");
3851 bool CFlashTextureSourceBase::IsFlashUILayoutFile(const char* pFlashFileName
)
3855 const char* pExt
= fpGetExtension(pFlashFileName
);
3859 return !stricmp(pExt
, ".layout");
3866 bool CFlashTextureSourceBase::DestroyTexOfFlashFile(const char* name
)
3870 IUIElement
* pElement
= gEnv
->pFlashUI
->GetUIElementByInstanceStr(name
);
3874 pElement
->DestroyThis();
3882 bool CFlashTextureSourceBase::CreateTexFromFlashFile(const char* name
)
3888 m_pFlashPlayer
->Clear(this);
3889 SAFE_RELEASE(m_pFlashPlayer
);
3891 m_pElement
= gEnv
->pFlashUI
->GetUIElementByInstanceStr(name
);
3894 CFlashPlayerInstanceWrapperUIElement
* pInstanceWrapper
= new CFlashPlayerInstanceWrapperUIElement();
3895 m_pElement
->SetVisible(true);
3896 pInstanceWrapper
->SetUIElement(m_pElement
);
3897 pInstanceWrapper
->Activate(true, this);
3898 m_pFlashPlayer
= pInstanceWrapper
;
3906 CFlashTextureSourceBase::~CFlashTextureSourceBase()
3908 FlashTextureSourceSharedRT_AutoUpdate::Remove(this);
3910 if (m_pElement
) // If module registration happened m_pElement is set
3912 gEnv
->pFlashUI
->UnregisterModule(this);
3916 m_pFlashPlayer
->Clear(this);
3918 SAFE_RELEASE(m_pFlashPlayer
);
3921 void CFlashTextureSourceBase::AddRef()
3923 CryInterlockedIncrement(&m_refCount
);
3926 void CFlashTextureSourceBase::Release()
3928 long refCnt
= CryInterlockedDecrement(&m_refCount
);
3933 void CFlashTextureSourceBase::Activate(bool activate
)
3935 m_pFlashPlayer
->Activate(activate
, this);
3938 #if defined(ENABLE_DYNTEXSRC_PROFILING)
3939 string
CFlashTextureSourceBase::GetProfileInfo() const
3942 const char* pMtlName
= "NULL";
3943 if (m_pMatSrc
|| m_pMatSrcParent
)
3945 if (m_pMatSrcParent
)
3947 if (m_pMatSrcParent
->GetName())
3948 pMtlName
= m_pMatSrcParent
->GetName();
3952 if (m_pMatSrc
->GetName())
3953 pMtlName
= m_pMatSrc
->GetName();
3957 const char* pSubMtlName
= "NULL";
3958 if (m_pMatSrcParent
)
3962 if (m_pMatSrc
->GetName())
3963 pSubMtlName
= m_pMatSrc
->GetName();
3971 CryFixedStringT
<128> info
;
3972 info
.Format("mat: %s%s%s%s", pMtlName
, pSubMtlName
? "|sub: " : "", pSubMtlName
? pSubMtlName
: "", !m_pFlashPlayer
->CanDeactivate() ? "|$4can't be deactivated!$O" : "");
3974 return info
.c_str();
3978 void* CFlashTextureSourceBase::GetSourceTemp(EDynTextureSource type
) const
3980 if (m_pFlashPlayer
!= nullptr && type
== DTS_I_FLASHPLAYER
)
3982 return m_pFlashPlayer
->GetTempPtr();
3987 void* CFlashTextureSourceBase::GetSourcePerm(EDynTextureSource type
)
3989 if (m_pFlashPlayer
!= nullptr && type
== DTS_I_FLASHPLAYER
)
3991 return m_pFlashPlayer
->GetPermPtr(this);
3996 const char* CFlashTextureSourceBase::GetSourceFilePath() const
3998 if (m_pFlashPlayer
!= nullptr)
4000 return m_pFlashPlayer
->GetSourceFilePath();
4005 bool CFlashTextureSourceBase::Apply(int nTUnit
, SamplerStateHandle nTS
)
4007 SDynTexture
* pDynTexture
= GetDynTexture();
4008 assert(pDynTexture
);
4009 if (!m_pFlashPlayer
|| !m_pFlashPlayer
->CheckPtr() || !pDynTexture
)
4012 SamplerStateHandle patchedTexStateID
= EDefaultSamplerStates::Unspecified
;
4015 for (; i
< NumCachedTexStateIDs
; ++i
)
4017 if (m_texStateIDs
[i
].original
== EDefaultSamplerStates::Unspecified
)
4020 if (m_texStateIDs
[i
].original
== nTS
)
4022 patchedTexStateID
= m_texStateIDs
[i
].patched
;
4023 assert(patchedTexStateID
!= EDefaultSamplerStates::Unspecified
);
4028 if (patchedTexStateID
== EDefaultSamplerStates::Unspecified
)
4030 SSamplerState State
= CDeviceObjectFactory::LookupSamplerState(nTS
).first
;
4031 State
.m_bSRGBLookup
= true;
4032 patchedTexStateID
= CDeviceObjectFactory::GetOrCreateSamplerStateHandle(State
);
4034 if (i
< NumCachedTexStateIDs
)
4036 m_texStateIDs
[i
].original
= nTS
;
4037 m_texStateIDs
[i
].patched
= patchedTexStateID
;
4041 pDynTexture
->Apply(nTUnit
, patchedTexStateID
);
4045 void CFlashTextureSourceBase::GetTexGenInfo(float& offsX
, float& offsY
, float& scaleX
, float& scaleY
) const
4047 SDynTexture
* pDynTexture
= GetDynTexture();
4048 assert(pDynTexture
);
4049 if (!pDynTexture
|| !pDynTexture
->IsValid())
4058 ITexture
* pSrcTex
= pDynTexture
->GetTexture();
4059 float invSrcWidth
= 1.0f
/ (float) pSrcTex
->GetWidth();
4060 float invSrcHeight
= 1.0f
/ (float) pSrcTex
->GetHeight();
4063 assert(m_width
<= pDynTexture
->m_nWidth
&& m_height
<= pDynTexture
->m_nHeight
);
4064 scaleX
= m_width
* invSrcWidth
;
4065 scaleY
= m_height
* invSrcHeight
;
4068 //////////////////////////////////////////////////////////////////////////
4069 CFlashTextureSource::CFlashTextureSource(const char* pFlashFileName
, const IRenderer::SLoadShaderItemArgs
* pArgs
)
4070 : CFlashTextureSourceBase(pFlashFileName
, pArgs
)
4072 // create render-target with mip-maps
4073 m_pDynTexture
= new SDynTexture(GetWidth(), GetHeight(), eTF_R8G8B8A8
, eTT_2D
, FT_USAGE_RENDERTARGET
| FT_STATE_CLAMP
| FT_FORCE_MIPS
| FT_USAGE_ALLOWREADSRGB
, "FlashTextureSourceUniqueRT");
4074 m_pMipMapper
= nullptr;
4077 CFlashTextureSource::~CFlashTextureSource()
4079 SAFE_DELETE(m_pMipMapper
);
4080 SAFE_DELETE(m_pDynTexture
);
4083 int CFlashTextureSource::GetWidth() const
4085 IFlashPlayerInstanceWrapper
* pFlash
= GetFlashPlayerInstanceWrapper();
4086 return pFlash
? max(Align8(pFlash
->GetWidth()), 16) : 16;
4089 int CFlashTextureSource::GetHeight() const
4091 IFlashPlayerInstanceWrapper
* pFlash
= GetFlashPlayerInstanceWrapper();
4092 return pFlash
? max(Align8(pFlash
->GetHeight()), 16) : 16;
4095 bool CFlashTextureSource::UpdateDynTex(int rtWidth
, int rtHeight
)
4097 bool needResize
= rtWidth
!= m_pDynTexture
->m_nWidth
|| rtHeight
!= m_pDynTexture
->m_nHeight
|| !m_pDynTexture
->IsValid();
4100 if (!m_pDynTexture
->Update(rtWidth
, rtHeight
))
4106 //////////////////////////////////////////////////////////////////////////
4107 SDynTexture
* CFlashTextureSourceSharedRT::ms_pDynTexture
= nullptr;
4108 CMipmapGenPass
* CFlashTextureSourceSharedRT::ms_pMipMapper
= nullptr;
4109 int CFlashTextureSourceSharedRT::ms_instCount
= 0;
4110 int CFlashTextureSourceSharedRT::ms_sharedRTWidth
= 256;
4111 int CFlashTextureSourceSharedRT::ms_sharedRTHeight
= 256;
4113 CFlashTextureSourceSharedRT::CFlashTextureSourceSharedRT(const char* pFlashFileName
, const IRenderer::SLoadShaderItemArgs
* pArgs
)
4114 : CFlashTextureSourceBase(pFlashFileName
, pArgs
)
4117 if (!ms_pDynTexture
)
4119 // create render-target with mip-maps
4120 ms_pDynTexture
= new SDynTexture(ms_sharedRTWidth
, ms_sharedRTHeight
, eTF_R8G8B8A8
, eTT_2D
, FT_USAGE_RENDERTARGET
| FT_STATE_CLAMP
| FT_FORCE_MIPS
| FT_USAGE_ALLOWREADSRGB
, "FlashTextureSourceSharedRT");
4121 ms_pMipMapper
= nullptr;
4125 CFlashTextureSourceSharedRT::~CFlashTextureSourceSharedRT()
4128 if (ms_instCount
<= 0)
4130 SAFE_DELETE(ms_pMipMapper
);
4131 SAFE_DELETE(ms_pDynTexture
);
4135 int CFlashTextureSourceSharedRT::GetSharedRTWidth()
4137 return CRenderer::CV_r_DynTexSourceSharedRTWidth
> 0 ? Align8(max(CRenderer::CV_r_DynTexSourceSharedRTWidth
, 16)) : ms_sharedRTWidth
;
4140 int CFlashTextureSourceSharedRT::GetSharedRTHeight()
4142 return CRenderer::CV_r_DynTexSourceSharedRTHeight
> 0 ? Align8(max(CRenderer::CV_r_DynTexSourceSharedRTHeight
, 16)) : ms_sharedRTHeight
;
4145 int CFlashTextureSourceSharedRT::NearestPowerOfTwo(int n
)
4155 return (k
- n
) <= (n
- (k
>> 1)) ? k
: (k
>> 1);
4158 void CFlashTextureSourceSharedRT::SetSharedRTDim(int width
, int height
)
4160 ms_sharedRTWidth
= NearestPowerOfTwo(width
> 16 ? width
: 16);
4161 ms_sharedRTHeight
= NearestPowerOfTwo(height
> 16 ? height
: 16);
4164 void CFlashTextureSourceSharedRT::SetupSharedRenderTargetRT()
4168 const int rtWidth
= GetSharedRTWidth();
4169 const int rtHeight
= GetSharedRTHeight();
4170 bool needResize
= rtWidth
!= ms_pDynTexture
->m_nWidth
|| rtHeight
!= ms_pDynTexture
->m_nHeight
;
4171 if (!ms_pDynTexture
->IsValid() || needResize
)
4173 ms_pDynTexture
->Update(rtWidth
, rtHeight
);
4174 ms_pDynTexture
->SetUpdateMask();
4176 CTexture
* pTex
= (CTexture
*) ms_pDynTexture
->GetTexture();
4177 // prevent leak, this code is only needed on D3D11 to force texture creating
4179 pTex
->GetSurface(-1, 0);
4180 ProbeDepthStencilSurfaceCreation(rtWidth
, rtHeight
);
4185 //////////////////////////////////////////////////////////////////////////
4186 CDynTextureSourceLayerActivator::PerLayerDynSrcMtls
CDynTextureSourceLayerActivator::s_perLayerDynSrcMtls
;
4188 void CDynTextureSourceLayerActivator::LoadLevelInfo()
4192 const char* pLevelPath
= iSystem
->GetI3DEngine()->GetLevelFilePath("dyntexsrclayeract.xml");
4194 XmlNodeRef root
= iSystem
->LoadXmlFromFile(pLevelPath
);
4197 const int numLayers
= root
->getChildCount();
4198 for (int curLayer
= 0; curLayer
< numLayers
; ++curLayer
)
4200 XmlNodeRef layer
= root
->getChild(curLayer
);
4203 const char* pLayerName
= layer
->getAttr("Name");
4206 const int numMtls
= layer
->getChildCount();
4208 std::vector
<string
> mtls
;
4209 mtls
.reserve(numMtls
);
4211 for (int curMtl
= 0; curMtl
< numMtls
; ++curMtl
)
4213 XmlNodeRef mtl
= layer
->getChild(curMtl
);
4216 const char* pMtlName
= mtl
->getAttr("Name");
4218 mtls
.push_back(pMtlName
);
4222 s_perLayerDynSrcMtls
.insert(PerLayerDynSrcMtls::value_type(pLayerName
, mtls
));
4229 void CDynTextureSourceLayerActivator::ReleaseData()
4231 stl::reconstruct(s_perLayerDynSrcMtls
);
4234 void CDynTextureSourceLayerActivator::ActivateLayer(const char* pLayerName
, bool activate
)
4236 PerLayerDynSrcMtls::const_iterator it
= pLayerName
? s_perLayerDynSrcMtls
.find(pLayerName
) : s_perLayerDynSrcMtls
.end();
4237 if (it
!= s_perLayerDynSrcMtls
.end())
4239 const std::vector
<string
>& mtls
= (*it
).second
;
4240 const size_t numMtls
= mtls
.size();
4242 const IMaterialManager
* pMatMan
= gEnv
->p3DEngine
->GetMaterialManager();
4244 for (size_t i
= 0; i
< numMtls
; ++i
)
4246 const char* pMtlName
= mtls
[i
].c_str();
4247 IMaterial
* pMtl
= pMatMan
->FindMaterial(pMtlName
);
4250 pMtl
->ActivateDynamicTextureSources(activate
);
4256 //////////////////////////////////////////////////////////////////////////
4257 void CRenderer::EF_AddRTStat(CTexture
* pTex
, int nFlags
, int nW
, int nH
)
4269 nSize
= CTexture::TextureDataSize(nW
, nH
, 1, 1, 1, eTF
);
4270 TS
.m_Name
= "Back buffer";
4274 eTF
= pTex
->GetDstFormat();
4276 nW
= pTex
->GetWidth();
4278 nH
= pTex
->GetHeight();
4279 nSize
= CTexture::TextureDataSize(nW
, nH
, 1, pTex
->GetNumMips(), 1, eTF
);
4280 const char* szName
= pTex
->GetName();
4281 if (szName
&& szName
[0] == '$')
4282 TS
.m_Name
= string("@") + string(&szName
[1]);
4291 TS
.m_Name
+= " (Target)";
4292 else if (nFlags
== 2)
4294 TS
.m_Name
+= " (Depth)";
4295 nSize
= nW
* nH
* 3;
4297 else if (nFlags
== 4)
4299 TS
.m_Name
+= " (Stencil)";
4302 else if (nFlags
== 3)
4304 TS
.m_Name
+= " (Target + Depth)";
4305 nSize
+= nW
* nH
* 3;
4307 else if (nFlags
== 6)
4309 TS
.m_Name
+= " (Depth + Stencil)";
4310 nSize
= nW
* nH
* 4;
4312 else if (nFlags
== 5)
4314 TS
.m_Name
+= " (Target + Stencil)";
4317 else if (nFlags
== 7)
4319 TS
.m_Name
+= " (Target + Depth + Stencil)";
4320 nSize
+= nW
* nH
* 4;
4331 m_RP
.m_RTStats
.push_back(TS
);
4334 void CRenderer::EF_PrintRTStats(const char* szName
)
4336 const int nYstep
= 14;
4337 int nY
= 30; // initial Y pos
4338 int nX
= 20; // initial X pos
4339 ColorF col
= Col_Green
;
4340 IRenderAuxText::Draw2dLabel((float)nX
, (float)nY
, 1.6f
, &col
.r
, false, "%s", szName
);
4347 for (int i
= 0; i
< m_RP
.m_RTStats
.size(); i
++)
4349 SRTargetStat
* pRT
= &m_RP
.m_RTStats
[i
];
4351 IRenderAuxText::Draw2dLabel((float)nX
, (float)nY
, 1.4f
, &col
.r
, false, "%s (%d x %d x %s), Size: %.3f Mb", pRT
->m_Name
.c_str(), pRT
->m_nWidth
, pRT
->m_nHeight
, CTexture::NameForTextureFormat(pRT
->m_eTF
), (float)pRT
->m_nSize
/ 1024.0f
/ 1024.0f
);
4353 if (nY
>= m_height
- 25)
4358 nSize
+= pRT
->m_nSize
;
4361 IRenderAuxText::Draw2dLabel((float)nX
, (float)(nY
+ 10), 1.4f
, &col
.r
, false, "Total: %d RT's, Size: %.3f Mb", m_RP
.m_RTStats
.size(), nSize
/ 1024.0f
/ 1024.0f
);
4364 STexPool::~STexPool()
4366 bool poolEmpty
= true;
4367 STexPoolItemHdr
* pITH
= m_ItemsList
.m_Next
;
4368 while (pITH
!= &m_ItemsList
)
4370 STexPoolItemHdr
* pNext
= pITH
->m_Next
;
4371 STexPoolItem
* pIT
= static_cast<STexPoolItem
*>(pITH
);
4373 assert(pIT
->m_pOwner
== this);
4375 CryLogAlways("***** Texture %p (%s) still in pool %p! Memory leak and crash will follow *****\n", pIT
->m_pTex
, pIT
->m_pTex
? pIT
->m_pTex
->GetName() : "NULL", this);
4380 pIT
->m_pTex
->ReleaseDeviceTexture(true); // Try to recover in release
4383 *const_cast<STexPool
**>(&pIT
->m_pOwner
) = NULL
;
4386 CRY_ASSERT_MESSAGE(poolEmpty
, "Texture pool was not empty on shutdown");
4389 const ETEX_Type
CTexture::GetTextureType() const
4394 const int CTexture::GetTextureID() const
4399 #ifdef TEXTURE_GET_SYSTEM_COPY_SUPPORT
4401 const ColorB
* CTexture::GetLowResSystemCopy(uint16
& nWidth
, uint16
& nHeight
, int** ppLowResSystemCopyAtlasId
)
4403 const LowResSystemCopyType::iterator
& it
= s_LowResSystemCopy
.find(this);
4404 if (it
!= CTexture::s_LowResSystemCopy
.end())
4406 nWidth
= (*it
).second
.m_nLowResCopyWidth
;
4407 nHeight
= (*it
).second
.m_nLowResCopyHeight
;
4408 *ppLowResSystemCopyAtlasId
= &(*it
).second
.m_nLowResSystemCopyAtlasId
;
4409 return (*it
).second
.m_lowResSystemCopy
.GetElements();
4416 #define eTF_BC1 eTF_DXT1
4417 #define eTF_BC2 eTF_DXT3
4418 #define eTF_BC3 eTF_DXT5
4421 void CTexture::PrepareLowResSystemCopy(byte
* pTexData
, bool bTexDataHasAllMips
)
4423 if (m_eTT
!= eTT_2D
|| (m_nMips
<= 1 && (m_nWidth
> 16 || m_nHeight
> 16)))
4426 // this function handles only compressed textures for now
4427 if (m_eDstFormat
!= eTF_BC3
&& m_eDstFormat
!= eTF_BC1
&& m_eDstFormat
!= eTF_BC2
&& m_eDstFormat
!= eTF_BC7
)
4430 // make sure we skip non diffuse textures
4431 if (strstr(GetName(), "_ddn")
4432 || strstr(GetName(), "_ddna")
4433 || strstr(GetName(), "_mask")
4434 || strstr(GetName(), "_spec.")
4435 || strstr(GetName(), "_gloss")
4436 || strstr(GetName(), "_displ")
4437 || strstr(GetName(), "characters")
4438 || strstr(GetName(), "$")
4444 SLowResSystemCopy
& rSysCopy
= s_LowResSystemCopy
[this];
4446 rSysCopy
.m_nLowResCopyWidth
= m_nWidth
;
4447 rSysCopy
.m_nLowResCopyHeight
= m_nHeight
;
4452 while ((rSysCopy
.m_nLowResCopyWidth
> 16 || rSysCopy
.m_nLowResCopyHeight
> 16 || nMipId
< 2) && (rSysCopy
.m_nLowResCopyWidth
>= 8 && rSysCopy
.m_nLowResCopyHeight
>= 8))
4454 nSrcOffset
+= TextureDataSize(rSysCopy
.m_nLowResCopyWidth
, rSysCopy
.m_nLowResCopyHeight
, 1, 1, 1, m_eDstFormat
);
4455 rSysCopy
.m_nLowResCopyWidth
/= 2;
4456 rSysCopy
.m_nLowResCopyHeight
/= 2;
4460 int nSizeDxtMip
= TextureDataSize(rSysCopy
.m_nLowResCopyWidth
, rSysCopy
.m_nLowResCopyHeight
, 1, 1, 1, m_eDstFormat
);
4461 int nSizeRgbaMip
= TextureDataSize(rSysCopy
.m_nLowResCopyWidth
, rSysCopy
.m_nLowResCopyHeight
, 1, 1, 1, eTF_R8G8B8A8
);
4463 rSysCopy
.m_lowResSystemCopy
.CheckAllocated(nSizeRgbaMip
/ sizeof(ColorB
));
4465 gRenDev
->DXTDecompress(pTexData
+ (bTexDataHasAllMips
? nSrcOffset
: 0), nSizeDxtMip
,
4466 (byte
*)rSysCopy
.m_lowResSystemCopy
.GetElements(), rSysCopy
.m_nLowResCopyWidth
, rSysCopy
.m_nLowResCopyHeight
, 1, m_eDstFormat
, false, 4);
4470 #endif // TEXTURE_GET_SYSTEM_COPY_SUPPORT
4472 void CTexture::AddInvalidateCallback(void* listener
, const SResourceBinding::InvalidateCallbackFunction
& callback
)
4474 AUTO_LOCK_T(CryCriticalSectionNonRecursive
, s_invalidationLock
);
4476 #if !CRY_PLATFORM_ORBIS || defined(__GXX_RTTI)
4477 CRY_ASSERT(callback
.target
<SResourceBinding::InvalidateCallbackSignature
*>() != nullptr);
4480 auto insertResult
= m_invalidateCallbacks
.emplace(listener
, callback
);
4481 ++insertResult
.first
->second
.refCount
;
4483 // We only allow one callback function per listener
4484 #if !CRY_PLATFORM_ORBIS || defined(__GXX_RTTI)
4485 CRY_ASSERT(*callback
.target
<SResourceBinding::InvalidateCallbackSignature
*>() == *insertResult
.first
->second
.callback
.target
<SResourceBinding::InvalidateCallbackSignature
*>());
4489 void CTexture::RemoveInvalidateCallbacks(void* listener
)
4491 AUTO_LOCK_T(CryCriticalSectionNonRecursive
, s_invalidationLock
);
4493 auto it
= m_invalidateCallbacks
.find(listener
);
4495 if (it
!= m_invalidateCallbacks
.end())
4497 if (--it
->second
.refCount
<= 0)
4498 m_invalidateCallbacks
.erase(listener
);
4502 void CTexture::InvalidateDeviceResource(uint32 dirtyFlags
)
4504 AUTO_LOCK_T(CryCriticalSectionNonRecursive
, s_invalidationLock
);
4506 for (auto it
= m_invalidateCallbacks
.begin(), end
= m_invalidateCallbacks
.end(); it
!= end
;)
4508 auto itCurrentCallback
= it
++;
4509 if (itCurrentCallback
->second
.callback(itCurrentCallback
->first
, dirtyFlags
) == false)
4510 m_invalidateCallbacks
.erase(itCurrentCallback
);